feat(coding-runtime): add managed Pi extension host
This commit is contained in:
@@ -0,0 +1,190 @@
|
||||
# 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: 47159b3cbdf06ea66db9a4425e0a9c13bcd73f7f
|
||||
- Owner: codex
|
||||
- Status: Completed — pending planner review
|
||||
|
||||
## Scope
|
||||
|
||||
- Implement `PI-070 — Managed extension host, interactions, and write lease`
|
||||
from the `【架构】opencode2pi` Spec/ticket graph on cumulative baseline
|
||||
`47159b3cbdf06ea66db9a4425e0a9c13bcd73f7f`.
|
||||
- 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`, ticket `PI-070`, and
|
||||
Spec `LEASE-001` through `LEASE-006`, `EXT-001` through `EXT-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_user` supports 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
|
||||
|
||||
1. 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.
|
||||
2. Implement the versioned managed extension bundle plus authenticated worker
|
||||
registry/bridge and prove real bridge round trips and stale identity rejection.
|
||||
3. Implement interaction storage/projection and the cancellable project write
|
||||
lease, then wire generation/run cleanup into the runtime without widening
|
||||
Host/Renderer interfaces.
|
||||
4. 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.mjs` bundle and
|
||||
changed Pi startup from `--no-tools` to an explicit built-in plus
|
||||
`ask_user` allowlist. 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_user` tool for select, confirm,
|
||||
input, and editor requests. Pi's fire-and-forget
|
||||
`extension_ui_response` records now use a dedicated one-way transport seam
|
||||
rather than pretending to be request/response commands.
|
||||
- Added a Host-side `PiInteractionStore` with 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 `PiProjectWriteLeaseCoordinator` and extension hooks that make
|
||||
`write`, `edit`, and `bash` share 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.
|
||||
- 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.2` through 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.
|
||||
- `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-100 must construct one shared `PiManagedExtensionHost` for the managed
|
||||
opener and `PiConversationRuntime`, 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`/`bash` executions 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_text`
|
||||
only 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.
|
||||
Reference in New Issue
Block a user