Archive · Tranche 2

The changelog — a hundred days, in order

Day by day, what changed and why — written as prose rather than commit messages. The single best record of how the project's thinking moved, including the days it talked itself out of something.

Original title
Changelog
Original date
9 May – 28 June 2026
Project phase
Whole campaign
Purpose at the time
Keep a plain-language record of what changed and the reasoning behind it, so decisions could be revisited without archaeology.
Status at the time
Live working document, written as the work happened. It stops in late June; the final six weeks are recorded in the sprint kit and the issue history instead.
Source provenance
Derived from internal/changelog.md (private working corpus; unpublished, unchanged).
Publication treatment
Substantially intact
Derived / prepared by
Claude (Fable 5) with Adrian Wedd, 18 August 2026
Prepared
2026-08-18
Human review
Adrian Wedd — publication review completed 19 August 2026
Published
2026-08-19
What was changed for publication
  • Attribution follows one rule: public role and public history keep the steering group lead's name; private deliberation does not. Where the changelog recorded him doing something already on the public record — speaking at the community meeting, the correction that it is Billie and not Billy — the name stands, and anonymising a person who was genuinely public would be a false courtesy. Where it recorded decision-making input that was never public — how a form label read to him, his confirmation that a professional check had cleared, an overnight request to change the surveys, his weighting of a survey question — the entry is generalised to "the steering lead" or "the steering group". The decision itself and its reasoning are kept in full in every case; only the named attribution of private judgement is removed. This was applied by the archive reviewer and did not require the individual's separate consent.
  • One generalisation. An entry recorded that a specific working-group member held a particular professional qualification, which cleared a gate on the community loan tier. In a town this size that is an identification of an unnamed third party. The fact that a professional check cleared the gate is kept; the attribution is removed.
  • The changelog stops on 28 June 2026. That is not an editorial cut — it is where the document stops. The last six weeks of the campaign happened under deadline pressure and were recorded in the sprint kit rather than here.
  • Technical entries about the website build are kept in full. They are a large fraction of where the effort actually went, and cutting them to make the project look purely civic would misrepresent it.

Document begins

What’s been happening

A running account of how this project has grown — what we built, why we built it, and what we learned along the way.


28 June 2026 — The site stops sounding afraid of itself

A pattern had crept across the public pages: every new clause of copy came with its own hedge. “Subject to feasibility.” “Nothing here is final or adopted.” “Not a financial offer.” “Nothing has been decided, committed, or purchased.” Each individual hedge was defensible in isolation; stacked four-deep at the top of every page, they produced the opposite of reassurance. A first-time visitor reading the site could reasonably conclude the community wasn’t serious about any of this — not because the hedges were wrong, but because a project that keeps reminding you nothing has been decided starts to sound like it doesn’t believe in itself.

A three-agent tone audit (hermes, codex, agy) named this explicitly: over-reassurance clustering, and the symptom that the site sounded afraid of itself. The fix was structural rather than cosmetic. Legal substance — “no money should be sent,” “confirmed in writing before anyone is asked to commit,” “these are drafts not the final instrument” — stays, said once, in one place per page. Everything else leads with the community story.

On /faq/, the lede dropped the triple negative (“nothing decided, committed, or purchased”) in favour of what is actually true: we’re in Stage 1, testing whether this is worth pursuing, here are honest answers. The property-status answer stopped reading like a legal brief and started reading like someone who knows what’s happening telling you about it. On /questions/, the disclaimer that had been living in the lede paragraph was moved to a single footer line where it belongs; the q8 loan answer stopped citing “final legal documents before anyone relies on them” and said instead what that means in practice; the q11 timeline answer dropped its five-clause hedge list. On /co-op/, three consecutive “these are drafts / not adopted / not a financial offer” paragraphs merged into one sentence; the draft banner stopped restating the disclaimer already printed on the face of the documents. On /pledge/, the legal notice shrank from four assertions to two — keeping both the substance and the brevity. On /community-voices/, the copy-paste permission statement (a genuine UX friction point — requiring people to transcribe a sentence verbatim into an email) became a natural instruction to mention consent in their own words.

The same session closed the /dashboard URL question: FAQ content moved to /faq/, and /dashboard now redirects to /admin/ — the actual project dashboard with live pledge data, kanban, and issue queue. The URL now matches what it says it is.


28 June 2026 — Steering feedback lands, and so does the loan tier

The steering lead sent the steering group’s first read of the live pledge form and homepage during this session, and the feedback changed several things at once.

The AI-generated community video came off the page. The concern wasn’t technical — the video worked, the poster image was good — it was contextual: AI-generated media is genuinely divisive right now, and the project does not need to give people a reason to discount it before they’ve heard the argument. The poster image stays as the Open Graph social card, which is a quieter use that doesn’t front-load the question.

The submit button became “Submit” rather than “Count me in.” This was the steering lead’s read on how the form’s audience would experience it: the more colourful label was landing as ambiguous about what the action actually does. People are already confused about whether an expression of interest is an email to someone or a formal record. The safer copy is the literal description of the action.

The closing date tightened to 1 July 2026 — one day earlier than the previous copy. The pledge data window and the EOI-to-Elders deadline are now aligned.

The biggest change was the loan tier. The steering lead confirmed that the necessary professional check had been made [attribution removed] — which cleared the gate that had been blocking the community loan section since the form was first designed. The gate existed because of a real risk: presenting a debt instrument publicly without proper disclosure framing could trigger the Corporations Act. That gate now has a human sign-off, and the LOAN_ENABLED environment variable on the standalone Worker was set to true the same session. Tier 3 — Community Loan — is live with four rate options (0%, 2%, 3%, 4%) and a plain-language “higher than 4%, please note your preferred rate” escape, all marked as indicative and subject to formal agreement. The working group’s own modelling had flagged community loans as more than half the anticipated funding; showing up to collect pledge data without the loan tier was structurally incomplete.

Across all of this, three agents (hermes, codex, agy) ran a combined voice-and-tone QA pass on both the pledge form and the homepage. The finding that mattered most was what might be called the over-reassurance paradox: the form had accumulated a dense ring of disclaimers — “no legal obligation,” “no money changes hands,” “not a financial commitment,” repeated in slightly different words three or four times in close proximity. The intent was to reassure; the effect was to sound like a scam trying not to sound like a scam. The fix was consolidation: one clear legal notice, stated once, then trust the reader to hold it while they engage with the actual content. The individual hedges were not wrong; the density was the problem.

A second QA pass (also three agents) swept the full set of public pages for SEO and structured data gaps. The practical outputs: the pledge page now carries the correct title (it had drifted back to “Final Pledge” in an earlier edit), the celebration video poster became the Open Graph image for social sharing, and the FAQ page on the site got a FAQPage JSON-LD schema so its Q&As are eligible for Google’s “People Also Ask” rich snippet treatment. FAQPage schema is a free win for a page that already contains clearly structured questions and answers — the only cost is marking up what’s already there.

The /dashboard URL, which had been hosting a short set of plain-language FAQ answers about property status and cost, was moved to /faq/ where it makes semantic sense. The /dashboard route now redirects to /admin/ — the actual project dashboard, with pledge data, kanban, and live issue counts. It is access-protected; if someone who is not on the steering group follows that link they will hit Cloudflare’s authentication prompt, which is the right behaviour rather than a dead end.


28 June 2026 — The pledge form goes live (quietly)

The working group now has a way to collect concrete financial intent — not survey bands, not “interested in contributing,” but actual amounts. The final pledge form landed at /pledge/ today, replacing the old feasibility survey that had been living at that URL since May.

The architecture was deliberate about what a Stage 1 pledge form should and should not do. It does not collect money, does not create a legal commitment, and does not imply the property is available or the co-op structure is settled. Every piece of text hedges correctly: “would be co-owners,” “subject to finalisation,” “pledge of intent, not a legal commitment,” “no money is being collected at this stage.” Three QA passes — one for cross-file consistency (field names, DB columns, ID references), one for technical security (CSRF, honeypot, consent chain, rate limiting), one for legal/guardrail compliance against the 12 non-negotiable checklist items — returned no BLOCK findings. The form’s success state was the item most at risk of accidentally implying membership had been granted; it reads instead as a receipt for recorded intent.

Underneath the form: a Cloudflare Worker (bottompub-submit-pledge) deployed as a standalone service, following the same pattern as the EOI and enquiry Workers, because Pages Functions cannot hold [[send_email]] bindings. The same source file serves both the Pages Function path (for immediate failover) and the standalone Worker (canonical production runtime for mail). A new pledges table in the shared D1 database, applied to production the same session. A membership milestone tracker, SVG timeline chart, pledge-size histogram, DGR preference distribution, and hero total panel in the admin vault at /admin/pledges — so steering can see the shape of intent as it accumulates, before any of it becomes capital.

The loan tier — which would allow supporters to pledge returnable debt rather than equity or donation — is intentionally absent from the live form. A server-side LOAN_ENABLED gate blocks any direct-POST attempts to store loan data until a solicitor confirms the tier can be publicly presented without triggering disclosure obligations under the Corporations Act. The UI slot is held open; the mechanism is in place; the human sign-off is what’s missing.

The /pledge-final/ draft review URL that the working group was using now 301-redirects to /pledge/. The /financial-survey/ path, which pointed at the old feasibility form, already redirected there — now /pledge-final/ does too.

The form is technically live but not community-deployed. Steering review is the gate before it goes out to the mailing list.


24 June 2026 — From “could this work?” to “what would make it work?”

The public story changed shape today. For the first few weeks the site had mostly been protecting the project from its own early enthusiasm: no overclaiming, no implied purchase, no promised returns, no pretending the hard parts were solved. That discipline still matters. But by late June the work no longer looked like a fragile thought experiment. There was media coverage to point to, a town-hall follow-up meeting on the calendar, public updates about the pledge signal approaching the million-dollar mark, and a working group producing draft co-operative rules rather than just talking about them.

So the news page caught up. It now carries the June media coverage — The Mercury and ABC Hobart Breakfast — alongside the working-group update and the community meeting notice. The page still does what it was built to do: log meaningful steps in plain language, without dressing them up. But the centre of gravity is different. The project is still at Stage 1, still not collecting money, still not making an offer; it is also visibly moving. That matters, because a community proposal can be harmed by overconfidence, but it can also be harmed by sounding as if it has already talked itself out of being possible.

The internal side caught up even more dramatically. The Access-protected vault stopped being a long list of documents and became a working cockpit: live tools first, then themed panels for status, people, governance, strategy, legal, finance, operating model, evidence, comms, technical work, and agents. Fifty-four tracked internal documents became findable by purpose instead of by memory. The renderer still uses an explicit allowlist — no directory walking, no accidental publication — but the experience now matches the scale of the work. If a steering member wants the accountant brief, the major-supporters kit, the feasibility draft, the guardrail checklist, or the EOI skills inventory, they no longer need to know where the source file lives.

Several of those documents are the reason the project can feel more possible without becoming less careful. The pre-feasibility draft gave the working group a structured place to test the business case against live assumptions. The finance assumptions book and EOI skills inventory made the human and capital signals easier to reason about, while explicitly labelling them as planning inputs rather than committed funds. The guardrail screening checklist turned the “don’t overclaim” rules into a practical publication check. The major-supporters strategy, kit, and prospect list moved the big-supporter conversation out of vibes and into segmented, risk-aware outreach.

A small public scaffold for working-group seats also appeared, intentionally unlinked. It is not a launch of named people or an implied board. It is a prepared surface for the moment when consented roles can be shown cleanly. That is the pattern this phase keeps repeating: prepare the public-facing frame before the public claim is ready to make.

The day ended with a healthier project posture. The work is no longer just defensive due diligence, and the changelog should not make it sound that way. The honest story is more hopeful than that: the community has given the working group enough reason to keep testing the path, and the working group has started building the machinery that could make a serious decision possible.


24 June 2026 — Briefing advisers we haven’t hired yet

The property’s expression-of-interest process closes 2 July, and that deadline reshaped the week. The working group decided to explore acquisition through a philanthropic returnable-deposit and exclusivity mechanism rather than competing in the open EOI with capital it does not have. That decision produced an eight-day operating kit — a critical path, a capital-stack scaffold, a donor approach pack, an Elders proposal draft, an evidence pack, and a due-diligence open-questions register — plus a new Topic G in the lawyer brief covering the deposit, exclusivity, and what the group can safely say before the deadline. All of it landed deliberately as working drafts, send-gated, kept out of the public vault.

The more interesting piece was what came next: we drafted the advisers’ answers before engaging the advisers. Two persona agents — one role-playing a careful Tasmanian co-op solicitor, one an NFP/co-op accountant — answered the lawyer brief (Topics A–G) and the accountant brief (structure, returns compliance, donor/deposit, tax) the way a cautious real adviser plausibly would. The point was never to substitute for advice; it was to anticipate the likely answers, rehearse the hard questions, and find the gaps in our own briefs before paying for the real thing. Each memo opens with an unmissable “this is an AI simulation, not advice” block, reasons only from the sources the brief itself cited, and refuses to invent a statutory section or a dollar figure it doesn’t have — writing “confirm against the current Act” exactly where a real adviser would. The legal memo’s single most useful output wasn’t an answer at all: it flagged that the brief never actually asks counsel about the residential-land contradiction in our title register, the highest false-statement risk we carry. The simulation found a hole in the brief.

Two QA lessons worth keeping. First, on the sprint kit: two independent reviewers (hermes and agy) read the full branch diff, and agy returned a “BLOCKERS” verdict on two numeric findings. Verified rather than obeyed, one was a real-but-trivial rounding nit and the other wasn’t a contradiction at all — two documents citing different, individually-labelled sources, which is exactly what they should do. The worthwhile wording nits both reviewers surfaced got applied; the false alarm got left alone. A “BLOCKERS” label is a claim to check, not an instruction to follow. Second, hermes — which had reliably returned “no final response” on agentic diff reviews three times before — produced a full, high-quality review this time, the difference being that the diff was fed inline in the prompt so it never needed a tool to fetch it. The fix for a flaky headless reviewer was to make the task non-agentic.

The two memos were then added to the Access-protected vault alongside the lawyer brief they answer, so steering can read brief and anticipated-answer side by side — with the vault listing itself leading on “AI-DRAFTED SIMULATION — not advice,” because the one way this goes wrong is someone mistaking a rehearsal for the real thing.


12 June 2026 — Sweeping up after the cutover

A post-cutover audit turned into a three-PR sprint, each one closing a different kind of debt the migration left behind.

The biggest was URL hygiene. The site now serves clean URLs — Cloudflare redirects /contact.html to /contact automatically — but the site’s own plumbing still spoke .html everywhere: twelve canonical tags, roughly sixty internal links, ten of fifteen static sitemap entries, the briefing renderer’s templates, even the service worker’s precache list. A canonical tag pointing at a URL that redirects away from itself sends crawlers a contradiction, and two of the nav’s links — Community and Contact — were paying a pointless redirect hop on every click. The sweep fixed all of it — each new URL shape verified against the live redirect targets rather than guessed — and bumped the service worker’s cache name so returning visitors drop any stale pre-cutover HTML they’re still carrying. The built site now contains zero live internal .html links, verified with a one-off grep across the entire build output, briefings and admin vault included. Deliberate exceptions: this changelog, the migration specs, and admin-vault prose that quotes old URLs keep their historical .html mentions, because they document what was true at the time.

The second PR tightened security headers: object-src 'none' on every CSP rule (nothing on the site uses plugins, so locking them out is free) and the preload token on HSTS. The preload token comes with a decision deliberately not made: submitting bottom.pub to the browser preload list is effectively permanent and commits every future subdomain to HTTPS forever, so the token is in place but the submission waits for a human call.

The third was accessibility. The CSS side of the site has respected prefers-reduced-motion for a while, but JavaScript-driven motion bypasses CSS entirely — all seven smooth-scroll calls and the homepage’s autoplaying hero video ignored the preference. Now scrolls jump instead of glide and the video pauses on its poster frame when a visitor has asked for reduced motion, including when they change the preference mid-visit. The contact form’s success panel also gained the aria-live announcement that its three sibling forms already had — it was the only one missing it, which is exactly the kind of inconsistency that creeps in when patterns are copied by hand.


10 June 2026 — The flip, and what only production could teach

The previous entry ended with the cutover “prepped but deliberately held.” It didn’t stay held long. The flip went through just after midday, and the migration branch — scaffold, nineteen pages, the deletion of the legacy tree — became what production serves.

Then came the most instructive half-hour of the whole migration. Three problems surfaced, all fixed the same afternoon, and each one was something no local build or preview could have shown us.

First, a redirect loop. The new build serves clean URLs, and Cloudflare automatically redirects the old .html forms to them. But three legacy rules in our _redirects file pointed the clean URLs back at their .html forms — each side bouncing the visitor to the other, forever. /privacy greeted browsers with ERR_TOO_MANY_REDIRECTS. The fix was deletion: the rules existed to do what Cloudflare now does on its own. The lesson got written into the file as a comment — under clean URLs, never add a rule whose target is the .html form of its source.

Second, a half-dressed footer. The migration hoisted the footer markup into the shared layout so every page renders it — but its styles had stayed behind in the homepage’s stylesheet. So the footer appeared styled on the homepage and as bare unstyled text everywhere else. Three pages also turned out to be rendering two footers — their own hand-written one plus the shared one — which is an accessibility violation on top of a visual bug. The styles moved into the shared stylesheet, the duplicates were removed.

Third — and this one had been silently lying to us for weeks — the cache headers. The footer fix deployed, and production still showed the unstyled footer. The origin had the new CSS; browsers were holding the old copy under a seven-day immutable cache header. Our _headers file had rules saying CSS and JS must be no-cache precisely to prevent this, but a catch-all /assets/* rule said immutable — and it turns out Cloudflare Pages doesn’t pick the most specific rule, or the last one. It concatenates every rule that matches, so our stylesheets were being served the contradictory instruction immutable, no-cache, and browsers were free to honour the stricter half. The fix wasn’t reordering anything (order doesn’t matter when everything concatenates) — it was deleting the catch-all entirely and enumerating per-extension rules that can never overlap. That catch-all had been masking every stable-named CSS or JS change since it was introduced. The sharper lesson was about verification: wrangler’s local simulation and real Cloudflare Pages disagree about how multi-rule headers combine, so header changes are now verified on a real preview deploy, never locally.

A migration’s preview can prove the pages are right. What it can’t prove is how the edge — redirects, caches, header resolution — behaves around them. That’s what the first half-hour in production was for.


9 June 2026 — The end of copy-paste HTML, actually

The plan from 4 June got executed. Nineteen pages that each carried their own copy of the nav, the footer, and the FOUC script now inherit all three from a single Astro layout. The thing we’d been hand-editing nineteen times is now edited once.

The migration ran in phases, and the interesting parts were the ones the plan didn’t fully anticipate. Phase 2 was parity — making the Astro output byte-for-byte faithful to the hand-written pages it replaced — and the QA pass that gated it caught a class of bug that’s invisible until you look for it. The skip-link — the accessibility shortcut that lets a keyboard user jump past the nav straight to the content — had been migrated with the wrong class name. The CSS rule that hides it until focus keys off .skip; the markup said skip-link. The result was a “Skip to main content” link sitting visible at the top of every single page. Three other parity fixes came out of the same pass: an og:url meta tag that was emitting empty on the one page without a canonical, a missing canonical on the design-system page, and the audit page’s hand-written social descriptions, which the generic template had flattened.

Phase 3 was the deletion, and this is where the 4 June prediction about the Content Security Policy paid off exactly as called. Removing the legacy site/ tree — fifty-three files — let us strip sixteen now-dead style-src hashes out of the _headers file. Astro had externalised every page’s styles into content-hashed CSS covered by style-src 'self', so the per-page fingerprints the old CSP tracked were pointing at nothing. The security file got shorter. The make check gate still runs on every push; it just has three inline hashes left to verify instead of nineteen — the FOUC script, the 404 page’s inline style, and one mermaid-boot script in the admin vault. A migration that touched every page in the project made the security boundary simpler, not more fragile.

Phase 4 — the production cutover — is prepped but deliberately held. The real risk in a static-site migration isn’t the build; it’s the service worker. Returning visitors carry a cached copy of the old asset manifest, and a stale worker will keep serving the pre-migration bundle long after the new one is live. So the service-worker cache version got bumped ahead of the flip, and a cutover runbook was written down rather than improvised: push, confirm the preview build is green, then change the one dashboard field that points the publish directory at dist/ instead of site/.

The QA itself was a small lesson in tooling. Three frontier reviewers — hermes, codex, and agy — were set on the branch to independently re-derive the CSP hash set, re-check deletion safety against a clean checkout, and hunt for the every-page regressions. Hermes came back clean and caught a tail of stale site/ path references in the docs. Codex and agy, launched the same way, sat for half an hour producing nothing — both had blocked waiting on an unclosed stdin in their non-interactive invocation (the fix was redirecting stdin from /dev/null), which reads as “still working” right up until you check that they’d burned zero CPU the whole time. Relaunched correctly, both finished in minutes and confirmed what hermes found: all three recomputed the same three live hashes independently, which is about as much confidence in a CSP change as you can buy. Codex turned up the last of the stale references — a design-system page still claiming “no Node.js build step” when the build now runs Astro and Pagefind, and a handful of method docs still pointing reviewers at deleted files. Those got repointed in the same session, which is what this entry is part of.


4 June 2026 — Planning the end of copy-paste HTML

The site has nineteen public pages. Each one has an identical nav, an identical footer, and an identical FOUC-prevention script in the head. Each one has been hand-edited every time the nav changed. This is fine at five pages and becomes a liability at twenty, which is where we’re headed.

Today the plan for fixing that got written down properly. EPIC-008 has been on the backlog for a while — migrate to Astro, define the layout once, inherit it everywhere — but “migrate to Astro” is not an implementation plan. So we wrote one.

The most important finding in the planning work wasn’t about Astro at all. It was about the Content Security Policy. The site runs a strict hash-based CSP: every inline <style> block on every page has a corresponding SHA-256 fingerprint in the _headers file, and a test suite (make check) verifies the match on every push. Astro’s default build mode inlines small stylesheets automatically, which would immediately invalidate all those hashes and break the gate.

The fix is a single config line — inlineStylesheets: 'never' — but it changes the whole architecture of the migration. With that setting, Astro moves every page’s <style> block into a separate CSS file. The per-page hash entries in _headers disappear entirely. The file gets simpler, not more complicated. The make check gate continues to work unchanged; it just has fewer things to verify.

The one inline element that genuinely has to stay inline is the FOUC prevention script — the tiny function that reads localStorage.getItem('bp.mode') before the first paint so the light/dark mode toggle doesn’t flicker. That script’s hash is already in the global /* rule. In Astro it gets marked is:inline, the content stays byte-identical, and the hash doesn’t change.

The other scope question was about what doesn’t migrate. Two parts of the site aren’t hand-written HTML at all: the briefings (rendered from Markdown at build time by render_briefings.py) and the admin pages (rendered from internal docs by render_admin.py). These don’t become Astro pages. They stay as post-build Python scripts; after astro build writes to dist/, the generators run and write their output directly into dist/briefings/ and dist/admin/. Then Pagefind indexes the whole dist/ tree. The build pipeline gains one step at the front and otherwise stays the same.

There was also a URL preservation note worth flagging: Astro’s default static output emits /audit/index.html where the current site has /audit.html. Every external link, every _headers rule, and every sitemap entry uses the .html form. Setting build.format: 'file' keeps the output filenames unchanged — a one-line config setting that avoids a lot of broken links.

The spec is in internal/epics/SPEC-008-astro-migration.md. The implementation is four phases: a vertical slice (one page end-to-end including a CF staging deploy), bulk migration of the remaining eighteen pages, QA and parity checking, then deletion of the source files the Astro pages replaced. The whole thing is estimated at two to three days of focused work.


4 June 2026 — The community gets its own survey

A request came in from the steering lead the night before, with two parts: rename the financial feasibility survey to “Bottom Pub Pledge”, and add a new community feedback survey with nine questions drafted by the steering group. The ask was to launch the next day.

The rename was straightforward in principle and wide in practice. “Survey” had become a known landmark — it was in the nav on every page of the site, in the homepage footer, in the main call-to-action button. Twenty-seven pages needed updating, plus the briefings renderer’s nav template. The mass replacement ran in a single Python pass to avoid the kind of per-file inconsistency that produces exactly one forgotten instance. The nav now reads “Pledge” where it used to read “Survey”, and the financial survey page’s title, heading, column label, and meta description all follow.

The new community survey at /community-survey.html carries the nine questions in full — what people liked most about the pub, what they’d change, what events they’d want, what other uses the building could serve, what they’d do with profits if the co-op was profitable, and a 13-option vision question about what success looks like in 20 years. That last question is the one the steering group’s own drafting weighted most heavily: “Still open and thriving when other pubs have closed” sits alongside “Preserved a heritage building for future generations” and “Helped keep young people in the region”. It is a more honest picture of the stakes than anything a feasibility report can give you.

The form needed a backend. A new Cloudflare Pages Function at /submit-community-survey was written to match the shape of the financial survey handler — same CORS origin check, same rate-limiter pattern, same D1-insert-then-email sequence — but with its own rate-limiter key, its own table, and its own email subject line. The database migration was run directly against the production D1 instance before the code went live, which is the right order of operations. A separate entry was added to schema.sql for fresh setups.

The security check that runs on every push immediately validated the new page’s inline style block — its SHA-256 hash happened to be identical to the financial survey’s, because the style block was copied verbatim, and that hash was already in the Content Security Policy. No new hashes needed.

Three parallel QA agents — codex, hermes, and agy — each read through the changes independently. All three flagged the same thing: the vision question in Q8 had twelve checkboxes, not thirteen. The original spec listed “Other (please specify)” as the thirteenth option in the checkbox group — not a standalone text field below the others, but a real selectable option alongside the rest. The fix was a single label element. The text field stayed for the “if Other, please describe” detail.

agy went further than the checklist. It caught that render_briefings.py — the script that regenerates all the research briefings — still had the old “Survey” nav link hardcoded in its template, meaning any future briefing run would undo the rename for that subtree. That was fixed in the same session.

CI stayed green throughout.


3 June 2026 — Tightening the design system, catching a CI break

The design tokens got a compliance pass: colours aligned to the declared token set, focus rings standardised, pill components renamed to “tag” to match how they’re actually used. Small changes individually, but they compound — every future component gets the right foundations without anyone having to remember what the exception was.

The hero video on the homepage got proper VideoObject structured data in the JSON-LD block. Not a visible change to anyone browsing the site, but search engines now know what the video is, when it was uploaded, and what it’s about. It matters more as the project’s public footprint grows.

The navigation QA pass that followed cleaned up the remaining inconsistencies in ARIA markup — focus trap on the mobile drawer, skip links, the briefings nav pulling in from the wrong template. The mobile drawer also picked up “Express interest” and “Mailing list” links it had been missing.

The design-system change broke CI. The inline style block on the homepage had changed — which changed its SHA-256 fingerprint — and the security header test caught it within seconds of the push. Two new hashes added to the /* CSP rule in site/_headers, the check went green, and the incident was closed before it had time to become one.


2 June 2026 — A homepage that knows what it’s for

The homepage had been trying to do too many things at once. The news feed was burying the call to action. The expression-of-interest form — a long, careful instrument — was tucked below the fold, downstream of five other sections. The media coverage was a raw transcript dump with a notice apologising for what was in it.

All three got their own address.

/news/ is now the place where the log of meaningful steps lives. The full archive — working-group formation, the EOI going live, heritage verification, the opening of skill seats — is there, in reverse chronological order, with pills for each category. The homepage no longer needs to carry it.

/express-interest/ is now a page in its own right, not a section you scroll down to find. The form is unchanged — every ID, every checkbox, every consent field verbatim, because site.js finds them by name and there’s no room for drift — but it now gets the silence and space it deserves. The topbar’s “Express interest” button, which had been pointing at an anchor below the fold, now points somewhere.

The media page was the hardest to fix, because fixing it properly meant being honest about what it was. The raw transcript is gone. What replaced it is two editorial cards — one for Huon News, one for ABC Hobart — each with the outlet name set large, the headline in display type, and a CTA that matches the medium: “Read the article →” for one, “Listen to the segment →” for the other. The corrections note survived the redesign, because it had to. The ABC audio still contains figures the project has publicly walked back, and anyone who clicks through to listen will hear them. A quiet italic aside, border-left, no drama — enough to signal that the segment is a historical source, not a current one.

The navigation that runs across the top of every page was also rationalised. Every public page now carries the same five links — Proposal, News, Survey, Media, Contact — plus the Express interest button that had previously lived only on the homepage. Twelve pages updated. Three orphaned anchor links (#say, #news, /#say) hunted down and replaced. A CI run caught a stale CSP hash within minutes of the push — the inline style block on the homepage had changed, its SHA-256 fingerprint with it, and the security header test that had been running since 10 May did exactly what it was built to do.

Three parallel QA agents — codex, hermes, and agy — each took a different slice of the change and found nothing. That was the expected result. It was still worth running.

Later in the day, the admin panel got its manual. The admin surface had been growing steadily since mid-May — EOI triage, enquiry lifecycle, mailing list, kanban, document vault — and there was no single place that explained how any of it actually worked. That changed with a guide at /admin/guide/ that walks through the whole thing in order: how to get in, what the dashboard counters mean and when to refresh them, how to read an EOI card, the full enquiry lifecycle from “new” through to “sent”, how to compose and preview a mailing list message without sending it by accident, and where to look when the infrastructure is misbehaving.

The infrastructure section was the one that had to exist. D1 is the storage layer, MAILER is the binding that sends email, and unsubscribe tokens live in a separate table — when something breaks, whoever is trying to fix it needs to know which piece failed and what the failure mode looks like. That context used to exist only in the heads of people who’d been in the room.

The source lives in internal/admin-guide.md and goes through the admin renderer (scripts/render_admin.py) to pick up the nav, CSS, CSP headers, and security configuration that every admin page shares. A future edit is a markdown change and one script run. The “Guide” link was added directly to the renderer’s nav-link list, so it appears on every generated admin page automatically — no per-page wiring required.


23 May 2026 — Fixing what the deploy pipeline was hiding

Two implementations of /submit-enquiry and /submit-eoi had drifted apart without anyone noticing. The functions/submit-*.js files in the repo had been getting hardened — CSRF Origin checks, empty-submission rejection, better error handling — but none of it was reaching production. Cloudflare zone Worker Routes were silently winning over Pages Functions whenever both matched the same path, so the standalone Workers (last touched 19 May) were the ones actually serving live requests.

A temporary diagnostic patch went up on /submit-enquiry just long enough to confirm what was happening at the edge, then was reverted on the same day. With the topology clear, the fixes that had piled up in functions/ could finally land for real. The empty-EOI submission bug was closed, and a canonical deploy path was added: a manual-dispatch GitHub Actions workflow that redeploys both standalone Workers from the same functions/submit-*.js files. No more two versions of the truth.

The choice to keep the standalone Workers — rather than letting Pages Functions take over /submit-* directly — is forced by Cloudflare Pages not yet supporting the [[send_email]] binding both handlers depend on. That decision, and the operational details that go with it (required secrets and their failure modes, post-deploy probes, the difference between what the CSRF probe catches and what it doesn’t), were written up as a tracked operator runbook at internal/runbook-submit-workers.md.

Three things were deliberately deferred rather than rushed in the same session: a dry-run of the new manual-dispatch workflow before it’s needed for real, a happy-path enquiry that exercises the full intake pipeline end-to-end with real artifacts, and a small handler bug that returns 500 on malformed POSTs when it should return 400. They went onto the backlog as issues #50, #51, and #52.


22 May 2026 — The day the project read itself

A handful of frontier models read the entire project — more than two dozen reports’ worth of analysis across four different AI systems — and came back with a hard list of seventeen things that needed to change before any of this could go more public. Some of the findings were uncomfortable. Public-facing copy was making promises the project couldn’t keep. The admin surface had auth holes. The claim scanner that was supposed to catch risky language had a loophole big enough that a whole subdirectory had been slipping past it. After three rounds of internal QA on the proposed fixes, all seventeen items landed together as a single coordinated change.

The most visible part of the change was tone. A new privacy page now spells out, plainly, what happens to a submitter’s data — an AI reads it, it lands in GitHub as an issue, Cloudflare carries it — and the consent text on both forms was rewritten to match. Names on the May 17 meeting transcript got redacted to roles. Castlemaine — which the homepage had been quoting numbers about — was reframed as a mixed-use community building rather than a directly comparable pub, because that’s what it actually is. The Grong Grong claim of being “demonstrably replicable” was downgraded with caveats about state law and licensing. The capital-pathways copy stopped suggesting “higher effective returns” and “anchor investor bridges”. Case-study rows the project had been calling “Confirmed” without external verification got demoted to “Indicative”.

Behind the scenes, the admin section got a real authentication boundary for the first time. A JWT validation function now checks every admin request against the Cloudflare Access team JWKS, and the default when the environment isn’t configured is to fail closed rather than wave the request through. The “approve and send” action on the enquiry triage flow derives the approving user from that validated token now, not from a header that anyone could spoof. Branch-preview deploys were added to the CSRF allowlist so admin posts from preview URLs stop bouncing off the origin check.

The claim scanner itself — the script that’s supposed to catch risky public language before it ships — turned out to have a basename-matching bug. Its allowlist was designed to whitelist specific files like index.html, but it was matching by filename alone, so site/media/index.html had been getting the same pass as site/index.html. The fix was to make the allowlist repo-relative, with a new rule alongside it that catches the specific phrases the frontier-model review surfaced. A new build-time script also checks that the rendered briefings still match the source documents they came from. A new make release-check target combines all of that with a live probe of twelve different paths through Cloudflare Access, asserting that none of them leak sensitive content to unauthenticated requests.

Earlier in the day, before the meta-review work landed, five working groups got their portfolio documents — the working notes that explain what each delegated working group actually does, what’s open in their scope, and who owns what. Governance and records, intake and volunteers, comms and channel ownership, grants and resourcing, and the evidence-curation protocol the research stream had been running on informally. Each portfolio is the document a new contributor reads on their first day in that working group.

The choice map went live around the same time: a public page listing every open decision the project hasn’t made yet, the risks attached to each, and a link to the admin context where the working is. Publishing it was deliberate. The point is to make uncertainty legible — anyone reading the site can see what hasn’t been figured out, instead of being shown a clean facade that hides it. A frontier-model review playbook was written up alongside the map, explaining publicly how the multi-model QA process actually works.

A handful of smaller fixes landed alongside the bigger pieces. The kanban issue modal can now be opened from a #issue-N URL hash, so a link to a specific card actually works when shared, and the admin-search dropdown — which had been silently broken on the dashboard — was restored.


21 May 2026 — The admin gets smarter

The admin panel got a significant upgrade today. It now speaks two dialects — the original EOI schema and the newer v2 format — and shows consent status, capacity, and skills detail directly in both the card and table views. No more clicking through to find out what someone actually said they could contribute.

A handful of rough edges got smoothed out: a “View contact details” label that was saying the wrong thing, a hamburger overlay that was hiding nav links it shouldn’t have, and a few QA issues around schema coverage and button styles that had crept in during the v2 work.

We also added a runbook for whoever steps into the intake coordinator role — a concrete guide to what happens when someone submits an EOI and what to do about it.


20 May 2026 — A very full day

This was the kind of day where a lot of threads got pulled at once.

The contact form stopped being a dead end. When someone sends an enquiry, they now see the reply Claude drafted for them — not just a generic “thanks, we got it.” The acknowledgement email was fixed to actually use those triage reply fields too, so the automated response reads like it was written by a person who read their message.

The EOI form grew up. It now mirrors all the fields from the original Google Form, so nothing gets lost in translation from what people were already used to filling out.

The public site got tidier. The topbar navigation was rationalised and the hamburger now persists properly on scroll. The hero cards were reordered, the ABC card was replaced with a more compact “In the news” summary, and two phrases that were creeping toward false certainty got softened back to Stage 1 language. The working group section was tightened for the same reason — we’re asking whether this is worth doing, not announcing that it’s happening.

Working groups got a home on the site, with confirmed details for the May 23 meeting. The Huon News article was added to the media page.

Behind the scenes, a lot of infrastructure work landed quietly: the kanban board got a toggle for closed issues, the admin vault expanded with new briefing links and image entries, a geospatial LISTmap briefing was added, the triage reply draft is now stored in D1 pending approval before it goes out, and the first Linktree snapshot was taken for future monitoring.

Email and admin notifications were also tightened — the full message body and submitter details now appear in both the admin email and the GitHub issue, so whoever triages an enquiry doesn’t have to dig.


19 May 2026 — Eyes on the property, rigour on the model

The project got its first proper automation for watching what’s happening with the property. A watchdog script now monitors listing status and surfaces errors — including the case where the property gets delisted — and feeds that into a synthesis brief that always shows the urgency section, even when the API is having a bad day.

A synthesis state script joined it, pulling together the current picture of where the project stands. Both have tests.

The agent operating model — the framework for how human and automated work fits together — shipped after several rounds of QA patching. It went through four rounds of fixes before it was solid enough to merge.

Five governance templates were packaged into a formation packet for the steering committee’s first meeting. The decision template got a synthesis-brief-date field so it’s always clear which picture of the world a decision was made against.

The EOI admin panel arrived too: a live reader of D1 submissions with CSV export, proper security headers, XSS protection, and unit tests. The homepage got a video hero from R2. The media page got an ABC section.

One small but important correction: the Grong Grong case study was calling people “Investors” when it should have said “Shareholders.”


18 May 2026 — The intake pipeline, end to end

The most significant thing that happened on this day: someone can now fill out the contact form, and something useful happens on the other end.

The /contact.html intake form went live with a honeypot field to filter bots. Submissions flow to D1, get triaged by Claude, become a GitHub issue, and trigger an email notification — all automatically. The kanban board was wired up to render those issues at build time and refresh live, with proper HTML escaping throughout.

Email infrastructure moved from Resend to Cloudflare Email Workers, which simplified the stack considerably.

The admin section got its own protected renderer, its own CSP rules, and its own document pipeline — fed by Git rather than a separate CMS. The steering committee selection framework was added to the vault (and briefly reverted, then re-added correctly).

The public-facing copy went through another honesty pass. “Audit” became “Research.” “Stress-testing” became “due diligence.” “Reality check” became “What we’ve learned.” The epistemic framing in the unknowns section was upgraded to three tiers based on what came out of the 17 May meeting. Research notes from five more pub case studies — Sea Lake, Hotel Theodore, Renmark, Mogumber, and others — were incorporated.


17 May 2026 — The first meeting goes on record

The community meeting the project had been quietly working toward actually happened. The transcript was published as a page on the site afterwards, so anyone who wasn’t in the room could read what was said. (One small correction landed the same day: it’s Billie, not Billy, throughout.)

That meeting turned out to be the first real signal the project had had from outside its own assumptions. The three-tier framing for unknowns that landed on the public site the next day came directly from what got raised in the room. A lot of the language for being honest about uncertainty — the careful hedges, the “subject to feasibility” framings, the case for treating Stage 1 as Stage 1 — came out of that conversation and shaped what followed for the next week.


16 May 2026 — A small piece of housekeeping

The colophon — the page that documents the site’s design choices — got folded into section §09 of the design system, with the old URL set to redirect. A small move, but it means the design system is now a single document instead of two.


15 May 2026 — Foundations documented

The colophon moved from the main nav into the footer on every page, which is where notes of that kind belong. More importantly, the CSP hash requirements and deployment rules got written into the project’s working guidance — small, easy-to-rediscover details that had been costing time every time someone touched them.


14 May 2026 — The pub gets a face

The site finally shows what we’re actually talking about. The placeholder facade images were replaced with a real photo of the Commercial Hotel. Open Graph and Twitter cards were added so links shared on social show something meaningful. The hero photo was optimised down to 226KB WebP with a JPEG fallback.


13 May 2026 — Going public

The repository went from private to public. Agent contract stubs were published alongside it, so the project’s working model — how human and automated work fit together — is legible to anyone who chooses to look.


11 May 2026 — Making it work on the device in your pocket

Almost an entire day spent on mobile. The nav drawer — the menu that slides in from the side — had accumulated a list of bugs: clipped to the topbar height, z-index fighting with the hamburger button, a close animation that raced against a focus timer, a CSS selector that never matched because toggleAttribute outputs strings not booleans.

All of it got fixed. The citations page and all briefing pages got the full site nav. Mobile doc cards got their layout corrected.

Caching was also sorted: CSS and JS get no-cache, fonts and images get immutable. The service worker was simplified to only cache HTML and let the browser handle everything else.


10 May 2026 — The scaffolding becomes a real building

Everything that makes a site trustworthy arrived on this day. Content Security Policy with hash-pinning. Isolation headers. A proper 404 page. security.txt and robots.txt. A security header test suite so regressions get caught automatically.

The site became a PWA — manifest, service worker, icons. SEO was switched on: noindex off, Open Graph tags, JSON-LD structured data, sitemap.

The EOI form was wired to a Cloudflare Pages Function and D1 database. Six briefings shipped: governance, legal/licensing, financial/ASIC, feasibility and costs, capital pathways, and an audit crosswalk. Google Analytics was added.

The homepage went through an editorial pass — cut, reordered, anchored on the two sentences that actually matter. The “we don’t know if it’s for sale” hedge was replaced with the verified facts. A town meeting notice went up.


9 May 2026 — Day one

The project existed. A public website prototype, working proposal drafts, research notes, a strategy memo, a risk register, a claim scanner, and a Cloudflare Pages build script. From nothing to something in a single day.

The briefings were already being rendered to HTML at build time rather than served as raw documents. Tasmania’s CNL adoption was cited correctly from the start — not conflated with Queensland’s. The placeholder thumbnails were already gone.

A foundation built to be stress-tested.

End of document ← Back to the archive