fix(pi): validate user-entry conversation forks
This commit is contained in:
@@ -0,0 +1,191 @@
|
||||
# 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: 941b015330206af648f944183846ac2857468847
|
||||
- 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.
|
||||
Reference in New Issue
Block a user