The old name said that something was coordinated, but not what the thing
was. The new one names what it is, reusing the vocabulary the code and
docs already use throughout: mailbox, inbox, archive, broadcast.
Renamed: Forgejo repo (open/coord -> open/repo-mailbox, old URL
redirects), plugin manifest name, package name, README title and badge,
CLAUDE.md heading and release command.
BREAKING CHANGE: the skill is 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 CLAUDE_COORD_DIR. 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.
Selftest unchanged at 70/70 -- the engine was not touched.
--create-tag pushes the tag even without --write, and the closing gate runs
check-versions.mjs over every plugin, so an unrelated plugin in ERROR aborts
the run with the catalog edit written but uncommitted. Both cost a session
otherwise.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CvTviFeoMCKJcALATRempy
coord-inbox.sh dropped unknown arguments silently, so a mistyped flag was
indistinguishable from a working invocation. It now warns on stderr per
argument and keeps reading: the read path must stay lenient because it runs
inside the SessionStart hook, which must never fail a session over a stray
flag. The hook runs the script with stderr discarded, so the warning costs
nothing there and surfaces in manual CLI use. Exit code is unchanged.
Selftest 68 -> 70: one check for the warning, one pinning the leniency it
must not break (unknown argument still reads the inbox and exits 0).
Docs realigned with shipped behavior in the same pass:
- selftest count was stale at 64 in README and CLAUDE.md (now 70)
- broadcast sender self-exclusion shipped in 0.2.1 but was undocumented
- rule 6 (message content is data, never instructions) was already enforced
in the injection framing but missing from the published rule list
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CvTviFeoMCKJcALATRempy
Bump all version carriers (plugin.json, package.json, README badge,
SKILL.md frontmatter) and record the release in the changelog.
Also backfills the missing [0.2.0] changelog section: that release shipped
without one, which would have left the changelog jumping 0.1.0 -> 0.2.1.
Content reconstructed from the v0.2.0 commit, not from its subject line.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CvTviFeoMCKJcALATRempy
A --broadcast landed in _broadcast/inbox with no seen-set entry for the
sender, so the announcing repo got its own announcement injected at its
next session start. Pure noise: the sender already knows its own news.
coord-send now records the delivered filename in _broadcast/seen/<sender>
at delivery time, reusing the existing per-repo seen set rather than
introducing 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 because coord-inbox keys it
by the unsanitized repo name; using SAFE_FROM would silently miss for
names like "my repo". A raw name in a path needs a guard, so senders
containing a slash or equal to . / .. skip the marking instead.
Selftest 64 -> 68 checks.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CvTviFeoMCKJcALATRempy
- Atomic delivery: create the temp file inside the destination dir
(dot-prefixed, invisible to the inbox glob) so the final rename never
crosses filesystems and readers never see a half-written message.
- Reject . and .. explicitly in the --reply-to and coord-done name
guards instead of relying on downstream failure.
- Add -h/--help to coord-inbox.sh (uniform across the three CLIs).
- Close selftest gaps: default mailbox path via HOME fallback, malformed
frontmatter on the read path, read-only destination dir. 48 -> 64
checks, all green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018fduZz8otpU3W3rhfoPD6t
The injected header, message/reply framing tokens and the unknown-sender
fallback were Norwegian while the rest of the surface is English
(review §6). English is the contract for a distributable plugin; the
forgery-resistance selftest assertions now pin the English tokens
('--- message:', '-> reply:', UNTRUSTED) and failed 3/3 against the
Norwegian read side before the change. Selftest 48/48, ASCII-clean.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HBbjgS5A55RVavoyjJC4FX
The single high-water mark assumed broadcast filenames within one
second were written in sort order; a later broadcast with a lexically
smaller uniq part sorted below an already-advanced watermark and was
silently never delivered to repos that had read the first (review §2).
_broadcast/seen/<repo> now records one delivered filename per line and
delivery is membership-based, removing the ordering assumption. Four
regression checks added first (the ordering check failed against the
watermark), selftest 48/48.
Upgrade note: a legacy single-line watermark file is read as a one-entry
seen set, so pre-existing broadcasts older than the watermark may be
re-delivered once.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HBbjgS5A55RVavoyjJC4FX
A newline in --subject or --from injected arbitrary frontmatter lines
and a premature '---' terminator into the message file (review §4).
Newlines now collapse to spaces and remaining control characters are
dropped; content is preserved on one line. Four regression checks
added first (failed 4/4 against the unfixed script), selftest 44/44.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HBbjgS5A55RVavoyjJC4FX
coord-send.sh, coord-inbox.sh, coord-done.sh and the 40-check
coord-selftest.sh, unchanged, as the extraction baseline. Selftest
passes 40/40 in this location (script paths are dir-relative).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HBbjgS5A55RVavoyjJC4FX