feat(bin): deliver local steers through durable task inboxes - #2856
Merged
Conversation
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains; the prior post-enqueue nonzero statuses now become successful delivered outcomes with explicit non-resend diagnostics, and the acknowledged parser-prefix behavior is unchanged. Reviews (8): Last reviewed commit: "no-mistakes: apply CI fixes" | Re-trigger Greptile |
kunchenguid
force-pushed
the
fm/fm-send-inbox-doorbell-r1
branch
from
August 23, 2026 11:17
0b16d56 to
571ed81
Compare
…orbell Stage 1 (local steers) of the captain-adopted reframe in data/fm-send-reliability-reframe-s1/report.md: an ordinary fm-send text steer to a task recorded in this home is appended as a sequenced durable record under state/<id>.inbox/ and the terminal receives only one constant self-describing doorbell line, best-effort. The worker acknowledges by moving the record into handled/; the watcher re-rings an unacknowledged message on an idle pane and escalates once as an ordinary stale wake. --resolve-key closes decisions at enqueue time, because the durable enqueue IS delivery to the task's record. bin/fm-task-inbox-lib.sh owns the record format, doorbell line, and re-ring ladder. The typed plane remains for what must reach the terminal itself: lifecycle keys, harness-native slash and codex $-skill invocations, explicit backend targets, and the remote secondmate leg (unchanged until the remote inbox leg ships separately). The composer classifier is demoted from delivery proof to an advisory ring guard that skips only on a proven pending verdict. Verified live against claude, codex, opencode, pi, grok, and muse: each real worker read its record, acted, and acked with the mv (docs/verification/runtime-backends.md "Steering-inbox doorbell").
…erved by the doorbell run
…x macOS wc padding in the tool-update suite
…failed exit out of stage 1 The CI monitor's fix changed the secondmate marking contract for parser-native invocations (appending the marker after the text) and softened the both-commit-and-marker-failed branch to exit 0. The merge authority ruled the marking question out of scope for this stage-1 transport PR (follow-up: fm-send-secondmate-harness-invocation-r1) and ruled the both-failed case a loud nonzero local failure. Restore both, keeping the monitor's legitimate migrations and hardening.
Captain-refined ruling on the F2/Greptile finding: the durable inbox record is what delivers the steer, so pending-reply bookkeeping trouble after a successful enqueue never exits nonzero - a resend-inviting status would make automated callers enqueue the delivered instruction again under a new sequence. With the recovery marker stored the watcher reconciles silently; with the commit and marker both lost the send surfaces a distinct reply-tracking-degraded do-not-resend warning and still exits 0. Nonzero remains only where nothing was delivered (or a decision close needs its manual command). Regression: record durable + both bookkeeping writes lost -> exit 0, one record, no duplicate.
kunchenguid
force-pushed
the
fm/fm-send-inbox-doorbell-r1
branch
from
August 23, 2026 19:00
e95ad30 to
aeb0d05
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
STAGE 1 (LOCAL steers only) of the captain-adopted inbox+doorbell steering design from data/fm-send-reliability-reframe-s1/report.md, replacing fm-send's typed-payload local data plane; the prior payload-delta/composer-verification approach was DROPPED and must not be resurrected. All requirements captain-approved, including two explicit gate rulings refined during validation: (A) SCOPE EXCLUSION - the pre-existing interaction where a MARKED secondmate parser-native invocation types marker-prefixed bytes (parser sees chat) is APPROVED as out-of-scope pre-existing behavior; follow-up fm-send-secondmate-harness-invocation-r1 owns it; do NOT change the marking contract (no appended-marker variant, no unmarked secondmate invocations) and do not flag it again - the stage-1 boundary comment in fm-send.sh documents this deliberately. (B) EXIT-STATUS RULING (final, refining the earlier both-failed call): on the inbox plane the durable record IS the delivery, so the record's fate alone governs the exit status - exit 0 whenever the record is durably written, including when pending-reply bookkeeping later fails; with the recovery marker stored the watcher reconciles silently, and with the commit and marker BOTH lost fm-send prints a distinct 'reply-tracking-degraded (steer delivered, do not resend)' warning and still exits 0, because any resend-inviting status would make automated callers duplicate a delivered instruction; nonzero is reserved for cases where nothing was delivered (unresolvable target, retired/changed endpoint under the metadata lock, unwritable record) or a decision-close append failed with its manual command attached; this exact contract is deliberate - do not re-flag either direction of it. Core design: (1) bin/fm-task-inbox-lib.sh is the ONE owner of the steering-inbox contract: sequenced durable records at state/.inbox/NNN.msg (temp-write + atomic rename, lock-serialized sequence allocation with bounded wait), the handled/ move as the acknowledgement, never-reissued sequences, BYTE-EXACT bodies (no added newline; raw read-back after the -- line), the constant self-describing doorbell line, and the delivery-attempt ladder (grace-paced; attempts include composer-protected skips and failed rings so nothing retries silently forever; escalate once per message with wake-before-marker ordering; reset on ack; bookkeeping tolerates a concurrently torn-down inbox; FM_TASK_INBOX_GRACE_SECS=90, FM_TASK_INBOX_RING_MAX=3). (2) fm-send local plane: CLI shape, resolution, fail-closed FM_HOME, gate-agent refusal kept; endpoint revalidated under the task metadata lock; durable record appended; ONE constant doorbell rung best-effort (advisory composer check skips only on exact proven pending; ambiguous verdicts still ring - skip-starvation observed live on grok 1.0.5); exit contract per ruling B; the exit-3 ladder and post-send composer proof REMOVED from the local plane. (3) --resolve-key closes the ledger and feeds the captain-hold intake at ENQUEUE time; pending-reply expectations marked delivered at enqueue. (4) Every brief scaffold carries the receive-and-ack paragraph; the relaunch note gains check-your-inbox; teardown removes the inbox. (5) Watcher: one cheap per-task check per poll - re-ring aged unhandled messages on a not-busy pane, wait on busy, escalate exactly once as an ordinary stale: wake with pre-wake revalidation; healthy/empty inboxes stay silent (silent file-move ack). (6) Typed-plane carve-outs UNCHANGED: --key lifecycle keys; harness-native slash and codex $-skill invocations classified on the pre-marker text; explicit backend targets; and the REMOTE secondmate leg, explicitly OUT OF SCOPE (cmd_send and the exit-3 contract crossing ssh stay byte-compatible; remote inbox leg ships separately). (7) KEEP per report section 5: every fail-closed refusal; fm-pending-reply-lib's REPLY direction untouched; fm-control lifecycle keys; spawn-time readiness/trust handling; composer classifier and capture adapters for non-send consumers, demoted to advisory. (8) Tests: portable regressions with real processes (byte-exact round-trips incl. trailing newlines, sequence dedup + idempotent ack, concurrent writers, the attempt ladder, real-watcher re-ring/busy-wait/silence/single-escalation, plane routing, enqueue-time close, endpoint revalidation, torn-down-inbox tolerance, and the ruling-B regression: record durable + both bookkeeping writes lost -> exit 0, distinct degraded warning, no duplicate record); existing suites migrated to the record plane without weakening; plus the env-gated live doorbell guard RUN 2026-08-23: claude, codex, opencode, pi, grok, muse all honored the doorbell end to end (docs/verification/runtime-backends.md, with the dated grok 1.0.5 composer-matrix staleness note; matrix refresh owed separately). Drive-by macOS BSD-wc fix in tests/fm-tool-update-check.test.sh rides along. KNOWN DEFERRED (do not fix in this run): the opt-in cmux live composer guard still expects the payload typed; the captain will route it as follow-up work. (9) Docs: AGENTS.md state entry + section 7 steering rewrite; configuration.md state clause + env knobs; scripts/tmux-backend/architecture/harness-adapters/stuck-crewmate-recovery scoped to the typed plane. PR note: homes pick this up after merge + self-update; landing timing coordinated with the main firstmate; STAGE 1 (local) with the remote leg to follow. One PR; yolo OFF; the captain owns the merge.
What Changed
fm-sendmessages through byte-exact, sequenced inbox records with a constant best-effort doorbell, while preserving typed delivery for native commands, explicit backend targets, and remote secondmates.Risk Assessment
Testing
Reviewed the base-to-target change, ran the focused inbox/watcher and fm-send routing regressions, and manually exercised the delivered record → doorbell → handled acknowledgement flow; all checks passed and the evidence transcript shows the end-user-visible behavior and persisted state.
Evidence: Inbox and doorbell end-to-end transcript
Source: Inbox and doorbell end-to-end transcript
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
🔧 **Review** - 1 issue found → auto-fixed (3) ✅
bin/fm-task-inbox-lib.sh:178- The doorbell targets one specific record rather than enforcing the inbox's numeric-order contract. Concrete path: 001's initial ring is swallowed, then 002's ring lands; the worker is explicitly told to read and act on 002, while 001 is only re-rung later by the watcher, reversing the steer order without error. Make the shared doorbell instruct the worker to list and process all unhandled records in numeric order (or otherwise prevent a newer record from bypassing the oldest).🔧 Fix: Preserve inbox ordering with drain-all doorbells
1 error still open:
bin/fm-watch.sh:303- The required ladder invariant says failed attempts must ensure “nothing retries silently forever,” but the watcher ignoresfm_task_inbox_record_ringfailure. If.ring-statecannot be written while the inbox still exists (for example, permissions or filesystem failure), each poll rings again without advancing toward escalation; only the private triage log records it. Handle non-vanished-inbox bookkeeping failure loudly rather than continuing an unbounded retry loop.🔧 Fix: Surface unwritable inbox ladder bookkeeping
1 error still open:
bin/fm-watch.sh:326- The bookkeeping-failure wake checks only that the inbox directory exists, not that the record remains unhandled. Concrete race: the ring prompts the worker to move the record into handled/,.ring-statewriting then fails, and this branch emits a stale wake claiming the already-acknowledged record remains unhandled. Revalidate[ -f "$rec" ]immediately before appending the wake and quietly reset/return when it was acknowledged.🔧 Fix: Silence ladder failures after inbox acknowledgement
✅ Re-checked - no issues remain.
✅ **Test** - passed
✅ No issues found.
bash tests/fm-task-inbox.test.shbash tests/fm-send-inbox.test.shManual sandbox execution ofbin/fm-send.shthrough a stubbed tmux backend, verifying exit 0, byte-exact persisted payload, constant doorbell-only terminal traffic, and acknowledgement via move tohandled/git status --shortconfirmed testing left the worktree clean✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.