docs: diagnose Pi branch creation failure
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
# Task: Diagnose branch creation runtime unavailable
|
||||
|
||||
## Identity
|
||||
|
||||
- Task ID: 20260825-fork-runtime-unavailable-8e7c4a21
|
||||
- Mode: Feature
|
||||
- Branch: codex/20260825-fork-runtime-unavailable-8e7c4a21-fork-runtime-unavailable
|
||||
- Worktree: D:\Datas\OthersProjects\makelore-fork-runtime-unavailable-8e7c4a21
|
||||
- Base commit: 45d933732a8fbc0dadb07a4a4d65f0d12000c2ea
|
||||
- Owner: codex-root
|
||||
- Status: Done
|
||||
|
||||
## Scope
|
||||
|
||||
- Diagnose the installed Windows client's `从这里创建新对话分支` action returning `本地编程运行时暂时不可用。` from the exact packaged product source `45d9337`.
|
||||
- Build a deterministic regression at the Renderer → Host → Pi runtime fork seam, identify the first failing ownership/runtime boundary, and report the verified cause.
|
||||
- Do not change product code unless the user subsequently authorizes implementation; diagnostic fixtures or instrumentation must remain task-scoped and be removed before completion unless promoted into an approved regression test.
|
||||
|
||||
## Intent And Constraints
|
||||
|
||||
- Preserve Main-owned `/api/coding/*`, per-Conversation worker/session ownership, mutation no-replay semantics, and safe fixed error projection.
|
||||
- Use installed-client logs only after redacting credentials, headers, prompts, project absolute paths, and user content. Do not expose or persist secrets.
|
||||
- Do not infer the cause from the generic user-facing error: distinguish request/selection errors, missing or stale worker ownership, fork RPC failure, session persistence failure, and packaging/runtime resolution.
|
||||
- Do not create subagents.
|
||||
|
||||
## Project Context Loaded
|
||||
|
||||
- Task ID: `20260825-fork-runtime-unavailable-8e7c4a21`
|
||||
- Mode: Feature
|
||||
- Branch: `codex/20260825-fork-runtime-unavailable-8e7c4a21-fork-runtime-unavailable`
|
||||
- Worktree: `D:\Datas\OthersProjects\makelore-fork-runtime-unavailable-8e7c4a21`
|
||||
- Base commit: `45d933732a8fbc0dadb07a4a4d65f0d12000c2ea`
|
||||
- Other active local tasks: eleven planning/integration records were inspected; none owns the current Pi fork route/runtime path. The main-worktree integration record concerns the superseded OpenCode model-switch path.
|
||||
- Overlap or semantic-conflict assessment: no blocking peer overlap. Canonical current-state/architecture documents are OpenCode-stale relative to the installed Pi product, so current Pi source and completed Pi task records are authoritative for this diagnosis.
|
||||
- Read: project entry/gate/index files, task record, positioning/current state, decision and architecture indexes, module/data-flow and domain/success documents, evidence/reflection/commitment/stale indexes, and all active peer task scopes.
|
||||
- Relevant understanding: the failing feature belongs to the Pi Conversation product chain and must retain Conversation-scoped ownership and no mutation replay. The packaged Windows artifact already passed Pi closure/load checks, which makes a total missing runtime less likely but does not prove the fork operation.
|
||||
- Gate result: Passed.
|
||||
|
||||
## Plan
|
||||
|
||||
1. Locate the exact UI string, fork route, safe error mapper, runtime method, and existing fork tests from the fixed package source.
|
||||
2. Construct and run the smallest unattended test that drives the same fork path and asserts the reported generic runtime-unavailable outcome.
|
||||
3. Inspect redacted installed-product diagnostics and persisted Conversation/session metadata only as needed to distinguish the ranked hypotheses.
|
||||
4. Minimize the failing state and state the verified cause, affected files, and an in-scope repair/verification proposal; do not implement without user authorization.
|
||||
|
||||
## Outcome
|
||||
|
||||
- Confirmed the reported message is caused by an invalid product-to-Pi fork entry, not by the Pi runtime being globally absent or crashed.
|
||||
- `CodingConversationTimeline` currently renders `从这里创建新对话分支` for every durable message with a `sourceEntryId`, including assistant messages (`src/pages/Chat/CodingConversationTimeline.tsx:190`). The existing PI-130 fixture explicitly asserts this assistant-message behavior.
|
||||
- The normative Pi cutover Spec assigns `/api/coding/conversations/:id/fork` to a **user entry**. A real pinned Pi `0.84.2` RPC experiment proved that the same persisted session accepts its user entry and deterministically rejects its assistant entry with `Invalid entry ID for forking`.
|
||||
- `createPiManagedWorkerOpener` forwards the Renderer-selected entry unchanged as Pi RPC `{ type: 'fork', entryId }` after opening the target worker (`electron/coding-runtime/pi/runtime.ts:292`). `PiRpcClient` converts the rejection to `PI_RPC_RESPONSE_ERROR`; because that error has no product `publicError`, `CodingConversationService.runtimeError` maps it to `503 CODING_RUNTIME_UNAVAILABLE`, whose fixed Chinese message is exactly `本地编程运行时暂时不可用。`.
|
||||
- The installed log did not provide a trustworthy click correlation: the observed `open_failure` timestamps overlap the automated package verifier. Those lines were excluded from the causal proof.
|
||||
- No product source was changed. Temporary diagnostic tests were removed after the reproduction.
|
||||
|
||||
## Verification
|
||||
|
||||
- `corepack pnpm install --frozen-lockfile` — passed with pnpm `10.33.4` and pinned Pi `0.84.2`.
|
||||
- Red-capable Renderer regression, run as `corepack pnpm exec vitest run tests/unit/coding-conversation-timeline.test.tsx` — failed deterministically in 18 ms because an assistant entry incorrectly rendered the fork button; the other four tests passed. The temporary assertion was then removed.
|
||||
- Real Pi `0.84.2` diagnostic through Electron Node and `PiWorkerProcess` — passed: a synthetic persisted session was CLI-forked, Pi RPC accepted the user entry and rejected the assistant entry with `Invalid entry ID for forking`; stderr remained empty. This distinguishes an RPC contract rejection from worker crash/startup failure. The temporary diagnostic file and scratch sessions were removed.
|
||||
- Static error-chain confirmation — `PI_RPC_RESPONSE_ERROR` has no product `publicError`, so the service maps it to `CODING_RUNTIME_UNAVAILABLE` and the Host route emits the exact reported Chinese message.
|
||||
- Diagnostic cleanup — no product/test diff remains; only this task record is task-owned output.
|
||||
|
||||
## Follow-ups
|
||||
|
||||
- Recommended implementation task: render/enable fork only for durable **user** message entries, and validate the same invariant in Main before creating target metadata or spawning a target worker. Invalid/stale source entries should return `400 CODING_CONVERSATION_REQUEST_INVALID`, not a misleading runtime-unavailable response.
|
||||
- Preserve the existing mutation no-replay rule. Do not retry fork automatically after timeout or an uncertain response.
|
||||
- Add three permanent regressions: Renderer hides assistant-entry fork actions and still submits user entries; Main rejects assistant/unknown entry ids before target creation; real Pi `0.84.2` user-entry fork succeeds through the managed opener/final packaged seam.
|
||||
- After implementation, run focused Timeline/Conversation service/Pi real-worker tests, typecheck, lint, full unit suite, `build:vite`, a real Electron branch-creation E2E, then rebuild and verify the Windows installer.
|
||||
|
||||
## Promotion Candidates
|
||||
|
||||
- None recorded.
|
||||
Reference in New Issue
Block a user