wardley-maps.sgit.ai / Admin
Admin & engineering
This site is hand-written static HTML with programmatically injected
chrome, deployed to GitHub Pages from dev. No framework, no build step you have
to run to read a page, and no server. The same pipeline as
pki.sgit.ai and
graphs.sgit.ai, with one addition no sibling has.
The pipeline
Every push to dev runs
deploy-pages.yml:
validate → tag → deploy, in that order, with each gating the next. A push to
main is deploy-only. Pull requests run validation alone, so branch work is gated
before it reaches the release branch.
| Stage | What it does | On failure |
|---|---|---|
| validate | node admin/build/validate.js — seven checks, below | No tag, no publish |
| tag-release | Reads version.txt, finds the commit whose subject carries the same version, verifies the bump is the next minor, tags that commit. Backfills any historical release from the commit subjects, idempotently. | No tag, no publish |
| deploy | Rsyncs the tree minus .git, .github and .sg_vault, and publishes to Pages. | — |
The release commit is HEAD on a direct push and HEAD's parent when a pull request lands as a merge commit, so every check anchors to the newest commit whose subject carries a version rather than to HEAD itself.
The release gate — seven checks
Four are the house gate, inherited unchanged in intent. Three exist because this site makes promises the others do not.
- Version agreement.
version.txtagainst every page's version badge, the versions table,llms.txt,llms-full.txtandindex.md— and that the versions table lists each release exactly once, because a blanket version-bumpsedthat touches the history table produces duplicates, which has shipped on a sibling site. - Internal links. Every relative
hrefandsrcin every page resolves to a file in the tree. - Canonical host. Every
rel="canonical"andog:urlpoints at the host inCNAME, and every page declares one. - Key-leak tripwire. Nothing in the tree may look like an sgit vault key. This site links to vaults; it must never contain a key.
- Licence stamp. Every raw markdown document under
/briefs/carries the CC BY 4.0 stamp. The site sits inside a CC BY-SA ecosystem; an unstamped document is the first step towards a mixed, unlabelled licence. - Maps ship their source, and render. Every
maps/*.mmdhas an.svgbeside it, no.svgis orphaned, and no rendered SVG contains Mermaid'serror-text. A brokenwardley-betasource renders a byte-identical "Syntax error in text" SVG with exit status zero — in a batch render that is indistinguishable from success, which is how thirteen broken maps sat in a repository for three months. - Resource pages carry a verification date. Every page under
/resources/has adata-verifiedstamp. It is the site's whole differentiator in that category and the one rule with no exceptions.
The link-verification job
No sibling site has one. This site needs one, because it spends a page saying
that awesome-wardley-maps, Wikipedia and Simon Wardley's own resources page all
list five dead things as live. A site that makes that criticism and does not check its own links
has no standing to make it.
verify-links.yml
runs every Monday and on demand: fetches every external URL the site publishes, writes
data/link-check.json with the run date,
commits it if a verdict actually moved — not merely the timestamp — and dispatches a deploy,
because a push made with GITHUB_TOKEN deliberately does not trigger another
workflow. Hosts that block automated retrieval are recorded as skipped, never as ok.
A dead link does not fail the build: the point is that links rot, and a red pipeline would tempt
somebody to delete the evidence. The report →
Why the chrome is generated
Every page is hand-written and a human can open any file and edit it. What is not
hand-maintained is the nav row, the version badge and the footer columns:
admin/build/chrome.py is the single definition of all
three and rewrites them in place across the tree. That is what stops a hundred-page site
drifting, and it is why the version badge can be enforced by CI at all.
What is generated, and from what
| Generator | Writes | From |
|---|---|---|
gen_resources.py | 45 pages under /resources/ | data/industry-resources.json + screenshots/captured.json. Wipes the directory first, so a renamed resource cannot leave an orphan page behind that still validates and still says "verified". |
gen_dinis.py | /dinis/ | data/dinis-published.json — 26 items, each with a date-precision flag, because seven are month-and-weekday only and synthesising a date would be inventing evidence. |
gen_concepts.py | /glossary/ and /agents/concepts.json | Parsed from briefs/01__concepts-index.md rather than retyped, so the page and the endpoint cannot drift from the research and a correction lands in one place. |
gen_documents.py | /documents/ | The raw markdown in /briefs/, which stays the source of truth and is served as-is. |
The scripts
| Script | What it does |
|---|---|
bin/bump.py | Bumps version.txt and adds a row to the versions table, in one step, so the two cannot disagree. |
bin/render-maps.sh | Renders every .mmd to .svg via Mermaid CLI 11.14.0 against an existing Chromium, and greps for the silent syntax error. |
bin/verify-links.js | The link check. HEAD then GET, redirects followed, blocked hosts recorded as skipped. |
screenshots/capture.js | Screenshots the 30 targets, recording status, title, final URL and timestamp for every attempt including failures. Has a PROXY_FETCH=1 mode for sandboxes where the process has egress and the browser does not. |
bin/optimise-shots.py | Resizes the captures to WebP and records the transformation per image — a screenshot offered as evidence should say that the published file is a derivative. Also flags captures that photographed an interstitial rather than a page. |
The repository
SGit-AI/SGit-AI__Website__Wardley-Maps
— dev is the release branch and what Pages serves. Content CC BY 4.0; code under the
repository licence. The licence position in full →