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

4.8 KiB

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.