13 KiB
13 KiB
Task: Fix Pi user-entry conversation fork
Identity
- Task ID: 20260825-pi-user-entry-fork-4a7d9c21
- Mode: Feature
- Branch: codex/20260825-pi-user-entry-fork-4a7d9c21-pi-user-entry-fork
- Worktree: D:\Datas\OthersProjects\makelore-pi-user-entry-fork-4a7d9c21
- Base commit:
941b015330 - Owner: codex-root
- Status: Done
Scope
- Restrict the Renderer fork action to durable user messages on the active Conversation path.
- Validate the same invariant in
CodingConversationService.forkbefore any target Conversation metadata, worker, session binding, archive, or cleanup resource can be created. - Preserve the existing real Pi
0.84.2fork RPC for a valid user entry and prove the resulting target binding/hydration through unit, managed runtime, Windows Electron, and final packaged-product seams. - Produce and verify a new Windows x64 NSIS without modifying the user's installed application.
Intent And Constraints
- Keep the Pi hard cutover and current project/Agent/Conversation ownership. Do not add an OpenCode fallback, runtime restart control, compatibility layer, schema migration, feature flag, Pi upgrade, or Provider/worker-pool redesign.
- A valid source is a message node on the source Snapshot's current active
path with the exact
sourceEntryId,role === 'user', and non-optimistic durable state. Missing, assistant, unknown, stale, abandoned-path, or optimistic sources fail before target creation. - Invalid input returns existing
400 CODING_CONVERSATION_REQUEST_INVALIDthrough the fixed safe Chinese route projection. Pi's raw rejection, stderr, session paths, prompts, credentials, and provider data must not reach Renderer or proof reports. - Keep fork mutation no-replay: a timeout or uncertain result is never automatically submitted again. A valid fork retains the existing source session and hydrates a distinct target binding under the same Agent.
- Preserve cumulative base
941b015330206af648f944183846ac2857468847, including product parent45d933732a8fbc0dadb07a4a4d65f0d12000c2eaand its Agent-owned Conversation hierarchy. Do not touch dirtymain, the diagnosis worktree/record, previous packaging worktrees, or user install. - Real external Provider remains Explicitly Waived / Accepted Risk with
realTurnVerified=false; macOS/native Linux status is unchanged and is not Pass evidence. Do not create subagents, push, or publish.
Project Context Loaded
Task context:
- Task ID:
20260825-pi-user-entry-fork-4a7d9c21 - Mode: feature
- Branch:
codex/20260825-pi-user-entry-fork-4a7d9c21-pi-user-entry-fork - Worktree:
D:\Datas\OthersProjects\makelore-pi-user-entry-fork-4a7d9c21 - Base commit:
941b015330206af648f944183846ac2857468847 - Other active local tasks: eleven non-ready owner records were inspected.
One AI Design E2E task has a narrow unrelated test-only scope; the occupied
mainintegration task owns historical OpenCode model-switch integration. The remaining older planning records still contain undefined placeholder scopes. - Overlap or semantic-conflict assessment: no known peer owns Pi fork,
CodingConversationTimeline,CodingConversationService, or packaged Pi fork proof semantics. Placeholder scopes remain unknown coordination state, but their stated titles and isolated worktrees expose no semantic conflict that changes this plan.
Read:
.project-docs/05-agent-entry/read-before-planning.md.project-docs/05-agent-entry/memory-index.md.project-docs/05-agent-entry/planning-gate.md- this active task record
- project positioning, current state, decision index, system overview, module map, data flow, business rules, success criteria, glossary, evidence, reflection, commitments, and stale-item indexes
- diagnosis task
20260825-fork-runtime-unavailable-8e7c4a21 - Pi cutover Spec and the relevant PI-050/060/100/130/150 ticket sections
- PI Conversation contracts, Renderer store, Host cutover, and cumulative Agent→Conversation hierarchy task records
- every non-ready peer's Scope, Intent And Constraints, and Promotion Candidates sections
Relevant understanding:
- Project goal: Makelore Code exposes a vendor-neutral, local project-scoped Conversation product while Electron Main exclusively owns Pi runtime, sessions, credentials, files, and recovery.
- Current integrated focus: shared canonical memory is OpenCode-stale relative to the cumulative Pi product. Current source, the Pi Spec/task chain, and the committed diagnosis are authoritative for this repair.
- Active task scope: correct the supported fork source and error boundary only; do not reinterpret a deterministic Pi entry rejection as runtime failure.
- Active constraints: target validation precedes metadata/resource creation;
valid user fork semantics and no-replay remain unchanged; the Agent-owned
Conversation hierarchy from
45d9337must remain intact. - Decisions affecting this task: Spec route
/api/coding/conversations/:id/forkis explicitly from a user entry; hydrated Snapshot nodes contain only the active path and expose durablesourceEntryIdwithout leaking Pi wire. - Evidence, reflections, or commitments affecting this task: real pinned Pi accepted the persisted user entry and rejected the assistant entry with empty stderr. Windows formal packaging must retain artifact/runtime closure; real Provider and non-Windows platform gates remain out of scope.
- Files or modules likely involved: Timeline and Chat E2E, shared/facade fork
types,
conversation-service.ts, focused Host/runtime tests, Pi packaged release proof, packaged smoke runner, and Windows artifact reports. - Unknowns, stale docs, or conflicts: canonical positioning is a placeholder and architecture/data-flow are OpenCode-stale. Several peer task scopes are placeholders, but no known decision conflicts with the precise Pi repair.
Gate result:
- Passed.
Plan
- Add failing Renderer and Main regressions for user-only visibility, exact callback identity, invalid active-path rejection, and zero target-side effects; verify they fail on the diagnosed behavior.
- Implement the smallest product-contract correction: user-only durable UI action and service-owned active-Snapshot validation before target create.
- Add valid user fork coverage through the real pinned Pi managed opener and service seam, checking distinct target binding, Pi session identity, hydrated Snapshot, source isolation, and clean worker shutdown.
- Extend Windows Electron E2E and final packaged Main/UI proof so assistant has no action, the user action creates/selects a same-Agent branch, the original remains unchanged, and no runtime-unavailable state or process residue appears.
- Run frozen install, focused tests, typecheck, lint, full unit, production
build, Windows Electron E2E, then commit a clean candidate and run formal
package:win, Windows/Pi closure verifiers, packaged proof, signing/hash, documentation drift, registry completion, and final clean-state checks.
Outcome
- Renderer now exposes the fork action only on non-optimistic user message
nodes with a durable
sourceEntryId; assistant and non-persisted nodes do not expose the action. CodingConversationService.forknow resolves the source Conversation's authoritative hydrated Snapshot and rejects missing, assistant, unknown, stale, or abandoned-path entries with400 CODING_CONVERSATION_REQUEST_INVALIDbefore target metadata creation. The Host keeps its fixed safe Chinese projection and never exposes Pi's rawInvalid entry ID for forkingresponse.- A valid user entry still reaches the locked Pi fork RPC. The permanent real
Pi
0.84.2regression proves source hydration, a same-Agent target with a distinct Pi session binding, correct before-entry target hydration, source isolation, and clean shutdown of both workers. - Windows Electron coverage now proves one user fork action for a history that
also contains an assistant entry, exact
sourceEntryIdsubmission, target selection under the same Agent, preserved source history, and absence of the runtime-unavailable banner. - The final packaged proxy proof now performs the user-entry fork through the real packaged Main composition and UI after a settled controlled turn. It checks distinct bindings, correct target hydrate, source preservation, zero prompt replay, user/assistant action visibility, process cleanup, and the existing credential/role-contract boundaries.
README.mdnow states that only persisted user messages are fork sources. No Provider, worker-pool, schema, compatibility, or fallback architecture changed.
Verification
corepack pnpm install --frozen-lockfile— passed with package-manager pinned pnpm10.33.4and Pi0.84.2.- Red phase — the focused Timeline/Main tests failed as expected: assistant exposed a second fork action, and invalid entries reached target creation.
- Focused green —
4files /29tests passed, including the real managed Pi service fork and release-proof wiring. corepack pnpm run typecheck— passed.corepack pnpm run lint:check— passed with the existing five warnings and no errors.corepack pnpm test— passed:180files /1525tests plus the isolated pressure test;2pre-existing skips.corepack pnpm run build:vite— passed for Renderer, Main, Preload, and release utility worker.- Focused Windows Electron Playwright — passed:
2tests, including the same-Agent user-entry branch flow and source isolation. corepack pnpm run test:electron:windows— passed:2files /4tests.corepack pnpm run package:win— passed from clean code/proof candidate5031979ca9c46ed00597a36f6412e321f6fdcdcf. Three earlier attempts stopped only at GitHub's fixed uv download withUND_ERR_CONNECT_TIMEOUT; the successful formal run downloaded both Windows architectures, rebuilt Vite, staged130Pi production packages and6assets, and generated a new x64 NSIS without reusing an old installer.corepack pnpm run verify:publish-runtime— passed with npm11.6.2.corepack pnpm run verify:artifact:win— passed and bound the artifact to clean verification HEAD5031979; Electron43.4.0, Node24.18.1, Python/pip/sqlite/SSL, uv0.10.0, npm, msgpackr, Canvas native assets, and Unicode copy all loaded from the final product. The repository does not embed the optionalbuildCommitpackage field, so binding uses the verifier's cleanverificationHeadcontract rather than a fabricated packaged field.corepack pnpm run verify:artifact:pi -- --samples 2— passed: finalapp.asar, Pi0.84.2CLI, all expected production packages/assets, five unpacked native assets, four managed Skills, extension/subagent markers, session persistence, local isolation, exit, and performance budgets were verified. Its nested matrix correctly remainspartial-passfor waived real Provider and deferred non-Windows evidence.corepack pnpm run test:pi-subagent:packaged— passed against the real final app.asar Main and Renderer. The first proof attempt correctly found no fork action on the just-settled live projection because it did not yet have a durable source id; the harness now restarts the isolated product and rehydrates the persisted binding before the installed-history action. Final evidence: source + target count2, same Agent, distinct targetpiSessionId/sessionKey, target workerready/ runidle, target hydrate before the selected user entry, source unchanged, no prompt replay, one user fork action, no assistant action, selected target, no runtime-unavailable or permanent-recovering UI, and all worker/process/resource counters released. The broader existing crash/protocol/resilience proof also remained green.- Pre-documentation installer evidence from
5031979:211891212bytes, SHA-256DE51AABA5A0F36810CE451328B45ACB7A03469E634DCBCCF52A8FA0608AA01BC; app.asar SHA-2564488C8C0F8653CE61438012A47BFCB9C7B8282967735AFA70C03EC45DE04674C. The post-documentation clean-HEAD artifact is rebuilt and fingerprinted in the final handoff so generated evidence is not recursively embedded into the artifact-producing commit. - Authenticode status is
NotSigned; no signed publisher claim is made. - Final packaged proof tracked process residue was empty, and an independent Windows process query found no Electron/Pi process associated with this worktree.
Follow-ups
- Real external Provider execution remains explicitly waived and is not proof
for this fix (
realTurnVerified=false). macOS and native non-WSL Linux states remain unchanged.
Promotion Candidates
- None. The current Pi Spec already states that fork is from a user entry; the product README and this task-owned record now match that existing decision.