The petrova.blog version band is bound to its sources, not written down
Date: 2026-08-06
Status: closed
Supersedes: none
Superseded-by: none — current
Implements: docs/specs/2026-08-05-petrova-apex-domain-topology.md §4 items 1–2
Context
Section titled “Context”PETROVA-APEX §4 flags the petrova.blog version band as the one item in the
whole apex proposal that is unambiguously safe to fix today, and as a genuine
MR-12 defect. It read:
v0.4 · MR-1..MR-12 · 8 fleets · updated 2026-05-11Every cell after the first was false:
| Cell | Claimed | Actual |
|---|---|---|
| MR range | MR-1..MR-12 | MR-1..MR-17 — 17 ## MR-N headings in core/playbook/META-RULES.md, and the same 17 in the canonical eva-hq copy |
| unit count | 8 fleets | 39 registry entries; the console says 39 REPOS. “Fleet” was never defined on the page |
| date | updated 2026-05-11 | ~3 months stale |
MR-12 says the CLAUDE.md is the projection, not the source. The band is a projection by exactly that definition, and it had drifted from all three of its sources — on the front page of the surface that publishes MR-12.
Root cause
Section titled “Root cause”The band was three string literals inside ensureRootIndex in
site/scripts/pull-content.ts, the script that materialises the landing page on
prebuild. A literal cannot notice that META-RULES gained five rules.
A second mechanism kept it alive: ensureRootIndex returned early when
index.md already existed, and index.md was the one path exempted from
site/.gitignore’s “pulled content is regenerated on every build” rule. So the
generated landing was also a committed file that no build would ever refresh.
Editing the committed copy and editing the template were two different acts, and
only one of them survived a build.
Decision
Section titled “Decision”Each cell is read at build time from the thing it describes. bandCells()
in pull-content.ts reads:
- the MR range from
core/playbook/META-RULES.md, counting## MR-Nheadings (headings, not mentions — the file cross-references MR numbers throughout its prose). That file is the in-repo mirror of the canonicaleva-hq/prompts/_shared/petrova/META-RULES.md; - the repo count from
registry.yaml; updatedfromgit log -1 --format=%cs.
A missing or unparseable source throws. No fallback literal. Silently
substituting a stale constant is the defect being removed; a red build is the
honest signal. Verified by moving META-RULES.md aside and confirming prebuild
fails with a named error rather than emitting a band.
8 fleets becomes 39 governed repos. §4 item 2 asks for the unit to be
named. “Fleet” appeared on no other surface and read as a contradiction next to
the console’s 39 REPOS; the registry counts repos, so the band counts repos.
ensureRootIndex now rewrites the landing on every prebuild, and index.md
is no longer tracked — the !src/content/docs/index.md exemption is removed
from site/.gitignore. The template lives in the script; the file is output.
Tracking output would dirty the tree on every build (the updated cell moves
with each commit) and would let a stale copy reappear in review, which is how
this defect survived.
The “cross-cutting MR-1..MR-12 set” subtitle in the same page’s start-grid carried the same stale range. It now reads “the cross-cutting meta-rule set” — no number to drift. This follows PETROVA-APEX §5 item 3, which asks that no apex copy cite an MR by number while the numbering is contested.
Rejected alternative
Section titled “Rejected alternative”Converting the landing to .mdx and computing the band in an Astro component.
Attempted first, and abandoned: the page body is hand-written HTML with a
fenced mermaid block, and MDX’s expression parser rejects it
(Unexpected content after expression). The generator was the correct binding
point regardless — it is where the template already lived.
This is §4 items 1 and 2 only. Deliberately not done here:
- §1 —
petrova.blueis not registered. That is a purchase. - §3 — the
petrova.hostre-root. A routing change against a live operator surface; §6 asks for its own decision doc first, per MR-7. - §4 item 3 — the reciprocal
petrova.hostlink above the fold. Blocked ondocs/decisions/2026-05-13-cross-platform-nav-contract.md, stillopen, and now governing four surfaces rather than three.
Consequences
Section titled “Consequences”- The band cannot drift again without a build failure or a visibly wrong number
in a diff of
pull-content.ts. site/src/content/docs/index.mddisappears fromgit ls-files. A clean checkout has no landing page untilprebuildruns — which is true of all 207 other pages undersrc/content/docs/already.- The band now depends on
core/playbook/, so a site build requires that mirror to be present. It is in-tree (not a submodule) since 2026-05-14, so this adds no checkout step. - Verified: 208 pages built,
MR-1..MR-12occurs zero times in the output, and the landing regenerates correctly from a tree with noindex.md.
Sign-off
Section titled “Sign-off”- Subagent: apex fold (this session)
- Human: alex@devarno.com — 2026-08-06