fix(pi): converge worker failures and thinking state

This commit is contained in:
2026-08-25 11:45:14 +08:00
parent 274187e3cf
commit 61817b161f
28 changed files with 2019 additions and 118 deletions

View File

@@ -0,0 +1,178 @@
# 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: 274187e3cfe2ae6cb97f2b4bcb422b3fdf06fbf2
- Owner: codex-root
- Status: In Progress
## 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
`running` or `aborting`.
- Make abort-after-exit and crash/abort/`agent_settled` ordering 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
Risk` with `realTurnVerified=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 `274187e3cfe2ae6cb97f2b4bcb422b3fdf06fbf2` contains the earlier proxy-token
and persisted-session reopen delivery. The diagnosis worktree is read-only;
dirty `main` and 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_state` are 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
`2d9d8274d77986fe96e88f02ccba2b5389d2e696` is a direct child of this
task's base and identifies this executor task as `PI-R001`. Its
`RES-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 pure-document commit will be brought
into the implementation branch before final delivery so planning and code
share one history; it is deferred until the current red-test/code work is at
a safe commit boundary.
## Plan
1. 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.
2. 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.
3. Implement the smallest lifecycle, diagnostics, and capability changes that
satisfy the existing Pi contracts, retaining the original error category
and session binding through recover.
4. 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.
5. Run frozen install, focused tests, typecheck, lint, full unit, `build:vite`,
Windows Electron E2E, formal `package:win`, artifact/runtime/closure
verification, and final packaged proofs from a clean committed candidate.
6. 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
`error` without overriding an earlier terminal `agent_settled`; abort after
exit cannot restore `running`.
- 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_EXITED` retains 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-pro` profile 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.
- Formal NSIS packaging and final packaged execution are still pending; no
installer or real-Provider result is claimed at this checkpoint.
## Verification
- `corepack pnpm install --frozen-lockfile` — pass with pinned pnpm `10.33.4`.
- Focused Pi/runtime/pool/RPC/extension/subagent/UI regressions — pass, latest
combined run: 6 files / 60 tests.
- `corepack pnpm run typecheck` — pass.
- `corepack pnpm run lint:check` — pass with 0 errors and 5 pre-existing
warnings in unrelated `Home`/`Makelore` files.
- `corepack pnpm test` — pass: 178 files / 1519 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.
- Formal `package:win`, artifact/runtime closure verifiers, final packaged
resilience proof, installer byte size/SHA-256, and zero-residue evidence —
pending the clean committed candidate.
## 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-R002` loopback soak and field incident classification start only after
`PI-R001` is delivered. They do not block this repair or broaden its current
implementation scope.
## Promotion Candidates
- None recorded.