diff --git a/docs/plans/2026-08-20_w4-document-contract-worklist.md b/docs/plans/2026-08-20_w4-document-contract-worklist.md new file mode 100644 index 00000000..eb34f746 --- /dev/null +++ b/docs/plans/2026-08-20_w4-document-contract-worklist.md @@ -0,0 +1,152 @@ +--- +kind: tracking +status: active +--- + +# W4 — document contract worklist + +Companion to `2026-08-20_stack-docs-flatten-and-alignment.md`. That document proposes the +contract; this one records what was applied, what was held, and what still needs a decision. + +Measured on `origin/next` at `63069149`. Author: veronica. Review: fred (Gate-16, author is +not reviewer), then a pi seat for the adversarial pass. + +## What "live" means here + +All `*.md` under `docs/`, minus `docs/archive/`, minus `docs/_old_structure/`. That is **127** +files. The flatten plan says 130; the arithmetic does not close (318 total = 134 archive + +57 `_old_structure` + 127 live, not 130). + +## Applied + +| bucket | count | note | +| --- | --- | --- | +| stamped `kind` + `status: active` | 104 | this pass | +| held, operator judgement | 19 | section "Needs a decision" below | +| held, cites the moving path | 3 | the three `SUPERSEDED` TASKS.md stamps | +| already stamped in W1 | 1 | `docs/fleet/FLEET-DOCTRINE.md`, untouched | + +Kinds applied: 54 `guide`, 34 `record`, 9 `spec`, 6 `tracking`, 1 `projection`. + +`parent` is **not** applied. It points at `docs/fleet/NORTH_STAR.yaml`, which the flatten moves +to `docs/NORTH_STAR.yaml`. Stamping it now means re-pointing 127 files by hand later. It lands +after the move, in one pass, with the post-move path. + +## Held: the three superseded stamps + +`docs/TASKS.md:5`, `docs/federation/TASKS.md:5`, and `docs/fleet/TASKS.md:5` each carry a W1 +stamp of the form: + +> **STATUS: SUPERSEDED — 2026-08-20.** kind `tracking` · superseded by `docs/fleet/NORTH_STAR.yaml` + +Two problems, both real: + +1. **The tooling cannot read them.** That line is a blockquote below the H1, not YAML front + matter. Plan section 6 check 5 ("every live document has a header; no document is + unclassified") parses front matter, so all three read as unclassified. The control that the + parse itself works is `docs/fleet/FLEET-DOCTRINE.md:3`, which is genuine front matter. +2. **They cite the moving path.** Three of the six citations of `docs/fleet/NORTH_STAR.yaml` + are these stamps. Converting them before the flatten lands makes them stale on merge. + +Converted after the flatten, not before. + +## Needs a decision + +Nineteen rows. Seventeen are the plan's section 9 list, minus `docs/fleet/north-star.md` +(renamed to `FLEET-DOCTRINE.md` by W1, so the row is closed) and minus the two `.yaml` rows, +which are a different problem — see the next section. Two rows are new, found while +classifying. + +Fill the `kind` column with a value from the contract, or `superseded-by: `. + +| path | proposed | why it is not mechanical | +| --- | --- | --- | +| `docs/README.md` | `guide` | It also **prescribes** the competing front-matter convention (see below). Whatever kind it gets, its body needs an edit. | +| `docs/SITEMAP.md` | `guide` or `projection` | If it is generated from the tree it is a projection and needs a drift test. If hand-maintained it is a guide that goes stale silently. Nobody has said which. | +| `docs/federation/SETUP.md` | `guide` | Reads as a guide. Federation tier status is the open part: if the tier is shelved this is `superseded`. | +| `docs/fleet/FLEET-CONFIG-DOCS-IA-CHECKLIST.md` | `record` | An acceptance checklist is evidence of a past gate, which is `record`. But if it is still being checked against, it is `tracking`. | +| `docs/fleet/FLEET-LAUNCH.md` | `guide` | Runbook. Depends on whether `launch-seat.sh` is deprecated in favour of `mosaic fleet` (campaign W3). If so, `superseded`. | +| `docs/fleet/LEGACY-EXAMPLE-PROFILE-DISPOSITION-INVENTORY.md` | `record` | An inventory of dispositions taken. `record` unless dispositions are still pending, which the title implies they were once. | +| `docs/fleet/README.md` | `guide` | Section index. Low risk; listed only because the plan lists it. | +| `docs/fleet/backlog-conventions.md` | `guide` | Conventions decide things, and `guide` explicitly decides nothing. May be `spec`. | +| `docs/fleet/f4-matrix-connector.md` | `spec` | F4 is a workstream. Whether it is live or abandoned decides `spec` versus `superseded`. | +| `docs/native-kanban-sot/DOCUMENTATION-CHECKLIST.md` | `record` | Same question as the fleet IA checklist. | +| `docs/native-kanban-sot/INDEX.md` | `guide` | Index of the canon. If it is generated from the canon it is a projection. | +| `docs/native-kanban-sot/KBN-010-THREAT-AUTH-CONSTRAINT-GATE.md` | `spec` | 415 lines of normative gate. `spec` fits; confirm it is not superseded by the shared contract. | +| `docs/native-kanban-sot/KBN-101-DB-ROLE-SPLIT.md` | `spec` | As above. | +| `docs/native-kanban-sot/KBN-101-ENVELOPE-A.md` | `spec` | Title says "v6, FINAL". If v6 supersedes v1-v5 elsewhere, those need `superseded-by` pointing here. | +| `docs/native-kanban-sot/SHARED-CONTRACT.md` | `spec` | "Remediated Shared Contract v1". Same versioning question. | +| `docs/release-integrity/probe-inventory.md` | `record` | An inventory. `tracking` if probes are still being added to it. | +| `docs/webui/PHASE-P-STRUCTURE.md` | `spec` | Zero inbound references (plan section 5.4). Either wire it in or mark it superseded; the kind is the smaller question. | +| `docs/native-kanban-sot/TASKS.md` | **conflict** | The file says of itself: "This file is a build plan, not a task tracker, and is NOT superseded." The contract says `tracking` is "live state, single-writer (manifests, `TASKS.md`). **Never a spec**." The file claims to be the thing its name forbids. Either the file is wrong or the contract's `TASKS.md` shorthand is. | +| `docs/requirements/native-kanban-sot.md` | **conflict** | Plan section 5.2 says if it is hand-authored canon it is `source-of-truth`. The contract's own table says `source-of-truth` is **machine-readable**. This is prose markdown with normative MUST/MUST NOT, RATIFIED 2026-07-14, decision owner Jason. It cannot satisfy both rules. Either it is a `spec` or the machine-readable criterion is wrong. | + +The last two are not slow rows, they are contradictions inside the contract. They want an +answer about the contract, not about the file. + +## The contract collides with an existing one + +`docs/README.md` lines 150-160 already document a front-matter convention, with its own +allowed values: + +```yaml +--- +title: Human-readable page title +type: guide # guide | concept | reference | decision | rfc | runbook +audience: developer # user | admin | developer | all +status: current # current | draft | deprecated | historical +source_of_truth: false +--- +``` + +Adoption is 4 of 127 files: `docs/ADMIN-GUIDE/security/sso-providers.md`, +`docs/DEVELOPER-GUIDE/testing/lease-broker-operations.md`, +`docs/USER-GUIDE/getting-started/quickstart.md`, `docs/USER-GUIDE/product/web-dashboard.md`. + +`status` is in both schemas with **disjoint vocabularies**. `type` and `kind` are two names for +one idea with different value sets. `source_of_truth: false` is a boolean spelling of +`kind: source-of-truth`. + +What this pass did, and it is a decision someone should ratify or reverse: the new contract +wins. Those 4 files had `status: current` rewritten to `status: active` and gained `kind:`. +Their `title`, `type`, `audience` and `source_of_truth` keys were left alone. Nothing reads any +of them — `git grep source_of_truth` outside `docs/` returns zero hits — so no consumer broke. + +`docs/README.md` still prescribes the old convention. It is an operator row above, so this pass +did not edit it. Until it is edited, the repository documents two conflicting header +conventions and points authors at the one being retired. + +## The contract has no form for a YAML document + +Two of the plan's 20 rows are not markdown: `docs/fleet/examples/roster-v2.yaml` and +`docs/openapi-tess.yaml`. Front matter is a markdown convention. A `.yaml` file can carry a +leading `---` document, but then it is two YAML documents and every existing parser of that +file sees a change. + +This is not an edge case. It applies to **`docs/fleet/NORTH_STAR.yaml`, the source of truth +itself**, which is the one file the contract most needs to classify. Section 6 check 5 says no +document is unclassified. As written, the source of truth cannot comply. + +Options, none of them chosen here: exclude `.yaml` from the contract and say so; carry their +metadata in a sidecar; or add a top-level `kind:` key inside the YAML body rather than as front +matter, which for `NORTH_STAR.yaml` is a schema change. + +## Method, and what it cannot tell you + +Classification is per-file, by title and path, recorded with a confidence. It is not a regex +sweep. The plan's own warning stands and is why the 19 rows above are held rather than guessed: +the first classifier pass classed a RATIFIED requirements document as a projection. + +Rows marked `med` in the working manifest and not listed above: the five `docs/plans/*` specs, +`docs/fleet/migration/example-profile-disposition.md`, the one ADR +(`decisions/mos-runtime-portability-m1.md`, called `record` because an ADR records a decision +taken), and the one RFC (`rfcs/optional-ai-egress-gateways.md`, called `spec` because it +proposes work not yet built). Those eight are stamped and are the most likely to be wrong. + +## Verification + +- 104 of 104 files parse with the expected `kind` and `status` in front matter. +- The check was shown to reject a wrong kind before it was trusted (asserting + `kind: record` on a file stamped `guide` fails). +- The whole diff removes 4 lines, all of them `status: current`. +- 23 files untouched, matching 19 + 3 + 1.