GitHub wiki sync
praetorctl forge sync-wiki [--output=docs/wiki] (internal/forge.GenerateWiki,
invoked from cmd/standardsctl/forge.go) generates the pages under docs/wiki/
from repository content; running it and committing its output is how an operator
refreshes them. The Wiki Sync workflow only copies that already-generated
docs/wiki/ into the repository wiki — it does not call sync-wiki itself, so a
regenerate-and-commit is still required to keep the published wiki current. The
workflow triggers on a push to main that touches docs/wiki/**,
.github/workflows/wiki-sync.yml, scripts/sync_github_wiki.sh,
docs/assets/figures/** or the figure engine files the sync runs
(tools/figures/build.mjs, checks.mjs and core.mjs), and on manual
workflow_dispatch; it does not run on every push. The workflow sets up Node
for that step; it needs no npm package.
The generated portal is named after the repository's identity:
repository.owner/repository.name in .standards.yaml, else the origin remote, with
forge.default_owner from the operator settings (--fleet-config,
--workstation-config, --manifest) as the last owner step
(config.ResolveRepositoryIdentity). A checkout that declares no identity and has no
origin remote fails instead of naming the portal after its directory layout
(TestResolveWikiRepoName_Negative_NoIdentityIsAnError in
internal/forge/wiki_test.go).
Every top-level entry directly under docs/wiki/ must be a regular, non-symlinked
file whose name ends in .md; scripts/sync_github_wiki.sh rejects any other
entry (a directory, symlink, or non-.md file) and exits 2 before copying
anything, so one bad entry blocks the whole sync. The source directory holds at
most 256 such files (MAX_WIKI_FILES); more also exits 2. The workflow updates
source-owned filenames and preserves other wiki pages. The workflow and each Git
network process have explicit time limits.
Figures
Every generated page except the moved HISS-16-Invariants stub draws its
diagram as a figure fence, and none carries Mermaid: Home names
governance-lifecycle, HISS-Invariants and HISS-Matrix name
verification-ladder, Architecture-Lattice names lattice-join, and
API-Reference names forge-federation (TestGenerateWiki_Positive and
TestGenerateWiki_Boundary_EveryFigureHasCommittedOutputs in
internal/forge/forge_test.go).
The wiki runs no JavaScript, so it cannot show the site's interactive figures.
After copying the pages into the wiki clone, scripts/sync_github_wiki.sh runs
node tools/figures/build.mjs portable --wiki on the copies. Each
figure fence becomes a <figure> holding a <picture> of the figure's
animated and static SVGs on the published site, each with its own recorded
width and height, with absolute URLs built from
the site_url in mkdocs.yml, then a link to the interactive figure on the
site (<site_url>wiki/<Page>/#fig-<slug>) and the text description. The pages
under docs/wiki/ keep their fences; only the wiki copies change. A fence that
names a figure without docs/assets/figures/<slug>.json stops the sync before
anything is committed. The figures guide covers the figures
themselves.
The images point at the published site, so a figure added in the same push shows in the wiki once the Pages deployment has finished.
Removing pages
Each sync records the names it published in .praetor-wiki-manifest at the root
of the wiki repository, one name per line. On the next run,
scripts/sync_github_wiki.sh removes only pages that the manifest lists and
docs/wiki/ no longer contains. Pages created in the wiki itself never appear in
the manifest, so the sync keeps them. The manifest is not a page: GitHub wikis run
on Gollum, which renders only files with a
markup extension.
- A wiki without a manifest removes nothing on that run and records one. A page
deleted from
docs/wiki/before the first recorded sync stays in the wiki until it is removed by hand. - Each entry is a literal page name. An entry that is empty, contains
/, or does not end in.md, a manifest listing more than 256 pages, or a manifest that is not a regular file stops the sync before any change. Correct the manifest in the wiki repository, or delete it to resume without removals. - Source file names must not contain line breaks, because the manifest is line-based.
GitHub exposes the wiki Git repository only after an initial page has been
created on GitHub. This prerequisite comes from GitHub's
wiki editing documentation.
Before cloning, the script runs git ls-remote on the wiki remote with the job
token. When Git answers repository '<url>' not found, read in the C locale, the
run mirrors nothing and still succeeds: it prints a ::notice:: and adds a line
to the step summary saying to save a first page through the Wiki tab and rerun
the workflow. GitHub gives the same answer for a repository the token cannot
read, which the repository's own job token always can.
Every other probe or clone failure remains an error: authentication, connectivity
and a timeout fail the run with Git's message, as does a local remote path that
does not exist (WikiProbeTests in scripts/test_sync_github_wiki.py, whose
stubbed Git answers for the GitHub remote). The workflow passes
github.token through a temporary askpass helper. The token is not placed in the
remote URL, command output, or Git configuration, and the helper is deleted when
the script exits.
Run the hermetic local regression suite with: