diff --git a/site/scripts/sync-wiki.mjs b/site/scripts/sync-wiki.mjs index 951291bf..1e0613e9 100755 --- a/site/scripts/sync-wiki.mjs +++ b/site/scripts/sync-wiki.mjs @@ -232,7 +232,7 @@ function rewriteMarkdownLinks(body, fromWikiRel) { function writeDoc(wikiRel, sourceAbs) { const dest = destFileForWikiRel(wikiRel); - if (!dest) return; + if (!dest) return false; let body = fs.readFileSync(sourceAbs, 'utf8'); if (body.startsWith('---\n')) { @@ -251,6 +251,7 @@ function writeDoc(wikiRel, sourceAbs) { const out = `---\ntitle: ${yamlEscape(title)}\n---\n\n${body}`; ensureDir(path.dirname(dest)); fs.writeFileSync(dest, out, 'utf8'); + return true; } function nestInto(items, item, depth) { @@ -376,15 +377,23 @@ function main() { // DESIGN.md is a root doorway, not design authority. Sync it explicitly for // old /constitution/ links instead of keeping a renderer-specific duplicate. - writeDoc('DESIGN.md', path.join(REPO_ROOT, 'DESIGN.md')); - let pageCount = 1; + let pageCount = writeDoc('DESIGN.md', path.join(REPO_ROOT, 'DESIGN.md')) ? 1 : 0; const mdFiles = walkFiles(WIKI_ROOT, (name) => name.endsWith('.md')); for (const abs of mdFiles) { const rel = path.relative(WIKI_ROOT, abs).split(path.sep).join('/'); const real = fs.realpathSync(abs); - writeDoc(rel, real); - pageCount += 1; + if (writeDoc(rel, real)) pageCount += 1; + } + + const emittedPageCount = walkFiles( + DOCS_OUT, + (name) => name.endsWith('.md'), + ).length; + if (pageCount !== emittedPageCount) { + throw new Error( + `sync receipt counted ${pageCount} pages but emitted ${emittedPageCount}`, + ); } const wikiAssets = walkFiles(WIKI_ROOT, (name) => diff --git a/wiki/interface/site.md b/wiki/interface/site.md index 33ae8f85..0c2c9516 100644 --- a/wiki/interface/site.md +++ b/wiki/interface/site.md @@ -36,7 +36,9 @@ Status note: docs theme implemented 2026-07-08 (site/src/styles/ On 2026-08-02 the public theme and its binding art law were renamed Liturgical Systems Brutalism; the canonical three-board reference set now carries composition across facility, operator, service, archive, and document - scales without making generated image contents literal world facts. + scales without making generated image contents literal world facts. On + 2026-08-04 the corpus sync receipt was made exact: it counts only documents + actually emitted and fails if that count differs from the generated tree. Stage: Process Design: - wiki/art/visual-identity.md#visual-identity-liturgical-systems-brutalism @@ -205,3 +207,7 @@ computer and its WORK / THINK / LIE signal before overt consequence. commit. `./tools/site-smoke.sh` fails when the public homepage is missing that marker, carries a different revision, or loses the WORK / THINK / LIE title contract. +12. Corpus synchronization reports the number of Markdown documents actually + emitted into Starlight. `wiki/SUMMARY.md` drives navigation but is not a + rendered page, and a count/output mismatch fails the build instead of + issuing a plausible false receipt. diff --git a/wiki/log/2026-08-04-wiki-renderer-receipt.md b/wiki/log/2026-08-04-wiki-renderer-receipt.md new file mode 100644 index 00000000..ca31209d --- /dev/null +++ b/wiki/log/2026-08-04-wiki-renderer-receipt.md @@ -0,0 +1,42 @@ +# 2026-08-04 — Wiki renderer receipt matches its tree + +``` +Type: log +``` + +## Finding + +The first full audit of `wiki/process/wiki.md` found the corpus and renderer +structurally sound, but its build receipt overcounted rendered documents by +one. `site/scripts/sync-wiki.mjs` incremented `pageCount` for every Markdown +source under `wiki/`, including `wiki/SUMMARY.md`; `writeDoc` deliberately +returns no destination for SUMMARY because it becomes the sidebar rather than +a document. The sync therefore said it wrote 827 pages while exactly 826 +Markdown documents existed: 825 renderable wiki pages and the legacy DESIGN +doorway. + +## Changed + +`writeDoc` now reports whether it emitted a document. The sync increments its +receipt only for successful writes, then independently counts Markdown files +in the generated Starlight tree and aborts if the two totals diverge. + +## Evidence + +- `tools/corpus_gate.sh`: all roles, headers, links, and doorway contracts pass. +- `tools/wiki_gate.sh`: no orphan pages or broken internal links. +- Production-base sync after adding this audit log: 827 emitted Markdown + documents, exactly matching the generated tree. The preceding build's 826 + documents carried the full source revision in the splash. +- Rendered `process/wiki` carries the SPEC banner; rendered `constitution` + carries NAVIGATION and “Doorway only — no design authority.” +- The generated sidebar retains all thirteen top-level corpus entries from + SUMMARY while SUMMARY itself remains correctly absent as a content page. + +## Defense + +`wiki/process/wiki.md` requires the public renderer to project the same typed +Markdown corpus, while `wiki/interface/site.md` makes public truth exactly +addressed. A synchronization receipt is part of that evidence boundary: it +must count the tree that exists, not source inputs deliberately used for a +different output. diff --git a/wiki/log/DEVLOG.md b/wiki/log/DEVLOG.md index 4c1fd554..be53c00a 100644 --- a/wiki/log/DEVLOG.md +++ b/wiki/log/DEVLOG.md @@ -16,6 +16,11 @@ add or amend a session log, then re-run the generator. - Intent: (see session log) - Log: [wiki/log/2026-08-04-worktree-activity-contract.md](2026-08-04-worktree-activity-contract.md) +## 2026-08-04 - Wiki renderer receipt matches its tree + +- Intent: (see session log) +- Log: [wiki/log/2026-08-04-wiki-renderer-receipt.md](2026-08-04-wiki-renderer-receipt.md) + ## 2026-08-04 - Wager current-mirror re-audit - Intent: (see session log) diff --git a/wiki/process/tick-ledger.md b/wiki/process/tick-ledger.md index a844944b..d16bb41f 100644 --- a/wiki/process/tick-ledger.md +++ b/wiki/process/tick-ledger.md @@ -34,6 +34,7 @@ Verdicts: **clean** (slice and code agree), **finding** (acted this tick), | `wiki/world/story/opening.md` + pre-sense status mirrors | 2026-07-27 | finding | the issue-#15 boot-voice implementation was superseded after Cameron saw the composed frame: Fire #33 removed `Sim::opening_interoception` and the standing SENSES / DELEGATION / THOUGHT / EARS block, leaving WORK / THINK (then LIE) plus one frontend-local input echo as the complete pre-sense surface. The opening, narration, DIGITAL, terminal, Bevy, agent, witness, objective, roadmap, and corpus-defense mirrors already carried that correction; this follow-up repairs the coverage row that still described the rejected implementation — [runtime correction](../log/2026-07-27-blind-opening-choice-and-receipt.md), [ledger reconciliation](../log/2026-07-27-opening-ledger-status-reconciliation.md). Issues #14/#15 remain open only because authenticated `tg` closure cannot unlock the login keyring. | | `wiki/process/tick.md` + issue automation | 2026-07-27 | finding | the queued retired-client violation held across binding procedure, both skill mirrors, four active prompt templates, tick intake, project status, and doctor. `tools/tangled_issues.py` now keeps repository discovery and authenticated issue writes on canonical Go `tg`, reconstructs deterministic display numbers from public issue records, folds public label-op history, and provides fail-closed structured list/view/create/edit/comment/close/label operations. A same-day live harvest exposed one wrong record assumption: comments are cross-account `sh.tangled.feed.comment` records linked through `subject.uri`, not issue-local child records. The repaired helper follows that backlink into the author's PDS and returns the markup text; a fixture pins the exact shape, and live issue #15 now returns Cameron's choice `1` — [migration and repair log](../log/2026-07-27-tangled-issue-client-migration.md) | | `wiki/process/repository-skills.md` + checked-in skill registry | 2026-08-04 | finding | the registry and declared Claude mirrors match exactly, but `session-wrap` still treated a tracked July handoff as current project state, named a retired harness-specific `cursor_dialog` memory tool, and told agents not to complete already-authorized landings. The stale handoff is removed; wrap now derives state from Git, registered worktrees, project status, and issues, finishes or explicitly preserves owned work, and leaves durable user memory to the invoking harness — [log](../log/2026-08-04-session-wrap-live-state.md). | +| `wiki/process/wiki.md` + `wiki/interface/site.md` corpus renderer | 2026-08-04 | finding | all 825 renderable wiki documents plus the legacy DESIGN doorway reached the local Starlight tree, corpus/wiki gates passed, SPEC and NAVIGATION authority labels rendered, production links retained `/misaligned`, and the exact source revision reached the splash. The audit found only the sync receipt was false by one: it counted `SUMMARY.md` as a page even though SUMMARY is a navigation manifest and deliberately emits no document. The sync now counts successful writes and fails closed if that count differs from the generated Markdown tree — [log](../log/2026-08-04-wiki-renderer-receipt.md). | | `wiki/world/places/basement-map.md` room topology | 2026-07-27 | finding | the queued five non-hall corridor cuts remained, and an executable all-room perimeter audit exposed the same dead-door shape at the loading-dock entry plus fixed objects blocking the interior faces of the roll door, HVAC door, both storage doors, Janitor door, and stairwell. Every non-hall approach now reaches its authored door from outside the prefab, every other perimeter tile remains closed, doorway interiors are clear, and the roll, sealed, tier-2, and tier-3 boundaries retain their exact kinds — [room-approach log](../log/2026-07-27-room-approaches-meet-doors.md). Prior [west-approach](../log/2026-07-26-west-hall-approach.md) and [hall-density](../log/2026-07-26-foundation-hall-density.md) repairs stand. | | `wiki/mechanics/sensor-network.md` generated sensor population / criteria 1-5, 8 | 2026-07-28 | finding | criterion 8's standing subscription cost existed only in the global Thought-sink ledger, so a player choosing which individual camera to keep could not read that camera's exact burden. Every retained foreign subscription now names its exact `Thought/tick` upkeep and live/starved state on the device's shared inspect card, within both frontends' visible fact budget; UNTAP removes that addressed cost. The integrated several-subscription starvation/inbox-overflow experience remains pending, so criterion 8 is partial rather than overclaimed — [standing-upkeep log](../log/2026-07-28-subscription-upkeep-inspect.md). Prior generated-camera placement and badge-passage findings stand — [placement repair](../log/2026-07-27-room-camera-floor-placement.md), [passage implementation](../log/2026-07-27-badge-reader-passage-custody.md), [population foundation](../log/2026-07-27-sensor-population-foundation.md). | | `wiki/interface/keymap.md` + terminal/Bevy input routes | 2026-08-04 | finding | the complete-inventory follow-up is closed: the canonical table now includes terminal `;` FOCUS EVENT and `Shift+t` SELECT MACHINES beside their Bevy pointer forms, README exposes terminal selection, and terminal law names the live cursor toggle instead of its retired box-prompt description — [inventory log](../log/2026-08-04-keymap-complete-binding-inventory.md). The earlier chord-local repair stands: terminal captures only complete Ctrl/Command+S/L chords, routes those and F3 before modal text, and lets every unrelated modified key reach its current surface — [persistence log](../log/2026-08-04-terminal-persistence-chords.md). Prior A-key and semantic-jump reconciliation stands — [prior](../log/2026-07-26-terminal-keymap-a-reconciliation.md). |