Files
pom-omp/docs/VERIFICATION.md
Antigravity 7b714bfc6b fix: make audit gates evidence-backed and correct stale check-count claims
- wire npm audit (prod + full dev tree) through readGate instead of hardcoded NOT RUN reasons
- record real results: production 0 vulns PASS; dev tree 16 dev-only advisories FAIL, disclosed with reach and remediation
- docs/VERIFICATION.md: six checks -> seven, add package-metadata section and mutation row, record executed row-7 proof
- README/SETTINGS: replace six-gate wording with the actual gate ledger
2026-08-19 11:40:18 +02:00

173 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: Documentation verification
description: The seven documentation-contract checks in scripts/check-docs.mjs and how to prove they fail
---
# Documentation verification
`scripts/check-docs.mjs` is the drift detector for facts that are mirrored out of source into
Markdown, `POM.yml`, `package.json`, and `RELEASE.json`. Every fact POM documents has exactly one
canonical owner in `src/`, `scripts/`, or `package.json`; the checker fails when a mirror stops
matching its owner.
The checker is read-only, self-contained ESM, and imports only `node:fs`, `node:path`, and
`node:url`. It never writes files, never runs a build, and needs no `node_modules`, so it stays
runnable while the npm registry is unreachable.
## Running the checker
```bash
node scripts/check-docs.mjs
```
Each check prints one line, with actionable detail indented beneath a failure:
```text
PASS check 1/6 resource-package-parity
PASS check 2/6 command-parity
note: /pom resume is absent from src/command.ts HELP; allowlisted in KNOWN_COMMAND_DIVERGENCES
FAIL check 3/6 layout-contract
docs/INVENTORY.md:43 names "06_exports", which src/persistence.ts bootstrapProject never creates; the canonical names are 06_ledgers and 07_exports
POM docs verification FAIL (1/6: layout-contract)
```
The final line is `POM docs verification PASS` with exit code 0, or
`POM docs verification FAIL (<count>/7: <check names>)` with exit code 1. All seven checks always
run; one failure never hides another.
## The seven checks
| # | Name | Canonical owner | Mirrors checked |
|---|---|---|---|
| 1 | `resource-package-parity` | `src/prompts.ts`, `src/themes.ts`, `src/events.ts` | `package.json` `files` |
| 2 | `command-parity` | `src/command.ts` `HELP` | `README.md` command map, `POM.yml` `commands:` |
| 3 | `layout-contract` | `src/persistence.ts` `bootstrapProject` | `docs/INVENTORY.md`, `skills/pom/references/artifacts.md` |
| 4 | `prompt-order-contract` | `src/prompts.ts` `composePromptStack` and `renderStagePrompt` | `POM.yml` `prompt_precedence` |
| 5 | `link-and-orphan` | the `docs/` tree on disk | every `docs/*.md` page |
| 6 | `release-evidence` | `scripts/release-manifest.mjs` gate readers | `RELEASE.json` `verification` |
| 7 | `package-metadata` | `package.json` `repository`, `homepage`, `bugs` | canonical `loca.zone` hosts, no placeholders |
### 1. resource-package-parity
Defends the published tarball against missing runtime resources. The checker regex-matches
`new URL("../<root>", import.meta.url)` in the three resource-loading modules, then asserts every
discovered root is listed in `package.json` `files` and exists in the repository. The root list is
derived from source on every run, so a newly bundled resource directory cannot be added in code and
silently left out of the package.
Historical defect: `prompts` was loaded by `src/prompts.ts` and `src/events.ts` but omitted from
`package.json` `files`, so an installed copy of the extension shipped without any prompt fragments
while the repository checkout worked. A hardcoded root list would not have caught it, and would
rot the next time a root is added, so discovery failure is itself a failure: if the regex matches
nothing the check reports a broken checker rather than an empty pass.
### 2. command-parity
Defends the advertised command surface. The verbs are extracted from the `HELP` template literal in
`src/command.ts`, from the `## Command map` table in `README.md`, and from the `commands:` block in
`POM.yml`. A bare `/pom` normalizes to the verb `dashboard`, and only the first token after `/pom`
is significant, so `/pom theme install` contributes `theme`. The three sets must agree.
Historical defect: `/pom settings` and `/pom doctor` were implemented and advertised by `HELP` but
missing from both documented command maps, so operators had no written record of two shipped verbs.
### 3. layout-contract
Defends the generated project layout. `06_exports` and `06_logs` are forbidden in
`docs/INVENTORY.md` and `skills/pom/references/artifacts.md`, and the canonical `06_ledgers` and
`07_exports` must both appear in `docs/INVENTORY.md`. Failures cite the offending line numbers.
Historical defect: docs described the export directory as `06_exports` and invented a `06_logs`
directory. `bootstrapProject` creates neither, so operators looked for output in paths that never
exist and scripted against directory names the kernel never writes.
### 4. prompt-order-contract
Defends prompt provenance ordering. `POM.yml` `prompt_precedence` must open with the immutable POM
production law that `composePromptStack` prepends, must state that project-local fragments replace
bundled fragments by matching ID, and must close with the executable stage contract. The stage
contract must appear only as the final entry.
Historical defect: the manifest listed the executable stage contract mid-list, contradicting
`renderStagePrompt`, which appends it last. Anyone reasoning about prompt precedence from the
manifest inferred the wrong effective law, since a later fragment overrides an earlier one.
### 5. link-and-orphan
Defends wiki navigability in two independent directions, reported separately. Every relative
Markdown link in `docs/*.md` must resolve to a path that exists on disk, with fragments and query
strings stripped and absolute, anchor-only, and scheme-qualified links skipped. Separately, every
`docs/*.md` page except `index.md` must be linked from `docs/index.md` or `docs/navigation.md`.
Historical defect: navigation entries used repository-root paths such as `README.md` and
`skills/pom/references/commands.md` from inside `docs/`, where they resolve to `docs/README.md` and
`docs/skills/...` and render as dead links. New pages were also added without a navigation entry,
leaving them reachable only by direct URL. The reachability half applies to this page too: a new
`docs/*.md` file, including `VERIFICATION.md`, must be linked from `docs/index.md` or
`docs/navigation.md` or the check reports it as unreachable.
### 6. release-evidence
Defends release honesty. Every key under `RELEASE.json` `verification` must be an object carrying a
`status` string of `PASS`, `FAIL`, `NOT RUN`, or `BLOCKED`. A bare string, number, null, or array
value fails, and so does an unrecognized status. `scripts/release-manifest.mjs` produces these
objects from evidence files under `00_admin/validation/`; this check is the regression guard that
keeps them evidence-bound.
Historical defect: the manifest carried hard-coded `"PASS"` strings for gates that had never been
executed, so the release claimed verification it could not support.
### 7. package-metadata
Defends canonical project coordinates. `package.json` `repository`, `homepage`, and `bugs` must each
be a string or an object carrying a string `url`, must not retain the `UNRESOLVED` placeholder, must
parse as absolute URLs, and must resolve to `loca.zone` or a subdomain of it, because no third-party
forge mirror has been confirmed for this package. A `repository.url` on owned infrastructure prints a
`note:` line recording its serving state.
Historical defect: the metadata fields carried `UNRESOLVED` placeholders, and later recorded a
`repository.url` that was reserved but not serving Git while the prose claimed it was usable.
## Known divergences
`KNOWN_COMMAND_DIVERGENCES` in `scripts/check-docs.mjs` is the only escape hatch, and it contains
exactly one entry: `resume`. `/pom resume [state-path]` is documented in the `README.md` command map
and in the `POM.yml` `commands:` block but is deliberately absent from `HELP`. `HELP` stays
canonical for what the built-in help advertises, the docs keep the verb, and check 2 prints the
divergence as a `note:` line so it stays visible while the check still passes deterministically. Any
divergence not in the allowlist fails.
## Mutation proofs
Each row is a specified procedure for proving that a check actually defends its contract: apply the
mutation, run `node scripts/check-docs.mjs`, confirm the named check reports `FAIL` with the
expected message, then revert the mutation and confirm the run returns to
`POM docs verification PASS`. Mutations are destructive edits to canonical files and must be
reverted before any commit or package step. Rows 16 specify the procedure and expected output
without recorded results. Row 7 was executed on 2026-08-19: pointing `homepage` at
`https://example.com/` produced `FAIL check 7/7 package-metadata` and
`POM docs verification FAIL (1/7: package-metadata)` with exit code 1, and restoring the file
returned `POM docs verification PASS` with exit code 0.
| Check | Mutation to apply | Expected failure |
|---|---|---|
| 1 `resource-package-parity` | Remove `"prompts"` from the `files` array in `package.json` | `FAIL check 1/7 resource-package-parity``package.json: files must contain "prompts" because src/prompts.ts and src/events.ts load it at runtime` |
| 2 `command-parity` | Delete the `/pom status [--json]` row from the `## Command map` table in `README.md` | `FAIL check 2/7 command-parity``/pom status is documented in src/command.ts HELP, POM.yml commands: but absent from README.md ## Command map` |
| 3 `layout-contract` | Rename `06_ledgers` to `06_logs` on the ledger line of `skills/pom/references/artifacts.md` | `FAIL check 3/7 layout-contract``skills/pom/references/artifacts.md:10 names "06_logs", which src/persistence.ts bootstrapProject never creates` |
| 4 `prompt-order-contract` | In `POM.yml` `prompt_precedence`, move the executable stage contract entry above the project-local fragment entry so it is no longer last | `FAIL check 4/7 prompt-order-contract``POM.yml: prompt_precedence must end with the executable stage contract appended by renderStagePrompt`, plus the misplaced-entry position |
| 5 `link-and-orphan` | In `docs/index.md`, change the Package inventory link target from `INVENTORY.md` to `INVENTORY-old.md` | `FAIL check 5/7 link-and-orphan``docs/index.md: broken relative link INVENTORY-old.md resolves to docs/INVENTORY-old.md, which does not exist on disk`, and `docs/INVENTORY.md: unreachable page` if `docs/navigation.md` no longer links it either |
| 6 `release-evidence` | Replace the `verification.runtimeSmoke` object in `RELEASE.json` with the bare string `"PASS"` | `FAIL check 6/7 release-evidence``RELEASE.json: verification.runtimeSmoke is the bare string "PASS"; every gate must be an evidence object carrying a status` |
| 7 `package-metadata` | Point `homepage` in `package.json` at `https://example.com/` | `FAIL check 7/7 package-metadata``package.json: homepage points at "example.com", which is outside the canonical loca.zone infrastructure` |
Row 5 mutates a link rather than deleting a file, so the mutation is a one-token edit and the revert
is exact. Row 6 must be reverted by regenerating the manifest with `npm run release:manifest` rather
than by hand, so the recorded hashes stay consistent with the packaged files.
## Relationship to the other gates
`node scripts/check-docs.mjs` is a documentation-contract gate, not a replacement for the release
ladder in `package.json`. It complements `node scripts/verify.mjs`, which checks structure and
counts, and `npm run release:check`, which proves `RELEASE.json` matches the packaged tree. The
documentation checker is the only gate that reads prose, so it is the only one that can catch a doc
that quietly contradicts source.