chore(release): v6.0.0 — "Prose is not a contract" (MAJOR: finding IDs name the check)
MAJOR, because M-BUG-28 changed what a finding ID means: the {NNN} in
CA-{SCANNER}-{NNN} names the CHECK, not its emission position. IDs are
therefore not unique per finding -- one check failing in three files emits
three findings sharing an ID -- and any consumer keying on `id` alone must
move to (id, file, line).
The release theme is a class of defect rather than a feature area. Three
sweeps (Q1, Q2, Q_AUDIT) kept surfacing the same shape: a command template
stated an invariant in prose, code on the other side depended on it, and
nothing checked that the two still agreed. Q1 put the write-scope gate in
code (measured: 9 writers under scanners/, 1 imported the gate). Q2 checks
each template's argv against the CLI that receives it (--stale-after 30
reached its CLI as one argument under zsh and was ignored while the command
reported success). Q_AUDIT measured and ranked the third instance --
data contracts hand-built by the model and parsed by engines that know one
frozen example -- with the recovery path on top, deliberately not yet fixed.
Measured this session, not carried forward:
37 commits since v5.13.0 (git log v5.13.0..HEAD --oneline | wc -l)
1752 tests, 0 failing, post-bump
self-audit --check-readme: PASS, readmeCheck.passed, 0 mismatches
check-versions.mjs: 0 ERROR (1 WARN = the unreleased bump this cut closes)
scanners 16, agents 7, commands 21, hooks 4, knowledge 8
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XKeJyEVn9GuBcBQbE6EYwm
This commit is contained in:
parent
c3af74dfbc
commit
b35ff449e8
3 changed files with 30 additions and 2 deletions
27
CHANGELOG.md
27
CHANGELOG.md
|
|
@ -7,6 +7,33 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
## [6.0.0] - 2026-08-18
|
||||
|
||||
### Summary
|
||||
"Prose is not a contract" — a MAJOR release whose theme is a *class* of defect rather than a feature
|
||||
area. Across three sweeps (Q1, Q2, Q_AUDIT) the same shape kept surfacing: a command template stated
|
||||
an invariant in prose, code on the other side depended on it, and nothing checked that the two still
|
||||
agreed. The write-scope **gate** was policy paraphrased in five templates while exactly one writer
|
||||
imported it. The **argv** a template built was never checked against the CLI receiving it —
|
||||
`--stale-after 30` arrived as a single argument, matched no flag, and the command reported success
|
||||
about a threshold the user had just overridden. And the **data contracts** — backup manifests,
|
||||
`state.yaml`, `scope.yaml` — are hand-built by the model and parsed by engines that know one frozen
|
||||
example. The first two are now enforced in code and tests; the third is measured and ranked in
|
||||
`docs/q-audit-prose-invariants.md`, with the recovery path (`rollback`) at the top as the surface
|
||||
that runs precisely when the user is already in trouble.
|
||||
|
||||
**Breaking — a finding ID's `{NNN}` names the check, not its emission position (`M-BUG-28`).**
|
||||
IDs are therefore not unique per finding: one check failing in three files emits three findings
|
||||
sharing an ID, and `(id, file, line)` is the instance key. Any consumer keying on `id` alone must
|
||||
move to the triple. `scanners/lib/finding-codes.mjs` is now the single authority — an undeclared or
|
||||
missing code **throws**, with no counter fallback, because a fallback lets a half-converted scanner
|
||||
ship IDs that look valid. Retired numbers are never reissued. Frozen `v5.0.0` baselines mask IDs
|
||||
rather than re-deriving them.
|
||||
|
||||
**37** commits since 5.13.0. **1752** tests, 0 failing. GAP dimensions **25 → 24** (one `/doctor`
|
||||
duplicate retired). No component-count change: scanners **16**, agents **7**, commands **21**,
|
||||
hooks **4**, knowledge entries **8**.
|
||||
|
||||
### Fixed
|
||||
- **`M-BUG-45` — `/config-audit knowledge-refresh --stale-after N` was silently dead under zsh.** The
|
||||
command built `STALE_AFTER="--stale-after 30"` and expanded it unquoted, relying on the shell to
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue