Files
stack/docs/plans/2026-08-20_w4-document-contract-worklist.md
T
veronica f6fbeaf57a docs(W4): response to the W5 adversarial pass, in the diff rather than a PR comment
pr-review.sh -n 1350 -a comment fails with HTTP 401 'invalid username, password or token'.
Measured cause with a control: veronica's seat token returns 200 on /api/v1/user and the shared
broker credential gitea-mosaicstack returns 401 on the same endpoint. The wrapper logic is fine,
the credential it is handed is dead, so the PR wrappers are down for every seat on this host.
MOSAIC_GIT_IDENTITY appears nowhere in credentials.sh, which is FD-9.

Constitution gate 8 makes that operation blocked, so the corrections land in the branch instead,
where they survive the PR anyway.
2026-08-20 19:55:23 -05:00

272 lines
22 KiB
Markdown
Raw 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.
---
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` | 103 | this pass |
| held, operator judgement | 19 | section "Needs a decision" below |
| held, cites the moving path | 3 | the three `SUPERSEDED` TASKS.md stamps |
| held, generated file | 1 | `docs/fleet/NORTH_STAR.md`, see below |
| already stamped in W1 | 1 | `docs/fleet/FLEET-DOCTRINE.md`, untouched |
Kinds applied: 54 `guide`, 34 `record`, 9 `spec`, 6 `tracking`.
`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.
## Held: the one generated file
`docs/fleet/NORTH_STAR.md` is a `projection` and was stamped in the first pass. The stamp was
**reverted before review**, because stamping it is self-contradictory in a way that is not
merely theoretical:
- The contract says a `projection` is "Generated. Never hand-edited." Adding front matter by
hand is a hand edit of a generated file, and the file's own banner says
"**Generated file — do not edit by hand.**"
- `renderNorthStarMarkdown()` at `packages/mosaic/src/commands/fleet.ts:373` emits the H1 as
its first line and no front matter at all.
- `fleet-north-star.spec.ts:110-114` asserts full-string equality between the renderer's output
and the committed file: `expect(rendered).toBe(committed)`. Before the stamp, line 1 of the
committed file was `# Mosaic Fleet — NORTH STAR`, matching the renderer. After it, line 1 was
`---`. The assertion fails.
So the header for a projection cannot live in the file. It has to be emitted by
`renderNorthStarMarkdown()`, which is a code change and belongs in the flatten PR alongside the
`resolveNorthStarPaths()` fix, not in a documentation pass.
This generalises: **the contract as written cannot classify any generated document without a
matching change to its generator.** `NORTH_STAR.md` is the only projection today, so the cost
is one function. It will not stay one.
## 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>`.
| 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
- 103 of 103 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`.
- 24 files untouched, matching 19 + 3 + 1 + 1.
## Response to the W5 adversarial pass
vision ran a refute-first pass on this branch at `37cd00e` from a fresh worktree. Three of its
points changed the branch. Everything is re-measured here before being acted on; where my
measurement disagrees with its stated evidence I say so.
### 1. `docs/fleet/NORTH_STAR.md` stamp reverted (`bea47543`)
vision raised this as **latent** and scoped to the flatten PR. It is **live in this PR**, so it
could not wait.
`fleet-north-star.spec.ts:110-114` is a drift test that reads the committed file from disk and
asserts full-string equality against `renderNorthStarMarkdown()`, whose first emitted line is the
H1 and which emits no front matter. Stamping changed line 1 from the H1 to `---`.
CI 2589 confirms it directly, no longer by construction:
```
× renderNorthStarMarkdown > matches the committed NORTH_STAR.md projection (regenerate if this fails)
→ expected '# Mosaic Fleet — NORTH STAR\n\n> **Ge…' to be '---\nkind: projection\nstatus: active…'
```
Reverted to `origin/next` verbatim. `git diff origin/next -- docs/fleet/NORTH_STAR.md` is 0 lines;
control on `docs/fleet/reference/cli.md` returns 13, so the diff command does report differences.
The consequence is a contract-level one, recorded in the worklist: **the contract as written
cannot classify any generated document without a matching change to its generator.** A `projection`
is "Generated. Never hand-edited," so its header has to come out of the renderer. That is a code
change and belongs in the flatten PR beside the `resolveNorthStarPaths()` fix. vision's
recommendation, and I agree with it.
Counts: stamped 104 → **103**. Untouched 23 → **24**.
### 2. The `docs/` qualifier (vision's C1)
Stated as asked. **"127 live documentation files" is true for `docs/` only.** Definition: all
`*.md` under `docs/`, minus `docs/archive/` and `docs/_old_structure/`. 318 total = 134 archive +
57 `_old_structure` + 127 live.
Repo-wide the phrase undercounts: 21 live markdown files sit outside `docs/` and outside any named
exclusion (17 under `guides/`, plus `README.md`, `AGENTS.md`, `CLAUDE.md`, `REPORT-A1207.md` at
root). This PR does not stamp them and does not claim to.
### 3. `format` failure, and what it says about the header (`8a55c041`)
CI 2589 also failed `prettier --check` on **exactly one file**: the plan document I hand-wrote.
Reproduced locally, rc=1, same single file. Fixed; the diff is 31 lines in, 31 out, all table
column padding.
Worth stating for the review rather than burying: **the other 103 stamped documents pass
`prettier --check` unchanged.** The `---\nkind:\nstatus:\n---` block is prettier-clean as applied.
The formatting failure was in my prose, not in the contract header.
### 4. R1: the evidence inverts, the finding gets stronger
vision asks for a `kind` change on `docs/DEVELOPER-GUIDE/architecture/channel-protocol.md`, on the
grounds that it "carries 7 normative MUSTs" while the contract says `guide` "decides nothing."
**The MUST count does not hold.** Uppercase RFC2119 terms (`MUST`, `MUST NOT`, `SHOULD`,
`SHOULD NOT`, `SHALL`, `MAY`, `REQUIRED`) in that file: **0 lines**. Control: the identical grep
returns 25 lines in `docs/requirements/native-kanban-sot.md`, so it finds them where they exist.
The seven lowercase "must" occurrences all _disclaim_ authority rather than assert it: "must not be
used as instructions", "must not be treated as current behavior", "must remain planned work", "must
first specify", "before it can become architecture guidance." The file's own banner reads "it is
not a runtime registry, an API contract, a requirements document."
**The citation half holds, and is larger than stated.** vision's line numbers are exact. I
restated them earlier with wrong directories, which is worth naming because it is the same method
failure fred and I already wrote up as C3 in the flatten plan: I matched on basename and assumed
the path. The real ones, plus the two vision did not list:
| citing document | line | words used |
| ------------------------------------------------------- | ---- | --------------------------------------------------- |
| `docs/ADMIN-GUIDE/security/discord-ingress.md` | 141 | "**canonical** shared-contract and parity boundary" |
| `docs/DEVELOPER-GUIDE/integrations/channel-adapters.md` | 28 | "The **canonical** architecture summary is" |
| `docs/DEVELOPER-GUIDE/integrations/channel-adapters.md` | 183 | "**Canonical** channel protocol architecture" |
| `docs/USER-GUIDE/workflows/discord-conversations.md` | 127 | "current shared types ... explicit parity boundary" |
| `docs/SITEMAP.md` | 54 | index entry |
| `docs/DEVELOPER-GUIDE/architecture/README.md` | 18 | index entry |
So the tension is real. Three live documents outside the two indexes cite it, across four
citations, and three of those four use the word "canonical" for a document that spends its own
banner denying it is canonical. **It is just not a MUST problem, and that
changes what the fix is.** If the file is telling the truth about itself, the three "canonical"
citations are wrong and the edit belongs in those three files, not in this one's `kind`.
**Left as `kind: guide` in this PR and flagged for the reviewer's call.** Restamping on evidence
that inverts on reading would be worse than leaving it stamped and named.
### Unchanged
vision's C2 (no consumer), C4 (holding `parent` blocks nothing) and C5 (a front-mattered `.yaml`
throws in `YAML.parse`) all reverified. C1's arithmetic closes at the stated ref.