# Task: Write Pi runtime hard-cutover implementation spec ## Identity - Task ID: 20260822-pi-runtime-spec-b6e2c9a4 - Mode: Feature - Branch: codex/20260822-pi-runtime-spec-b6e2c9a4-pi-runtime-spec - Worktree: D:\Datas\OthersProjects\makelore-pi-runtime-spec-b6e2c9a4 - Base commit: fba68e86d93c66d2c50f53d215de76a7c69c97a7 - Owner: codex - Status: Ready for integration ## Scope - Convert the approved OpenCode-to-Pi hard-cutover design into a normative, implementation-ready specification. - Define product behavior, architecture and ownership boundaries, runtime and process contracts, data schemas, Host API and Renderer protocols, migration, packaging, performance, observability, verification, and Definition of Done. - Produce an associated dependency ticket graph with explicit ready frontiers, ownership areas, outputs, and acceptance criteria suitable for a later implementation run. - Track task-scoped qualification results against that graph without promoting partial platform evidence into a `PI-000` Go decision. - Apply the user's 2026-08-22 scope amendment: Phase-0 platform qualification is Windows x64 + Linux x64; macOS x64/arm64 is Explicitly Waived / Deferred for `PI-000` only and moves to mandatory `PI-150` release validation. - Apply the user's later 2026-08-22 Provider-risk decision: real external Provider Account/protocol and real-provider two-worker qualification are Explicitly Waived / Accepted Risk, never Pass; retain packaged loopback/ provider-shaped evidence with `realTurnVerified=false`. - Documentation only: do not change product code, dependencies, canonical memory, runtime behavior, or external issue/PR state. ## Intent And Constraints - Pi is the sole target coding runtime. Do not retain an OpenCode fallback, feature flag, compatibility Adapter, old Host API facade, or dual runtime. - Preserve `.niancode/project.json`, stable Agent IDs, existing app/protocol/ storage compatibility identifiers, and Main ownership of runtime, provider, secret, file, and system access. - Keep Pi wire types and session paths out of Renderer; specify a Makelore-owned Snapshot/Patch contract and deep Main-owned runtime Module. - Treat packaged runtime qualification, packaged provider-shaped compatibility/ concurrency/abort, and resource budgets as a blocking Phase-0 gate rather than assumed facts. - Treat `QG-004`/`QG-005` as explicit human waivers, not Pass: the user accepts the unverified real Provider Account protocol compatibility and real two-worker provider overlap/isolation risks, so external credentials are no longer a `PI-000`, `PI-150`, or release blocker. - Make first-Conversation Composer readiness independent of runtime and metadata readiness; distinguish local runtime overhead from Provider latency. - Specify old OpenCode Session handling as backup plus non-continuation, not as compatibility behavior. - The named `implement-spec` skill assumes an existing spec and tickets. For this request, use its execution-graph discipline to create the missing spec and tickets, but do not start implementation, create a PR, or create subagents. The user explicitly prohibited subagents. ## Project Context Loaded - The `maintain-project-docs` Concurrent Task Gate and Planning Gate passed in the isolated worktree above at base `fba68e8`. - The main worktree remains owned by a blocked OpenCode model-switch integration task and contains a separately owned untracked task record; neither is modified here. - Required canonical positioning/current-state/decision/architecture/domain/ evidence/reflection/commitment records and the relevant Pi/OpenCode peer task records were read before writing. - No accepted ADR conflicts with the hard-cutover proposal. Current OpenCode behavior is integrated state that a future Pi implementation will supersede. - The canonical project-positioning document remains a placeholder, so product scope is taken only from repository guidance and confirmed current state. - Gate result: Passed. - Human scope decision: on 2026-08-22 the user explicitly accepted deferring macOS x64/arm64 qualification from `PI-000` to `PI-150`. This does not create macOS Pass evidence and does not waive the final cross-platform release gate. - Human Provider-risk decision: on 2026-08-22 the user explicitly accepted the missing real external Provider compatibility, concurrency and isolation evidence. `QG-004`/`QG-005` are Explicitly Waived / Accepted Risk, not Pass; `QG-007` remains Pending / not triggered because a waiver is not a failure. ## Plan 1. Translate the detailed design into normative requirements and stable product contracts without copying vendor wire types into public interfaces. 2. Define schemas, lifecycle/state rules, event mapping, migration, packaging, performance budgets, failure behavior, and traceable acceptance criteria. 3. Build a dependency ticket graph whose initial ready frontier begins with the packaged Pi qualification gate and whose terminal ticket proves zero OpenCode runtime residue. 4. Validate cross-references, dependency closure, Markdown structure, task ownership, and project-documentation gates. ## Outcome - Added the normative implementation specification `.project-docs/10-decisions/proposals/20260822-pi-runtime-spec-b6e2c9a4__pi-runtime-cutover-spec.md`. - Added the associated execution graph `.project-docs/10-decisions/proposals/20260822-pi-runtime-spec-b6e2c9a4__pi-runtime-cutover-tickets.md`. - The Spec defines 134 unique normative requirements across 19 groups for the hard cutover, product behavior, Main/Renderer boundary, schema v2, Provider and managed resources, Pi process/RPC/worker pool, extensions, Snapshot/Patch event projection, Host API, changes/browser, migration, packaging, observability, performance, recovery, verification, and Definition of Done. - The ticket document defines 18 bounded tickets and 31 dependency edges. The graph is acyclic, its initial ready frontier is only `PI-000`, and every ticket includes dependencies, ownership, required work, acceptance, and verification. - Packaged Pi qualification is a blocking gate. If RPC, packaged provider-shaped contract/concurrency/abort, resource use, or cold/warm budgets fail, the implementation must stop and amend the architecture before product migration; it cannot add an OpenCode fallback or dual RPC/SDK production path. Missing explicitly waived real external Provider evidence is not a confirmed failure. - The first-Conversation correction is a hard UX requirement: project/partner/ Conversation creation is local-only, Composer editability is independent of runtime/metadata readiness, and local preparation has bounded, observable failure instead of minute-long disabled state. - No product code, dependencies, external tickets, PR, canonical project memory, or runtime behavior changed. No subagents were created. - Synchronized the first `PI-000` implementation result from task `20260822-pi-runtime-qualification-c52e8a14` into the ticket graph. The final planning state is Done with explicit waivers: the exact Pi 0.84.2 identity, Windows x64 and WSL2 Linux x64 workspace/staged/controlled packaged RPC/ session/process/closure behavior, four-protocol packaged loopback, provider-shaped overlap/abort and local budgets have evidence. Real external turns for all four protocols remain missing and are Accepted Risk, not Pass. - Synchronized the controlled Electron Builder `app.asar` and four-protocol loopback results. The packaged seam resolves all 130 Windows-applicable production packages and six runtime assets, passes cold/warm budgets and leaves no process residue. The loopback matrix proves request/SSE/image/ header/model/environment-credential plumbing plus provider-shaped overlap and abort isolation, but is explicitly not real Provider Account evidence. - Synchronized the WSL2 Ubuntu 24.04 Linux x64 evidence. Workspace, staged closure, and controlled Electron Builder `dir/app.asar` all meet the local cold/warm budgets; the controlled artifact resolves 131 applicable packages, six runtime assets and unpacked native assets, and leaves no Pi process residue. Linux packaged loopback overlap was 292/290/277/288 ms for the four protocols, with exactly four POSTs per protocol and abort isolation passing. - Interpreted the accepted `QG-002` wording narrowly and explicitly: it requires a Linux packaged app seam but does not state a non-WSL kernel, compositor, AppImage, or deb requirement. The WSL2 controlled artifact therefore counts as PI-000 Linux seam evidence with a recorded limitation; final Linux release formats remain `PI-150` evidence and are not claimed here. - Synchronized the macOS packaged-resource preflight defect and fix. The old artifact-side derivation would resolve `/Contents/MacOS/resources/app.asar`; the actual location is `/Contents/Resources/app.asar`. The outer platform-aware `packagedResourcesDirectory()` now computes the directory once and passes it through `PI_PROBE_RESOURCES_DIRECTORY`, so the closure inspector no longer derives it independently. - Kept macOS explicitly unqualified. A darwin path test and a Windows actual controlled-packaged regression establish the fix and absence of a Windows regression, but neither is a macOS x64/arm64 execution sample. - Applied the user's 2026-08-22 amendment: macOS x64/arm64 is now Explicitly Waived / Deferred for `PI-000`, not Pass. Workspace/staged/controlled packaged/loopback/metrics move to `PI-150`, where both architectures remain mandatory. The user accepted the risk of later packaging/native/resource/ performance defects and release-stage rework; the risk was not eliminated. - Clarified the pre-existing artifact wording: `PI-000` proves the controlled packaged qualification artifact on Windows/Linux, while `PI-150` owns final product artifacts. The controlled probe is not the final bundler. - After the later Provider waiver and a full PI-000/DAG audit, marked `PI-000` Done with explicit waivers and advanced the exact Ready Frontier to `PI-010`, `PI-020`, and `PI-030`. The published shrinkwrap/devDependencies mismatch remains an explicit `PI-030` permanent-staging constraint rather than final packaging proof; it is work owned by the now-ready ticket, not an unresolved PI-000 gate. - Bound the final planning documents to the verified PI-000 implementation baseline `2bc423ebc58589307442ebdaf1c81d83ec9dc2d5` (`feat: qualify Pi runtime cutover foundation`). The implementation task is `ready_for_integration`, its worktree is clean, and the PI-010 task `20260822-pi-conversation-contracts-a61d9c42` has been created from that exact commit with status `planning`. - Corrected two stale planning statements before final commit: the Spec now records the user's implementation authorization instead of saying it awaits acceptance, and PI-040 now verifies Provider catalog behavior with packaged provider-shaped fixtures rather than making waived real-account prompts a hard acceptance requirement. ## Verification - Read the complete source design and the relevant Pi evaluation, concurrency, message-mapping, first-session diagnosis, and current OpenCode integration task records after passing the planning gate. - Requirement audit: 134 definitions, 134 unique IDs, no duplicate definitions; all 19 requirement groups appear in the ticket traceability section. - Ticket graph audit: 18 declared nodes, 31 edges, all graph nodes have matching detail sections, no missing dependencies, and a complete acyclic topological order from `PI-000` through `PI-160`. - Ticket shape audit: every ticket contains Objective, Dependencies, Owns, Required work, Acceptance, and Verification. - Markdown code fences are balanced: 34 in the Spec and 4 in the ticket graph. - Placeholder scan found no unfinished TODO/TBD/template markers; the literal `todo/todos` occurrences only describe intentional removal of the old API. - Trailing-whitespace/final-newline check passed for all three owned files. - Task-scoped `git diff --no-index --check` produced only expected LF-to-CRLF notices and no whitespace errors. - `check_project_docs.py`: passed. - `check_doc_drift.py --task-id 20260822-pi-runtime-spec-b6e2c9a4`: passed and reported only the two task-scoped proposal files and this task record. - Product tests were intentionally not run because this task changes only task-scoped documentation and no product behavior. - Read the complete source task record and task-scoped evidence for `20260822-pi-runtime-qualification-c52e8a14`. Its Markdown status is `Completed — Done with explicit waivers`, the ownership registry reports `ready_for_integration`, and its clean worktree is at verified commit `2bc423ebc58589307442ebdaf1c81d83ec9dc2d5`. - Rechecked the qualification result against `PI-000` Acceptance and Stop condition: every non-waived requirement is satisfied by Windows/WSL2-Linux controlled packaged evidence. Real Provider Accounts/turn concurrency remain unverified Accepted Risk; macOS remains unqualified and mandatory at `PI-150`. - Reviewed the controlled packaged evidence: 5 cold samples reported p50/p95/max 668/682/682 ms, 5 warm samples 660/663/663 ms, 10 RSS samples 138404/141320/141320 KiB, and exit 16/18/18 ms. Session/reopen/failure/local overlap/abort/stdin-close passed with no controlled artifact or Pi RPC process residue. - Reviewed all four packaged loopback protocol contracts: each made exactly four POSTs and passed base URL/path, protocol credential header, custom header, model, PNG image, two-worker settled overlap, one-worker abort isolation, and clean stdin close. The final tightened rerun reported overlap of 304/309/290/297 ms. No external Provider request or cost occurred, so the normative `QG-004` and `QG-005` are Explicitly Waived / Accepted Risk, not Pass. Under the user-amended Phase-0 platform scope, `QG-002`, `QG-003`, and `QG-006` are Pass for Windows x64 + Linux x64; macOS remains Explicitly Waived / Deferred, not Pass. - Verified that the implementation report fields now match this amended planning contract. `buildMissingEvidence()` reports Phase-0 aggregation as Windows x64 + Linux x64, labels macOS x64/arm64 as user-deferred to `PI-150`, and retains the four missing real-provider protocol samples. The focused test asserts that exact wording; the final implementation task records 9 focused tests, scoped ESLint, typecheck, and a 1-sample actual probe as passing. The retained missing samples and `realTurnVerified=false` now document Accepted Risk rather than a blocker. The 18-node/31-edge DAG is unchanged; `PI-000` Done unlocks `PI-010`, `PI-020`, and `PI-030`. - Recorded the Provider URL rule discovered by the fixture: Anthropic receives the Provider root and appends `/v1/messages`; OpenAI-style protocols receive a `/v1` base and append `chat/completions` or `responses`. - Reviewed the Linux 5+5 samples: workspace cold/warm p95 853/437 ms, staged 428/440 ms, controlled packaged 545/569 ms; respective RSS p95 values were 170388/175956/181928 KiB and exit p95 values 8/8/7 ms. All 131 applicable Linux packages and six runtime assets resolved, including unpacked native assets, with no residual artifact/Pi RPC process. - Reviewed the Linux packaged loopback matrix: exactly four POSTs per protocol, overlap 292/290/277/288 ms, correct path/auth/custom-header/model/image, abort isolation and clean exit. The accompanying 7 tests, scoped ESLint, typecheck, and 1-sample integration probe passed in the implementation task. - Corrected the planning QG status table to use the normative Spec numbering: `QG-003` is dependency closure, `QG-004` Provider Accounts, `QG-005` real provider concurrency, `QG-006` metrics, and `QG-007` the SDK-switch stop condition. The implementation evidence's task-local labels are retained only as source context and do not redefine the Spec. - Reviewed the portability-fix verification: 8 focused tests passed, including darwin executable → `Contents/Resources`; scoped ESLint and typecheck passed. The post-fix Windows 1-sample controlled packaged regression reported cold/ warm ready 650/641 ms, with all 130 applicable packages, six runtime assets, and unpacked native assets present. - Reviewed the execution-environment inventory: there is no repository CI definition, macOS runner/SSH host, GitLab runner CLI, or Provider credential environment variable. The missing Provider environment is now Accepted Risk and non-blocking; the missing macOS environment remains a deferred `PI-150` release gap. - Post-sync graph audit still reports 18 nodes, 31 edges, only `PI-000` at indegree zero, and a complete acyclic topology; no dependency edge changed. - Scope-amendment audit preserved all 18 nodes and 31 edges. The Ready Frontier after `PI-000` Done is exactly `PI-010`, `PI-020`, `PI-030`; all other nodes retain at least one unfinished dependency. - Post-amendment requirement audit still reports 134 definitions, 134 unique IDs, and no duplicates. The ticket audit reports 18 Mermaid nodes, 18 detail sections, 31 edges, only `PI-000` at indegree zero, and all 18 nodes visited by the acyclic topology check. - Post-amendment contradiction scan found no remaining statement that treats missing macOS evidence as a `PI-000` blocker or Pass. The Spec and tickets consistently make the waiver Phase-0-only and `PI-150` release-blocking. - Provider-waiver audit found no remaining proposal statement requiring a real external Provider Account/credential to close `PI-000` or release. The exact accepted risks are auth/endpoint/proxy/rate-limit/response variance; real base URL/header/environment credential/model/image compatibility; real provider concurrency/serialization/limiting; and cross-worker abort/event/ session/model/credential isolation. `QG-004`/`QG-005` are never labeled Pass, and `QG-007` remains Pending / not triggered. - PI-000 closure audit covered all eight Required work items plus Acceptance and Stop condition. Items 1/2/3/4/7/8 pass on the revised Windows/Linux scope; items 5/6 retain passing packaged loopback/provider-shaped substitute smoke and explicit real-Provider Accepted Risk. No third incomplete item or confirmed failure remains, so Done with explicit waivers is consistent with the ticket contract. - Post-sync `check_project_docs.py` and `check_doc_drift.py --task-id 20260822-pi-runtime-spec-b6e2c9a4` passed; trailing-whitespace inspection reported zero findings. - Re-ran both project-documentation gates after the user-authorized scope amendment; both passed against only the two task-scoped proposal files and this task record. Markdown fences remained balanced and trailing-whitespace inspection reported zero findings. - Final Provider-waiver audit preserved 134 unique requirements across all 19 traced groups and the unchanged 18-node/31-edge acyclic DAG. Recomputing readiness with only `PI-000` Done yields exactly `PI-010`, `PI-020`, `PI-030`; every other ticket retains an unfinished predecessor. Ticket-shape, QG-state, explicit-risk, macOS-release-gate, hard-cutover, cross-reference, stale-blocker and formatting assertions all passed. - Verified the PI-000 implementation commit metadata, parent and changed-file set. Commit `2bc423e` is based on the planning baseline `fba68e8` and contains only the PI-000 dependency/lockfile, probe/test, task-record and evidence changes expected from the qualification ticket. - Verified the PI-010 ownership handoff through the task registry and worktree: task `20260822-pi-conversation-contracts-a61d9c42` is based exactly on `2bc423e`, remains in `planning`, and its only untracked file is its own task record. The planner's three-document write set does not overlap PI-010's product-code ownership. ## Follow-ups - Continue `PI-010`, which has entered planning from the verified PI-000 baseline; `PI-020` and `PI-030` remain the other eligible Ready Frontier tickets. The dependency-qualified frontier remains exactly `PI-010`, `PI-020`, `PI-030` until a later status update recomputes it. Real external Provider fixtures for `openai-completions`, `openai-responses`, `anthropic-messages`, and `openrouter` are optional non-blocking risk-reduction work; if collected, retain `realTurnVerified=false` until actual evidence exists and never retroactively relabel the waiver as Pass. - At `PI-150`, obtain the deferred macOS x64 and macOS arm64 evidence. For each architecture, use an independent checkout and frozen install; run workspace 5+5, staged 5+5, controlled packaged 5+5, packaged loopback, closure/native/ resource checks, metrics, and final target artifact verifier/smoke. Do not reuse x64/arm64 `node_modules`, Electron downloads, or artifacts. Missing either architecture blocks cross-platform release-ready status. - Treat non-WSL Linux, compositor, AppImage/deb, and the final product packaging wiring as `PI-150` release evidence unless the accepted PI-000 Spec is amended to require them earlier; do not imply the controlled WSL2 artifact proves those release boundaries. - If a non-waived packaging, packaged provider-shaped contract/concurrency/ abort-isolation, image-serialization, or budget gate fails, return to the planner for the specified SDK-in-Electron-utility-process amendment; do not add an OpenCode fallback or RPC/SDK dual production path. If deferred macOS validation fails at `PI-150`, block release and perform the required packaging/runtime/architecture rework; the Phase-0 waiver cannot be reused as a release waiver. - If old OpenCode chat history must remain readable, create a separate exporter in the last OpenCode-containing release; do not add an OpenCode reader/runtime to the Pi release. ## Promotion Candidates - Accepted ADR: Pi is Makelore Code's sole runtime and no OpenCode fallback is shipped. - Canonical architecture: one Main-owned worker per active/warm Conversation, a product-only `CodingConversationRuntime` Interface, and Renderer-only Snapshot/Patch state. - Domain rules: product Conversation IDs, structured model selections, explicit unresolved migration state, same-project mutation lease, and old OpenCode Session backup/non-continuation policy. - Success criteria: first-Conversation Composer readiness, cold/warm runtime and prompt acceptance budgets, independent two-Conversation workers with packaged provider-shaped overlap/abort, explicit real-Provider Accepted Risk, subagent caps, and zero residual OpenCode runtime in source/package/artifact.