Document begins
What was actually running underneath
A visitor saw a website. Underneath it was a good deal more machinery than a Stage 1 community proposal strictly needed, and being honest about where the effort went means saying so: a large share of this project’s total work was software, not civic organising.
That is not entirely a confession. Several of these pieces are the reason the archive you are reading can be trusted.
The shape of it
Static site (22 pages + 13 build-time gates
rendered briefings)
├── generated from source ──────► claim scanner (blocks banned copy)
├── public briefings CSP hash check (blocks unhashed inline code)
└── protected areas archive scanner (blocks unreviewed archive pages)
│ provenance gate (blocks pages with no source trail)
▼
Edge platform
├── static assets ........... served directly
├── serverless functions .... form submission, admin views
├── two standalone workers .. the mail-sending paths
├── database ................ expressions of interest, pledges, enquiries, subscribers
└── Zero Trust .............. identity check on the two protected areas
The decisions worth recording
The build refuses to ship banned language. A scanner reads the project’s own text for fixed-return, guaranteed-dividend, owner-willingness and property-availability claims, and exits non-zero if it finds any. It has run on every push since day one of the repository — before there was much content to scan. That ordering is the point: the guardrail predates the temptation.
Every inline style and script is fingerprinted. The site enforces a strict content-security policy in which inline code is permitted only by cryptographic hash. A test verifies that every inline block in the built site has a matching hash in the headers, and fails the build otherwise. It caught things repeatedly during this archive’s construction — including, twice, a stray inline style attribute that would have silently failed to render for visitors.
Missing configuration fails closed, loudly. Several behaviours are wired to environment variables that are deliberately not optional. If the identity-check configuration is absent, protected areas return an error rather than quietly serving the content. A staged-rollout escape hatch exists, and it has to be switched on explicitly and by name. The principle is that a misconfiguration should look broken, not look fine.
Protection is identity, not obscurity. The two protected areas are behind a Zero Trust identity check on both the custom domain and the platform preview domains — the latter because ephemeral preview URLs are a classic way for “protected” content to leak. Robots directives and unlisted URLs are defence in depth, never the boundary. A pre-deploy script probes the live URLs to confirm the protection is failing closed.
Migrations are applied the same session, not “before going live”. A database migration that exists but has not been run is code that will fail silently at runtime. The rule the project settled on is blunt: if a change adds a migration, it is applied to production in the same working session, before the change is closed.
What went wrong
A migration to a different site framework consumed a large share of June. It was the right call technically and it is a fair question whether a community group with three weeks until a property deadline should have been doing it at all. The changelog records both the work and the reasoning.
Two Worker deployment models coexisted and were repeatedly confused. Functions bundled into the site’s own deployment could not hold mail-sending bindings, so the mail paths also existed as standalone Workers built from the same source. Two runtimes, one codebase, different deployment triggers and different log pipelines. It worked, and it cost real time in confusion.
The build-log blind spot. A failure in the site generation step is visible in the build log. A failure at runtime inside a Function is not — it returns an error to a visitor and appears nowhere unless log forwarding is configured. That gap is why several problems were found by looking at a page rather than by a monitor. The state machinery page has more on how badly monitoring went.
The part that was worth it
Strip away the migration and the deployment confusion, and what is left is four automated gates that a volunteer group could not have enforced by discipline alone:
- copy that overclaims cannot be deployed;
- inline code that has not been fingerprinted cannot be deployed;
- an archive page without a provenance trail cannot be built;
- an archive page carrying a publication date without a named human reviewer cannot be built.
None of those depends on anyone remembering. That is the whole argument for building them.