Commit graph

7 commits

Author SHA1 Message Date
11178fa168 feat(engine): warn on unknown coord-inbox arguments
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
2026-07-25 06:39:21 +02:00
9aa9e07d75 fix(engine): never deliver a broadcast back to its own sender
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
2026-07-25 06:11:26 +02:00
0a79e786fc feat(engine): harden mailbox CLIs for v0.2.0
- 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
2026-07-24 19:57:40 +02:00
2d70433adf feat(inbox): translate the read-side protocol strings to English
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
2026-07-24 01:42:15 +02:00
b9bec85a80 fix(inbox): replace the broadcast watermark with a per-repo seen set
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
2026-07-24 01:41:14 +02:00
3af724f209 fix(send): collapse CR/LF in subject/from before writing frontmatter
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
2026-07-24 01:39:56 +02:00
7a1c183492 feat(scripts): import coord engine verbatim from the local install
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
2026-07-24 01:38:28 +02:00