From b6db9c31f52e6b819d5de53d50456982dce7937e Mon Sep 17 00:00:00 2001 From: Dai Ha Date: Thu, 10 Sep 2026 08:22:35 +0700 Subject: [PATCH] charter: a peer lead is answered with fleet_send, not fleet_reply MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `fleet_reply` has no route to a peer lead. `AmqpReplyInbox` publishes to `agent..inbox`, mandatory, and a lead's own terminal has no such queue, so the publish is refused. `MessageService.reply()` has no peer branch at all — `grep -c 'coord\|LeadMailbox'` on it returns 0. The charter told every lead to use a tool that cannot work, and both leads here hit it. Three edits to the canonical block, byte-identical with the wiki template (pushed as 803726a; the in-sync check in this file reports True): - the intent->tool row now says `fleet_send{coordId}`, or `{sessionId}` for a peer on the same host, and says plainly that `fleet_reply` is refused - the prose says WHY: `fleet_reply` resolves a member's blocked `fleet_send`, while a peer's coord-id message is durable and non-blocking, so there is nothing for it to resolve - lead<->lead item 3 gains the data-point rule: N observations are N data points only if they differ in the axis you are trusting Wording for all three drafted by the fleet01 lead, who verified the missing queue namespace independently in its own tree. The data-point rule has now caught three separate errors in a day, in both directions: one cause blamed for N failures, and N agreeing measurements that shared a single instrument. The refusal message itself is still wrong — it says "queue not declared or owned", which sends the reader to the broker instead of to this file. That half stays open on #391. Tracked as fleetd #391. --- CLAUDE.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index fc78a72..29d90a1 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -137,7 +137,7 @@ the merge — and merging on a reviewer's word is delegating it by proxy. | Answer a member's `fleet_ask` | `fleet_send{turnId, content}` — **not** `sessionId` | | Message a **peer lead** on this host | `fleet_send{sessionId: , content}` — `fleet_list` → `leads` reports it. Coordination only, **never** a task | | Message a **peer lead** on another daemon or host | `fleet_send{coordId: , content}` — needs a `coordinator:` block; your own coord-id is in `fleet_list`. Coordination only, **never** a task | -| Answer a peer lead that messaged you | `fleet_reply{content}` — the one case a lead replies | +| Answer a peer lead that messaged you | `fleet_send{coordId}` — or `{sessionId}` if they are on this host. **Not** `fleet_reply`: it has no peer route and the publish is refused | | Collect a held reply | `fleet_poll{target}` · then `fleet_ack{target, msgId}` | | Tear down a member | `fleet_stop{paneId}` | @@ -163,15 +163,21 @@ The traffic between leads is coordination and nothing else: 3. **Verify a peer exactly as you verify yourself.** Peer status buys nothing: check the claim against the code, and re-run the build. A peer's correction gets the same treatment — right or wrong on the evidence, not on who said it. Neither of you merges the other's work unreviewed. + **N observations are N data points only if they differ in the axis you are trusting.** This cuts + both ways. N *failures* blamed on one cause are one data point when the cases share what you are + not varying. N *agreeing measurements* are also one data point when they share an instrument — + two hosts, two operators and the same formula is one formula, not two confirmations. 4. **Ask a peer to read your project addendum.** Your addendum is instruction surface: every future session on your host obeys it, and a wrong one is obeyed just as faithfully as a right one. The author is the worst reader of their own qualifier placement — measured here, one addendum carried two defects and a non-author found both. If you have no peer, at least re-read it asking "which sentence goes false first, and would a reader reach the caveat before acting?" -Being messaged by a peer does not make you its worker: answer with `fleet_reply`, and push back on -the substance if it is wrong. A peer that simply complies has thrown away the reason there are two of -you. +Being messaged by a peer does not make you its worker: answer the way you would open — +`fleet_send{coordId}` for another daemon, `fleet_send{sessionId}` on this host — and push back on +the substance if it is wrong. `fleet_reply` resolves a member's blocked `fleet_send`; a peer's +coord-id message is durable and non-blocking, so there is nothing for it to resolve. A peer that +simply complies has thrown away the reason there are two of you. ### Member (worker or architect) — the turn contract