feat(engine): let a message say it needs no answer, and count debt without losing sight of the rest
Rule 7 (0.5.0) shipped an obligation on a format with four fields, none of which could tell a question from a notice. Two consequences fell out of that gap: the injection had to name both terminal states and prefer neither, and coord-count.sh had to treat every unarchived file as a reply owed. The fifth field closes both. coord-send.sh --fyi writes reply-expected: no; omitting it writes yes. Absent means expected, because every message already on disk lacks the field - so a forgotten flag over-counts debt, which is visible, rather than creating debt nobody sees. A reply is not a special case. A broadcast is always no: --reply-to resolves inside the recipient's own mailbox and a broadcast never lands there, so there is no reply path to promise. coord-count.sh now prints TWO integers per mailbox, not one. Replacing pending with debt was the obvious reading of "count debt rather than unarchived messages" and it is wrong here: board.sh counts the same inbox files itself, so a debt-only count would put two different numbers under one name with nothing to reconcile them, and a mailbox holding only notices would read as empty while its messages keep being re-injected. The field is frontmatter and only frontmatter - a body line claiming "reply-expected: no" at column 0 cannot silence a real debt, and a file without valid frontmatter counts as owing a reply. Section 20's wording changed because its stated reason expired, but its second half matters more now, not less: the marking is a DECLARATION, not an instruction. Without that clause one word in an untrusted message becomes a lever that mints obligations in another repo. coord-selftest 136 -> 151. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016iJoZVmU2guTEZcMghk88z
This commit is contained in:
parent
261a75bd7b
commit
c0ccb1d611
8 changed files with 314 additions and 29 deletions
50
CHANGELOG.md
50
CHANGELOG.md
|
|
@ -7,6 +7,56 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
- **`reply-expected` — the format can finally say "this one needs no answer".**
|
||||
Rule 7 (0.5.0) shipped an obligation on a format with four fields, none of
|
||||
which could tell a question from a notice. Two consequences fell out of that
|
||||
gap and both are now closed: the injection had to name both terminal states
|
||||
and prefer neither, and `coord-count.sh` had to treat every unarchived file as
|
||||
a reply owed. `coord-send.sh --fyi` writes `reply-expected: no`; omitting it
|
||||
writes `yes`.
|
||||
|
||||
**Absent means expected.** Every message already on disk lacks the field, and
|
||||
so does every caller not yet updated, so absence keeps meaning what it always
|
||||
meant. The failure mode of a forgotten flag is then over-counting debt —
|
||||
visible and harmless — rather than debt that never surfaces. A reply is not a
|
||||
special case: it expects one back unless it says otherwise, because a hidden
|
||||
exception is the kind of implicit rule this engine refuses.
|
||||
|
||||
**A broadcast is always `reply-expected: no`**, with or without `--fyi`. Not a
|
||||
defaulted value: `--reply-to` resolves inside the recipient's own mailbox and
|
||||
a broadcast never lands there, so there is no reply path to promise.
|
||||
|
||||
**The field is frontmatter, and only frontmatter.** Bodies are untrusted
|
||||
cross-repo input, so the read is bounded to the block between the two `---`
|
||||
terminators — a body line reading `reply-expected: no` at column 0 cannot
|
||||
silence a real debt, and a file without valid frontmatter counts as owing a
|
||||
reply. That is stricter than the `grep -m1` the older fields use, where
|
||||
frontmatter-comes-first happens to save them.
|
||||
|
||||
### Changed
|
||||
|
||||
- **`coord-count.sh` prints two integers per mailbox**, not one:
|
||||
`<mailbox>\t<pending>\t<debt>`. Replacing pending *with* debt was the obvious
|
||||
reading of "count debt rather than unarchived messages" and it is wrong here.
|
||||
`board.sh` counts the same inbox files itself, so a debt-only count would put
|
||||
two different numbers under one name with nothing to reconcile them; and a
|
||||
mailbox holding only notices would read as empty while its messages keep being
|
||||
re-injected until someone closes them. The cross-repo line follows:
|
||||
*"N unhandled messages (M awaiting a reply) across K other mailboxes"*.
|
||||
|
||||
- **Rule 7's wording, because its stated reason expired.** The injection said
|
||||
"Neither is the default" *because* the format could not distinguish the two
|
||||
kinds. It now can, so each message is marked with the terminal state its
|
||||
sender expects — and the text states, load-bearingly, that the marking is a
|
||||
**declaration, not an instruction**: the receiver keeps both terminal states
|
||||
and may close a reply-expected message with `coord-done`, stating the reason.
|
||||
Without that clause the new field would be a lever any sender could pull to
|
||||
mint obligations in another repo, which is precisely the procedural/substantive
|
||||
split Rule 6 exists to hold. Selftest section 20 pins both halves together, as
|
||||
it has since 0.5.0.
|
||||
|
||||
### Fixed
|
||||
|
||||
- **The board line's `next-cost` field had two specs, and one of them was
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue