chore(release): bump to 0.30.0
Two commits landed after v0.29.0 and neither is reachable: every entry point on this machine runs the version-pinned plugin cache, not the tree. Minor rather than patch because the behaviour is EXTENDED, not merely repaired - coord-count.sh and board.sh gained a new exit status (3, "the world you named is not there"), and pre-state-line-guard.mjs gained CLAUDE_STATE_MAX_LINES. Exit codes are a contract, and the installed cache still runs the old one. Version synced across all seven version-bearing files - plugin.json, package.json, the README badge, and the four SKILL.md frontmatters - so release-plugin.mjs's plugin.json == README-badge == target check passes. The three remaining 0.29.0 mentions (CLAUDE.md:915, CLAUDE.md:960, board.sh:1388) are historical prose about when things shipped and must keep saying 0.29.0. CHANGELOG covers BOTH unreleased commits, not just the newest: d8fdeaa's five defects were one class - a failed measurement rendering as a reassuring value - and the entry carries what that session found about itself, that --plan's free-capacity test had to move from "$7 + 0" to a string comparison against "0", because "?" coerces to 0 in arithmetic and would have certified an UNMEASURED tree as free capacity. The defect reappearing one layer down, wearing the fix as a disguise. No tag and no catalog change: that is the catalog session's order, which runs release-plugin.mjs to do the tag and the ref bump atomically. Doing both here would take a decision on the catalog's behalf without its context. Suites verified under system bash 3.2, not Homebrew 5.3: coord 242, board 300, route 69, orders 110, guard 54; npm test 11/11. Order 20260826T115026Z-998059640-from-.claude
This commit is contained in:
parent
c5b4c9d6b6
commit
3e4a3bc62a
8 changed files with 112 additions and 7 deletions
105
CHANGELOG.md
105
CHANGELOG.md
|
|
@ -5,6 +5,111 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [0.30.0] - 2026-08-26
|
||||
|
||||
Two commits landed after `v0.29.0` and neither is reachable: every entry point
|
||||
on this machine runs the version-pinned plugin cache, not the tree. Minor
|
||||
rather than patch because the behaviour is EXTENDED, not merely repaired -
|
||||
`coord-count.sh` and `board.sh` gained a new exit status and the state-line
|
||||
guard gained an environment variable. Exit codes are a contract, and the
|
||||
installed cache still runs the old one.
|
||||
|
||||
All five defects here are the same class: **a failed measurement rendering as
|
||||
a reassuring value** - a broken or uninstrumented query returning a
|
||||
positive-looking null, consumed as a fact about the world.
|
||||
|
||||
### Fixed
|
||||
|
||||
- **`coord-count.sh`: a mailbox root that does not exist was byte-identical to
|
||||
one where nobody has pending mail** - zero lines on stdout, exit 0, nothing
|
||||
on stderr. `board.sh` consumes that TSV. The contract is now three statuses:
|
||||
0 = counted, 2 = usage error, **3 = mailbox root absent**. 3 rather than 2 on
|
||||
purpose: 2 already means "you called me wrong" and this means "the world you
|
||||
named is not there" - two different repairs, and a consumer that only ever
|
||||
sees one integer cannot tell them apart. Both nonzero paths print NOTHING on
|
||||
stdout, so neither can be mistaken for a count of zero. What the old
|
||||
"always 0" claim protected is kept and made precise: no state OF THE MAILBOX
|
||||
can produce a nonzero exit, so a SessionStart still cannot be failed by mail.
|
||||
An existing-but-empty root stays a silent, clean 0, and the selftest pins
|
||||
that silence as hard as it pins the failure.
|
||||
- **`coord-count.sh`'s header promised exit 0 unconditionally, and that was
|
||||
already false** - `--exclude` with no value exited 2 - so the documented
|
||||
contract contradicted code a reader could run. The header text is now pinned
|
||||
by a check of its own: a doc line nothing tests is a doc line that drifts,
|
||||
which is how this one drifted.
|
||||
- **`board.sh`: `git status --porcelain | wc -l` yields zero lines whether the
|
||||
tree is CLEAN or git refused to answer**, so DRT printed **0** and every
|
||||
reader took it as "nothing uncommitted here". Reachable, not theoretical:
|
||||
discovery tests `.git` with `-e` so worktrees are found, and a worktree whose
|
||||
parent checkout was deleted exits 128. The exit status is now the
|
||||
discriminator and an unmeasured tree reads **`?`** - the same token
|
||||
`coord-count.sh` already uses for an age it could not compute.
|
||||
|
||||
**The fix was worthless without its two awk consumers, and one of them is
|
||||
the point:** `--plan`'s free-capacity test compared `$7 + 0`, and `"?"`
|
||||
coerces to **0** in arithmetic - so an UNMEASURED tree would have been
|
||||
certified as free capacity. That is the defect reappearing one layer down,
|
||||
wearing the fix as a disguise. It now compares the field as a STRING against
|
||||
exactly `"0"`; only a tree measured clean is clean. The SUM roll-up, where a
|
||||
`?` would silently add 0, now NAMES the repos it could not add.
|
||||
- **`board.sh`: a scan root that does not exist was skipped in silence**, so a
|
||||
typo in `--roots`, a moved home directory and a genuinely empty tree were one
|
||||
single output with the denominator never reported. Every bad root is now
|
||||
named on stderr; the exit status changes only when NO root was scanned at all
|
||||
(**3**, for the same reason as above). A mix still exits 0 and still prints
|
||||
the board - some repos really were scanned. This REPLACES an older assertion
|
||||
reading `check "missing root is a clean no-op"`: the defect encoded as a
|
||||
passing test, which is why nothing ever caught it. `brief-nightly.sh` needs
|
||||
no change and gains from this - it already treats a nonzero `--brief` as
|
||||
failure and keeps yesterday's briefing, so a mistyped root now preserves the
|
||||
file instead of overwriting it with an empty render.
|
||||
|
||||
### Added
|
||||
|
||||
- **`CLAUDE_STATE_MAX_LINES` overrides the state-line guard's limit**, the same
|
||||
kind of knob `CLAUDE_COORD_DIR` is for the mailbox root. As a bare constant
|
||||
the limit forced every boundary fixture to hardcode the number the code
|
||||
carried - two copies of one policy, both rewritten by hand the last time the
|
||||
operator moved it (60 -> 120). It is **not** a bypass claim; this guard has
|
||||
always been escapable by writing the file another way. The one thing it must
|
||||
never do is silently fail to take effect, so an UNUSABLE value (`""`, `"0"`,
|
||||
negatives, anything not made of digits) **denies with a message naming the
|
||||
variable** instead of falling back to 120 - a caller who set it and got the
|
||||
default anyway would be reading a limit that was never in force.
|
||||
|
||||
### Changed
|
||||
|
||||
- **The README's Install block is now fenced (` ```bash `)** while the rest of
|
||||
the README keeps its indented blocks. The org-side D-census reported this
|
||||
repo as the only plugin of 12 with no start command; the premise was
|
||||
imprecise - the lines were present, indented - but the finding held, because
|
||||
the machine-readable entry point keys on a fenced block and 10 of 11 sibling
|
||||
plugin READMEs use one. Measured before and after: 11 of 11 now match. Only
|
||||
the Install block was converted; the other 39 indented blocks were not
|
||||
ordered changed and converting them would bury a two-line fix in a
|
||||
whole-file diff.
|
||||
|
||||
### Known gaps, stated rather than closed
|
||||
|
||||
- `coord-inbox.sh:57` and `coord-order-inbox.sh:60/64` carry the identical
|
||||
`[ -d "$COORD" ] || exit 0` shape that was fixed in `coord-count.sh`. The
|
||||
denominator was measured, not estimated, and they were deliberately left
|
||||
alone: they are the INJECTION path, their output is prose a session reads
|
||||
rather than a TSV a program parses, and their contract really is "never fail
|
||||
a SessionStart".
|
||||
- `board.sh` does not yet CONSUME `coord-count.sh`'s new exit 3. The signal
|
||||
exists; the `HAVE_COUNT` machinery does not read it. Tracked as separate
|
||||
work rather than widened into this release in silence.
|
||||
|
||||
### Testing
|
||||
|
||||
Suites at this release, verified under system bash 3.2 (not Homebrew 5.3):
|
||||
coord 242, board 300, route 69, orders 110, state-line-guard 54; `npm test`
|
||||
11/11. Every design choice above was mutation-tested, and every negative check
|
||||
carries a known-positive control - one selftest section's first cut was
|
||||
VACUOUSLY green (wrong basename, plus a fixture path that was never exported)
|
||||
and is recorded in `CLAUDE.md` rather than quietly fixed.
|
||||
|
||||
## [0.29.0] - 2026-08-23
|
||||
|
||||
Answers a question the board could not answer before: which repos are finished
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue