cc-os/plugins/os-doc-hygiene/openspec/changes/archive/2026-06-18-add-report-schema/proposal.md

81 lines
4.8 KiB
Markdown
Raw Normal View History

# Change: Add Report Schema
## Why
The machine report schema is the linchpin of doc-hygiene: it is the contract
that the `check` skill produces and that the `clean` skill, `sweep`, and the
token estimator all consume. Per the build order, it gates everything — no
component can be built correctly until the report's shape is fixed. The PRD and
CLAUDE.md state it is "designed and frozen first."
This change specifies that schema as a frozen contract before any code exists,
so that the deterministic core and the AI layers are built against a single,
stable structure rather than re-deriving it. It is spec-authoring only: no
scripts and no schema code are produced here.
## What Changes
- Define the **top-level machine report** structure: schema version, scan
metadata (scope, files scanned, generated-at timestamp, tool version), the
candidate **shortlist**, and a per-file **entries** list.
- Define the **per-file report entry** fields: `path`, `category` (with the
fixed stale/bloat sub-type taxonomy), `signals`, recommended `op`, `op_type`
(`deterministic` | `generative`), the op characterization booleans
`is_destructive` and `is_reversible`, a **derived** `safety_tier`
(`auto` | `confirm`), an optional `exact_edit` (present iff `op_type` is
`deterministic`), and a per-entry `token_estimate`.
- Fix the **category taxonomy** as a closed enum: stale =
`contradicted` | `orphaned` | `superseded` | `provisional` |
`completed-in-place` | `duplicated`; bloat = `distill` | `split` | `freeze`.
- Make **`op_type` a property of the chosen `op`** (not a free field, not a
subtype lookup): `op_type` must be consistent with `op`, with `exact_edit`
present iff `op_type` is `deterministic`, validated deterministically.
- Make **`safety_tier` derived deterministically** per invariant #7: the model
proposes `op`, `op_type`, `is_destructive`, and `is_reversible`; a script
function `safety_tier(op_type, is_destructive, is_reversible)` computes the
tier (generative ⟹ confirm; destructive or irreversible ⟹ confirm; only
deterministic + reversible + objective ⟹ auto). The model cannot emit `auto`
for a generative or destructive op.
- Scope the **`token_estimate`** to match the PRD build order: in v1 only
`raw_tokens` (deterministic local-tokenizer count, no API call) is required;
`injection_frequency` and `weighted_tokens` are optional/nullable v1 fields
whose population (injection-frequency weighting + bottom-up rollup) is the v2
bonus. The schema shape is fixed now so the contract never changes.
- Freeze the **`exact_edit.kind`** closed enum: one `kind` per deterministic op
family the PRD names (`delete-range`, `move-to-archive`, `insert-frontmatter`
for freeze-stamp, `replace-text` for known-target link fix, `dedupe` for
exact-dup removal), each with its required sub-fields and inherent
`(is_destructive, is_reversible)` characterization that feeds the `safety_tier`
derivation.
- Declare the schema a **frozen contract** enforced by `invariants.md` (which now
exists and carries the schema-freeze and `safety_tier` derivation invariants):
changing any field, enum value, or semantic requires updating `invariants.md`
with explicit human approval.
- Provide schema-shape verification: a **schema-validator script** plus two
hand-authored **schema fixtures** under `examples/golden/` (one valid machine
report, one invalid) proving the validator accepts/rejects correctly. These are
schema-shape fixtures, **not** classifier golden examples — the latter are
deferred until the `check` change exists (the classifier that would produce them
does not exist yet, so hand-authoring them now risks diverging from real
classifier output).
## Impact
- Affected specs: creates a new `report-schema` capability.
- Affected code: none yet. This is the contract every later component (scanner,
`check` skill, `clean` skill / patch-applier, token estimator, `sweep`) will
consume; those are out of scope here. The only artifacts this change produces
beyond the spec are the schema-validator script and the two `examples/golden/`
schema fixtures used to verify the schema shape.
- Human-readable report ownership: this change specifies only the **machine**
report. The human-readable `.md` report SHAPE is a sibling user-facing contract
owned by the upcoming `check` change. It is load-bearing for the confirm-tier
escalation UX (it is what the user reads when approving `confirm` ops), so it
must be treated as a contract in its own right — out of scope here, but its
owner is named so it is not left ownerless.
- Deferred: **classifier golden examples** are deferred to after the `check`
change (the classifier that produces them does not exist yet). This change ships
only schema-shape fixtures, which are distinct.
- Dependencies: none. This change is the first in the build order and unblocks
the deterministic core and the `check` skill.