Skip to content

fix: recover stalled omp lane wakes and preserve supervision ownership - #48

Merged
MrGTV-love merged 34 commits into
mainfrom
fm/fm-omp-lane-wake-unsubmitted-r2
Oct 8, 2026
Merged

MrGTV-love merged 34 commits into
mainfrom
fm/fm-omp-lane-wake-unsubmitted-r2

Conversation

@MrGTV-love

Copy link
Copy Markdown
Owner

Intent

vs hold up work??!!

why did you hold up the work vs switching models?

Context: the captain said this on 2026-10-05 about the fleet sitting idle; the standing expectation is that work never sits stalled. On 2026-10-06 (19:50-20:55 CDT) Vernant lane supervisors (omp secondmates) d1, d4 (twice), d6 and d7 raised "secondmate wake-loop stalled". Firstmate found the injected watcher wake text ("FIRSTMATE_OP: v1 watcher: FIRSTMATE WATCHER WAKE: stale: ... Run bin/fm-wake-drain.sh first ...") sitting UNSUBMITTED inside each lane's omp box composer; fm-send <lane> --key Enter submitted it and each lane then processed the wake. Separately, state/.omp-turnend-extension-loaded pointed at dead omp PIDs in lane homes ~/.treehouse/firstmate-7bab20/{1,4,5,7}/firstmate (and home 2 until it was restarted), while state/.omp-watch-extension-loaded pointed at the live omp, so fm_omp_extension_owns_supervision returned 1. fm-secondmate-restart rewrote both markers for d1 and d3. Related merged work: PR 33 (omp box composer recognition, root cause: omp live-reloads overlay files).

What Changed

  • Recover unchanged watcher wakes restored to an idle omp composer with bounded resubmission while preserving operator drafts; confirm consumption at accepted user messages and keep extension markers owned by the live session rather than descendant omp processes.
  • Recognize omp’s busy box composers and Waiting signals, refresh pending input before retrying Enter, and prevent busy-only submit confirmation for omp in tmux and Herdr. Require an empty composer for parent drain steers and retain stalled-loop alarms without injecting into omp secondmates.
  • Expand regression coverage for wake recovery, marker ownership, submit races, and injection guards; add an opt-in live Herdr/omp recovery test and update backend, supervision, and recovery documentation.

Risk Assessment

⚠️ Medium: No substantiated remaining defects were found, but asynchronous wake recovery and shared submission confirmation across multiple backends remain sensitive to vendor event timing.

Testing

Installed omp 18.8.1 passed live restoration, draft-preservation, marker-ownership, and submission scenarios on isolated Herdr and tmux setups; the adversarial run correctly rejected ordinary queued delivery as restoration proof. Portable regressions passed after ancestry isolation, while the initial Herdr invocation and later wake-suite portion hit command deadlines. Fixture setup problems were corrected, rendered terminal evidence and logs were retained, and disposable resources were removed.

  • Live validation: ✅ go - 6 of 6 scenarios driven live against the product
Scenario Result Live Evidence
Escape restores a queued watcher wake and omp automatically resubmits and handles it ✅ pass live wake-restoration.html directly shows wakelab1.status in the composer; live-wake-guard.log confirms subsequent handling and exit 0.
Recovering an interrupted watcher wake preserves the operator’s draft exactly ✅ pass live wake-restoration.html shows the fresh wakelab2.status wake beside operator draft kept, followed by the unchanged draft after recovery.
A descendant omp session cannot replace the owning lane’s loaded-marker PIDs ✅ pass live The live guard launched a real descendant omp and verified both markers still named owning session PID 46230 before parent repair and after the parent resumed.
A working Herdr omp lane exposes empty and pending composer states and accepts injected text ✅ pass live live-wake-guard.log records successful busy-composer classification and an injected doorbell leaving the composer empty.
A working tmux omp lane confirms mid-turn submission and processes the injected message ✅ pass live tmux-live.log shows pending draft classification and confirmed submission; tmux-doorbell-handled.html shows the actual standalone TMUX_DOORBELL_HANDLED response after the running command completed.
When ordinary queued delivery finishes before Escape, the guard retries fresh turns and refuses a false recovery pass ✅ pass live deferred-escape-events.jsonl records real idle agent states before three delayed Escapes; live-no-restoration-adversary.log records the expected bounded rejection instead of recovery success.
Evidence: Direct wake restoration and unchanged operator draft

Source: Direct wake restoration and unchanged operator draft

<!doctype html><meta charset="utf-8"><title>Live omp Escape restoration evidence</title><body style="background:#111;color:#ddd;font:14px monospace"><h1>Actual omp 18.8.1 terminal captures</h1><p>Captured from isolated Herdr lab; ANSI styling retained. Scroll each frame horizontally for the 320-column viewport.</p><h2>Wake restored after Escape</h2><p>Capture 1791441372626588000; fm-lab-omp-wake-restore-9004-20944</p><pre style="overflow:auto;padding:16px;border:1px solid #555;white-space:pre"><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"> ● Read </span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#00b4ff;background:#111111;font-weight:normal;opacity:1">xd://fm_watch_arm_omp</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1">                                                                                                                                                                                                                                                                                                   

</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#dddddd;background:#0f1216;font-weight:normal;opacity:1">                                                                                                                                                                                                                                                                                                                                </span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1">
</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#dddddd;background:#0f1216;font-weight:normal;opacity:1"> </span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#00ff88;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#00ff88;background:#0f1216;font-weight:normal;opacity:1">•</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#dddddd;background:#0f1216;font-weight:normal;opacity:1"> </span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#00b4ff;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#00b4ff;background:#0f1216;font-weight:normal;opacity:1">Arm firstmate watcher</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#dddddd;background:#0f1216;font-weight:normal;opacity:1">                                                                                                                                                                                                                                                                                                        </span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1">
</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#dddddd;background:#0f1216;font-weight:normal;opacity:1"> </span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#9ca3b0;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#9ca3b0;background:#0f1216;font-weight:normal;opacity:1">watcher: started omp extension arm child 1; future ordinary re-arms are automatic; call fm_watch_arm_omp again only after a later notification says the cycle is missing, failed, or unhealthy</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#dddddd;background:#0f1216;font-weight:normal;opacity:1">                                                                                                                                 </span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1">
</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#dddddd;background:#0f1216;font-weight:normal;opacity:1"> </span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#6b7280;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#6b7280;background:#0f1216;font-weight:normal;opacity:1">⟦⌃O: Expand⟧</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#dddddd;background:#0f1216;font-weight:normal;opacity:1">                                                                                                                                                                                                                                                                                                                   </span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1">
</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#dddddd;background:#0f1216;font-weight:normal;opacity:1">                                                                                                                                                                                                                                                                                                                                </span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1">

 ARMED                                                                                                                                                                                                                                                                                                                          

</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#dddddd;background:#0f1216;font-weight:normal;opacity:1">                                                                                                                                                                                                                                                                                                                                </span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1">
</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#dddddd;background:#0f1216;font-weight:normal;opacity:1"> </span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#e5e5e7;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#e5e5e7;background:#0f1216;font-weight:normal;opacity:1">Run the bash command </span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#00ff88;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#00ff88;background:#0f1216;font-weight:normal;opacity:1">sleep 90</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#e5e5e7;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#e5e5e7;background:#0f1216;font-weight:normal;opacity:1"> and when it finishes reply DONE.</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#dddddd;background:#0f1216;font-weight:normal;opacity:1">                                                                                                                                                                                                                                                                 </span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1">
</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#dddddd;background:#0f1216;fo

... [106483 bytes truncated] ...

kground:#111111;font-weight:normal;opacity:1"></span><span style="color:#00b4ff;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#00b4ff;background:#0f1216;font-weight:normal;opacity:1">⠦ 12s</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#dddddd;background:#0f1216;font-weight:normal;opacity:1"> </span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#2a3038;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#2a3038;background:#0f1216;font-weight:normal;opacity:1">&gt;</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#dddddd;background:#0f1216;font-weight:normal;opacity:1"> </span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#00b4ff;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#00b4ff;background:#0f1216;font-weight:normal;opacity:1">◔ GPT-6.1-Sol</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#00ff88;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#00ff88;background:#0f1216;font-weight:normal;opacity:1"> 👁</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#dddddd;background:#0f1216;font-weight:normal;opacity:1"> </span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#2a3038;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#2a3038;background:#0f1216;font-weight:normal;opacity:1">&gt;</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#dddddd;background:#0f1216;font-weight:normal;opacity:1"> </span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#e8ecf4;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#e8ecf4;background:#0f1216;font-weight:normal;opacity:1">🗑 fm-omp-wake-restore.sjiIje/project</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#dddddd;background:#0f1216;font-weight:normal;opacity:1"> </span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#2a3038;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#2a3038;background:#0f1216;font-weight:normal;opacity:1">&gt;</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#dddddd;background:#0f1216;font-weight:normal;opacity:1"> </span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#ffb347;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#ffb347;background:#0f1216;font-weight:normal;opacity:1">⑂ detached *2</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#dddddd;background:#0f1216;font-weight:normal;opacity:1"> </span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#9ca3b0;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#9ca3b0;background:#0f1216;font-weight:normal;opacity:1">?2</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#dddddd;background:#0f1216;font-weight:normal;opacity:1"> </span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#2a3038;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#2a3038;background:#0f1216;font-weight:normal;opacity:1">&gt;</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#dddddd;background:#0f1216;font-weight:normal;opacity:1"> </span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#d4c090;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#d4c090;background:#0f1216;font-weight:normal;opacity:1">S0.09 + 👁 0.09</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#dddddd;background:#0f1216;font-weight:normal;opacity:1"> </span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#0f1216;background:#111111;font-weight:normal;opacity:1">▶</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#00b4ff;background:#111111;font-weight:normal;opacity:1">────────────────8%</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#2a3038;background:#111111;font-weight:normal;opacity:1">──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#9ca3b0;background:#111111;font-weight:normal;opacity:1">╎</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#2a3038;background:#111111;font-weight:normal;opacity:1">────────────────────</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#3998bf;background:#111111;font-weight:normal;opacity:1">┃</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#2a3038;background:#111111;font-weight:normal;opacity:1">────────────────────────────</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#3998bf;background:#111111;font-weight:normal;opacity:1">272K</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#2a3038;background:#111111;font-weight:normal;opacity:1">─</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#0f1216;background:#111111;font-weight:normal;opacity:1">◀</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#dddddd;background:#0f1216;font-weight:normal;opacity:1"> 🆔 01a11a38 </span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#6a7078;background:#111111;font-weight:normal;opacity:1">──╮</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1">
</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#6a7078;background:#111111;font-weight:normal;opacity:1">╰─ </span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#e5e5e7;background:#111111;font-weight:normal;opacity:1">operator draft kept</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1">                                                                                                                                                                                                                                                                                                       </span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span><span style="color:#6a7078;background:#111111;font-weight:normal;opacity:1"> ─╯</span><span style="color:#dddddd;background:#111111;font-weight:normal;opacity:1"></span></pre></body>
Evidence: Successful live Herdr wake guard

Source: Successful live Herdr wake guard

COMMAND: FM_OMP_WAKE_RESTORE_LIVE=1 FM_OMP_WAKE_RESTORE_LIVE_MODEL=openai-codex/gpt-6.1-sol bash tests/fm-omp-wake-restore-live-e2e.test.sh
Note: switching to 'b78bae43d62e0cade7bcf2ed107dbf828e36dab5'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

  git switch -c <new-branch-name>

Or undo this operation with:

  git switch -

Turn off this advice by setting config variable advice.detachedHead to false

ok - live omp wake restore: omp (omp/18.8.1) on herdr 0.9.1 re-submitted a wake that Esc restored to the composer, and the lane handled it
ok - live omp wake restore: omp (omp/18.8.1) on herdr 0.9.1 left the operator's draft exactly as typed while it re-submitted the wake
ok - live omp markers: omp (omp/18.8.1) on herdr 0.9.1 kept both loaded markers on the session pid 46230 before parent repair and after the parent resumed
ok - live omp busy composer: omp (omp/18.8.1) on herdr 0.9.1 reads empty and pending while a turn runs
ok - live omp busy composer: omp (omp/18.8.1) on herdr 0.9.1 took an injected doorbell mid-turn and left the composer empty
EXIT: 0
Evidence: Real tmux message processing response

Source: Real tmux message processing response

<!doctype html><meta charset="utf-8"><title>Live omp tmux capture</title><body style="background:#111;color:#ddd"><h1>doorbell-handled</h1><pre style="font:14px monospace">████████████
                                               ██  ██       ▄▀▀▄ █▀▄▀▄ █▀▀▄
                                               ██  ██       ▀▄▄▀ █ █ █ █▄▄▀
                                               ▒▒  ██                  █
                                                   ██       v18.8.1

                                        Tip: You can /btw to ask a side question

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
 Update Available
 New version 18.8.4 is available. Run: omp update
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────


 Run only the bash command sleep 90, then reply DONE. Do not modify files.


╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ $ sleep 90                                                                                                           │
├─── Output ───────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Backgrounded early to handle an incoming message; the command keeps running.                                         │
│ ⟦Backgrounded: bg_1 | Timeout: 100s⟧                                                                                 │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯


 After the current command, reply exactly TMUX_DOORBELL_HANDLED. Do not modify files.


✔ 1 job settled 1 done
└─ • ⟦bash⟧ bg_1 sleep 90 · 1m30s
     (no output)

 TMUX_DOORBELL_HANDLED

╭── π &gt; ◔ GPT-6.1-Sol 👁 &gt; 🌳 32d18ed9638d/01M4D24DCSAPVMYEXMYCEPMEW2 &gt; ⑂ detached *1 ?2 &gt; S0.05 + 👁 0.02 ▶─7%─╎┃272K───╮
╰─                                                                                                                    ─╯</pre></body>
Evidence: Live tmux composer and submission transcript

Source: Live tmux composer and submission transcript


=== idle-box ===
████████████
                                               ██  ██       ▄▀▀▄ █▀▄▀▄ █▀▀▄
                                               ██  ██       ▀▄▄▀ █ █ █ █▄▄▀
                                               ▒▒  ██                  █
                                                   ██       v18.8.1

                                        Tip: You can /btw to ask a side question

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
 Update Available
 New version 18.8.4 is available. Run: omp update
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

╭── π > ◔ GPT-6.1-Sol 👁 > 🌳 32d18ed9638d/01M4D24DCSAPVMYEXMYCEPMEW2 > ⑂ detached *1 ?2 > (sub) ▶─8%────────╎─┃─272K───╮
╰─                                                                                       ⇧⇥ to change thinking effort ─╯
Idle composer: empty
Cursor: 15,3,omp,40,120
Busy-turn submission verdict: empty

=== busy-pending-draft ===
████████████
                                               ██  ██       ▄▀▀▄ █▀▄▀▄ █▀▀▄
                                               ██  ██       ▀▄▄▀ █ █ █ █▄▄▀
                                               ▒▒  ██                  █
                                                   ██       v18.8.1

                                        Tip: You can /btw to ask a side question

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
 Update Available
 New version 18.8.4 is available. Run: omp update
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────


 Run only the bash command sleep 90, then reply DONE. Do not modify files.


╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ $ sleep 90                                                                                                           │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯

  ⎋ Waiting ninety seconds

╭── ⠧ 2s > ◔ GPT-6.1-Sol 👁 > 🌳 32d18ed9638d/01M4D24DCSAPVMYEXMYCEPMEW2 > ⑂ detached *1 ?2 > (sub) ▶─8%──────╎┃─272K───╮
╰─ operator tmux draft kept                                                                                           ─╯
Busy doorbell submission verdict: empty

=== queued-doorbell ===
████████████
                                               ██  ██       ▄▀▀▄ █▀▄▀▄ █▀▀▄
                                               ██  ██       ▀▄▄▀ █ █ █ █▄▄▀
                                               ▒▒  ██                  █
                                                   ██       v18.8.1

                                        Tip: You can /btw to ask a side question

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
 Update Available
 New version 18.8.4 is available. Run: omp update
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────


 Run only the bash command sleep 90, then reply DONE. Do not modify files.


╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ $ sleep 90                                                                                                           │
├─── Output ───────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Backgrounded early to handle an incoming message; the command keeps running.                                         │
│ ⟦Backgrounded: bg_1 | Timeout: 100s⟧                                                                                 │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯


 After the current command, reply exactly TMUX_DOORBELL_HANDLED. Do not modify files.


  ⎋ Waiting ninety seconds

╭── ⠧ 4s > ◔ GPT-6.1-Sol 👁 > 🌳 32d18ed9638d/01M4D24DCSAPVMYEXMYCEPMEW2 > ⑂ detached *1 ?2 > S0.04 ▶─7%─╎┃272K─◀ ⚙ 1 ──╮
╰─                                                                                                                    ─╯

=== doorbell-handled ===
████████████
                                               ██  ██       ▄▀▀▄ █▀▄▀▄ █▀▀▄
                                               ██  ██       ▀▄▄▀ █ █ █ █▄▄▀
                                               ▒▒  ██                  █
                                                   ██       v18.8.1

                                        Tip: You can /btw to ask a side question

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
 Update Available
 New version 18.8.4 is available. Run: omp update
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────


 Run only the bash command sleep 90, then reply DONE. Do not modify files.


╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ $ sleep 90                                                                                                           │
├─── Output ───────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Backgrounded early to handle an incoming message; the command keeps running.                                         │
│ ⟦Backgrounded: bg_1 | Timeout: 100s⟧                                                                                 │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯


 After the current command, reply exactly TMUX_DOORBELL_HANDLED. Do not modify files.


✔ 1 job settled 1 done
└─ • ⟦bash⟧ bg_1 sleep 90 · 1m30s
     (no output)

 TMUX_DOORBELL_HANDLED

╭── π > ◔ GPT-6.1-Sol 👁 > 🌳 32d18ed9638d/01M4D24DCSAPVMYEXMYCEPMEW2 > ⑂ detached *1 ?2 > S0.05 + 👁 0.02 ▶─7%─╎┃272K───╮
╰─                                                                                                                    ─╯
PASS: real omp box composer classified empty/pending mid-turn; injected follow-up cleared and was processed.

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

🔧 **Review** - 1 issue found → auto-fixed ✅
  • ⚠️ tests/fm-omp-wake-restore-live-e2e.test.sh:253 - Both live recovery probes can report success without exercising restored-editor recovery. Concrete sequence: wake_is_queued confirms a busy turn and fresh queued wake at lines 223–242, but the turn completes between that check and Escape. Ordinary follow-up delivery drains the queue and leaves the editor empty, satisfying the clean-wake assertions at lines 250–257 even with recovery disabled. Ordinary delivery also preserves the operator draft, satisfying the sibling probe at lines 261–271. The previous run's Round 2 finding was selected for correction, but this proof gap remains in the target. Before either success result, require observation of the fresh wake in a pending composer after Escape, or equivalent direct recovery evidence excluding ordinary queued delivery. If restoration was missed, retry from a fresh busy turn a bounded number of times and then fail. This is a source-derived race, not a live reproduction; the remedy is confined to the live guard.

🔧 Fix applied.
✅ Re-checked - no issues remain.

✅ **Test** - passed

✅ No issues found.

  • Live validation: ✅ go - 6 of 6 scenarios driven live against the product
Scenario Result Live Evidence
Escape restores a queued watcher wake and omp automatically resubmits and handles it ✅ pass live wake-restoration.html directly shows wakelab1.status in the composer; live-wake-guard.log confirms subsequent handling and exit 0.
Recovering an interrupted watcher wake preserves the operator’s draft exactly ✅ pass live wake-restoration.html shows the fresh wakelab2.status wake beside operator draft kept, followed by the unchanged draft after recovery.
A descendant omp session cannot replace the owning lane’s loaded-marker PIDs ✅ pass live The live guard launched a real descendant omp and verified both markers still named owning session PID 46230 before parent repair and after the parent resumed.
A working Herdr omp lane exposes empty and pending composer states and accepts injected text ✅ pass live live-wake-guard.log records successful busy-composer classification and an injected doorbell leaving the composer empty.
A working tmux omp lane confirms mid-turn submission and processes the injected message ✅ pass live tmux-live.log shows pending draft classification and confirmed submission; tmux-doorbell-handled.html shows the actual standalone TMUX_DOORBELL_HANDLED response after the running command completed.
When ordinary queued delivery finishes before Escape, the guard retries fresh turns and refuses a false recovery pass ✅ pass live deferred-escape-events.jsonl records real idle agent states before three delayed Escapes; live-no-restoration-adversary.log records the expected bounded rejection instead of recovery success.
  • bash tests/fm-tmux-submit-busy.test.sh — passed submission-confirmation, unavailable-identity, retry, and non-omp compatibility regressions.
  • bash tests/fm-composer-lib.test.sh — passed composer classification and busy-state regressions.
  • bash tests/fm-omp-harness.test.sh — initially encountered contamination from the runner’s real omp ancestry; reran through the disposable ancestry-isolated runner python3 .nm-live/omp-regression.py, and the complete suite passed, including preparation-cancellation retention and marker ownership.
  • bash tests/fm-backend-herdr.test.sh — first invocation exceeded its deadline; the subsequent invocation through .nm-live/herdr-selected.sh executed the full Herdr suite and completed successfully because the attempted selector was ineffective.
  • bash tests/fm-wake-queue.test.sh — exercised the changed secondmate stall and no-input boundaries, but the later portion was interrupted by the shared command deadline; not reported as a complete-suite pass.
  • FM_OMP_WAKE_RESTORE_LIVE=1 FM_OMP_WAKE_RESTORE_LIVE_MODEL=openai-codex/gpt-6.1-sol bash tests/fm-omp-wake-restore-live-e2e.test.sh — ran through the evidence relay with workspace-local disposable fixtures; passed after correcting fixture setup.
  • python3 .nm-live/tmux.py — drove installed omp through a marked lab home and private tmux socket with a 120×40 truecolor terminal; observed busy draft classification, confirmed submission, and the actual TMUX_DOORBELL_HANDLED response.
  • env LIVE_ADVERSARY=1 python3 .nm-live/run.py — delayed each real Escape until ordinary queued delivery finished; verified three fresh attempts followed by the expected no-restoration rejection.
  • Captured and rendered actual terminal frames, retained CLI transcripts and late-Escape agent-state responses, tore down the named labs and private tmux server, and removed disposable drivers and worktree test resources.
✅ **Document** - passed

✅ No issues found.

🔧 **Lint** - 1 issue found → auto-fixed ✅
  • ⚠️ linter found issues (exit code 1)

🔧 Fix applied.
✅ Re-checked - no issues remain.

✅ **Push** - passed

✅ No issues found.

…e loaded markers on the session

omp puts a queued user follow-up back into the composer when a run is
interrupted, so a watcher wake queued behind a running turn sat there
unsubmitted and the lane looked idle with a frozen wake queue. Separately, a
working lane's box composer (spinner and elapsed time in the top border) read
unknown, so a doorbell or restart request typed into a working lane could not
be seen as unsubmitted, and a descendant omp that auto-discovered the same
extensions overwrote the turn-end marker with its own soon-dead pid.

- omp watch extension: after agent_end, find its own wake in the composer,
  remove only that text, and send it again (bounded), leaving operator text
  exactly as typed.
- Stalled-loop check: submit a pending composer that holds nothing but watcher
  wakes with one bare Enter (fm_task_inbox_submit_held_wake), never typing,
  and keep the parent alarm for any other composer content.
- Composer classifier: read omp's working box border (spinner plus elapsed
  time); the Herdr submit re-reads a pending verdict once before any retry so
  a stale frame cannot earn an Enter that aborts a running turn.
- omp extensions: only the process named in state/.lock records its marker or
  arms a watcher, and the turn-end guard re-asserts its marker at every turn
  boundary.
- Behavioral tests for each, an opt-in live Herdr guard, and the dated
  verification entry.
…est-run.sh, tests/fm-contributions.test.sh, and docs/fm-test-portable-shards.md. Parallel shard 1 and the coverage guard shared one cause: the new wake-restore test pushed unhinted serial scripts above 15%. Added its observed 51 ms timing from a zero-failure CI shard, explicitly documenting that it measured the opt-in capability skip, not live recovery. Serial shard 5 failed because its generated-check budget fixture raced wall-clock ticks and child startup. Both configured and inherited cases now use a controlled logical deadline and a fixture-local pass-through timeout, preserving assertions that a read occurred and durable records remained unchanged. Production timeout, wake-lock, and drain behavior are unchanged. Verification passed: executable --check-coverage reported complete coverage of 254 tests with 31/212 serial scripts unhinted; focused union/disjointness and parallel-balance regressions passed; configured/inherited budget regressions passed. A 20-second-budget negative control completed observation and failed the unchanged-record assertion as expected. Broader local verification remained limited by timeouts: the full runner suite and exhaustive shard-list regression reached 900 seconds, and a separate hint-bound regression reached 300 seconds. No full-suite green result is claimed. Temporary evidence and invocation files were removed; no pipeline control or push was performed
@MrGTV-love

Copy link
Copy Markdown
Owner Author

This PR supersedes #40.

Why it replaces PR 40:

  • PR 40's published branch could not be updated without a force push, and the validation run for it ended in a timeout in the review agent, which left its branch history impossible to reconcile safely.
  • PR 40's line carried an unrelated change to the wake lock and queue drain. That change is removed here, and the wake-lock and drain code is exactly what main has. It is tracked as a separate follow-up.
  • This branch is the same work rebased onto current main with the later review fixes: the delivery-confirmation exclusion now covers only a positively identified omp pane and a missing identity, so other harnesses keep their previous behavior.

The old branch is left in place.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant