repo-mailbox/scripts
Kjell Tore Guttormsen 29a94dd7e4 fix(coord): refuse a control character in --to instead of sanitizing it
--to is the only line-oriented field sanitize_field never covered, and the
fix is a refusal rather than a sanitize pass because --to is also the
destination DIRECTORY name ($COORD/$TO/inbox, and $COORD/$TO/orders in
coord-order-send.sh). Collapsing a newline to a space would deliver the
message to a mailbox the sender never named - the same misdelivery the
retired ktg-plugin-marketplace address is rejected rather than redirected
to avoid.

Both corruptions were measured on the live engine first, each with exit 0
and a "delivered" line:

  --to "x\nreply-expected: no"  the injected line lands INSIDE the
      frontmatter block, above the reply-expected: yes the engine itself
      wrote, so coord-count reads owed=0 and the declared debt is silenced -
      defeating coord-count's own rule that only the frontmatter block may
      speak, since the injected line IS in the block.
  --to "tabbed<TAB>repo"        coord-count prints five tab-separated fields
      where its contract is four, so a consumer reads the mailbox name as the
      part before the tab and the pending count as the part after.

board.sh consumes that TSV, so both reach the board.

The guard sits after reply-mode resolution: --reply-to takes its target from
the original's from: line, untrusted cross-repo input, and that is the one
target name nobody typed.

Denominator measured rather than assumed: two scripts build a directory from
a caller-supplied name, and coord-order-send.sh had the identical defect,
where it costs more - an order filed under a name no session can hold is the
silent evaporation the ownership chain exists to prevent, while board.sh's
ORDRE column counts the intended repo's queue and stays 0 with nothing
reporting a failure. The read-side --repo arguments resolve an EXISTING
directory, so a control character there finds nothing and writes nothing;
checked and left alone.

Closes finding 7 of docs/2026-08-14-confident-zero-review.md.

Tests (red first, both suites): coord-selftest section 35 (10 checks) and
orders-selftest section 10 (6 checks), each with the mandatory
known-positive controls - an ordinary name still delivers, and so does a
dot-prefixed one, since a dot name is a real repo. coord 230/230, board
252/252, route 69/69, orders 110/110, guard 40/40, npm test 11/11.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AgKcURiXwGKhqCKhwD1NAp
2026-08-18 17:00:34 +02:00
..
board-selftest.sh fix(board): discover dot-prefixed repos (.profile) without dotglob's scope creep 2026-08-18 15:01:00 +02:00
board.sh fix(board): discover dot-prefixed repos (.profile) without dotglob's scope creep 2026-08-18 15:01:00 +02:00
brief-nightly.sh feat(brief): render the nightly cross-repo briefing without a model 2026-08-01 22:38:46 +02:00
coord-count.sh fix(coord-count): distinguish claimed from unmeasured, fix Linux date parse 2026-08-14 23:44:01 +02:00
coord-done.sh feat(engine): make a bulk close state what Rule 7 says must be stated 2026-07-31 15:48:42 +02:00
coord-inbox.sh feat(engine): let a message say it needs no answer, and count debt without losing sight of the rest 2026-07-31 15:46:14 +02:00
coord-order-claim.sh fix(orders): call the order-verbs by absolute path, not bare PATH names 2026-08-18 09:16:59 +02:00
coord-order-done.sh fix(orders): narrow the return-reason escape so a plain arrow survives 2026-08-17 21:24:37 +02:00
coord-order-inbox.sh fix(orders): call the order-verbs by absolute path, not bare PATH names 2026-08-18 09:16:59 +02:00
coord-order-send.sh fix(coord): refuse a control character in --to instead of sanitizing it 2026-08-18 17:00:34 +02:00
coord-selftest.sh fix(coord): refuse a control character in --to instead of sanitizing it 2026-08-18 17:00:34 +02:00
coord-send.sh fix(coord): refuse a control character in --to instead of sanitizing it 2026-08-18 17:00:34 +02:00
coord-sweep.sh fix(coord-send): stop rejecting dot-prefixed repo names 2026-08-09 21:09:23 +02:00
orders-selftest.sh fix(coord): refuse a control character in --to instead of sanitizing it 2026-08-18 17:00:34 +02:00
route-selftest.sh feat(route)!: Fable rows are a hand-written override, never a route.sh outcome 2026-08-09 22:03:05 +02:00
route.sh feat(route)!: Fable rows are a hand-written override, never a route.sh outcome 2026-08-09 22:03:05 +02:00
state-line-guard-selftest.sh feat(state-line-guard): deny status=done while commits are unpushed 2026-08-16 22:06:44 +02:00