feat: add Pi process and RPC foundation

This commit is contained in:
2026-08-22 20:05:59 +08:00
parent b6f693048d
commit 9a31dacb2a
14 changed files with 1955 additions and 26 deletions

View File

@@ -0,0 +1,90 @@
# Task: Implement PI-030 Pi process and RPC foundation
## Identity
- Task ID: 20260822-pi-process-rpc-d4f9a2c1
- Mode: Feature
- Branch: codex/20260822-pi-process-rpc-d4f9a2c1-pi-process-rpc
- Worktree: D:\Datas\OthersProjects\makelore-pi-process-rpc-d4f9a2c1
- Base commit: b6f693048d0edf831aa8c04d9790f67921ebdab9
- Owner: codex
- Status: Completed
## Scope
- Implement `PI-030 Pi process and RPC foundation` from the merged Pi cutover Spec/ticket graph.
- Add the Main-private Pi worker process, strict LF JSONL framer, correlated RPC client, bounded diagnostics, and stable process/RPC errors under `electron/coding-runtime/pi`.
- Add a programmable fake Pi child fixture and focused tests for chunking, malformed/oversized output, out-of-order response, event dispatch, timeout/abort, retry boundaries, crash, backpressure, stderr redaction, and process-tree cleanup.
- Add the permanent Pi production-closure staging script, deterministic runtime manifest, closure verifier, and initial package-resource wiring.
- Verify the locked real Pi `get_state` path and staged entry load/exit without connecting PI to project CRUD, Host API, Renderer, Provider catalog, worker pool, or schema migration.
## Intent And Constraints
- Pi remains pinned to `@earendil-works/pi-coding-agent@0.84.2`; launch through Electron executable plus `ELECTRON_RUN_AS_NODE=1` with explicit RPC, offline, no-approve, and no automatic resource-discovery arguments.
- Stdout is protocol-only; any malformed, invalid UTF-8, oversized, blank/non-JSONL, or trailing partial record invalidates and terminates only that worker. Stderr is bounded, sanitized diagnostic text and never participates in RPC.
- Correlate every command by ID, support out-of-order responses and independent events, settle every pending request on timeout/abort/exit/invalidation, and never auto-retry prompt/steer/follow-up/fork/compact.
- Graceful shutdown closes stdin and waits at most three seconds; forced cleanup must terminate the complete child tree. No promise or process may remain after disposal.
- Convert the PI-000 temporary staging workaround into an explicit production bundler: copy the published package root without its installed dependency tree, remove the ten root devDependencies in the staged copy so npm 11 can consume the production-only shrinkwrap, run the repository-pinned npm with scripts/audit/fund disabled, and verify package identities/assets independent of same-version physical flattening.
- Runtime manifest content must be deterministic and path-independent. Do not add checksum/hash sidecars, compatibility layers, dual RPC/SDK paths, Provider logic, Renderer wire types, or incidental OpenCode refactors.
- Preserve the explicit user waivers: real Provider compatibility/concurrency/credential isolation remains unverified Accepted Risk, not Pass; macOS x64/arm64 execution remains deferred to mandatory PI-150 validation.
## Project Context Loaded
- `maintain-project-docs` Concurrent Task Gate and Planning Gate passed in the isolated worktree above at base `b6f6930`.
- The base history contains planning `a8c0806`, PI-000 `2bc423e`, merged baseline `72f7a26`, PI-010 implementation `4deba3a`, and PI-010 completion record `b6f6930`.
- The planner task recomputed the 18-node/31-edge DAG after PI-010 and recommended PI-030 as the unique next implementation ticket, while PI-020 remains Ready but intentionally waits.
- Required project entry/current-state/architecture/domain/evidence/commitment records, the merged Pi Spec/tickets, PI-000 evidence, and PI-010 task record were read before planning.
- Other locally planning task records were inspected read-only. Their scopes concern OpenCode model switching, Canvas, Robot, release, or old reviews; none owns Pi process/RPC/bundling. No semantic or file-write conflict was found.
- The canonical project-positioning file remains a placeholder. Repository guidance, current integrated state, and the merged Pi proposal/ticket graph are the authority for this task.
- `codebase-design` keeps the public worker surface small while framing, correlation, retries, diagnostics, and cleanup remain implementation-private. The user-prohibited parallel-subagent design path is not used.
## Plan
1. Implement stable process/RPC errors, the strict LF JSONL framer, and the correlated RPC client with focused unit tests.
2. Implement the Pi worker-process lifecycle and programmable fake child, including target-only invalidation, bounded diagnostics, graceful/forced process-tree cleanup, timeout/abort, and backpressure behavior.
3. Implement permanent production-closure staging, package/version/asset verification, deterministic manifest generation, and initial package/build resource wiring.
4. Run the fake-child matrix, real locked Pi `get_state`, staged-entry load/exit, typecheck, lint, full tests, production compile, and task-documentation gates.
5. Commit the implementation and task record, mark the task ready for integration, and send the result to the architecture/planner task.
## Outcome
- Implemented the Main-private Pi process/RPC foundation with stable process errors, strict byte-bounded LF JSONL framing, command correlation, out-of-order response handling, event dispatch, timeout/AbortSignal settlement, read-only-once retry boundaries, and write/backpressure handling.
- Implemented an Electron-Node Pi worker with explicit offline/no-approve/no-auto-resource arguments, generation-scoped invalidation, bounded/redacted stderr and protocol diagnostics, stdin-close graceful shutdown, and full-tree forced cleanup.
- Added a programmable fake child covering response/event/out-of-order/partial/malformed/blank/invalid UTF-8/oversized/trailing partial/timeout/retry/stderr/crash/descendant cases, plus a locked real Pi `get_state` smoke through Electron 43.4.0 / Node 24.18.1.
- Implemented permanent npm 11.6.2 production staging from the published package and production-only shrinkwrap. The staged copy explicitly removes the ten mismatched root devDependencies, installs with `--omit=dev --ignore-scripts`, verifies package identities independently of physical flattening, inventories native/WASM assets, and emits a deterministic path-free manifest.
- Wired host-target staging into build/package commands and product `extraResources`. During the production-shaped artifact probe, confirmed that Electron Builder omits a FileSet root named `node_modules`; corrected all OS mappings to copy runtime root files and `node_modules` through two explicit FileSets.
- The controlled Electron Builder `dir` artifact loads Pi from `resources/pi-runtime`, contains all 130 expected production package identities and all 6 inventoried assets, preserves a session, exits by closing stdin, and passes two-worker local overlap/abort isolation.
- Real Provider account verification remains explicitly waived by user decision: protocol/account compatibility, real concurrency, credential isolation, and provider-specific behavior are Accepted Risk and remain `realTurnVerified=false`, not Pass. macOS x64/arm64 execution remains deferred to PI-150 and is not claimed as Pass.
## Verification
- `pnpm install --frozen-lockfile`: passed with the repository-pinned pnpm 10.33.4.
- Focused process/RPC/runtime tests: 4 files, 30 tests passed.
- `pnpm run typecheck`: passed.
- Scoped ESLint for every changed TypeScript/JavaScript implementation and test file: passed.
- `pnpm run lint:check`: passed with 0 errors and 6 pre-existing warnings outside this task's files.
- `pnpm test`: 182 files, 2118 tests passed. The first loaded full-suite run exposed two sub-250ms test-only timing budgets; those were raised while retaining the timeout semantics, then the focused and full suites passed.
- `pnpm run build:vite`: passed for Renderer, Main, Preload, and release utility output; existing Vite dynamic-import and chunk-size warnings remain unchanged.
- `pnpm run bundle:pi-runtime`: passed for `win32-x64`, generating a 130-package/6-asset production closure.
- Repeated permanent staging generated byte-identical manifest content; the manifest contains no local path, timestamp, checksum, or build-directory identity.
- `node scripts/probe-pi-packaged-runtime.mjs --samples 1 --timeout-ms 10000 --report release/pi-runtime-probe-result.json`: passed against the production-shaped `resources/pi-runtime` layout. Packaged closure had zero missing/relocated packages and zero missing assets; cold ready was 610 ms, warm ready 580 ms, and both measured exits were 13 ms by stdin close.
- Forced Windows child-tree cleanup test passed; no macOS execution was performed by explicit user direction.
## Follow-ups
- `PI-040` may consume the process foundation after `PI-020` supplies schema v2; it owns Provider catalog, secrets, managed prompt/skill/resource projection, and must not move those concerns into this worker.
- `PI-050` may compose this single-worker primitive into the worker pool/session registry after `PI-010`, `PI-020`, `PI-030`, and `PI-040` are integrated.
- `PI-150` must run final release-artifact validation for Windows/Linux and the explicitly deferred macOS x64/arm64 targets. The real Provider waiver stays Accepted Risk unless the user later requests non-blocking evidence collection.
## Promotion Candidates
- Target: Pi runtime packaging architecture and final PI-150 verifier guidance.
Proposal: record that Electron Builder unconditionally skips a FileSet source root named `node_modules`; production Pi resources therefore require one FileSet for the staged root excluding `node_modules` and a second FileSet rooted at staged `node_modules`.
Evidence: the first production-shaped controlled artifact omitted all 130 dependencies and 6 assets; the two-FileSet mapping produced zero missing packages/assets and loaded the real Pi entry from `resources/pi-runtime`.
Future impact: prevents a later release build from silently shipping only the Pi root package while dropping its production dependency closure.
Semantic conflicts: none; this refines the existing `resources/pi-runtime` packaging contract without changing runtime ownership.
- Target: Pi runtime staging architecture.
Proposal: promote npm 11.6.2 plus staged-copy root-devDependency removal and identity-based closure validation as the permanent reproducible handling for the published Pi 0.84.2 package/shrinkwrap mismatch.
Evidence: clean staging, flattening fixture, deterministic manifest comparison, and packaged load/exit all passed.
Future impact: PI-150 can reuse the same builder and verifier rather than recreating the PI-000 temporary workaround.
Semantic conflicts: none; the source package and frozen shrinkwrap remain unmodified.