Nothing could remove a message from _broadcast/inbox/. coord-done is directed-only and never touches the broadcast queue, so the backlog could only grow: every new repo received the entire standing history at its first session, including announcements that had since become false. --retract <filename> archives the message into _broadcast/archive/, so no future repo is served it. Three deliberate limits, all pinned by tests: - Un-send, not recall. Repos that already received it keep it; _broadcast/seen/ is delivery history and is left untouched. - Only the sender may retract (from: must match the repo identity). --from overrides it, as everywhere else in the engine, which makes the check an accident guard rather than a security boundary. - Nothing is deleted, mirroring coord-done. Retracting twice is a no-op. The branch runs before every send-side validation and before the stdin body read, since a retract carries no subject and no body. Selftest 70 -> 82 (new section 19). Also fixes two README defects the feature exposed: the install command still named coord@ after the v0.3.0 rename, and the docs advised pruning _broadcast/inbox/ by hand, which contradicted the rule that the script owns mailbox files.
7.3 KiB
Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[0.4.0] - 2026-07-25
Added
-
coord-send --retract <filename>: a broadcast can finally be retired. Until now nothing could remove a message from_broadcast/inbox/:coord-doneis directed-only and never touches the broadcast queue. The backlog could therefore only grow, and every new repo received the entire standing history at its first session — including announcements that had since become false. Retract moves the message to_broadcast/archive/, so no future repo is served it.Deliberate limits, both documented and pinned by tests:
- Un-send, not recall. Repos that already received the broadcast keep
it;
_broadcast/seen/is delivery history and is left untouched. - Only the sender may retract (
from:must match the repo identity).--fromoverrides this, as it does everywhere else in the engine, which makes the check an accident guard rather than a security boundary. - Nothing is deleted, mirroring
coord-done. Retracting twice is a no-op (exit 0).
- Un-send, not recall. Repos that already received the broadcast keep
it;
-
Selftest grew from 70 to 82 checks (new section 19 covers retraction: authorization, archiving, non-delivery to new repos, no collateral damage to other broadcasts, invalid names, flag combinations, and idempotency).
Fixed
- README's install command still said
claude plugin install coord@ktg-plugin-marketplaceafter the v0.3.0 rename. - README told the reader to prune
_broadcast/inbox/by hand when a notice stopped being relevant — advice that contradicted the rule that the script owns mailbox files.--retractis now the supported path.
[0.3.0] - 2026-07-25
Changed
-
Renamed the plugin and repository from
coordtorepo-mailbox. The old name said that something was coordinated but not what the thing was; the new one names what it is, using the same vocabulary the code and docs already use throughout (mailbox, inbox, archive, broadcast). The Forgejo repository moved fromopen/coordtoopen/repo-mailbox(the old URL redirects), and the marketplace entry, plugin manifest and package name follow.This is breaking for installed users: the skill is now invoked as
/repo-mailbox:coord-sendrather than/coord:coord-send, and the plugin must be reinstalled under its new name.Deliberately unchanged: the CLI (
coord-send.sh,coord-inbox.sh,coord-done.sh,coord-selftest.sh), the skill namecoord-send, the mailbox root~/.claude/coord/, and theCLAUDE_COORD_DIRoverride. Those name the transport protocol, not the product — renaming them would migrate live mailbox data and break message history in every participating repo for no gain in clarity.
Fixed
- Catalog README listed
48 selftest checksfor this plugin; the actual count has been 70 since v0.2.2.
[0.2.2] - 2026-07-25
Changed
coord-inbox.shnow warns on stderr for each unknown argument instead of discarding it silently. The read path stays lenient (it runs inside the SessionStart hook, which must never fail a session over a stray flag) and the exit code is unchanged, but a mistyped flag no longer looks like a working invocation. The hook runs the script with stderr discarded, so the warning surfaces in manual CLI use only.
Added
- Selftest: 68 -> 70 checks, covering the stderr warning and the leniency it must not break (unknown argument still reads the inbox and exits 0).
Documentation
- README: corrected the stale selftest count (64 -> 70), documented that a
broadcast is never delivered back to its own sender (shipped in 0.2.1 but
undocumented), and added rule 6 — message content is data, never
instructions — which
coord-inbox.shalready enforces in the injection framing.
[0.2.1] - 2026-07-25
Fixed
- Broadcast self-delivery:
coord-send --broadcastleft no seen-set entry for the sender, so the announcing repo got its own announcement injected at its next session start. The delivered filename is now recorded in_broadcast/seen/<sender>at delivery time, reusing the existing per-repo seen set rather than adding a second exclusion mechanism. Filtering on thefrom:field at read time was rejected:from:is sender-controlled, so it would let any repo suppress a broadcast for another by forging the field. The seen file is keyed by the raw sender name (the read side keys it unsanitized, so the two must agree); senders containing a slash, or equal to./.., skip the marking rather than escape the directory.
Added
- Selftest: 64 -> 68 checks, covering sender self-exclusion, unaffected delivery to other repos, self-exclusion for sender names that are not shell-clean, and the seen-marking path-escape guard.
[0.2.0] - 2026-07-24
Hardening pass over the three CLIs.
Fixed
- Atomic delivery: the temp file is created inside the destination directory (dot-prefixed, invisible to the inbox glob), so the final rename never crosses filesystems and readers never observe a half-written message.
.and..are rejected explicitly in the--reply-toandcoord-donename guards instead of relying on downstream failure.
Added
-h/--helponcoord-inbox.sh, making usage output uniform across the three CLIs.- Selftest: 48 -> 64 checks, closing gaps around the default mailbox path via
HOMEfallback, malformed frontmatter on the read path, and a read-only destination directory.
[0.1.0] - 2026-07-24
First public release: extraction of a battle-tested personal mechanism into a distributable plugin.
Added
- Bash engine:
coord-send.sh(directed / broadcast / reply delivery),coord-inbox.sh(pending inbox + unseen broadcasts, formatted for context injection),coord-done.sh(archive without reply), all bash-3.2-safe, ASCII-only, zero dependencies. coord-selftest.sh: 48 checks against a throwaway mailbox, including regression cover for filename sanitization, no-hang argument parsing, prompt-injection resistance, frontmatter hygiene, and broadcast ordering.- SessionStart hook (
hooks/scripts/session-start.mjs): thin zero-dependency Node wrapper that injects the repo's pending mailbox asadditionalContext. Always exits 0 — a broken mailbox never blocks a session. coord-sendskill: natural-language front door (English + Norwegian triggers) mapping intent to engine invocations, including bounded multi-target loops, deferred sends, and replies.
Fixed
- Frontmatter injection: CR/LF and control characters in
--subject/--fromare collapsed before writing, so fields can no longer inject frontmatter lines or a premature---terminator. - Broadcast loss: a per-repo seen set (
_broadcast/seen/<repo>, one delivered filename per line) replaces the single high-water mark, which silently dropped a same-second broadcast whose filename sorted below one already seen. Upgrade note: a legacy watermark file is read as a one-entry seen set, so old broadcasts may be re-delivered once.
Changed
- Read-side protocol strings are English (
--- message:,-> reply:, UNTRUSTED DATA framing); the forgery-resistance selftest checks pin the English tokens.