fork-landing: block Pi's turn end from agent_end instead of reacting after settle (upstream #1082) - #28
Closed
sbracewell64 wants to merge 5 commits into
Closed
fork-landing: block Pi's turn end from agent_end instead of reacting after settle (upstream #1082)#28sbracewell64 wants to merge 5 commits into
sbracewell64 wants to merge 5 commits into
Conversation
…settle The Pi primary turn-end guard hooked agent_settled, which fires after the agent loop has already exited. That emits the idle signal first, so anything watching for idle sees a blind turn end, and the forced follow-up only re-opens a turn that already ended. Pi drains both message queues before emitting agent_end, so a follow-up queued from an agent_end handler makes _handlePostAgentRun() return true and the session calls agent.continue(). The same run keeps going and agent_settled never fires until the guard stops queuing. Pi therefore blocks genuinely, like the Claude and Codex Stop hooks, rather than passively. Measured against pi 0.81.1 with a local mock provider: the shipped agent_end guard emits one idle signal, the agent_settled version emits two. A probe that re-queued from agent_end blocked 12 consecutive times with no ceiling, so the single-follow-up limit is Firstmate's latch and not a Pi limit. The re-entrancy latch is unchanged. Because agent_end also fires at auto-retry and compaction boundaries, a run needing one of those while supervision is already unhealthy spends its latched follow-up there instead of at the final boundary; the recovery instruction still lands in the same run, so this is an ordering nuance rather than a blind turn end. Adds tests/fm-turnend-guard.test.sh:test_pi_extension_blocks_before_the_idle_signal, which models Pi's loop and fails against the agent_settled version.
…ng agent_end path
Owner
Author
|
Closing. This was opened as a fork-landing branch cut from fork The required Superseded pending a captain ruling. The shared contribution branch and its open upstream PR were never modified. |
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.
Fork-landing branch for the contribution currently open upstream as kunchenguid#1082.
This branch is a separate branch cut from fork
main, carrying only that contribution's own changes. The shared branchfm/pi-only-harness-planis not touched and remains at20ca39f, so upstream kunchenguid#1082 is unaffected.Screening
The merge result is larger than the contribution's own changes by +32 / -1, entirely in two documentation files. That difference is the reconciliation itself and is itemised below, not unexplained drift.
Conflict reconciliation
The contribution moves Pi's turn-end guard from the passive
agent_settledcallback to blocking onagent_end. Trunk had independently rewritten Grok's adapter to select native blocking from the running Stop payload. Both changes touch the same paragraphs.Reconciled so the contribution's deliberate change (Pi, and by extension
pi-signed, which trunk documents as an identity-preserving reuse of Pi's protocol) is applied, while every newer trunk statement about Grok is preserved verbatim:.agents/skills/harness-adapters/SKILL.md,docs/turnend-guard.md,bin/fm-turnend-guard.sh— Pi/pi-signed described as blocking directly; trunk's Grok capability-selection text kept.docs/turnend-guard.mdregression list — the contribution's two new cases added to trunk's list rather than replacing it.docs/verification/supervision.md— the contribution's measured Pi 0.81.1 row replaces the stale 0.80.5 row; trunk's Grok 0.2.112/0.2.73 row and its whole adaptive-matrix evidence block are kept. Trunk's "Current entry points" block is retained and the contribution's own final correction (CI behaviour unverified from the worktree) is kept over its earlier draft's stronger claim.The contribution's duplicate Grok trust sentence was dropped in favour of trunk's fuller existing one.
Verification
bin/fm-lint.shclean (ShellCheck 0.11.0).tests/fm-turnend-guard.test.sh: one case,Pi guard must block the turn end before the idle signal fires, reportsnot okon this machine. This is a pre-existing environment limitation, not a regression: Node v22.22.1 here is built without TypeScript type stripping, and the identical case fails the same way on the unrebased contribution branch. The contribution's own verification record documents this exact limitation.