Repository navigation
fix: recognize omp box composers for safe worker control - #33
Merged
Merged
Conversation
… 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
force-pushed
the
fm/fm-omp-composer-unknown-blocks-control
branch
from
October 6, 2026 23:03
93f4376 to
9602493
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
"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
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.
Evidence: Actual composer safety and Claude replacement viewports
Source: Actual composer safety and Claude replacement viewports
Evidence: Adversarial drafts and omp-to-Claude lifecycle transcript
Source: Adversarial drafts and omp-to-Claude lifecycle transcript
Evidence: Idle omp exit and same-endpoint relaunch transcript
Source: Idle omp exit and same-endpoint relaunch transcript
Evidence: Baseline refusal reproduced on the live box capture
Source: Baseline refusal reproduced on the live box capture
Evidence: Expected guard refusal after failed second startup
Source: Expected guard refusal after failed second startup
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 effortas 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 returnsempty, allowing fm-control.sh:635-666 to append and submit/quitinto 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 onlyFM_OMP_COMPOSER_BOX_LIVE_RELAUNCH=1, but fm_live_gate receives onlyFM_OMP_COMPOSER_BOX_LIVE. If a required tool is absent, the explicitly requested relaunch verification exits successfully with a capability skip;FM_LIVE=0also 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 optionsFM_COMPOSER_OMP_BOX_TOP_REandFM_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 onlyFM_OMP_COMPOSER_BOX_LIVE_RELAUNCH=1, but fm_live_gate receives onlyFM_OMP_COMPOSER_BOX_LIVE. If a required tool is absent, the explicitly requested relaunch verification exits successfully with a capability skip;FM_LIVE=0also 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 onlyFM_OMP_COMPOSER_BOX_LIVE_RELAUNCH=1, but fm_live_gate receives onlyFM_OMP_COMPOSER_BOX_LIVE. If a required tool is absent, the explicitly requested relaunch verification exits successfully with a capability skip;FM_LIVE=0also 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 runsuccessfully 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.
bash tests/fm-composer-lib.test.sh— targeted composer classification and extraction regressions.bash tests/fm-omp-composer-box-live-e2e.test.shwithFM_OMP_COMPOSER_BOX_LIVE=1andFM_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 publicfm-control.shrefusal behavior; setup errors were corrected before the successful run.Compared the base and targetfm_composer_classify_screenimplementations against the same newly captured live idle-box ANSI viewport: base returnedunknown; target returnedempty.fm-control.sh <disposable-task> relaunch --harness claude --note 'Verify replacement liveness only; do not edit any file.'— verified live Claude identity, preserved pane, metadata, HEAD, and uncommitted file;claude auth statusconfirmed an existing login.Re-ran the live guard through.live-validation/r6-lab.py, making the second launch execute realomp --versionand 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.
env TMPDIR="$PWD/.live-validation/tmp" bash tests/fm-composer-lib.test.shFM_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="$PWD/.live-validation/omp-state" omp config list --jsonandomp 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 andfm-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 targetfm_composer_classify_screenimplementations against the same actual live omp ANSI capture: base returnedunknown; target returnedempty.All Herdr operations usedbin/fm-herdr-lab.shwith named non-default sessions. Every lab was torn down, rendered viewport evidence was retained, and.live-validationwas 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.