13 KiB
13 KiB
Task: Implement PI-070 managed extension host interactions and write lease
Identity
- Task ID: 20260823-pi-extension-host-7e4c91a2
- Mode: Feature
- Branch: codex/20260823-pi-extension-host-7e4c91a2-pi-extension-host
- Worktree: D:\Datas\OthersProjects\makelore-pi-extension-host-7e4c91a2
- Base commit:
47159b3cbd - Owner: codex
- Status: Completed — planner Pass
Scope
- Implement
PI-070 — Managed extension host, interactions, and write leasefrom the【架构】opencode2piSpec/ticket graph on cumulative baseline47159b3cbdf06ea66db9a4425e0a9c13bcd73f7f. - Own the Main-private versioned Makelore Pi extension entry, authenticated worker bridge/registry, interaction lifecycle, project mutation write lease, and the smallest PI-060 projector/runtime integration required to expose safe product state.
- Add focused real-bridge, stale-token/generation, interaction lifecycle, and lease concurrency/cancellation tests. Do not wire Renderer Host routes, subagents, product browser/tools, or final packaging owned by later tickets.
Intent And Constraints
- Follow planner task
20260822-pi-runtime-spec-b6e2c9a4, ticketPI-070, and SpecLEASE-001throughLEASE-006,EXT-001throughEXT-006, and section 9.3 interaction semantics. - Load exactly one explicit versioned Makelore extension bundle. Project/user Pi extension discovery remains disabled; no generic plugin platform, permission engine, compatibility layer, signature/hash framework, or remote authorization scaffold is in scope.
- Electron Main owns bridge tokens, worker identity, project identity, interactions, leases, and diagnostics. Every bridge request must match the registered conversation, worker generation, run, and short-lived token; disposed/recovered workers and old generations fail closed without affecting the current worker.
ask_usersupports select/confirm/input/editor and correlates responses only by the pending interaction ID. Worker abort/crash/dispose cancels pending interactions. Unknown UI/widget/details are bounded diagnostics, never raw product state or logs.- Mutation write/edit/bash work uses one cancellable FIFO project lease; reads and pure reasoning bypass it, different projects may mutate concurrently, and complete/error/abort/timeout/crash/dispose always release ownership.
- Draft/editor suggestions are revision-conditional and must not overwrite a newer user draft. Host routes and Renderer consumption remain for PI-100/ PI-130; this ticket records the Main-side contract only.
- Real external Provider validation remains Explicitly Waived / Accepted
Risk with
realTurnVerified=false; macOS x64/arm64 remains deferred to mandatory PI-150 validation. Neither is a Pass. - Do not create subagents. Keep changes surgical and rooted in this isolated worktree.
Plan
- Verify the locked Pi 0.84.2 extension/tool interface and the existing PI-040/050/060 seams; define the smallest product-owned bridge interface.
- Implement the versioned managed extension bundle plus authenticated worker registry/bridge and prove real bridge round trips and stale identity rejection.
- Implement interaction storage/projection and the cancellable project write lease, then wire generation/run cleanup into the runtime without widening Host/Renderer interfaces.
- Run focused tests, all Pi tests, typecheck, lint, build, and relevant Electron/package checks; update this task record, pass documentation drift, commit, and hand the exact implementation HEAD to the planner for review.
Outcome
- Implemented a Main-private, versioned
makelore-runtime-v1.mjsbundle and changed Pi startup from--no-toolsto an explicit built-in plusask_userallowlist. Discovery remains disabled with--no-extensions, while the managed opener appends exactly one product-owned--extension. - Added
PiManagedExtensionHost, a loopback-only HTTP bridge with one random bearer token per worker generation. Every request must match token, Conversation, generation, and active run; worker invalidation/dispose makes the token unusable and releases all owned or waiting resources. Active run binding is inherited synchronously by a replacement generation before its child process starts, closing the stale-rebuild race. - Added the self-contained extension
ask_usertool for select, confirm, input, and editor requests. Pi's fire-and-forgetextension_ui_responserecords now use a dedicated one-way transport seam rather than pretending to be request/response commands. - Added a Host-side
PiInteractionStorewith exact interaction/option correlation, current generation/run validation, terminal status projection, and generation-scoped abort/crash/dispose cancellation. Runtime dialog events pass through the store before entering product patches. - Added a FIFO
PiProjectWriteLeaseCoordinatorand extension hooks that makewrite,edit, andbashshare one mutation lease per project. Reads and reasoning bypass it; different projects proceed in parallel. Tool result, agent end, session shutdown, abort, crash, recovery, dispose, and Host shutdown all reach an idempotent release path; waiting bridge requests are cancellable. - Added safe projection for notify/status/registered widget/title/editor-text events. Unknown widget/UI payloads become bounded method-only diagnostics; editor text is emitted only when the current draft revision still equals the run-start revision.
- The Pi 0.84.2 real-child smoke now loads the materialized managed extension through Electron Node and confirms RPC readiness without extension-load or stdout-protocol failure. No real external Provider was contacted.
- Planner review of initial candidate
3861c32returned Needs Fix / Not Done with four deterministic supported-path findings. The correction closes each finding without changing the PI DAG: recover clears the old run before worker replacement and replacement only continues a run still active in the pool; interaction response ownership is atomic across double-submit and generation invalidation; Host close stops new connections, waits tracked request handlers, and terminates stale lease waiters; UI diagnostics retain only the newest 256 bounded entries. - Added exact regressions for active-run recover, delayed interaction send plus generation cancellation, holder+waiter Host shutdown, and 1,000 unknown UI events. All four planner reproductions now pass locally; PI-070 remains the sole frontier until planner re-review marks the correction Done.
- Planner independent re-review of cumulative code HEAD
31de325cd8d41b9e0e46df2cb9759f6a5086c10creturned Pass with no remaining Standards or Spec finding. PI-070 is Done; the unchanged 18-node/31-edge graph and 134 unique requirements now expose the parallel Ready Frontier{PI-080, PI-090, PI-100}. - Real Provider validation remains Explicitly Waived / Accepted Risk with
realTurnVerified=false; provider concurrency, credential isolation, and protocol compatibility are not Pass. macOS x64/arm64 remains deferred to PI-150 and is not Pass.
Verification
corepack pnpm run typecheck— passed.corepack pnpm run lint:check— passed with 0 errors; the repository's 6 pre-existing React warnings remain outside PI-070.- Focused PI-070 plus predecessor regression suite — 9 files / 41 tests passed, covering worker transport/pool/runtime, exact interaction response, stale identity, loopback bridge, lease FIFO/cancellation, draft revision, and managed opener arguments.
corepack pnpm vitest run tests/unit/pi-extension-bundle.test.ts— 1/1 passed by loading the actual materialized bundle, executing its mutation hooks, and observing real bridge lease blocking/release; a read hook bypassed the lease.corepack pnpm vitest run tests/unit/pi-worker-process-real.test.ts— 1/1 passed against locked@earendil-works/pi-coding-agent@0.84.2through the Electron Node child process with the managed extension explicitly loaded.corepack pnpm test— 199 files / 2192 tests passed before the final bundle integration test was added; that new test then passed independently, making all 200 current test files green across the two recorded runs.- Planner correction focused suite — 4 files / 9 tests passed, including all four deterministic review regressions.
- Post-correction all-Pi run — 19 files / 91 tests passed; the existing
pi-conversation-runtimeWindows temporary JSONrename EPERMoccurred in the aggregate run, then the same test passed 1/1 in isolation. No Pi behavior assertion failed. - Post-correction full suite — 199 files / 2194 tests passed; only that same
pre-existing Windows temporary-file
rename EPERMprevented a single green aggregate result. The affected runtime test passed immediately in isolation, so all 200 files / 2195 tests are green across the recorded aggregate plus isolated rerun. The failure is not in a PI-070-owned path and no retry or filesystem workaround was added. - Post-correction
corepack pnpm run typecheckandlint:check— passed; lint remains 0 errors with the same 6 unrelated warnings. - Post-correction
corepack pnpm run build:vite— passed for all four build targets with unchanged existing warnings. - Planner independent re-review — passed. It replayed all four original
failures successfully, ran the complete correction regression at 4 files /
9 tests, and passed typecheck, scoped ESLint,
build:vite, diff whitespace, project-doc, and drift checks. Source worktree and cumulative code HEAD were verified clean. corepack pnpm run build:vite— passed for Renderer, Electron Main, Preload, and release utility output. Existing dynamic-import and chunk-size warnings remain unchanged.git diff --check— passed.- Electron E2E was not applicable: PI-070 intentionally adds no Renderer or Host API route; PI-100/PI-130 own that user-visible wiring. macOS and real Provider checks were intentionally not run under the explicit decisions above.
Follow-ups
- PI-080, PI-090, and PI-100 are now simultaneously Ready and may proceed in separate owned worktrees; the DAG imposes no order among them.
- PI-100 must construct one shared
PiManagedExtensionHostfor the managed opener andPiConversationRuntime, expose sanitized interaction methods through Host API, and keep bridge tokens/leases Main-private. - PI-130 must consume safe UI projections, supply the actual per-Conversation draft revision, register only product-owned widget keys, and render terminal interaction states without exposing Pi wire payloads.
- PI-080/PI-120 child workers must use this same project lease and worker-run identity model; they must not introduce a second per-child mutation lock.
- PI-150 owns staging the managed extension in final packaged closures and the deferred macOS x64/arm64 matrix.
- Real Provider concurrency, credential isolation, authentication, abort,
image/model/session behavior, and protocol variation remain accepted
unverified risks with
realTurnVerified=false.
Promotion Candidates
- Target: Pi runtime extension and process architecture. Proposal: retain discovery-disabled startup and load exactly one explicitly materialized, versioned Makelore extension; keep its loopback endpoint, bearer token registry, run context, interactions, and diagnostics inside Electron Main. Evidence: managed opener assertions, the locked Pi 0.84.2 real-child smoke, stale-token/generation bridge tests, and the actual-bundle integration test all pass. Future impact: PI-100 and PI-150 can wire Host routes and packaging without creating a project/user plugin surface or moving Pi protocol objects into Renderer. Semantic conflicts: canonical product-state documents still describe the active OpenCode product and must not claim Pi is live before the later cutover ticket is integrated. Human confirmation required: no for the internal architecture; yes before canonical product-state text claims the Pi cutover is released.
- Target: Pi mutation concurrency architecture.
Proposal: all parent and future child
write/edit/bashexecutions for a project share one cancellable FIFO Main-owned lease; read-only tools and other projects bypass that queue. Evidence: coordinator and real HTTP/bundle tests prove same-project serialization, cross-project parallelism, cancellation, terminal release, and current-worker survival after stale identity rejection. Future impact: PI-080/PI-120 can add subagents without inventing competing locks or weakening project isolation. Semantic conflicts: none found. Human confirmation required: no. - Target: PI-130 draft and extension UI projection.
Proposal: capture draft revision at run start and apply
set_editor_textonly if the revision is unchanged; accept status/widget projections only for registered product keys and retain bounded method-only diagnostics for unknown payloads. Evidence: focused projector tests prove accepted and stale draft paths plus unknown-widget suppression without raw details. Future impact: prevents asynchronous agent UI events from overwriting newer user edits and keeps extension detail schemas product-owned. Semantic conflicts: none found. Human confirmation required: no.