Admin
Two things live under /admin/: how this site is built and released, which exists, and the environment admin pages, which are proposed.
How the site is built
There is no build step and no bundler. The committed tree is the deployed tree. Five generators under admin/build/ write the parts that must not drift (the chrome, the status tables, the release table, the markdown twins, the machine indexes), each with a --check mode, and an eight-check gate in admin/build/validate.js refuses a release that disagrees with itself. The same command, python3 admin/build/gate.py, runs locally and in CI. Every push to dev is a release: the version in admin/build/version.txt is repeated in the commit subject as site vX.Y.Z : what, CI tags it, deploys it, and then polls the live site until it serves that version. The whole procedure is in docs/ops/release.md.
The eight checks
- Version agreement.
version.txtequals every page badge, the newest row of the versions table,llms.txt,llms-full.txt,index.mdandconfig/environments.json#siteVersion; no version is listed twice. - Internal links and fragments resolve, in every HTML and markdown file.
- Canonical host. Every page has
rel=canonicalandog:urlon the host inCNAME. - Leak tripwire on every file in the tree: sgit vault and read keys, AWS and GitHub tokens, API keys, PEM private key blocks, Slack tokens, Google OAuth client secrets, service-account JSON, bare twelve-digit numbers. The fix for a trip is always a redaction, never a wider pattern.
- Vendor manifest. Every file under
vendor/matches its SHA-256; no script is loaded from another origin anywhere underapp/,components/,admin/ortests/. - Storage rules in sync. The hash of
infra/rules/storage.rulesequals the hash recorded indata/features.json, so a rules change without a release note fails. - Reality.
docs/reality.mdis whatdata/features.jsongenerates. - No storage of secrets in code. Every
localStorage.setItemandsessionStorage.setItemuses a key listed inapp/config/storage-keys.js.
The admin pages, proposed
The admin pages will work only when the visitor signs in with a Google account that has IAM on the selected environment's GCP project. There will be no admin role in the app: the project's IAM is the role, and the pages are a client for GCP's own APIs, calling them with the visitor's own token held in memory. Every write action will show the exact request before sending it. None of this exists yet.
| Area | Feature | Status | Where | Notes |
|---|---|---|---|---|
| admin | Comms page: the asks back to the project lead and the nine build steps with status, from data/steps.json | shipped v0.1.1 | admin/comms.html | gen_versions.py renders the step tracker; a done step must name a release that exists. |
| admin | Admin sign-in with the visitor's own Google account, token in memory only | proposed | admin/oauth.js | Step 7. Implicit flow to verify first; PKCE fallback. |
| admin | Setup checklist: every per-project resource as a row, with Fix where fixable client-side | proposed | admin/setup-checklist.html | Step 3 read-only, step 7 with fixes. |
| admin | Auth config, storage, rules diff and deploy, users, environment export | proposed | admin/*.html | Step 7. GCP IAM is the role; the pages are a client for GCP's own APIs. |
| admin | Release history page generated from data/versions.json | shipped v0.1.0 | admin/versions.html | One row per release; the newest row must equal version.txt. |
The pipeline, as it stands
| Area | Feature | Status | Where | Notes |
|---|---|---|---|---|
| pipeline | One version in admin/build/version.txt, repeated in every badge, twin, index and config | shipped v0.1.0 | admin/build/version.txt | Check 1 of the gate fails on any disagreement. |
| pipeline | Chrome (head, nav, footer, version badge, CSP, canonical) generated into every page from one definition | shipped v0.1.0 | admin/build/chrome.py | gen_chrome.py --check is part of the gate. |
| pipeline | Markdown twin of every HTML page, links pointing at markdown | shipped v0.1.0 | admin/build/gen_twins.py | index.html has index.md beside it; the twin carries the site version. |
| pipeline | llms.txt, llms-full.txt and sitemap.xml generated on every release | shipped v0.1.0 | admin/build/gen_llms.py | llms-full.txt concatenates every twin and every design document. |
| pipeline | docs/reality.md and the status tables generated from data/features.json | shipped v0.1.0 | admin/build/gen_features.py | If the reality document does not list it, it does not exist. |
| pipeline | The eight-check release gate, no dependencies | shipped v0.1.0 | admin/build/validate.js | Version agreement, internal links, canonical host, leak tripwire, vendor manifest, rules in sync, reality, storage keys. |
| pipeline | The same gate locally and in CI, one command | shipped v0.1.0 | admin/build/gate.py | The CI validate job runs gate.py; a release that fails locally fails the same way in CI. |
| pipeline | Every push to dev is a release: version.txt and the commit subject agree, CI tags it | shipped v0.1.0 | admin/build/tag_release.py | Anchors on the newest commit whose subject is 'site vX.Y.Z : ...', asserts the next minor or patch or major .0, backfills missing tags. |
| pipeline | Deploy to GitHub Pages from the validated tree | shipped v0.1.0 | .github/workflows/deploy-pages.yml | Excludes .git, .github, infra, tests/unit and node_modules. Actions pinned by commit SHA. |
| pipeline | verify-live: the run is red until the live site serves the released version | shipped v0.1.0 | admin/build/verify_live.py | Green does not mean live. Polls version.txt and the homepage badge for up to ten minutes. |
| pipeline | Every third-party file vendored and hashed in vendor/MANIFEST.json; no runtime script from another origin | shipped v0.1.0 | vendor/MANIFEST.json | Check 5 of the gate. Today the only vendored file is the family design tokens. |
The admin section
- How the site is built: this page.
- Release history: one row per release, generated from
data/versions.json. - Comms: the asks back to the project lead and the nine build steps with their status, generated from
data/steps.json. - What needs a human, exactly, and the rest of the documents, each rendered from its markdown with the raw file one click away.
- The build itself, served as plain files: chrome.py (the nav, footer, badges and CSP), validate.js (the eight checks), version.txt, nav.js (the menu interaction, the only script on the site at this version).