Files
makelore/.project-docs/30-worklog/tasks/20260825-pi-user-entry-fork-4a7d9c21.md
T

10 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: Verifying

Scope

  • Restrict the Renderer fork action to durable user messages on the active Conversation path.
  • Validate the same invariant in CodingConversationService.fork before any target Conversation metadata, worker, session binding, archive, or cleanup resource can be created.
  • Preserve the existing real Pi 0.84.2 fork 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_INVALID through 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 parent 45d933732a8fbc0dadb07a4a4d65f0d12000c2ea and its Agent-owned Conversation hierarchy. Do not touch dirty main, 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 main integration 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 45d9337 must remain intact.
  • Decisions affecting this task: Spec route /api/coding/conversations/:id/fork is explicitly from a user entry; hydrated Snapshot nodes contain only the active path and expose durable sourceEntryId without 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

  1. 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.
  2. Implement the smallest product-contract correction: user-only durable UI action and service-owned active-Snapshot validation before target create.
  3. 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.
  4. 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.
  5. 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.fork now resolves the source Conversation's authoritative hydrated Snapshot and rejects missing, assistant, unknown, stale, or abandoned-path entries with 400 CODING_CONVERSATION_REQUEST_INVALID before target metadata creation. The Host keeps its fixed safe Chinese projection and never exposes Pi's raw Invalid entry ID for forking response.
  • A valid user entry still reaches the locked Pi fork RPC. The permanent real Pi 0.84.2 regression 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 sourceEntryId submission, 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.md now 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 pnpm 10.33.4 and Pi 0.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 — 4 files / 29 tests 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: 180 files / 1525 tests plus the isolated pressure test; 2 pre-existing skips.
  • corepack pnpm run build:vite — passed for Renderer, Main, Preload, and release utility worker.
  • Focused Windows Electron Playwright — passed: 2 tests, including the same-Agent user-entry branch flow and source isolation.
  • corepack pnpm run test:electron:windows — passed: 2 files / 4 tests.
  • Formal Windows package, artifact closure, packaged UI/Main fork proof, signing, fingerprint, and zero-residue evidence remain the active gate.

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.