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.
170 lines
7.3 KiB
Markdown
170 lines
7.3 KiB
Markdown
# Changelog
|
|
|
|
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.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-done` is 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).
|
|
`--from` overrides 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).
|
|
|
|
- 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-marketplace` after 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. `--retract` is now the supported path.
|
|
|
|
## [0.3.0] - 2026-07-25
|
|
|
|
### Changed
|
|
|
|
- **Renamed the plugin and repository from `coord` to `repo-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
|
|
from `open/coord` to `open/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-send` rather 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 name `coord-send`, the
|
|
mailbox root `~/.claude/coord/`, and the `CLAUDE_COORD_DIR` override. 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 checks` for this plugin; the actual count
|
|
has been 70 since v0.2.2.
|
|
|
|
## [0.2.2] - 2026-07-25
|
|
|
|
### Changed
|
|
|
|
- `coord-inbox.sh` now 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.sh` already enforces in the injection
|
|
framing.
|
|
|
|
## [0.2.1] - 2026-07-25
|
|
|
|
### Fixed
|
|
|
|
- Broadcast self-delivery: `coord-send --broadcast` left 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 the
|
|
`from:` 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-to` and `coord-done`
|
|
name guards instead of relying on downstream failure.
|
|
|
|
### Added
|
|
|
|
- `-h`/`--help` on `coord-inbox.sh`, making usage output uniform across the
|
|
three CLIs.
|
|
- Selftest: 48 -> 64 checks, closing gaps around the default mailbox path via
|
|
`HOME` fallback, 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 as
|
|
`additionalContext`. Always exits 0 — a broken mailbox never blocks a session.
|
|
- `coord-send` skill: 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`/`--from`
|
|
are 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.
|