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
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "repo-mailbox",
|
||||
"version": "0.29.0",
|
||||
"version": "0.30.0",
|
||||
"description": "Local mailbox for coordination between Claude Code sessions in different repositories. Directed messages and broadcasts as plain Markdown files on your own disk, injected as context at session start. Local, private, no network.",
|
||||
"author": {
|
||||
"name": "Kjell Tore Guttormsen"
|
||||
|
|
|
|||
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
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ Session A in repo X leaves a message for repo Y; the next session in repo Y gets
|
|||
|
||||
*AI-generated: all code produced by Claude Code through dialog-driven development.*
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "repo-mailbox",
|
||||
"version": "0.29.0",
|
||||
"version": "0.30.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"engines": {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ description: >-
|
|||
user names no repo and no tool — choosing *between* repos is this skill. Not for
|
||||
"where were we" inside the current repo: that is this repo's own STATE.md,
|
||||
already injected at session start.
|
||||
version: "0.29.0"
|
||||
version: "0.30.0"
|
||||
---
|
||||
|
||||
# board — which repo deserves the next session
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ description: >-
|
|||
covers retiring a broadcast that has become wrong or obsolete: "retract that
|
||||
broadcast", "that announcement is outdated, pull it", "trekk tilbake kringkastingen",
|
||||
"den broadcasten er utdatert".
|
||||
version: "0.29.0"
|
||||
version: "0.30.0"
|
||||
---
|
||||
|
||||
# coord-send — natural-language front door for inter-repo messages
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ description: >-
|
|||
skill. Not for choosing WHICH repo deserves the next session (that is `board`),
|
||||
not for scoring model and effort alone (that is `route`), and not for sending a
|
||||
message to another repo (that is `coord-send`).
|
||||
version: "0.29.0"
|
||||
version: "0.30.0"
|
||||
---
|
||||
|
||||
# dispatch — hand a session a task it can actually start on
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ description: >-
|
|||
the operator names no model and no tool — choosing the model for the next
|
||||
session IS this skill. Not for choosing which REPO gets the next session:
|
||||
that is the `board` skill.
|
||||
version: "0.29.0"
|
||||
version: "0.30.0"
|
||||
---
|
||||
|
||||
# route — what the next session should run with
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue