295 lines
18 KiB
Markdown
295 lines
18 KiB
Markdown
# Task: Prevent background sleep from terminating active Pi runs
|
|
|
|
## Identity
|
|
|
|
- Task ID: 20260825-pi-background-run-lease-6a4e2c91
|
|
- Mode: Feature
|
|
- Branch: codex/20260825-pi-background-run-lease-6a4e2c91-pi-background-run-lease
|
|
- Worktree: D:\Datas\OthersProjects\makelore-pi-background-run-lease-6a4e2c91
|
|
- Base commit: 92f4c91088e79252aca76af3279b184da68e1eb7
|
|
- Owner: codex-root
|
|
- Status: Ready for integration
|
|
|
|
## Scope
|
|
|
|
- Follow up the installed `621ebb1` Windows artifact: treat an RPC
|
|
confirmation timeout for an already-written Pi top-level mutation as
|
|
uncertain ownership rather than a definite terminal failure. Keep the
|
|
target run permit, process ownership, and Main background lease until a
|
|
correlated late result/event, worker failure, abort, recover, or other
|
|
authoritative cleanup converges it.
|
|
- Prevent prompt, follow-up, steer, compact, model reconfiguration, and fork
|
|
mutations from overlapping an unresolved uncertain mutation in the same
|
|
Conversation, while preserving sibling Conversation independence.
|
|
- Give manual compact a long-mutation lifecycle through compaction completion
|
|
and authoritative settle, and keep `CODING_REQUEST_UNCERTAIN` distinct from
|
|
local-runtime-unavailable UI semantics.
|
|
|
|
- Add a Main-owned authoritative background lease for every queued or accepted
|
|
top-level Pi Conversation run, acquired before mutation queueing and held
|
|
through parent/child work until authoritative terminal cleanup.
|
|
- Close the `BackgroundLifecycleController.sleepIfIdle()` in-flight race so a
|
|
lease acquired while `onSleep` is awaiting prevents the later runtime stop,
|
|
while preserving hidden-idle warm-worker eviction after all runs settle.
|
|
- Terminalize supported intentional disposal of an active target Conversation
|
|
before runtime projection state is removed, without replaying an accepted or
|
|
uncertain mutation or affecting sibling Conversations.
|
|
- Replace ambiguous Main stop reason `dispose` at supported callers with a
|
|
bounded caller-specific reason, and retain content-free lifecycle evidence.
|
|
- Extend focused Main/runtime/Renderer tests, Windows Electron E2E, final-ASAR
|
|
packaged proof, and formal Windows NSIS/artifact verification.
|
|
|
|
## Intent And Constraints
|
|
|
|
- Preserve the Pi hard cutover and exact Pi `0.84.2`; do not add OpenCode
|
|
fallback, a Provider watchdog, automatic mutation replay, a global daemon,
|
|
schema migration, feature flag, compatibility track, or Pi upgrade.
|
|
- The authoritative lease is Main-owned. Renderer visibility or IPC lease
|
|
delivery must not own run liveness. Acquire synchronously before a top-level
|
|
mutation can be queued/accepted; a parent lease covers its child/subagent.
|
|
- Release the lease exactly once only after authoritative settle, definite
|
|
pre-accept rejection, terminal crash/protocol failure, completed cancel,
|
|
explicit dispose cleanup, or application shutdown cleanup. Generation or
|
|
resource replacement for the same logical run must not release it early.
|
|
- Preserve target isolation, the existing same-session recover contract, and
|
|
no-replay semantics. Intentional termination while the UI remains alive must
|
|
project a recoverable terminal state; it must not fabricate success.
|
|
- Keep stop reasons finite and content-free. Diagnostics may retain only safe
|
|
lifecycle classification, reason, redacted identifiers, generation,
|
|
code/signal, stage, and duration; no prompt/tool/header/token/session text or
|
|
complete project path may enter logs or Renderer DTOs.
|
|
- Do not edit the read-only diagnosis task or overwrite the user's installed
|
|
Makelore. Do not push or publish. Real Provider remains Explicitly Waived /
|
|
Accepted Risk (`realTurnVerified=false`); macOS/native Linux gates are out.
|
|
|
|
## Project Context Loaded
|
|
|
|
- Concurrent Task Gate passed with isolated ownership of this task, branch,
|
|
and worktree at base `92f4c91088e79252aca76af3279b184da68e1eb7`.
|
|
- Diagnosis commit `dc820b2` is a docs-only sibling based on `941b015`, not an
|
|
ancestor of the cumulative product HEAD; its task record was read-only and
|
|
is not used as the implementation base.
|
|
- Shared canonical memory remains OpenCode-stale relative to the cumulative Pi
|
|
product. Current source, the Pi resilience contract, cumulative Pi task
|
|
records, and the read-only output-stall diagnosis are authoritative here.
|
|
- Eleven non-ready peer records were inspected. One owns an old main/OpenCode
|
|
integration and the others are unrelated or placeholder scopes; no known
|
|
peer owns Pi background lifecycle, runtime disposal, or packaged proof
|
|
semantics. Placeholder scopes remain unknown coordination state but expose
|
|
no semantic conflict that changes this isolated plan.
|
|
- Relevant constraints are Main-owned run liveness, target-scoped monotonic
|
|
terminalization, same-binding recovery, bounded stop reasons, no mutation
|
|
replay, and final Windows packaged proof with zero residual resources.
|
|
- Planning Gate result: Passed.
|
|
|
|
## Plan
|
|
|
|
Follow-up plan from cumulative HEAD `621ebb17810394f6f7b97154cb01217bc9112857`:
|
|
|
|
1. Add deterministic red tests for delayed Pi prompt preflight confirmation,
|
|
delayed compact confirmation, late failure/exit/abort convergence,
|
|
same-Conversation mutation exclusion, sibling isolation, and Renderer
|
|
uncertainty unlock.
|
|
2. Make RPC confirmation timeout preserve authoritative uncertain ownership
|
|
without replay, then converge exactly once from late response/events or
|
|
explicit cleanup.
|
|
3. Extend final-ASAR packaged proof beyond the old ten-second threshold and
|
|
re-run the full Windows release gate from a clean follow-up commit.
|
|
|
|
1. Trace actual background lifecycle, Pi mutation/dispose, composition, and
|
|
stop-reason callers; build a deterministic combined red test for the exact
|
|
hidden-active-run failure and the in-flight sleep race.
|
|
2. Add the narrow Main-owned lease dependency, acquire before top-level
|
|
queue/acceptance, and release exactly once across settle/reject/crash/
|
|
protocol/abort/dispose/shutdown paths.
|
|
3. Reuse the existing Conversation projection chain to terminalize active
|
|
intentional disposal before state removal, and pass caller-specific bounded
|
|
reasons without changing settled runs or sibling Conversations.
|
|
4. Extend Renderer/Host/Windows E2E and final packaged proof for hidden active
|
|
completion, later idle stop, explicit-dispose unlock/recover/isolation, no
|
|
replay, safe diagnostics, and zero resource/process residue.
|
|
5. Run focused tests, typecheck, lint, full unit, build, Windows Electron E2E,
|
|
then commit a clean candidate and run formal `package:win`, Windows/Pi
|
|
closure verification, packaged proof, artifact fingerprinting, and the Task
|
|
Documentation Gate.
|
|
|
|
## Outcome
|
|
|
|
### Installed-package P1 follow-up
|
|
|
|
- Pi RPC mutation confirmation now has an explicit retained-correlation mode.
|
|
Crossing the former 10-second Host confirmation threshold returns the safe
|
|
recoverable `CODING_REQUEST_UNCERTAIN` contract but does not retire the RPC
|
|
id or release the pool's active run, revision run, process permit, or Main
|
|
background lease.
|
|
- A late correlated success clears the provisional run error without ending
|
|
the run; a late explicit RPC failure terminalizes only the target; worker
|
|
invalidation, abort/recover cleanup, or authoritative `agent_settled`
|
|
converge the same ownership exactly once. `agent_settled` also confirms a
|
|
mutation when it arrives before the RPC success response, avoiding a hung
|
|
Host acceptance promise or terminal-state regression.
|
|
- Prompt, queued follow-up/steer, compact, model reconfiguration, and fork are
|
|
blocked for the same Conversation while uncertainty is unresolved. The
|
|
service performs model/fork rejection before metadata persistence or fork
|
|
target creation; sibling Conversations retain independent permits.
|
|
- Manual compact uses the same retained ownership through
|
|
`compaction_start`, `compaction_end`, correlated RPC settlement, and
|
|
hydrate. Locked Pi `0.84.2` does not emit `agent_settled` for a manual
|
|
compact, so the pool now emits a target-scoped top-level settlement after
|
|
the correlated compact success (including a late success) and the runtime
|
|
releases its lease exactly once. If `compaction_end(error)` terminalizes the
|
|
projection before the RPC rejection arrives, the later failure cleanup also
|
|
releases the already-terminal run lease idempotently.
|
|
- The final-ASAR proof now arms controlled 12-second Provider and Pi RPC
|
|
response delays, materializes proof-only compact thresholds in the isolated
|
|
userData, and records running/uncertain followed by completed/idle states.
|
|
- Renderer submission/action errors retain their stable backend code. An
|
|
uncertain submission keeps the draft and prevents overlap, shows the
|
|
actionable delay message instead of a runtime-outage banner, and the Header
|
|
derives away a stale compact uncertainty once a newer generation/sequence
|
|
reaches a non-uncertain terminal state.
|
|
Model, thinking, compact, and fork controls are disabled while the run is
|
|
active; abort and recover remain available.
|
|
|
|
- Implemented a Main-owned per-Conversation top-level run lease in the Pi
|
|
runtime. Prompt and compact acquire before optimistic/queue acceptance;
|
|
steer/follow-up reuse the parent run lease. Settle, definite rejection,
|
|
crash, protocol invalidation, abort convergence, explicit recovery,
|
|
intentional disposal, and shutdown release through an idempotent owner map.
|
|
- Closed both background-stop races: the lifecycle controller rechecks
|
|
visibility and leases after asynchronous sleep preparation, and the Pi pool
|
|
rechecks the target's authoritative active-work predicate after pending
|
|
prepare/rebuild work and immediately before worker cancellation.
|
|
- Background sleep now refuses the entire coding-runtime sleep while any run
|
|
is queued or active, while settled hidden workers remain eligible for normal
|
|
eviction. A parent lease remains held while child/subagent resources finish.
|
|
- Active intentional disposal projects the existing safe recoverable terminal
|
|
failure on the target Conversation chain before cleanup/removal, preserves
|
|
the durable session binding, does not replay the accepted prompt, and leaves
|
|
sibling Conversations unchanged.
|
|
- Replaced the ambiguous `dispose` worker stop reason with caller-owned finite
|
|
reasons for background sleep, project deactivation/removal, Conversation
|
|
deletion, auth cleanup, model reconfiguration, fork cleanup, app shutdown,
|
|
and existing internal replacement/cleanup paths.
|
|
- Extended the final-ASAR resilience proof to use the real Main composition for
|
|
hidden active-run survival, settled idle eviction, intentional-dispose UI
|
|
unlock/recover/isolation, safe lifecycle reason evidence, background lease
|
|
counts, and zero residual resource/process verification.
|
|
- The clean implementation candidate completed Windows NSIS creation, both
|
|
artifact/closure verifiers, and the final packaged Main/UI/fault proof. The
|
|
task record is amended into the cumulative delivery commit before the formal
|
|
commands are rerun for the returned artifact.
|
|
|
|
## Verification
|
|
|
|
### Installed-package P1 follow-up candidate
|
|
|
|
- Red phase — 5 expected failures across RPC correlation, pool ownership,
|
|
Main background lease, compact overlap, and Renderer reconciliation: the
|
|
old implementation retired the correlation and released active ownership at
|
|
10 seconds, returned a raw timeout, and retained the UI uncertainty after a
|
|
completed run.
|
|
- Focused green gate — passed: 10 files / 121 tests, including delayed prompt
|
|
and compact, late success/failure, settled-before-response, same-target
|
|
mutation exclusion with zero fork/model persistence, sibling isolation,
|
|
safe Host error mapping, Renderer automatic unlock, and final-ASAR wiring.
|
|
- `pnpm run typecheck` — passed after the final runtime/Renderer/proof changes.
|
|
- `pnpm run lint:check` — passed with zero errors and the same 5 pre-existing
|
|
warnings in `src/pages/Home/index.tsx` and `src/pages/Makelore/index.tsx`.
|
|
- `pnpm test` — passed: 181 regular files / 1538 tests passed / 2 skipped,
|
|
followed by the isolated pressure file / 1 test passed.
|
|
- `pnpm run build:vite` — passed for Renderer, Main, Preload, and utility
|
|
bundles; only existing dynamic-import and chunk-size warnings were emitted.
|
|
- `pnpm run test:electron:windows` — passed: 2 files / 4 tests.
|
|
- Final clean-HEAD NSIS, artifact closure, 12-second packaged UI/Main proof,
|
|
Authenticode, and zero-residual-process results are run after this task
|
|
documentation commit so the returned artifact binds to the docs-bearing
|
|
cumulative HEAD.
|
|
- The first candidate packaged proof intentionally required
|
|
`CODING_REQUEST_UNCERTAIN` but the controlled Provider's message-shape
|
|
matcher did not arm the delay; diagnostics showed both runs, both Main
|
|
leases, both Pi processes, and both Provider requests still active with no
|
|
runtime failure. The proof was corrected to arm prompt and compact delay
|
|
explicitly through E2E-only Main seams, removing message-shape dependence;
|
|
this was a proof-wiring failure, not a product fallback or relaxed gate.
|
|
- The explicit Provider arm then proved the loopback HTTP response remained
|
|
open for 12 seconds, but locked Pi acknowledged the local prompt RPC before
|
|
the first Provider response on this controlled path. The proof therefore
|
|
separates the two facts instead of claiming causality: the Provider response
|
|
remains delayed for 12 seconds, and an E2E-only one-shot Pi RPC response hold
|
|
independently crosses the 10-second client threshold. The hold is armed only
|
|
through the existing Main fault-injection surface, is absent from Renderer
|
|
and product configuration, and preserves the real packaged Pi command,
|
|
session, Provider request, events, and cleanup path.
|
|
- The final-ASAR candidate proof passed after the compact settlement fix:
|
|
prompt and compact each crossed the former 10-second confirmation threshold
|
|
while retaining target ownership; compact reached a durable completed node,
|
|
context/run idle, Provider active count zero, and background lease zero;
|
|
stale uncertainty disappeared from the real UI. Hidden idle eviction then
|
|
used `background_sleep`, the explicit crash/protocol/dispose matrix retained
|
|
sibling isolation and same-session recovery, and all tracked proof PIDs and
|
|
resource counters reached zero. This remains controlled loopback/fault
|
|
injection evidence with `realTurnVerified=false`.
|
|
|
|
- `pnpm install --frozen-lockfile` — passed with package-manager-pinned pnpm
|
|
`10.33.4` and locked Pi `0.84.2`.
|
|
- Red phase: the new background lifecycle in-flight test observed one unwanted
|
|
`onStopRuntime` call; the real Pi-runtime/lifecycle combination observed zero
|
|
Main run leases after prompt acceptance.
|
|
- Focused regression gate — passed: 8 files / 106 tests, covering lifecycle,
|
|
running+queued Pi work, parent/child lease retention, exactly-once release,
|
|
crash/protocol/abort/recover, forced disposal, worker reason diagnostics,
|
|
project/auth callers, and packaged proof wiring.
|
|
- `pnpm run typecheck` — passed.
|
|
- `pnpm run lint:check` — passed with 5 pre-existing warnings and zero errors.
|
|
- `pnpm test` — passed: 182 files, 1529 tests passed, 2 skipped.
|
|
- `pnpm run build:vite` — passed for Renderer, Main, Preload, and utility
|
|
bundles; only existing dynamic-import/chunk-size warnings were emitted.
|
|
- `pnpm run test:electron:windows` — passed: 2 files / 4 tests.
|
|
- Clean-candidate `pnpm run package:win` — passed; generated the Windows x64
|
|
NSIS without overwriting an installed Makelore directory.
|
|
- `pnpm run verify:artifact:win` — passed for NSIS/unpacked Electron, app.asar,
|
|
bundled Python/uv/npm, and Windows native modules; verifier HEAD matched the
|
|
clean implementation candidate.
|
|
- `pnpm run verify:artifact:pi` — passed: exact Pi `0.84.2`, 130 production
|
|
packages, 6 asset groups, zero missing/relocated package or asset, 5 native
|
|
assets outside ASAR, managed Skills, and materialized extension/subagent.
|
|
- `pnpm run test:pi-subagent:packaged` — passed from packaged app.asar Main:
|
|
two UI/Main runs retained 2 background leases and 2 worker processes while
|
|
hidden past grace; both settled, released leases, then warm idle workers
|
|
stopped with reason `background_sleep`. Controlled intentional disposal
|
|
projected `CODING_RUNTIME_START_FAILED` as recoverable, kept the sibling
|
|
running and both bindings intact, and did not change Provider request counts.
|
|
Recover reused the binding without mutation replay. Final workers, Pi
|
|
processes, process leases, run permits, child permits/dispatches, extension
|
|
registrations, write leases, and background leases all reached zero.
|
|
- Packaged proof clean exit — passed with zero lingering tracked Electron/Pi
|
|
PIDs. Lifecycle evidence distinguished unexpected exit, protocol
|
|
invalidation, and intentional stop; every stop/replacement had a reason and
|
|
redaction/content-free checks passed.
|
|
- Authenticode inspection — `NotSigned`; no signing identity was available.
|
|
- The returned installer is rebuilt and reverified from the amended cumulative
|
|
clean HEAD; its exact path, size, SHA-256, and signing state are reported in
|
|
the delivery response.
|
|
|
|
## Follow-ups
|
|
|
|
- PI-R002 soak/field attribution remains a separate follow-up and is not a
|
|
blocker for this deterministic failure-convergence hotfix.
|
|
- Real external Provider concurrency, credential isolation, and protocol
|
|
compatibility remain Explicitly Waived / Accepted Risk with
|
|
`realTurnVerified=false`; loopback/fault injection is not a Provider Pass.
|
|
- macOS and native non-WSL Linux gate status is unchanged and not promoted.
|
|
|
|
## Promotion Candidates
|
|
|
|
- Target canonical document: Pi runtime architecture/resilience documentation.
|
|
Proposal: record Main-owned top-level run leases, post-`onSleep` activity
|
|
recheck, terminal-before-dispose monotonicity, and finite caller-owned stop
|
|
reasons as accepted invariants. Evidence: focused lifecycle/runtime tests,
|
|
Windows Electron E2E, final-ASAR hidden-run/idle-eviction/intentional-dispose
|
|
proof, and zero-resource shutdown. Future impact: new Pi mutation or stop
|
|
callers must join these seams rather than relying on Renderer visibility.
|
|
Semantic conflicts: none known with the accepted Pi hard cutover/resilience
|
|
plan. Human confirmation required: yes, during Integration Gate.
|