refactor(doc): one route from a revision to an Archive (spec-wcr #2, #4) doc.Scan/DocumentSource were production-dead after service.Archive landed — their only consumer was doc's own test fixture — and they were the seam that made web's layering violation writable: a surface could reach past service/ into gitx and build its own archive. Deleted, so doc/ now owns no way to read a revision and service.Archive is the single route from rev to Archive. The fixture reads through ListDocuments + FromDocuments instead. TestScanReportsGitErrors covered an unknown revision failing rather than walking empty, which gitx did not test itself. Relocated there as TestWalkOfAnUnknownRevisionFails rather than dropped. linkHierarchy passed path.Dir(p.Path) where every other call site passes DirOf. Unobservable today: the two differ only at the space root, and there the section-proximity step is subsumed by the same-directory step above it, so "." only ever skipped a lookup that had already answered. Verified by reverting and re-running. Changed anyway — it stays unobservable only by coincidence of two ranking rules — with a test pinning the invariant that `parent:` resolves to whatever the same wikilink in the body resolves to. spec-wcr
feat: doc — warren's vault+render absorbed onto the git-object read path warren scanned a directory (filepath.WalkDir + os.ReadFile). There is no checkout here, so Scan walks a git tree through gitx instead and feeds the FromPages seam: the approved head, a pinned sha and a proposal branch are one code path with a different revision, and nothing downstream of Archive knows where its pages came from. Frontmatter is core's, not warren's. Front embeds core.Frontmatter and adds only what core deliberately does not model — parent, aliases, planned, and the ordered key list used for display and search text. Two parsers that disagree about a document header is a bug that surfaces in the ID registry months later. Documents key on their frontmatter id, falling back to their path: paths move and ids do not, and a duplicated id resolves to neither document rather than letting one win silently, matching what the merge already does with the approved branch. A header core rejects degrades to "no frontmatter" instead of failing, because --push-option=skip-validation means such a document can exist and refusing to render it would turn a typo into an outage.