This repository was archived by the owner on Aug 25, 2026. It is now read-only.
feat(backend): deepen experimental Herdr adapter - #73
Merged
Merged
Conversation
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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
Deepen experimental Herdr adapter: husk/respawn, prune-safety, eventwait, composer-lib, transition helpers, unit tests. Preserve JT locks and lab refuse-default. Do not port zellij/orca/cmux.
What Changed
Risk Assessment
Testing
The configured baseline command had already passed and was rerun successfully on the target. Focused automated tests covered husk/respawn, exact prune-safety, eventwait, composer and transition helpers, JT locks, lab refuse-default behavior, and backend routing. The full behavior suite passed. A read-only live Herdr smoke verified protocol 16; no mutating real-Herdr e2e was run because it would create external lab state. Reviewer-visible CLI transcripts are saved in the evidence artifacts above.
Evidence: Focused Herdr and safety tests
Evidence: Full behavior suite
Evidence: Real Herdr smoke
ok - real Herdr smoke: client protocol 16 and live server verified (read-only)Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
🔧 **Review** - 4 issues found → auto-fixed (7) ✅
bin/fm-composer-lib.sh:199- The classifier returnsunknownfor a bare shell prompt, but the daemon's injection guard only defers onpending;inject_msgtherefore proceeds to send text to a dead shell, where Enter can execute it. Makeunknowna blocking pre-injection result.bin/fm-backend.sh:287- The authoritative intent requires “Deepen experimental Herdr adapter: ... eventwait ...”. The diff addsfm_backend_wait_transition, but no production caller invokes it; matches are limited to definitions and unit tests, so runtime supervision remains poll-only. Please confirm whether eventwait was intentionally left unwired.bin/backends/herdr.sh:367- Seed pruning now closes only the pane. For a dead pane,fm_backend_herdr_pane_for_tabcan return no pane and pruning exits; even forno-agent, closing the pane may leave the seeded tab behind. Close and verify the exact seeded tab id after the safety checks.bin/backends/herdr.sh:790- The namedsessionargument is ignored by the capability probe:herdr statusandherdr api schemause ambient routing instead offm_backend_herdr_cli, despite the adapter's explicit-session contract. A named Herdr session can therefore be probed against the wrong server/schema.🔧 Fix: Fixed all four Herdr review findings
1 warning still open:
bin/backends/herdr.sh:781-fm_backend_herdr_socket_pathfilters for the requested session but invokes ambientherdr session list --jsonwithout routing throughfm_backend_herdr_cli "$session". For named sessions this can resolve the wrong server or no socket, causing eventwait to fail and silently fall back to polling.🔧 Fix: Route Herdr socket discovery through explicit sessions
2 warnings still open:
bin/backends/herdr.sh:515- After creating the replacement tab, any later failure exits without closing the new tab. The spawn cleanup trap is installed only afterfm_backend_create_taskreturns, so seed-prune or husk-verification failures can leave an unowned Herdr tab behind. Add failure cleanup for the created tab id before returning.bin/backends/herdr.sh:522- Husk cleanup verification pipes the response directly through.result.tabs[]?; a successful but malformed tab-list response produces no output and is treated as proof that no duplicate husk remains. Validate the response shape before accepting cleanup, otherwise stale duplicate-label tabs can survive and block later spawns.🔧 Fix: Close created tabs on Herdr post-create failures
1 warning still open:
bin/backends/herdr.sh:488- The new EXIT cleanup only closes a tab whentab_idwas parsed, and it suppresses any close failure. If Herdr successfully creates a tab but returns a malformed response withouttab_id, execution exits at the parse check with no fallback cleanup; a failed close is also treated as handled. Preserve a safe fallback for malformed responses and verify the created tab is absent.🔧 Fix: Fail closed on malformed Herdr tab cleanup
1 warning still open:
bin/backends/herdr.sh:453- When the create response lacks a tab ID, cleanup treats zero newly observed tabs as success. A stale or incomplete label query can therefore leave the created tab behind while the EXIT trap reports cleanup succeeded; fail closed unless the created tab's absence is authoritatively verified.🔧 Fix: Fail closed on unobserved malformed Herdr tabs
2 issues (1 error, 1 warning) still open:
bin/backends/herdr.sh:511- The EXIT trap is active before the initial duplicate-tab lookup. If that lookup fails before any create, cleanup re-queries with an empty baseline and can mistake an existing live tab for the newly created tab, then close it. Gate fallback cleanup on a create-attempted flag and never close tabs after pre-create failures.bin/backends/herdr.sh:330- When workspace metadata binding fails, workspace close errors are discarded. A workspace-create call may already have succeeded, leaving an orphaned Herdr workspace and seeded tab after the spawn returns failure; verify cleanup and surface failure if the workspace cannot be closed.🔧 Fix: Protect live tabs and verify Herdr workspace rollback
1 warning still open:
bin/backends/herdr.sh:346- Ifworkspace createsucceeds but returns malformed output withoutworkspace_id, this exits at the parse check without attempting cleanup, leaving the newly created workspace and seeded tab orphaned. Preserve a pre-create workspace baseline and identify/close the unique new workspace, or fail with a verified cleanup path.🔧 Fix: Rollback malformed Herdr workspace creations safely
✅ Re-checked - no issues remain.
🔧 **Test** - 1 issue found → auto-fixed ✅
bash bin/fm-run-behavior-tests.sh🔧 Fix: Update stale AFK defer assertion
✅ Re-checked - no issues remain.
bash bin/fm-run-behavior-tests.shbash tests/fm-backend-herdr.test.shpython3 tests/fm-backend-herdr-eventwait.test.pybash tests/fm-composer-lib.test.shbash tests/fm-transition-lib.test.shbash tests/fm-watch-herdr-event.test.shbash tests/fm-herdr-lab.test.shbash tests/fm-gate-refuse.test.shbash bin/fm-run-behavior-tests.shFM_HERDR_SMOKE=1 bash tests/fm-backend-herdr-smoke.test.shRemoved generatedbin/backends/__pycache__/test residue and verifiedgit status --shortis clean.✅ **Document** - passed
✅ No issues found.
🔧 **Lint** - 1 issue found → auto-fixed ✅
🔧 Fix: Captain: export Herdr event capability marker
✅ Re-checked - no issues remain.
✅ **Push** - passed
✅ No issues found.