Skip to content

fix(post-edit): join foreground commands before the next turn - #543

Open
ooiuuii wants to merge 1 commit into
openpi-dev:mainfrom
ooiuuii:feat/post-edit-lifecycle
Open

ooiuuii wants to merge 1 commit into
openpi-dev:mainfrom
ooiuuii:feat/post-edit-lifecycle

Conversation

@ooiuuii

@ooiuuii ooiuuii commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

Problem

Post-edit currently serializes its own commands but does not coordinate them with the following Agent run. A foreground formatter started by agent_settled can still be writing while the next parent turn reads or edits the same file.

The native lifecycle matters here: Pi marks the run idle before settlement handlers finish, and a custom message with triggerTurn: true enters the parent through a different path from ordinary prompt preflight. Merely awaiting agent_settled or fencing before_agent_start is not sufficient.

Value

Keep the existing opt-in, thin post-edit extension useful for foreground formatters without adding an editing-tool replacement, automatic repair loop, or second orchestration layer. Users can cancel a waiting Agent without losing track of the still-running command.

Approach

  • Retain an execution promise until pi.exec actually completes. Requesting abort does not release it early.
  • Join outstanding runs at native agent_start, covering ordinary prompts and custom-message parent wakeups with the current Agent cancellation signal installed.
  • Keep an abort-aware tool_call backstop for native Write/Edit/Bash. A canceled or session-invalidated call is blocked rather than admitted after the wait.
  • Snapshot command and working directory when scheduling. Disabling post-edit drops queued work but lets the active command finish; session reset drops queued work and requests cancellation.
  • Treat killed: true as interruption even if Pi reports exit code zero. Keep notices bounded, sanitized, and suppressed for stale sessions.

The command must be finite and foreground-owned. This is not an acceptance gate or a workspace-wide lock: other sessions, concurrent subagents, user shell commands, external editors, and detached descendants remain outside its guarantee. Native Pi cancellation does not promise process-tree termination. A hung command can keep the next turn waiting; cancellation releases the Agent's wait, not the command's ownership. No timeout silently declares completion.

Validation

Environment: Windows, Node 22.22.0, Bun 1.3.14, locked Pi 0.85.1. Git's shell directory was on the test process PATH. Development configuration was isolated from daily Pi settings; pi list resolved one local OpenPI checkout.

bun run check
node --test --experimental-strip-types tests/extensions/post-edit/index.test.ts tests/extensions/post-edit/lifecycle.test.ts
  • Final checks: passed (config/docs contracts, build, formatting, lint, TypeScript).
  • Final focused tests: 21 passed — 14 unit cases and 7 native-Pi integration cases.
  • Red/green proof: the initial five native integration cases all failed against the original implementation. A scoped review then identified custom-message wakeups and cancelable waits; two additional native cases failed before those fixes and pass afterward. Final structured review reported no actionable findings.

The integration tests use real Pi sessions, native tools, real pi.exec, and a real foreground formatter. A localhost TCP release controls completion deterministically; file contents and model/tool entry points establish ordering. The provider is synthetic and local-only, so no credentials or remote model calls are required. Dedicated tool-backstop tests omit only the start-hook registration to isolate that backstop; ordinary prompt, custom-message, and cancellation tests retain it.

Full-suite limitations, not hidden as green: bun run test on this host first hit five unrelated timing failures; those files passed in a serial rerun. A broader diagnostic using repository discovery with bounded file concurrency passed the parallel Node group (1,563 passed, 10 skipped) and all Vitest tests (220 passed). The Windows serial group had 87 passed, 7 failed, 4 skipped, with failures in unchanged background-terminal process-tree teardown tests. A representative kill-status failure reproduced independently; that test's dependency chain does not import post-edit. No background-terminal fixes or test suppressions are included here. Final post-edit checks above were rerun after the lifecycle fixes.

No live-provider or manual visual TUI test is claimed. The native integration runs use TUI-mode extension contexts programmatically.

Impact

  • User-visible: a following TUI Agent run waits for outstanding foreground post-edit work; failures/interruption remain notifications, not automatic repair requests.
  • Model-visible context/tools: no new tools, schema, system prompt, or injected messages. Interrupted guarded calls return a blocking reason.
  • Runtime/lifecycle: joins commands at native lifecycle boundaries; abort-aware waits preserve cancellation and command ownership.
  • Persisted config/data: none. Empty/off default, existing /openpi-setup entry point and command limit are unchanged.
  • Compatibility/risk: foreground finite commands only; no headless activation, global locking, or detached-process guarantee. Existing long-running watchers are unsuitable and now explicitly documented as such.

@github-actions github-actions Bot added documentation Improvements or additions to documentation area:setup OpenPI setup, configuration, or setup documentation labels Sep 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:setup OpenPI setup, configuration, or setup documentation documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant