fix: hide Pi watcher wakes and harden supervision state#973
Open
BazsaX254 wants to merge 5 commits into
Open
Conversation
added 5 commits
July 24, 2026 11:11
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
Fix FirstMate's Pi watcher bridge so internal signal, stale, result/check, and monitoring notifications wake the model through trusted hidden transport without rendering raw watcher prompts, local paths, queue-drain commands, or supervision instructions in captain chat. Preserve durable queue-first handling, model-free monitoring, exactly-one successor arm, extension-owned continuity, turn-end safety, actionable failure wakes, and all supported harness/backend behavior. Treat a current run-step-backed no-mistakes validation decision as a verified parked wait rather than a stall; retain bounded cadence for declared external waits; continue escalating genuinely stopped, looping, confused, or unresponsive workers; and retire watcher tracking for torn-down worker identities. Require deterministic unit and strict-TypeScript coverage plus a live interactive Pi 0.81.1 regression proving hidden delivery is received exactly once without transcript leakage, with focused, broad, lint, documentation, PR, and CI validation.
What Changed
Risk Assessment
✅ Low: The append-count guard closes the empty-queue wake race, and the deterministic regression covers teardown between active filtering and enqueue while preserving exactly-once wake behavior after task-ID reuse.
Testing
Targeted commit inspection, deterministic Pi/OpenCode watcher tests, strict Pi 0.81.1 TypeScript checking, triage/queue/checkpoint/teardown tests, model-free daemon lifecycle checks, and a credentialed interactive Pi 0.81.1 run passed the requested behavior; the live test needed one retry after an unrelated provider-sentinel fluctuation. The relevant Calm operational-follow-up path passed, but its later rendered-export section could not run because Chrome/Chromium is absent, and the broader daemon script eventually hit an unrelated root-user chmod assumption after all relevant daemon cases passed. No screenshot was produced because the isolated terminal harness deletes its tmux lab on exit; its reviewer-visible assertion transcript is preserved as the live log. The worktree remained clean with no surviving test processes or transient lab directories.
Evidence: Live Pi 0.81.1 acceptance
ok - Pi 0.81.1 live E2E covered hidden exactly-once watcher transport, native Calm Working visibility, Ahoy first/later messages, legacy transcripts, near misses, and watcher continuityEvidence: Deterministic watcher extension
Evidence: Watcher triage and parked-wait behavior
Evidence: Durable wake queue
Evidence: Model-free daemon lifecycle
Evidence: Worker identity teardown
Evidence: Strict TypeScript contract
ok - tracked Pi extensions pass strict no-emit typecheck against Pi 0.81.1Pipeline
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-teardown.sh:1214- The required criterion “retire watcher tracking for torn-down worker identities” is incomplete here: this hunk deletes pane-keyed state but leaves task-keyed.seen-$ID_status,.seen-$ID_turn-ended,.hb-surfaced-$ID, and.subsuper-seen-status-$IDmarkers. Because task IDs can be reused after teardown, an identical new status can match these old suppressors and be treated as already surfaced, losing a genuine wake. Clear all task-keyed watcher/daemon dedup state during teardown and cover ID reuse.🔧 Fix: Retire task dedup state during worker teardown
1 error still open:
bin/fm-teardown.sh:1216- The required “retire watcher tracking for torn-down worker identities” guarantee remains racy: thisrmcan finish whilefm-watch.shis sleeping on an already-collected signal, after which the watcher writes the old signature back to.seen-*without rechecking metadata (lines 779–824). Reusing that task ID with the same signature can again suppress its actionable status. Decide whether retirement must cover concurrent watcher scans; recommended smallest fix is to revalidate each pending row after the grace period and ensure any marker written after teardown is removed when its task metadata is absent, with a synchronized teardown-during-grace regression. Declining leaves the accepted cleanup reliable only when teardown does not overlap signal processing.🔧 Fix: Drop retired signals across watcher teardown races
1 error still open:
bin/fm-watch.sh:845- The required “Preserve durable queue-first handling” invariant is violated by the new second revalidation: if teardown removes every task afteractive_pendingis built but before lines 823–825, all rows are skipped, yet line 845 still emits the signal wake with no durable queue record. The smallest fix is to count successfulfm_wake_appendcalls and continue monitoring instead of callingwakewhen none were appended; add a regression paused between active filtering and enqueue. Without it, the model can receive a wake whose required queue drain is empty.🔧 Fix: Prevent signal wakes without durable queue records
✅ Re-checked - no issues remain.
tests/fm-pi-primary-live-e2e.test.sh:240- The credentialed live regression is provider-sensitive: its first run stopped before watcher delivery because the model omitted the requested PRIOR_BOUNDARY_ACK sentinel and answered “Nothing happened after your previous message.” A bounded retry passed the complete Pi 0.81.1 hidden-delivery regression.git status --short --branchand commit-range diff/name inspection against10ee7797e50c88c9865d8fb382cdfee5c2b8bcd1tests/fm-pi-watch-extension.test.shPATH="/root/.hermes/lsp/node_modules/typescript/bin:$PATH" tests/fm-pi-primary-types.test.shtests/fm-watch-triage.test.shtests/fm-teardown.test.shPATH="/root/.hermes/node/bin:$PATH" tests/fm-calm-pi-extension.test.shPATH="/root/.hermes/node/bin:$PATH" FM_PI_LIVE_E2E=1 tests/fm-pi-primary-live-e2e.test.sh(two attempts; retry passed)tests/fm-wake-queue.test.shtests/fm-watch-checkpoint.test.shtests/fm-wake-daemon-lifecycle-e2e.test.shtests/fm-daemon.test.shFinalgit status --short, transient lab search, and live-process check✅ **Document** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.