13 KiB
13 KiB
Task: Fix Pi worker exit terminalization and thinking contract
Identity
- Task ID: 20260825-pi-worker-exit-thinking-5e7c2a91
- Mode: Feature
- Branch: codex/20260825-pi-worker-exit-thinking-5e7c2a91-pi-worker-exit-thinking
- Worktree: D:\Datas\OthersProjects\makelore-pi-worker-exit-thinking-5e7c2a91
- Base commit:
274187e3cf - Owner: codex-root
- Status: Completed
Scope
- Fix the installed Windows Pi Conversation lifecycle so an accepted run whose
matching worker generation exits or is protocol-invalidated converges within
a bounded time to a recoverable terminal failure instead of remaining
runningoraborting. - Make abort-after-exit and crash/abort/
agent_settledordering monotonic on the target Conversation projection chain while preserving target isolation, the original session binding, and no replay of an uncertain prompt. - Add Main-only worker lifecycle forensics that distinguish unexpected exit, protocol invalidation, and intentional stop with a required finite reason, generation, stage, code/signal, and bounded redacted stderr.
- Persist and display only the thinking level Pi actually supports and accepts, and derive managed custom-model reasoning compatibility from the authoritative capability data without implicitly replacing a worker generation.
- Add focused, Host/SSE/Renderer, Windows Electron, and final packaged fault- injection regressions; build and verify a new Windows x64 NSIS installer.
Intent And Constraints
- Keep the Pi hard cutover. Do not add an OpenCode fallback, compatibility layer, generic Provider watchdog, feature flag, or uncertain prompt replay.
- Serialize crash, abort, and settled handling by Conversation + generation. A terminal run is monotonic; a stale generation cannot modify the active Conversation; one crash cannot affect another Conversation.
- On crash/protocol invalidation, finally settle the target run and converge
its queue permit, process lease, pending interaction, extension run, child
worker, and project write lease. Normal live-worker abort continues to wait
for authoritative
agent_settled. - Thinking changes and same-account model changes must not restart a normally running worker. Provider/resource/credential revisions rebuild only after the accepted run settles, with an explicit generation-replacement reason.
- Every Main-initiated stop must use a bounded reason enum covering application shutdown, idle eviction, stale-resource rebuild, recover, dispose, fork replacement, protocol invalidation, and test injection or their exact current implementation equivalents. Do not log prompt/response/tool/header/token, expose stderr to Renderer, or write credentials into diagnostics.
- Preserve direct API-key, OAuth, local Provider, existing session persistence,
fork/recover behavior, and the user's installed application under
D:\Tools\泥土\niancode\Makelore. - Use pinned pnpm
10.33.4, frozen install semantics, focused/full verification, formal Windows packaging, final artifact/runtime closure checks, and isolated packaged product fault injection with zero residual proof processes. - Real external Provider verification remains
Explicitly Waived / Accepted RiskwithrealTurnVerified=false; loopback/fault injection is not a real Provider Pass. macOS and native non-WSL Linux status is unchanged.
Project Context Loaded
- Concurrent Task Gate passed in the isolated worktree owned by
codex-root; task identity, branch, worktree, base, and task record match the registry. - Planning Gate passed after reading project entry/memory/current-state, architecture/domain/decision/evidence/reflection/commitment/stale records, the Pi hard-cutover runtime/ticket constraints, both cumulative Windows Pi hotfix records, the read-only stuck-processing diagnosis, and all active peer task scopes.
- Base
274187e3cfe2ae6cb97f2b4bcb422b3fdf06fbf2contains the earlier proxy-token and persisted-session reopen delivery. The diagnosis worktree is read-only; dirtymainand all other task worktrees remain untouched. - Shared canonical architecture/current-state files predate the Pi delivery. The current source, Pi cutover contract, cumulative task records, and the accepted diagnostic evidence are authoritative for this repair.
- The active peer tasks are older, unrelated, test-only, or read-only. The one main-worktree OpenCode integration task explicitly does not package; no unresolved semantic conflict changes this plan.
- Eleven copied-session packaged loopback cases settled normally, so Provider
SSE, session corruption, and
task_stateare not established causes. The incident trigger remains unknown until the replacement artifact records the bounded exit/stop classification. - No subagents are used, per user direction and repository policy.
- The committed planning supplement
2d9d8274d77986fe96e88f02ccba2b5389d2e696is a direct child of this task's base and identifies this executor task asPI-R001. ItsRES-INV-001..009,RES-ACC-001..016, release blockers, Main-only privacy boundary, and final packaged fault-injection matrix are additional acceptance contracts for this implementation. The content first entered as the conflict-free cherry-pick2b13454; the exact source commit2d9d827was then retained as a merge parent, so planning and implementation share one history without rewriting either line of work. At the executor tip the specification is materialized under the task-owned path20260825-pi-worker-exit-thinking-5e7c2a91__pi-runtime-resilience-hardening.md; the planner task record remains available in the original commit history instead of violating feature-task document ownership.
Plan
- Inspect runtime, pool, process/RPC, extension/child/lease, model capability, Host/SSE, Renderer, E2E, and packaged proof seams; map all worker stop callers and generation-replacement reasons before changing contracts.
- Add focused red regressions for active accepted-run exit, abort-after-exit, exit/abort/settled ordering, target isolation and resource convergence; unexpected/protocol/intentional diagnostics and redaction; effective thinking persistence and no worker replacement.
- Implement the smallest lifecycle, diagnostics, and capability changes that satisfy the existing Pi contracts, retaining the original error category and session binding through recover.
- Extend Host SSE/Renderer unlock-and-recover and Windows packaged deterministic fault-injection proof for running exit, abort-after-exit, settled-before-close, strict JSONL invalidation, deliberate stop, isolation, no prompt replay, no unexplained generation replacement, and zero residual processes.
- Run frozen install, focused tests, typecheck, lint, full unit,
build:vite, Windows Electron E2E, formalpackage:win, artifact/runtime/closure verification, and final packaged proofs from a clean committed candidate. - Record exact commits, changed files, verification results, structured packaged evidence, installer size/SHA-256, accepted/deferred risks, clean git state, and complete the Task Documentation Gate.
Outcome
- Implemented matching-generation worker crash/protocol terminalization on the
per-Conversation projection chain. An accepted run now reaches recoverable
errorwithout overriding an earlier terminalagent_settled; abort after exit cannot restorerunning. - Generation invalidation now cancels command, interaction, child/dispatch, extension-run, process-permit, and write-lease resources for only the target Conversation. Recover reopens the same persisted Pi binding and never replays the uncertain accepted prompt.
- Added finite, required Main stop/replacement reasons and separate structured
lifecycle classification for unexpected exit, strict protocol invalidation,
and intentional stop.
PI_RPC_EXITEDretains bounded stderr after token, header, credential, and managed-path redaction; prompt/response/tool content is not copied into lifecycle diagnostics or Renderer state. - Same-account model and thinking changes no longer replace the worker.
Hydration and mutations query Pi capabilities/state and persist/project only
the effective level. The managed
deepseek-v4-proprofile now derives its reasoning, DeepSeek compatibility, context/output limits, and supported product thinking level from the imported authoritative capability profile; unsupported levels reject instead of presenting false success. - Renderer error state displays
本地 Agent 已中断,原请求未自动重发。, leaves the Composer editable, exposes recovery, and does not remain in processing/recovering. The packaged proof now drives the real final-ASAR Main composition through target exit, abort-after-exit, protocol invalidation, settled-before-close, target recovery, sibling isolation, child/write-lease cleanup, explicit deliberate stop, redacted lifecycle evidence, and clean process exit. - Concurrent packaged workers exposed a reachable Windows rename collision while materializing the same managed extension. Materialization is now single-flight per extensions directory; eight concurrent registrations share one atomic result without changing the extension contract.
- Formal Windows
package:wincompleted from the clean code candidate, including pinned Python/uv acquisition, Vite production build, Pi runtime bundling, and NSIS generation. The final product verifiers and the final-ASAR resilience proof pass. Real Provider verification is not claimed.
Verification
corepack pnpm install --frozen-lockfile— pass with pinned pnpm10.33.4.- Focused Pi/runtime/pool/RPC/extension/subagent/UI regressions — pass, including 6 files / 60 tests for the lifecycle contract and 2 files / 9 tests after the extension materialization concurrency repair.
corepack pnpm run typecheck— pass.corepack pnpm run lint:check— pass with 0 errors and 5 pre-existing warnings in unrelatedHome/Makelorefiles.corepack pnpm test— pass: 178 files / 1520 passed / 2 skipped, plus the isolated pressure file 1/1 passed.corepack pnpm run build:vite— pass for Renderer, Main, Preload, and utility bundles; existing dynamic-import and chunk-size warnings remain non-blocking.corepack pnpm run test:electron:windows— pass: 2 files / 4 tests.corepack pnpm run package:win— pass from the clean7aa9f79product-code candidate. Two earlier attempts were blocked only by a transient GitHub uv 0.10.0 download timeout; the final formal command downloaded both x64/arm64 archives and completed without staging reuse.corepack pnpm run verify:artifact:win— pass: finalapp.asar, Electron43.4.0, Node24.18.1, bundled Python/pip/sqlite/SSL, uv0.10.0, npm11.6.2, required native modules/assets, and NSIS validated. The pre-task-doc candidate installer was211912226bytes with SHA-25654559D5ADEFAF84F3F124A535A811778E2A347E1B5247F43C0D5A31BBDFC6C0D; the post-documentation clean-HEAD artifact metadata is reported in the final handoff rather than being recursively embedded into the artifact-producing commit.corepack pnpm run verify:artifact:pi— pass: Pi0.84.2, finalresources/pi-runtime/dist/cli.js, 130 production packages, 6 runtime assets, 5 native assets outside asar, managed Skills, and materialized extension/subagent closure all present and executable.corepack pnpm run verify:publish-runtime— pass with npm11.6.2.corepack pnpm run test:pi-subagent:packaged— pass against the real final-ASAR Main composition. Target worker exit and strict protocol invalidation reached bounded recoverable terminal states; abort-after-exit did not restorerunning; settled-before-close stayed terminal; sibling Conversation kept running; recover reused the same binding and did not replay the uncertain prompt. Lifecycle classifications and all stop/replacement reasons were present and redacted, Renderer was unlocked with recovery available, all pool/subagent/extension/write-lease counters returned to zero, and no tracked Electron/Pi process lingered after exit.realTurnVerified=false.- The first final proof attempt selected the still-running isolation Conversation after reload, and the next locator matched both sidebar and header controls. The harness now selects the fault-target sidebar entry deterministically and emits Main/UI state on failure; no product assertion, timeout, or lifecycle contract was relaxed.
Follow-ups
- Later soak and any new real-external-Provider occurrence may use the new bounded diagnostics to identify the initiating exit class. They are not substitutes for this task's required deterministic convergence proof.
- Real Provider protocol/concurrency/credential-isolation verification remains
explicitly waived accepted risk and must continue to report
realTurnVerified=false. PI-R002loopback soak and field incident classification start only afterPI-R001is delivered. They do not block this repair or broaden its current implementation scope.
Promotion Candidates
- None recorded.