feat: add external host-root supervision - #2
Closed
YrFnS wants to merge 45 commits into
Closed
Conversation
…e remains blocked
…nchenguid#1500) * fix(bin): deliver process-event results and retire ended sources Two defects reproduced during a real Lavish adapter session. One human `Send & End` produced four captured results: the real feedback, then recurring empty ended sessions. The generic runner had no way to learn a source was finished, so every reconcile restarted a poll that returned immediately. The runner now asks the source's own adapter - `fm-procevent-<adapter>.sh terminal <result-file>` - and on exit 0 alone re-proves ownership, drops the registration, and releases its own claim under one source boundary. Terminal knowledge stays adapter-owned: for Lavish that is an ended session, a missing session, and the final feedback delivery the published poll marks with `session_ended`. An adapter with no terminal command keeps its source armed exactly as before. Capture before publication, captured-result durability, queued wake durability, bounded re-announcement, handled deduplication, one-owner ownership, and explicit idempotent retirement are all unchanged. A captured result queued its `check` wake durably, but a healthy watcher with a fresh beacon never delivered it; the result surfaced only after a manual drain. Publication happens outside the watcher (in the runner) or unconditionally (in reconcile), so the watcher had no newly actionable signal to report and never reached its rewake path. It now reports a queued-but-unsurfaced process-event record through the same actionable exit every other wake uses, deduplicated by the same `.seen-*` marker discipline the signal scan uses, so the record is always durable before it is suppressed. The durable queue remains the authority and no second notifier, poller, timer, queue, or adapter-specific wake path is added. Regressions cover both, driven end to end: an armed Lavish source against a stand-in for the published poll polls once, captures once, publishes one distinct event, and retires itself; two fixture adapters prove the terminal decision follows the adapter alone; and a real capture plus a real watcher prove one proactive wake before any drain, with no duplicate wake while the record stays queued or after it is acknowledged. * no-mistakes(review): Harden process-event retirement and proactive delivery * no-mistakes(review): Route process-event delivery through shared wake owner * no-mistakes(document): Clarify process-event delivery and retirement documentation * no-mistakes(lint): Fix ShellCheck control-flow warnings * no-mistakes(lint): Fix wake output status lint warning
Owner
Author
|
Closing this duplicate fork PR; the validated branch updates the existing upstream PR kunchenguid#1238. |
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
Update FirstMate PR kunchenguid#1238 to the latest upstream main and fix the real Herdr/Pi user experience where one worker caused repeated routine 'Captain, shipshape.' responses during intermediate Pi turns. Preserve FirstMate's push-based architecture: the main supervisor should remain idle while a worker runs, and the worker should wake it once when the logical run settles with a final report, blocker, or decision. Do not merely hide the phrase or weaken final-completion detection. For Pi workers, inner turn boundaries and queued continuations must stay silent; semantic idle must be recorded before the settled notification is emitted. Keep other harnesses and non-host-root behavior unchanged, validate the behavior with executable tests, update the existing PR branch, and do not merge the PR.
What Changed
Risk Assessment
Testing
Commit ancestry, focused lifecycle tests, real Herdr host-root operation, non-host compatibility, broader host-root safeguards, and rebased upstream process-event behavior all passed. A live Herdr/Pi run captured both terminal turns and proved one post-idle notification; two earlier live attempts reached the correct lifecycle but required evidence-only fixes for pane capture and line wrapping. The working tree remained clean. Screenshots were not applicable because this is a terminal lifecycle change; real terminal and ordered event transcripts were captured instead.
Evidence: Live Herdr/Pi lifecycle transcript
Herdr 0.7.5 / Pi 0.83.0: no notification after the first turn; follow-up queued; second turn completed; agent_settled reported isIdle=true; exactly one notification then observed state=idle source=pi-ext.Evidence: Live Pi terminal showing both turns and final report
Evidence: Production-extension lifecycle regression transcript
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
🔧 **Review** - 2 issues found → auto-fixed (2) ✅
bin/fm-spawn.sh:1817- The criterion requires “semantic idle must be recorded before the settled notification is emitted,” butbusyEventignoresfm-busy-event.shfailures and always resolves, so this new notification still runs after a stale generation, lock timeout, unarmed task, or write failure. The stale-incarnation test re-arms the task and confirms state remains busy but never asserts that no false marker was emitted. Gate notification on a successful idle write and cover that failure path.bin/fm-spawn.sh:1814- The criterion requires “Keep other harnesses and non-host-root behavior unchanged,” but the changedagent_settledhandler sits in the unconditionalpi|pi-signedbranch, replacingturn_endsignaling for every ordinary Pi worker. The new test attests/fm-busy-adapter-wiring.test.sh:111explicitly exercises and requires this behavior withoutFM_HOST_ROOT. Scope the change to host-root mode unless broadening default Pi behavior is explicitly approved.🔧 Fix: Gate host-root Pi notifications on successful idle
1 warning still open:
.agents/skills/harness-adapters/SKILL.md:312- The runtime now limits settled-only notification to host-root mode, but this operator contract still says all Pi workers notify fromagent_settledand must never notify fromturn_end. Qualify this as host-root-only and document that ordinary Pi retains per-turn notification; otherwise future adapter work may reintroduce the corrected non-host regression.🔧 Fix: Clarify Pi notification behavior by host mode
✅ Re-checked - no issues remain.
✅ **Test** - passed
✅ No issues found.
git log --graph --oneline --decorate --all --max-count=25andgit merge-base --is-ancestor d36a214 HEADbash tests/fm-busy-adapter-wiring.test.shbash tests/fm-backend-herdr-host-root-e2e.test.shbash tests/fm-host-root-mode.test.shbash tests/fm-spawn-dispatch-profile.test.shbash tests/fm-procevent.test.shbash tests/fm-watch-triage.test.shbash /tmp/no-mistakes-evidence/01KZ0V4R8X7NH9RFXYEW21EGP2/live-herdr-pi-lifecycle.shgit status --short --untracked-files=alland isolated Herdr-session cleanup verification✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.