Commit graph

5 commits

Author SHA1 Message Date
316b8acdd2 feat(engine): retire a broadcast with coord-send --retract
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.
2026-07-25 15:11:47 +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
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