Skip to content

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
mainfrom
landing/3-pi-only-harness-plan
Closed

fork-landing: block Pi's turn end from agent_end instead of reacting after settle (upstream #1082)#28
sbracewell64 wants to merge 5 commits into
mainfrom
landing/3-pi-only-harness-plan

Conversation

@sbracewell64

Copy link
Copy Markdown
Owner

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 branch fm/pi-only-harness-plan is not touched and remains at 20ca39f, so upstream kunchenguid#1082 is unaffected.

Screening

Measure Result
Contribution's own changes 7 files, +270 / -26
Merge result vs fork trunk 7 files, +302 / -25
Trunk content lost none (trunk is an ancestor)

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_settled callback to blocking on agent_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.md regression 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.sh clean (ShellCheck 0.11.0).
  • tests/fm-turnend-guard.test.sh: one case, Pi guard must block the turn end before the idle signal fires, reports not ok on 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.

…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.
@sbracewell64

Copy link
Copy Markdown
Owner Author

Closing. This was opened as a fork-landing branch cut from fork main.

The required PR must be raised via no-mistakes check reads a marker the pipeline itself writes into the PR body. The pipeline never validated this new head, so this PR cannot carry a genuine signature, and writing one by hand would forge an attestation. That makes a landing branch structurally unable to be legitimately green.

Superseded pending a captain ruling. The shared contribution branch and its open upstream PR were never modified.

@sbracewell64
sbracewell64 deleted the landing/3-pi-only-harness-plan branch August 2, 2026 18:56
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