feat(engine)!: counting is not delivering, and an empty inbox is not all clear
Reading IS delivery in this engine: coord-inbox.sh prints a broadcast and then records it as seen. That made "what is pending elsewhere" unanswerable -- asking the read path per repo would have consumed every repo's broadcast backlog as a side effect, once, silently, and unrecoverably, since the seen set is delivery history that retraction deliberately leaves alone. coord-count.sh answers it by counting files and writing nothing: no seen set, no .origin. It keys on MAILBOXES rather than repos -- it enumerates $COORD/* and never scans a filesystem for checkouts -- so a repo without a mailbox is not missing from the count, it is absent from the domain. Drained mailboxes are omitted rather than reported as zero, because the question is "who is owed a reply" and a list of zeroes answers a different one at every reader's expense. The read path now closes with one aggregate line built from it. The case that motivated this is the session whose own inbox is empty: it saw silence and concluded "all clear" while mail sat unanswered everywhere else. BREAKING (injection contract): the read path is no longer silent whenever THIS repo has nothing pending. It is a silent no-op only when the whole mailbox is empty. Coupling the line to having your own mail would have hidden it from its only real audience. Three selftest assertions that used "no output at all" as a proxy for "nothing was delivered" now assert the absence of the content itself, which is what they always meant. The line is an AGGREGATE of two integers, never a roster. A list of names would reproduce other repos' situation inside this repo's injection -- the state boundary the mailbox exists to respect -- and mailbox names are cross-repo input. Two integers cannot carry anything that escapes the framing. Its disclaimer is engine behavior, not politeness (Rule 7): the line lands directly beneath "handle this inbox FIRST", and without it the numbers read as an extension of that obligation and a session starts answering other repos' mail. Pinned in selftest section 26 exactly as section 20 pins the priority text. The hook's header drops "(unread messages)" for the same reason -- it would now announce mail that does not exist. Selftest 116 -> 136. Every new negative check is anchored to a positive assertion in the same output, because a missing script makes "X is absent" true by vacuity and would have gone green proving nothing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U6EixQo6hpoRCVtiAXdnFs
This commit is contained in:
parent
28e7cb42cd
commit
ec92c866c1
10 changed files with 303 additions and 20 deletions
46
CHANGELOG.md
46
CHANGELOG.md
|
|
@ -5,6 +5,52 @@ 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.8.0] - 2026-07-27
|
||||
|
||||
### Added
|
||||
|
||||
- **`coord-count.sh` — counting without delivering.** Reading *is* delivery in
|
||||
this engine: `coord-inbox.sh` prints a broadcast and then records it as seen,
|
||||
so there was no way to ask "what is pending" without answering it. Asking per
|
||||
repo would have consumed every repo's broadcast backlog as a side effect —
|
||||
once, silently, and unrecoverably, since the seen set is delivery history that
|
||||
retraction deliberately leaves alone. `coord-count.sh` counts files instead
|
||||
and writes nothing: no seen set, no `.origin`.
|
||||
|
||||
It keys on **mailboxes**, not repos. It enumerates `$COORD/*` and never scans
|
||||
a filesystem for checkouts, so a repo without a mailbox is not missing from
|
||||
the count — it is absent from the domain. Drained mailboxes are omitted rather
|
||||
than reported as zero, the reserved `_` namespace is skipped, and `--exclude`
|
||||
drops one mailbox (the caller's own).
|
||||
|
||||
- **A cross-repo line in the SessionStart injection.** A session whose own inbox
|
||||
was empty saw silence and concluded "all clear" while mail sat unanswered in
|
||||
every other mailbox. The read path now appends one aggregate line:
|
||||
|
||||
Elsewhere in the mailbox: 3 unhandled messages across 2 other mailboxes.
|
||||
Counted, not delivered -- none of it is yours to handle here. Run
|
||||
coord-count for the per-mailbox breakdown.
|
||||
|
||||
Deliberately an **aggregate of two integers, not a roster**. A list of names
|
||||
would reproduce every other repo's situation inside this repo's injection —
|
||||
the state boundary the mailbox exists to respect — and mailbox names are
|
||||
cross-repo input. Two integers cannot carry anything that escapes framing.
|
||||
|
||||
The disclaimer is engine behavior, not politeness (Rule 7): the line lands
|
||||
directly beneath *"handle this inbox FIRST"*, and without it the numbers read
|
||||
as an extension of that obligation. Pinned in selftest section 26, exactly as
|
||||
section 20 pins the priority text.
|
||||
|
||||
### Changed
|
||||
|
||||
- **BREAKING (injection contract): the read path is no longer silent whenever
|
||||
*this* repo has nothing pending.** It is now a silent no-op only when the
|
||||
whole mailbox is empty. The empty-inbox session is precisely the one that
|
||||
needed the cross-repo line, so coupling the line to having your own mail would
|
||||
have hidden it from its only real audience. Three selftest assertions that
|
||||
used "no output at all" as a proxy for "nothing was delivered" now assert the
|
||||
absence of the content itself, which is what they always meant.
|
||||
|
||||
## [0.7.0] - 2026-07-27
|
||||
|
||||
### Added
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue