Skip to content

fix: recognize omp box composers for safe worker control - #33

Merged
MrGTV-love merged 6 commits into
mainfrom
fm/fm-omp-composer-unknown-blocks-control
Oct 6, 2026
Merged

MrGTV-love merged 6 commits into
mainfrom
fm/fm-omp-composer-unknown-blocks-control

Conversation

@MrGTV-love

@MrGTV-love MrGTV-love commented Oct 6, 2026 •

Copy link
Copy Markdown
Owner

Intent

"lets close them and transition many of them to claude" (the live omp worker sessions that still hold ~1 GB Mnemopi embedding helpers under memory pressure; the captain also said "I have a lot of capcity on claude, so let's use it too via tc run").

Context: on 2026-10-06 16:21 CT, bin/fm-control.sh relaunch --harness claude for 11 idle omp workers in the main home was refused for every one with "composer state is 'unknown', not proven empty; refusing to type the /quit exit command". The same refusal ('unknown' / 'pending-unproven') blocked bin/fm-secondmate-restart.sh for all 7 Vernant lanes at 15:55. The workers are idle at an empty composer (one showed "F5 to retry" after "1 job settled 1 failed"). A captured screen is in data/fm-omp-composer-unknown-blocks-control/screen-fm-model-index.txt: omp draws a rounded box whose TOP border carries its status line ("╭── π > ◒ GPT-6.1-Sol ... ──╮") and whose bottom border is "╰─ ... ─╯" with an empty interior, even though .omp/fm-session-overlay.yml pins composer.shape: borderless.

What Changed

  • Recognize omp’s status-bearing rounded box and folded input row so proven-empty workers can exit or relaunch safely, while preserving pending drafts and treating unstyled hint text as unknown.
  • Add classifier regression coverage and an isolated Herdr lifecycle guard with opt-in relaunch checks; document box rendering and overlay live reload while retaining the borderless composer pin.
  • Include live-validation n-gram prediction state artifacts.

Risk Assessment

✅ Low: The change is bounded to recognizing the observed omp box composer through the existing shared classifier, preserves ambiguous-input refusal, and introduces no substantiated material defect or intent contradiction.

Testing

Focused composer regressions and isolated live Herdr scenarios passed after correcting the guard’s startup-registration race and disabling fixture ghost completions. Real viewport captures and lifecycle transcripts demonstrate draft preservation, empty-box exit/relaunch, failed-turn recovery, and Claude replacement liveness. Claude remained at an external-import permission prompt; no model-execution claim is made. All labs and transient fixtures were removed.

  • Live validation: ✅ go - 8 of 8 scenarios driven live against the product
Scenario Result Live Evidence
Exit a live empty rounded-box omp worker without removing its endpoint ✅ pass live omp-ready-lifecycle.log; composer-safety-and-claude-transition.html; composer-before-after.log
Attempt exit with an ordinary unsent draft and preserve the draft ✅ pass live claude-exact-lifecycle.log; composer-safety-and-claude-transition.html
Type the exact effort hint and retain ambiguity when capture styling is absent ✅ pass live claude-exact-lifecycle.log; rendered typed-hint viewport in composer-safety-and-claude-transition.html
Attempt exit with prompt glyphs, border characters, and wrapped text as drafts ✅ pass live claude-exact-lifecycle.log; composer-safety-and-claude-transition.html
Relaunch a proven live empty-box omp worker in the same endpoint ✅ pass live omp-ready-lifecycle.log
Transition an idle box-shaped omp worker to a live Claude replacement ✅ pass live claude-exact-lifecycle.log; composer-safety-and-claude-transition.html
Relaunch an idle box composer after a real failed provider turn ✅ pass live retry-lifecycle.log; retry-failed-turn-idle.html
Reject relaunch verification when the second omp launch dies during startup ✅ pass live failed-second-launch.log
Evidence: Actual composer safety and Claude replacement viewports

Source: Actual composer safety and Claude replacement viewports

<!doctype html><meta charset="utf-8"><title>Live omp composer safety and Claude transition</title><style>body{background:#151515;color:#ddd;padding:24px;font:14px system-ui}pre{font:14px/1.45 ui-monospace,SFMono-Regular,Menlo,monospace;white-space:pre;}section{padding:20px 0;border-top:1px solid #555}</style><h1>Actual Herdr lab viewport captures</h1><p>omp 18.6.3; lifecycle through fm-control; Claude replacement verified by native registration and process liveness. No model-response assertion.</p><section><h2>Idle omp rounded box</h2><pre><span style="">
                                            </span><span style=""></span><span style="color:#f84fcc;">█</span><span style=""></span><span style="color:#ef51d0;">█</span><span style=""></span><span style="color:#e652d3;">█</span><span style=""></span><span style="color:#dc54d7;">█</span><span style=""></span><span style="color:#d356db;">█</span><span style=""></span><span style="color:#ca58de;">█</span><span style=""></span><span style="color:#c159e2;">█</span><span style=""></span><span style="color:#b85be5;">█</span><span style=""></span><span style="color:#af5de9;">█</span><span style=""></span><span style="color:#a55fed;">█</span><span style=""></span><span style="color:#9c60f0;">█</span><span style=""></span><span style="color:#9362f4;">█</span><span style="">    
                                               </span><span style=""></span><span style="color:#c359e1;">█</span><span style=""></span><span style="color:#ba5be5;">█</span><span style="">  </span><span style=""></span><span style="color:#9e60ef;">█</span><span style=""></span><span style="color:#9562f3;">█</span><span style="">       ▄▀▀▄ █▀▄▀▄ █▀▀▄
                                               </span><span style=""></span><span style="color:#aa5eeb;">█</span><span style=""></span><span style="color:#a15fef;">█</span><span style="">  </span><span style=""></span><span style="color:#7f72f2;">█</span><span style=""></span><span style="color:#727ef0;">█</span><span style="">       ▀▄▄▀ █ █ █ █▄▄▀
                                               </span><span style=""></span><span style="color:#9065f4;">▒</span><span style=""></span><span style="color:#8270f2;">▒</span><span style="">  </span><span style=""></span><span style="color:#5a91ee;">█</span><span style=""></span><span style="color:#4d9cec;">█</span><span style="">                  █
                                                   </span><span style=""></span><span style="color:#35afea;">█</span><span style=""></span><span style="color:#28bae8;">█</span><span style="">       </span><span style=""></span><span style="color:#6b7280;">v18.6.3</span><span style="">

                        </span><span style=""></span><span style="color:#d4c090;">Tip: </span><span style=""></span><span style="color:#9ca3b0;">Type `#` anywhere in your prompt for quick actions — copy the line</span><span style="">
                                      </span><span style=""></span><span style="color:#9ca3b0;">or the whole prompt, undo, jump the cursor</span><span style="">

</span><span style=""></span><span style="color:#ffb347;">───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────</span><span style="">
 </span><span style=""></span><span style="color:#ffb347;">Update Available</span><span style="">                                                                                                      
 </span><span style=""></span><span style="color:#9ca3b0;">New version 18.7.0 is available. Run: </span><span style=""></span><span style="color:#00b4ff;">omp update</span><span style="">                                                                      
</span><span style=""></span><span style="color:#ffb347;">───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────</span><span style="">

</span><span style=""></span><span style="color:#00b4ff;">╭──</span><span style=""></span><span style="background:#0f1216;"> </span><span style=""></span><span style="color:#6b7280;"></span><span style="color:#6b7280;background:#0f1216;">π</span><span style=""></span><span style="background:#0f1216;"> </span><span style=""></span><span style="color:#2a3038;"></span><span style="color:#2a3038;background:#0f1216;">&gt;</span><span style=""></span><span style="background:#0f1216;"> </span><span style=""></span><span style="color:#00b4ff;"></span><span style="color:#00b4ff;background:#0f1216;">◒ Gemini 3.1 Pro Preview</span><span style=""></span><span style="background:#0f1216;"> </span><span style=""></span><span style="color:#2a3038;"></span><span style="color:#2a3038;background:#0f1216;">&gt;</span><span style=""></span><span style="background:#0f1216;"> </span><span style=""></span><span style="color:#e8ecf4;"></span><span style="color:#e8ecf4;background:#0f1216;">🌳 proj/wt</span><span style=""></span><span style="background:#0f1216;"> </span><span style=""></span><span style="color:#2a3038;"></span><span style="color:#2a3038;background:#0f1216;">&gt;</span><span style=""></span><span style="background:#0f1216;"> </span><span style=""></span><span style="color:#00ff88;"></span><span style="color:#00ff88;background:#0f1216;">⑂ ompbox96318</span><span style=""></span><span style="background:#0f1216;"> </span><span style=""></span><span style="color:#0f1216;">▶</span><span style=""></span><span style="color:#00b4ff;">─2%</span><span style=""></span><span style="color:#2a3038;">────────────────────────────────────────</span><span style=""></span><span style="color:#3998bf;">┃</span><span style=""></span><span style="color:#2a3038;">──────</span><span style=""></span><span style="color:#3998bf;">1M</span><span style=""></span><span style="color:#2a3038;">─</span><span style=""></span><span style="color:#00b4ff;">──╮</span><span style="">
</span><span style=""></span><span style="color:#00b4ff;">╰─ </span><span style=""></span><span style="color:#e5e5e7;">                                                                                     </span><span style=""></span><span style="color:#00b4ff;">⇧⇥</span><span style=""></span><span style="color:#e5e5e7;"> </span><span style=""></span><span style="color:#6b7280;">to change thinking effort</span><span style=""></span><span style="color:#00b4ff;"> ─╯</span></pre></section><section><h2>Typed hint copy remains pending</h2><pre><span style="">
                                            </span><span style=""></span><span style="color:#f84fcc;">█</span><span style=""></span><span style="color:#ef51d0;">█</span><span style=""></span><span style="color:#e652d3;">█</span><span style=""></span><span style="color:#dc54d7;">█</span><span style=""></span><span style="color:#d356db;">█</span><span style=""></span><span style="color:#ca58de;">█</span><span style=""></span><span style="color:#c159e2;">█</span><span style=""></span><span style="color:#b85be5;">█</span><span style=""></span><span style="color:#af5de9;">█</span><span style=""></span><span style="color:#a55fed;">█</span><span style=""></span><span style="color:#9c60f0;">█</span><span style=""></span><span style="color:#9362f4;">█</span><span style="">    
                                               </span><span style=""></span><span style="color:#c359e1;">█</span><span style=""></span><span style="color:#ba5be5;">█</span><span style="">  </span><span style=""

... [27130 bytes truncated] ...

                                       </span><span style=""></span><span style="color:#35afea;">█</span><span style=""></span><span style="color:#28bae8;">█</span><span style="">       </span><span style=""></span><span style="color:#6b7280;">v18.6.3</span><span style="">

                       </span><span style=""></span><span style="color:#d4c090;">Tip: </span><span style=""></span><span style="color:#9ca3b0;">Bulk data to classify or triage? Say `jevify` in your message — the</span><span style="">
                         </span><span style=""></span><span style="color:#9ca3b0;">eval kernel&#x27;s `judge()` processes the batch and you read only what it</span><span style="">
                                           </span><span style=""></span><span style="color:#9ca3b0;">flags — watch it glow as you type</span><span style="">

</span><span style=""></span><span style="color:#ffb347;">───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────</span><span style="">
 </span><span style=""></span><span style="color:#ffb347;">Update Available</span><span style="">                                                                                                      
 </span><span style=""></span><span style="color:#9ca3b0;">New version 18.7.0 is available. Run: </span><span style=""></span><span style="color:#00b4ff;">omp update</span><span style="">                                                                      
</span><span style=""></span><span style="color:#ffb347;">───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────</span><span style="">

</span><span style=""></span><span style="color:#00b4ff;">╭──</span><span style=""></span><span style="background:#0f1216;"> </span><span style=""></span><span style="color:#6b7280;"></span><span style="color:#6b7280;background:#0f1216;">π</span><span style=""></span><span style="background:#0f1216;"> </span><span style=""></span><span style="color:#2a3038;"></span><span style="color:#2a3038;background:#0f1216;">&gt;</span><span style=""></span><span style="background:#0f1216;"> </span><span style=""></span><span style="color:#00b4ff;"></span><span style="color:#00b4ff;background:#0f1216;">◒ Gemini 3.1 Pro Preview</span><span style=""></span><span style="background:#0f1216;"> </span><span style=""></span><span style="color:#2a3038;"></span><span style="color:#2a3038;background:#0f1216;">&gt;</span><span style=""></span><span style="background:#0f1216;"> </span><span style=""></span><span style="color:#e8ecf4;"></span><span style="color:#e8ecf4;background:#0f1216;">🌳 proj/wt</span><span style=""></span><span style="background:#0f1216;"> </span><span style=""></span><span style="color:#2a3038;"></span><span style="color:#2a3038;background:#0f1216;">&gt;</span><span style=""></span><span style="background:#0f1216;"> </span><span style=""></span><span style="color:#00ff88;"></span><span style="color:#00ff88;background:#0f1216;">⑂ ompbox96318</span><span style=""></span><span style="background:#0f1216;"> </span><span style=""></span><span style="color:#0f1216;">▶</span><span style=""></span><span style="color:#00b4ff;">─2%</span><span style=""></span><span style="color:#2a3038;">────────────────────────────────────────</span><span style=""></span><span style="color:#3998bf;">┃</span><span style=""></span><span style="color:#2a3038;">──────</span><span style=""></span><span style="color:#3998bf;">1M</span><span style=""></span><span style="color:#2a3038;">─</span><span style=""></span><span style="color:#00b4ff;">──╮</span><span style="">
</span><span style=""></span><span style="color:#00b4ff;">╰─ </span><span style=""></span><span style="color:#e5e5e7;">                                                                                     </span><span style=""></span><span style="color:#00b4ff;">⇧⇥</span><span style=""></span><span style="color:#e5e5e7;"> </span><span style=""></span><span style="color:#6b7280;">to change thinking effort</span><span style=""></span><span style="color:#00b4ff;"> ─╯</span></pre></section><section><h2>Claude replacement in preserved pane (external-import prompt)</h2><pre>g a literal * at that position. Use Bash(rm*/.claude/settings*) for wildcard matching.
Permission ask rule (~/.claude/settings.json): Bash(mv*/.claude/hooks/*:*) mixes * with the traili
ng :* prefix syntax, so it is matched as a literal prefix (the * is not expanded) and matches only commands containing 
a literal * at that position. Use Bash(mv*/.claude/hooks/*) for wildcard matching.
Permission ask rule (~/.claude/settings.json): Bash(mv*/.claude/settings*:*) mixes * with the trai
ling :* prefix syntax, so it is matched as a literal prefix (the * is not expanded) and matches only commands containin
g a literal * at that position. Use Bash(mv*/.claude/settings*) for wildcard matching.
Permission ask rule (~/.claude/settings.json): Bash(*&gt;*/.claude/settings*:*) mixes * with the trai
ling :* prefix syntax, so it is matched as a literal prefix (the * is not expanded) and matches only commands containin
g a literal * at that position. Use Bash(*&gt;*/.claude/settings*) for wildcard matching.
Permission ask rule (~/.claude/settings.json): Bash(*&gt;*/.claude/hooks/*:*) mixes * with the traili
ng :* prefix syntax, so it is matched as a literal prefix (the * is not expanded) and matches only commands containing 
a literal * at that position. Use Bash(*&gt;*/.claude/hooks/*) for wildcard matching.
Permission ask rule (~/.claude/settings.json): Bash(rm*/.tac/governance/*:*) mixes * with the trai
ling :* prefix syntax, so it is matched as a literal prefix (the * is not expanded) and matches only commands containin
g a literal * at that position. Use Bash(rm*/.tac/governance/*) for wildcard matching.
Permission ask rule (~/.claude/settings.json): Bash(mv*/.tac/governance/*:*) mixes * with the trai
ling :* prefix syntax, so it is matched as a literal prefix (the * is not expanded) and matches only commands containin
g a literal * at that position. Use Bash(mv*/.tac/governance/*) for wildcard matching.
Permission ask rule (~/.claude/settings.json): Bash(*&gt;*/.tac/governance/*:*) mixes * with the trai
ling :* prefix syntax, so it is matched as a literal prefix (the * is not expanded) and matches only commands containin
g a literal * at that position. Use Bash(*&gt;*/.tac/governance/*) for wildcard matching.

───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
  Allow external CLAUDE.md file imports?

  This project&#x27;s CLAUDE.md or .claude/rules imports files outside the current working directory. Never allow this for
  third-party repositories.

  External imports:
    ~/.no-mistakes/worktrees/32d18ed9638d/01M49M05K2KST38EB9PT2GA4QJ/AGENTS.md

  Important: Only use Claude Code with files you trust. Accessing untrusted files may pose security risks
  https://code.claude.com/docs/en/security

  ❯ No, disable external imports
    Yes, allow external imports

  Enter to confirm · Esc to cancel</pre></section>
Evidence: Adversarial drafts and omp-to-Claude lifecycle transcript

Source: Adversarial drafts and omp-to-Claude lifecycle transcript

~/.no-mistakes/worktrees/32d18ed9638d/01M49M05K2KST38EB9PT2GA4QJ/.live-validation/tmp/fm-omp-composer-box-live.uYOLDi/control-home
ok - live omp box composer: omp (omp/18.6.3) on herdr 0.9.1 draws the box shape (status in the top border, folded last row) in isolated session fm-lab-omp-composer-box-96979-20790
initial composer=empty agent=alive endpoint=fm-lab-omp-composer-box-96979-20790:w1:p1
ok - live omp box composer: omp (omp/18.6.3) on herdr 0.9.1 idle empty composer reads empty through the production Herdr adapter
Initial plain-capture state=unknown
hint-copy styled=pending plain=unknown plain-content=⇧⇥ to change thinking effort
fm-gate-refuse: gate agent lifecycle permitted only against lab home ~/.no-mistakes/worktrees/32d18ed9638d/01M49M05K2KST38EB9PT2GA4QJ/.live-validation/tmp/fm-omp-composer-box-live.uYOLDi/control-home
error: task ompbox96318's composer visibly holds pending text; refusing to type the /quit exit command because it would concatenate onto that text. Clear or submit the pending text, then retry 'exit'
ok - actual omp hint-copy draft preserved; exit refused; extracted=⇧⇥ to change thinking effort
fm-gate-refuse: gate agent lifecycle permitted only against lab home ~/.no-mistakes/worktrees/32d18ed9638d/01M49M05K2KST38EB9PT2GA4QJ/.live-validation/tmp/fm-omp-composer-box-live.uYOLDi/control-home
error: task ompbox96318's composer visibly holds pending text; refusing to type the /quit exit command because it would concatenate onto that text. Clear or submit the pending text, then retry 'exit'
ok - actual omp shell-glyph draft preserved; exit refused; extracted=>
fm-gate-refuse: gate agent lifecycle permitted only against lab home ~/.no-mistakes/worktrees/32d18ed9638d/01M49M05K2KST38EB9PT2GA4QJ/.live-validation/tmp/fm-omp-composer-box-live.uYOLDi/control-home
error: task ompbox96318's composer visibly holds pending text; refusing to type the /quit exit command because it would concatenate onto that text. Clear or submit the pending text, then retry 'exit'
ok - actual omp agent-glyph draft preserved; exit refused; extracted=❯
fm-gate-refuse: gate agent lifecycle permitted only against lab home ~/.no-mistakes/worktrees/32d18ed9638d/01M49M05K2KST38EB9PT2GA4QJ/.live-validation/tmp/fm-omp-composer-box-live.uYOLDi/control-home
error: task ompbox96318's composer visibly holds pending text; refusing to type the /quit exit command because it would concatenate onto that text. Clear or submit the pending text, then retry 'exit'
ok - actual omp border-text draft preserved; exit refused; extracted=─ typed draft ─
fm-gate-refuse: gate agent lifecycle permitted only against lab home ~/.no-mistakes/worktrees/32d18ed9638d/01M49M05K2KST38EB9PT2GA4QJ/.live-validation/tmp/fm-omp-composer-box-live.uYOLDi/control-home
error: task ompbox96318's composer visibly holds pending text; refusing to type the /quit exit command because it would concatenate onto that text. Clear or submit the pending text, then retry 'exit'
ok - actual omp wrapped-draft draft preserved; exit refused; extracted=one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen twenty twenty-one twenty-two twenty-three twenty-four twenty-five twenty-six
fm-gate-refuse: gate agent lifecycle permitted only against lab home ~/.no-mistakes/worktrees/32d18ed9638d/01M49M05K2KST38EB9PT2GA4QJ/.live-validation/tmp/fm-omp-composer-box-live.uYOLDi/control-home
error: task ompbox96318's composer visibly holds pending text; refusing to type the /quit exit command because it would concatenate onto that text. Clear or submit the pending text, then retry 'exit'
ok - live omp box composer: omp (omp/18.6.3) on herdr 0.9.1 reads a typed draft pending and fm-control exit refuses it by name without typing
fm-gate-refuse: gate agent lifecycle permitted only against lab home ~/.no-mistakes/worktrees/32d18ed9638d/01M49M05K2KST38EB9PT2GA4QJ/.live-validation/tmp/fm-omp-composer-box-live.uYOLDi/control-home
stopped ompbox96318 harness=omp backend=herdr endpoint=fm-lab-omp-composer-box-96979-20790:w1:p1 worktree=~/.no-mistakes/worktrees/32d18ed9638d/01M49M05K2KST38EB9PT2GA4QJ/.live-validation/tmp/fm-omp-composer-box-live.uYOLDi/wt
ok - live omp box composer: omp (omp/18.6.3) on herdr 0.9.1 fm-control exit stops the idle box-shaped worker and preserves its endpoint
relaunch precondition composer=empty agent=alive endpoint=fm-lab-omp-composer-box-96979-20790:w1:p1
fm-gate-refuse: gate agent lifecycle permitted only against lab home ~/.no-mistakes/worktrees/32d18ed9638d/01M49M05K2KST38EB9PT2GA4QJ/.live-validation/tmp/fm-omp-composer-box-live.uYOLDi/control-home
fm-gate-refuse: gate agent lifecycle permitted only against lab home ~/.no-mistakes/worktrees/32d18ed9638d/01M49M05K2KST38EB9PT2GA4QJ/.live-validation/tmp/fm-omp-composer-box-live.uYOLDi/control-home
warning: ~/.no-mistakes/worktrees/32d18ed9638d/01M49M05K2KST38EB9PT2GA4QJ/.live-validation/tmp/fm-omp-composer-box-live.uYOLDi/control-home/data/ompbox96318/launch-brief.md records no ship branch; defaulting to legacy branch fm/ompbox96318
warning: ~/.no-mistakes/worktrees/32d18ed9638d/01M49M05K2KST38EB9PT2GA4QJ/.live-validation/tmp/fm-omp-composer-box-live.uYOLDi/control-home/data/ompbox96318/launch-brief.md records no delivery contract line (scaffolded before ship briefs recorded one); launching on the explicit --mode no-mistakes - confirm its definition of done matches
relaunched ompbox96318 harness=claude from=omp model=default effort=default backend=herdr endpoint=fm-lab-omp-composer-box-96979-20790:w1:p1 worktree=~/.no-mistakes/worktrees/32d18ed9638d/01M49M05K2KST38EB9PT2GA4QJ/.live-validation/tmp/fm-omp-composer-box-live.uYOLDi/wt
{"id":"cli:agent:get","result":{"agent":{"agent":"claude","agent_status":"blocked","cwd":"~/.no-mistakes/worktrees/32d18ed9638d/01M49M05K2KST38EB9PT2GA4QJ/.live-validation/tmp/fm-omp-composer-box-live.uYOLDi/wt","focused":true,"foreground_cwd":"~/.no-mistakes/worktrees/32d18ed9638d/01M49M05K2KST38EB9PT2GA4QJ/.live-validation/tmp/fm-omp-composer-box-live.uYOLDi/wt","pane_id":"w1:p1","revision":1,"state_change_seq":5,"tab_id":"w1:t1","terminal_id":"term_65d33ec51ed131","terminal_title":"π > wt","terminal_title_stripped":"π > wt","workspace_id":"w1"},"type":"agent_info"}}
{"id":"cli:pane:get","result":{"pane":{"agent":"claude","agent_status":"blocked","cwd":"~/.no-mistakes/worktrees/32d18ed9638d/01M49M05K2KST38EB9PT2GA4QJ/.live-validation/tmp/fm-omp-composer-box-live.uYOLDi/wt","focused":true,"foreground_cwd":"~/.no-mistakes/worktrees/32d18ed9638d/01M49M05K2KST38EB9PT2GA4QJ/.live-validation/tmp/fm-omp-composer-box-live.uYOLDi/wt","pane_id":"w1:p1","revision":1,"scroll":{"max_offset_from_bottom":91,"offset_from_bottom":0,"viewport_rows":40},"tab_id":"w1:t1","terminal_id":"term_65d33ec51ed131","terminal_title":"π > wt","terminal_title_stripped":"π > wt","workspace_id":"w1"},"type":"pane_info"}}
ok - live omp box composer: omp (omp/18.6.3) on herdr 0.9.1 fm-control relaunch replaces the box-shaped worker with a live agent in the same endpoint
Evidence: Idle omp exit and same-endpoint relaunch transcript

Source: Idle omp exit and same-endpoint relaunch transcript

~/.no-mistakes/worktrees/32d18ed9638d/01M49M05K2KST38EB9PT2GA4QJ/.live-validation/tmp/fm-omp-composer-box-live.cGn3CP/control-home
ok - live omp box composer: omp (omp/18.6.3) on herdr 0.9.1 draws the box shape (status in the top border, folded last row) in isolated session fm-lab-omp-composer-box-14166-29272
initial composer=empty agent=alive endpoint=fm-lab-omp-composer-box-14166-29272:w1:p1
ok - live omp box composer: omp (omp/18.6.3) on herdr 0.9.1 idle empty composer reads empty through the production Herdr adapter
fm-gate-refuse: gate agent lifecycle permitted only against lab home ~/.no-mistakes/worktrees/32d18ed9638d/01M49M05K2KST38EB9PT2GA4QJ/.live-validation/tmp/fm-omp-composer-box-live.cGn3CP/control-home
error: task ompbox13847's composer visibly holds pending text; refusing to type the /quit exit command because it would concatenate onto that text. Clear or submit the pending text, then retry 'exit'
ok - live omp box composer: omp (omp/18.6.3) on herdr 0.9.1 reads a typed draft pending and fm-control exit refuses it by name without typing
fm-gate-refuse: gate agent lifecycle permitted only against lab home ~/.no-mistakes/worktrees/32d18ed9638d/01M49M05K2KST38EB9PT2GA4QJ/.live-validation/tmp/fm-omp-composer-box-live.cGn3CP/control-home
stopped ompbox13847 harness=omp backend=herdr endpoint=fm-lab-omp-composer-box-14166-29272:w1:p1 worktree=~/.no-mistakes/worktrees/32d18ed9638d/01M49M05K2KST38EB9PT2GA4QJ/.live-validation/tmp/fm-omp-composer-box-live.cGn3CP/wt
ok - live omp box composer: omp (omp/18.6.3) on herdr 0.9.1 fm-control exit stops the idle box-shaped worker and preserves its endpoint
relaunch precondition composer=empty agent=alive endpoint=fm-lab-omp-composer-box-14166-29272:w1:p1
fm-gate-refuse: gate agent lifecycle permitted only against lab home ~/.no-mistakes/worktrees/32d18ed9638d/01M49M05K2KST38EB9PT2GA4QJ/.live-validation/tmp/fm-omp-composer-box-live.cGn3CP/control-home
fm-gate-refuse: gate agent lifecycle permitted only against lab home ~/.no-mistakes/worktrees/32d18ed9638d/01M49M05K2KST38EB9PT2GA4QJ/.live-validation/tmp/fm-omp-composer-box-live.cGn3CP/control-home
warning: ~/.no-mistakes/worktrees/32d18ed9638d/01M49M05K2KST38EB9PT2GA4QJ/.live-validation/tmp/fm-omp-composer-box-live.cGn3CP/control-home/data/ompbox13847/launch-brief.md records no ship branch; defaulting to legacy branch fm/ompbox13847
warning: ~/.no-mistakes/worktrees/32d18ed9638d/01M49M05K2KST38EB9PT2GA4QJ/.live-validation/tmp/fm-omp-composer-box-live.cGn3CP/control-home/data/ompbox13847/launch-brief.md records no delivery contract line (scaffolded before ship briefs recorded one); launching on the explicit --mode no-mistakes - confirm its definition of done matches
relaunched ompbox13847 harness=omp from=omp model=default effort=default backend=herdr endpoint=fm-lab-omp-composer-box-14166-29272:w1:p1 worktree=~/.no-mistakes/worktrees/32d18ed9638d/01M49M05K2KST38EB9PT2GA4QJ/.live-validation/tmp/fm-omp-composer-box-live.cGn3CP/wt
ok - live omp box composer: omp (omp/18.6.3) on herdr 0.9.1 fm-control relaunch replaces the box-shaped worker with a live agent in the same endpoint
Evidence: Baseline refusal reproduced on the live box capture

Source: Baseline refusal reproduced on the live box capture

Same actual omp 18.6.3 rounded-box ANSI viewport captured during this run:
base 03eaea6 composer state: unknown
target composer state: empty
Evidence: Expected guard refusal after failed second startup

Source: Expected guard refusal after failed second startup

~/.no-mistakes/worktrees/32d18ed9638d/01M49M05K2KST38EB9PT2GA4QJ/.live-validation/tmp/fm-omp-composer-box-live.Bse4FN/control-home
ok - live omp box composer: omp (omp/18.6.3) on herdr 0.9.1 draws the box shape (status in the top border, folded last row) in isolated session fm-lab-omp-composer-box-20308-7393
initial composer=empty agent=alive endpoint=fm-lab-omp-composer-box-20308-7393:w1:p1
ok - live omp box composer: omp (omp/18.6.3) on herdr 0.9.1 idle empty composer reads empty through the production Herdr adapter
fm-gate-refuse: gate agent lifecycle permitted only against lab home ~/.no-mistakes/worktrees/32d18ed9638d/01M49M05K2KST38EB9PT2GA4QJ/.live-validation/tmp/fm-omp-composer-box-live.Bse4FN/control-home
error: task ompbox19800's composer visibly holds pending text; refusing to type the /quit exit command because it would concatenate onto that text. Clear or submit the pending text, then retry 'exit'
ok - live omp box composer: omp (omp/18.6.3) on herdr 0.9.1 reads a typed draft pending and fm-control exit refuses it by name without typing
fm-gate-refuse: gate agent lifecycle permitted only against lab home ~/.no-mistakes/worktrees/32d18ed9638d/01M49M05K2KST38EB9PT2GA4QJ/.live-validation/tmp/fm-omp-composer-box-live.Bse4FN/control-home
stopped ompbox19800 harness=omp backend=herdr endpoint=fm-lab-omp-composer-box-20308-7393:w1:p1 worktree=~/.no-mistakes/worktrees/32d18ed9638d/01M49M05K2KST38EB9PT2GA4QJ/.live-validation/tmp/fm-omp-composer-box-live.Bse4FN/wt
ok - live omp box composer: omp (omp/18.6.3) on herdr 0.9.1 fm-control exit stops the idle box-shaped worker and preserves its endpoint
not ok - omp (omp/18.6.3) on herdr 0.9.1: the second launch never proved a live agent with an empty box composer (agent='dead', composer='unknown')

                                            ████████████
                                               ██  ██       ▄▀▀▄ █▀▄▀▄ █▀▀▄
                                               ██  ██       ▀▄▄▀ █ █ █ █▄▄▀
                                               ▒▒  ██                  █
                                                   ██       v18.6.3

                                Tip: Press ⇧⇥ to cycle through reasoning effort levels


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

 Closing session…


╭── π > ◒ Gemini 3.1 Pro Preview > 🌳 proj/wt > ⑂ ompbox19800 ▶─2%────────────────────────────────────────┃──────1M───╮
╰─                                                                                      ⇧⇥ to change thinking effort ─╯
Mac-Studio:wt charlesabrooker$ env PI_CODING_AGENT_DIR='~/.no-mistakes/worktrees/32d18ed9638d/01M4
9M05K2KST38EB9PT2GA4QJ/.live-validation/omp-state' OMP_SKIP_SETUP=1 FM_OMP_HARNESS=omp omp --definitely-invalid-live-gu
ard-option --cwd '~/.no-mistakes/worktrees/32d18ed9638d/01M49M05K2KST38EB9PT2GA4QJ/.live-validatio
n/tmp/fm-omp-composer-box-live.Bse4FN/wt'
Error: unknown flag: --definitely-invalid-live-guard-option
Run `omp --help` for available flags.
Mac-Studio:wt charlesabrooker$
{"error":{"code":"agent_not_found","message":"agent target w1:p1 not found"},"id":"cli:agent:get"}
{"id":"cli:pane:get","result":{"pane":{"agent_status":"unknown","cwd":"~/.no-mistakes/worktrees/32d18ed9638d/01M49M05K2KST38EB9PT2GA4QJ/.live-validation/tmp/fm-omp-composer-box-live.Bse4FN/wt","focused":true,"foreground_cwd":"~/.no-mistakes/worktrees/32d18ed9638d/01M49M05K2KST38EB9PT2GA4QJ/.live-validation/tmp/fm-omp-composer-box-live.Bse4FN/wt","pane_id":"w1:p1","revision":1,"scroll":{"max_offset_from_bottom":0,"offset_from_bottom":0,"viewport_rows":40},"tab_id":"w1:t1","terminal_id":"term_65d33ecae6f061","terminal_title":"π > wt","terminal_title_stripped":"π > wt","workspace_id":"w1"},"type":"pane_info"}}

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

🔧 **Review** - 4 issues found → auto-fixed (3) ✅
  • 🚨 bin/fm-composer-lib.sh:1339 - A plain capture treats a real draft equal to ⇧⇥ to change thinking effort as empty. Concrete sequence: type that string into an omp box, then take Herdr's supported ANSI-failure/plain-success fallback (bin/backends/herdr.sh:3240-3242). The unconditional hint acceptance returns empty, allowing fm-control.sh:635-666 to append and submit /quit into the existing draft. The same invariant is violated by bin/fm-composer-lib.sh:1724-1725, which erases this draft during extraction, and tests/fm-composer-lib.test.sh:549, which requires the ambiguous plain bytes to read empty; the styled typed-input counterpart at :552-553 demonstrates the collision. Preserve ambiguity at the shared omp-box hint boundary: without styling proof, return unknown rather than empty and do not discard the text during extraction.
  • ⚠️ tests/fm-omp-composer-box-live-e2e.test.sh:44 - The documented command sets only FM_OMP_COMPOSER_BOX_LIVE_RELAUNCH=1, but fm_live_gate receives only FM_OMP_COMPOSER_BOX_LIVE. If a required tool is absent, the explicitly requested relaunch verification exits successfully with a capability skip; FM_LIVE=0 also suppresses it. Relevant siblings are the relaunch entry point at :248 and the refresh command in docs/verification/runtime-backends.md:965. Make relaunch=1 force the shared capability gate, while keeping relaunch=0 from disabling the token-free portion.
  • ⚠️ tests/fm-omp-composer-box-live-e2e.test.sh:107 - The new grep assertion checks an exact configuration line rather than its YAML meaning, contrary to the test-quality rule for machine-consumed declarative artifacts. Together with the textual transformation at :106, it can fail on a behavior-preserving formatting change. Remove this source-content assertion: the real omp consumer is already invoked at :159, and its rendered box shape is asserted at :180-185.
  • ⚠️ bin/fm-composer-lib.sh:1269 - Simplification: the change introduces configurable matching options FM_COMPOSER_OMP_BOX_TOP_RE and FM_COMPOSER_OMP_BOX_HINT_RE, although the intent requires recognizing the verified omp box shape, not allowing operators to redefine its identity or idle hint. The hint override is also consumed at bin/fm-composer-lib.sh:1323 and :1723. No stated requirement needs these additional acceptance paths. Remove the new overrides and use the fixed verified patterns; this recommendation concerns scope, so it needs the author's decision.

🔧 Fix applied.
3 warnings still open:

  • ⚠️ tests/fm-omp-composer-box-live-e2e.test.sh:44 - The documented command sets only FM_OMP_COMPOSER_BOX_LIVE_RELAUNCH=1, but fm_live_gate receives only FM_OMP_COMPOSER_BOX_LIVE. If a required tool is absent, the explicitly requested relaunch verification exits successfully with a capability skip; FM_LIVE=0 also suppresses it. Relevant siblings are the relaunch entry point at :248 and the refresh command in docs/verification/runtime-backends.md:965. Make relaunch=1 force the shared capability gate, while keeping relaunch=0 from disabling the token-free portion.
  • ⚠️ tests/fm-omp-composer-box-live-e2e.test.sh:107 - The new grep assertion checks an exact configuration line rather than its YAML meaning, contrary to the test-quality rule for machine-consumed declarative artifacts. Together with the textual transformation at :106, it can fail on a behavior-preserving formatting change. Remove this source-content assertion: the real omp consumer is already invoked at :159, and its rendered box shape is asserted at :180-185.
  • ⚠️ tests/fm-omp-composer-box-live-e2e.test.sh:267 - Simplification: the model-generated instruction-acknowledgement component exceeds the intent to recognize box composers and safely exit/relaunch workers. Token generation (:115), the response-only brief (:128–136), and the 180-second token poll (:267–274) verify unchanged instruction-following behavior rather than composer or lifecycle correctness. The assertion also accepts a token already contained in the submitted launch brief (:134; bin/fm-spawn.sh:3119,2107), without distinguishing assistant output from input. Remove this acknowledgement component and its success claims at tests/fm-omp-composer-box-live-e2e.test.sh:275 and docs/verification/runtime-backends.md:980; retain real relaunch coverage using replacement-agent liveness and endpoint preservation. Removal, rather than hardening this additional model-response verifier, is the smallest remedy; this scope decision needs authorization.

🔧 Fix applied.
4 warnings still open:

  • ⚠️ tests/fm-omp-composer-box-live-e2e.test.sh:44 - The documented command sets only FM_OMP_COMPOSER_BOX_LIVE_RELAUNCH=1, but fm_live_gate receives only FM_OMP_COMPOSER_BOX_LIVE. If a required tool is absent, the explicitly requested relaunch verification exits successfully with a capability skip; FM_LIVE=0 also suppresses it. Relevant siblings are the relaunch entry point at :248 and the refresh command in docs/verification/runtime-backends.md:965. Make relaunch=1 force the shared capability gate, while keeping relaunch=0 from disabling the token-free portion.
  • ⚠️ tests/fm-omp-composer-box-live-e2e.test.sh:107 - The new grep assertion checks an exact configuration line rather than its YAML meaning, contrary to the test-quality rule for machine-consumed declarative artifacts. Together with the textual transformation at :106, it can fail on a behavior-preserving formatting change. Remove this source-content assertion: the real omp consumer is already invoked at :159, and its rendered box shape is asserted at :180-185.
  • ⚠️ tests/fm-omp-composer-box-live-e2e.test.sh:267 - Simplification: the model-generated instruction-acknowledgement component exceeds the intent to recognize box composers and safely exit/relaunch workers. Token generation (:115), the response-only brief (:128–136), and the 180-second token poll (:267–274) verify unchanged instruction-following behavior rather than composer or lifecycle correctness. The assertion also accepts a token already contained in the submitted launch brief (:134; bin/fm-spawn.sh:3119,2107), without distinguishing assistant output from input. Remove this acknowledgement component and its success claims at tests/fm-omp-composer-box-live-e2e.test.sh:275 and docs/verification/runtime-backends.md:980; retain real relaunch coverage using replacement-agent liveness and endpoint preservation. Removal, rather than hardening this additional model-response verifier, is the smallest remedy; this scope decision needs authorization.
  • ⚠️ tests/fm-omp-composer-box-live-e2e.test.sh:253 - The second-launch wait falls through after 60 unsuccessful reads without checking its precondition. Concrete sequence: pane run successfully submits the launch command, but that omp process exits during startup; the composer never reads empty, yet fm-control relaunch accepts the dead agent as already stopped (bin/fm-control.sh:572-574), launches a replacement, and the guard passes. It therefore claims to have relaunched an idle box-shaped worker without exercising that path. Round 2's replacement-liveness fix leaves this precondition unchecked. Relevant changed sites are tests/fm-omp-composer-box-live-e2e.test.sh:250 (launch submission), :254-258 (unchecked wait before control), :264-267 (replacement-only proof and success claim), and docs/verification/runtime-backends.md:981 (matching claim). Require a live agent and a proven empty box composer before invoking relaunch; fail when the wait expires.

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

✅ No issues found.

✅ **Test** - passed

✅ No issues found.

  • Live validation: ✅ go - 7 of 7 scenarios driven live against the product
Scenario Result Live Evidence
Inspect an idle rounded omp box and prove its composer empty ✅ pass live omp-box-live-e2e.log; adversarial-and-claude.log; idle-box.png
Attempt exit with glyph-only or wrapped drafts without overwriting them ✅ pass live adversarial-and-claude.log; wrapped-draft.png
Type the exact idle hint and preserve ambiguity when ANSI capture is unavailable ✅ pass live adversarial-and-claude.log; typed-hint.png
Clear a draft and stop the empty-box worker while retaining its pane ✅ pass live omp-box-live-e2e.log
Relaunch a live empty-box omp worker into a live replacement in the same endpoint ✅ pass live omp-box-live-e2e.log
Transition an idle omp box to Claude without losing the endpoint or local work ✅ pass live adversarial-and-claude.log; claude-agent.json; claude-transition-metadata.txt; claude-replacement.png
Reject relaunch verification when the second launch exits before becoming a live empty box ✅ pass live relaunch-precondition-guard.log; relaunch-precondition-fault.log
  • bash tests/fm-composer-lib.test.sh — targeted composer classification and extraction regressions.
  • bash tests/fm-omp-composer-box-live-e2e.test.sh with FM_OMP_COMPOSER_BOX_LIVE=1 and FM_OMP_COMPOSER_BOX_LIVE_RELAUNCH=1 — real omp through the production Herdr adapter in a disposable named lab.
  • python3 .live-validation/supplement.py — disposable driver exercising glyph-only drafts, wrapped input, exact idle-hint text, ANSI-failure/plain-success fallback, and public fm-control.sh refusal behavior; setup errors were corrected before the successful run.
  • Compared the base and target fm_composer_classify_screen implementations against the same newly captured live idle-box ANSI viewport: base returned unknown; target returned empty.
  • fm-control.sh &lt;disposable-task&gt; relaunch --harness claude --note &#39;Verify replacement liveness only; do not edit any file.&#39; — verified live Claude identity, preserved pane, metadata, HEAD, and uncommitted file; claude auth status confirmed an existing login.
  • Re-ran the live guard through .live-validation/r6-lab.py, making the second launch execute real omp --version and exit before drawing a composer; verified the guard rejected the dead/unknown precondition without launching a replacement.
  • Captured actual Herdr ANSI viewports, rendered them as HTML, and captured reviewer-visible images with Chromium; completed guarded lab teardowns and removed disposable drivers, homes, worktrees, and temporary artifacts.

✅ No issues found.

  • Live validation: ✅ go - 8 of 8 scenarios driven live against the product
Scenario Result Live Evidence
Exit a live empty rounded-box omp worker without removing its endpoint ✅ pass live omp-ready-lifecycle.log; composer-safety-and-claude-transition.html; composer-before-after.log
Attempt exit with an ordinary unsent draft and preserve the draft ✅ pass live claude-exact-lifecycle.log; composer-safety-and-claude-transition.html
Type the exact effort hint and retain ambiguity when capture styling is absent ✅ pass live claude-exact-lifecycle.log; rendered typed-hint viewport in composer-safety-and-claude-transition.html
Attempt exit with prompt glyphs, border characters, and wrapped text as drafts ✅ pass live claude-exact-lifecycle.log; composer-safety-and-claude-transition.html
Relaunch a proven live empty-box omp worker in the same endpoint ✅ pass live omp-ready-lifecycle.log
Transition an idle box-shaped omp worker to a live Claude replacement ✅ pass live claude-exact-lifecycle.log; composer-safety-and-claude-transition.html
Relaunch an idle box composer after a real failed provider turn ✅ pass live retry-lifecycle.log; retry-failed-turn-idle.html
Reject relaunch verification when the second omp launch dies during startup ✅ pass live failed-second-launch.log
  • env TMPDIR="$PWD/.live-validation/tmp" bash tests/fm-composer-lib.test.sh
  • FM_OMP_COMPOSER_BOX_LIVE=1 FM_OMP_COMPOSER_BOX_LIVE_RELAUNCH=1 bash .live-validation/guard.sh — isolated, evidence-enabled copy of the existing E2E guard; reproduced the registration race, then passed with readiness waiting.
  • env PI_CODING_AGENT_DIR=&#34;$PWD/.live-validation/omp-state&#34; omp config list --json and omp config set spelling.autocomplete off — disabled fixture ghost completions after they changed the plain hint-collision capture.
  • FM_OMP_COMPOSER_BOX_LIVE=1 FM_OMP_COMPOSER_BOX_LIVE_RELAUNCH=1 bash .live-validation/claude-adversarial.sh — exercised draft boundaries and fm-control relaunch --harness claude.
  • FM_OMP_COMPOSER_BOX_LIVE=1 FM_OMP_COMPOSER_BOX_LIVE_RELAUNCH=1 bash .live-validation/failed-turn-relaunch.sh — exercised a real provider-error screen followed by relaunch.
  • FM_OMP_COMPOSER_BOX_LIVE=1 FM_OMP_COMPOSER_BOX_LIVE_RELAUNCH=1 bash .live-validation/failed-second-launch.sh — deliberately failed omp startup; observed the expected guard failure before relaunch.
  • Executed the base and target fm_composer_classify_screen implementations against the same actual live omp ANSI capture: base returned unknown; target returned empty.
  • All Herdr operations used bin/fm-herdr-lab.sh with named non-default sessions. Every lab was torn down, rendered viewport evidence was retained, and .live-validation was removed.
✅ **Document** - passed

✅ No issues found.

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

✅ No issues found.

… workers

omp live-reloads the overlay files it was started with, so workers launched
before the overlay split lost their composer.shape: borderless pin and fell
back to the box shape: status line in the top border, editor last row folded
into the bottom border. The shared classifier read that screen as unknown,
so fm-control exit and relaunch refused every idle omp worker.

Teach the classifier this shape, proven only by omp's status identity in a
rounded top border and a folded "╰─ ... ─╯" last row. Empty reads empty,
typed text (including a lone prompt glyph) reads pending, and every other
variant stays unknown. Add behavioral tests from the captured screen and a
live Herdr guard that drives fm-control exit and relaunch on a real omp.
@MrGTV-love
MrGTV-love force-pushed the fm/fm-omp-composer-unknown-blocks-control branch from 93f4376 to 9602493 Compare October 6, 2026 23:03
@MrGTV-love
MrGTV-love merged commit 8f7b00e into main Oct 6, 2026
21 checks passed
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