204 lines
11 KiB
Markdown
204 lines
11 KiB
Markdown
# Task: Fix packaged Pi proxy token initialization and recovery
|
|
|
|
## Identity
|
|
|
|
- Task ID: 20260824-pi-runtime-unavailable-hotfix-4e9c7a31
|
|
- Mode: Feature
|
|
- Branch: codex/20260824-pi-runtime-unavailable-hotfix-4e9c7a31-pi-runtime-unavailable-hotfix
|
|
- Worktree: D:\Datas\OthersProjects\makelore-pi-runtime-unavailable-hotfix-4e9c7a31
|
|
- Base commit: fa510c49761485cbd323801923dbe2472d6981bb
|
|
- Owner: codex-root
|
|
- Status: Ready for Integration
|
|
|
|
## Scope
|
|
|
|
- Fix the Windows packaged Pi startup failure for the
|
|
`works_square_ai_gateway_proxy` account without changing the OpenCode-to-Pi
|
|
architecture or starting PI-160.
|
|
- Resolve the Main Host API credential lazily for persistent parent open,
|
|
rebuild/recover, and ephemeral child open; preserve Main ownership and prove
|
|
token rotation does not reuse a captured value.
|
|
- Map Pi's typed `PROVIDER_AUTH_REQUIRED` failure through the existing single
|
|
refresh/reopen boundary, and make Renderer Conversation recovery failure
|
|
leave `recovering` for a retryable per-Conversation error without losing
|
|
user state.
|
|
- Produce and verify a Windows x64 NSIS installer from the final clean
|
|
candidate, including a real packaged Main-composition proxy first-
|
|
Conversation proof and token non-disclosure checks.
|
|
|
|
## Intent And Constraints
|
|
|
|
- Base exactly on `fa510c49761485cbd323801923dbe2472d6981bb`, which is the
|
|
common HEAD of the PI-150 release-proof and diagnostic worktrees and contains
|
|
code candidate `09841c8`; do not rewrite or drop cumulative PI-150 history.
|
|
- Do not modify the old PI-150 worktree, diagnostic worktree, occupied/dirty
|
|
`main`, or the user's installed application under
|
|
`D:\Tools\泥土\niancode\Makelore`.
|
|
- Keep the Host token Main-owned and memory-only. Never write it to argv,
|
|
`models.json`, logs, diagnostics, task evidence, or Renderer state.
|
|
- Do not upgrade Pi, add a fallback/compatibility layer, refactor Host auth, or
|
|
change direct API-key, OAuth, or local Provider behavior.
|
|
- Real Provider verification remains `Explicitly Waived / Accepted Risk` with
|
|
`realTurnVerified=false`; macOS and native non-WSL Linux gate status is
|
|
unchanged.
|
|
- Use the exact package-manager version pinned by `packageManager`, frozen
|
|
install semantics, focused regressions, full repository verification, and
|
|
the formal Windows packaging path.
|
|
|
|
## Project Context Loaded
|
|
|
|
- Concurrent Task Gate: Passed in the isolated worktree above; ownership is
|
|
`codex-root`, feature mode, and the task record matches the registry.
|
|
- Planning Gate: Passed after reading the diagnostic record, PI-150 source
|
|
record, memory index, positioning/current-state/decision/architecture/domain/
|
|
evidence/reflection/commitment/stale records, and all active peer scopes.
|
|
- The shared canonical snapshot is older than the Pi feature chain. The
|
|
diagnostic record, cumulative PI-150 source record, current source, and the
|
|
delegated repair boundary are authoritative for this task.
|
|
- Other active tasks use separate worktrees. The main-worktree integration task
|
|
concerns the older OpenCode model-switch path and explicitly does not package;
|
|
no semantic conflict requires changing this hotfix plan.
|
|
- No subagents are used by explicit user direction.
|
|
|
|
## Plan
|
|
|
|
1. Inspect the exact composition, opener, auth-classifier, recovery-store, test,
|
|
Windows Electron E2E, and packaged proof seams; identify the smallest
|
|
production and test surface.
|
|
2. Add red-capable focused regressions for lazy/current token reads across
|
|
parent/rebuild/recover/child, typed auth mapping and bounded refresh, recovery
|
|
failure/retry, and unaffected direct/OAuth/local Provider paths.
|
|
3. Implement the lazy Main-owned credential getter, typed error classification,
|
|
and retryable recovery-state transition with surgical changes only.
|
|
4. Run focused tests, typecheck, lint, the full unit suite, production build,
|
|
and Windows Electron E2E; fix only failures caused by this hotfix.
|
|
5. Commit the clean implementation candidate, run formal `package:win`, execute
|
|
Windows artifact/runtime closure checks, and run a final packaged Main-
|
|
composition proxy first-Conversation proof including token-secrecy and clean
|
|
process-exit assertions.
|
|
6. Record exact commits, changed files, verification results, NSIS size/hash,
|
|
structured packaged evidence and unchanged release waivers; pass the Task
|
|
Documentation Gate and mark the task ready for integration.
|
|
|
|
## Outcome
|
|
|
|
- Implemented a lazy `getLocalProxyCredential` seam from Electron Main through
|
|
the single coding composition. Composition construction no longer reads or
|
|
captures the pre-server token; persistent parent first-open, recover/rebuild,
|
|
and ephemeral child open all resolve the getter at the worker-open boundary.
|
|
- Extended the existing typed Provider-auth classifier to recognize only
|
|
`PiProviderConfigError.code === PROVIDER_AUTH_REQUIRED`. Initial prepare and
|
|
prompt authentication failures now use the existing maximum-one refresh and
|
|
reopen coordinator and project as `CODING_PROVIDER_AUTH_REQUIRED`.
|
|
- Made Renderer recovery failures leave `recovering` for the target
|
|
Conversation's retryable `error` state while preserving the selected
|
|
Conversation, last good Snapshot, draft, and attachments; a later retry can
|
|
recover normally.
|
|
- Added focused rotation/non-disclosure regressions for parent first-open,
|
|
recover, rebuild, and child open while retaining the pre-existing direct
|
|
API-key/OAuth/local credential coverage.
|
|
- Extended the final packaged proof entry so the actual global Main composition
|
|
can exercise `works_square_ai_gateway_proxy` through the current authenticated
|
|
Host proxy, create the first Conversation from the real UI, establish a Pi
|
|
binding, accept input, dispatch a real packaged parent and child, and verify
|
|
argv/models/log/diagnostic token non-disclosure. Its upstream is controlled
|
|
loopback and the report remains `realTurnVerified=false`.
|
|
- The first packaged proxy run additionally proved that Host authentication was
|
|
accepted but exposed a second Windows release blocker: Pi's Node fetch adds
|
|
`sec-fetch-mode: cors`, and forwarding that transport-owned header into
|
|
Electron `net.fetch` fails with `net::ERR_INVALID_ARGUMENT` before the
|
|
upstream receives the request. The Host proxy now drops only that header;
|
|
direct API-key/OAuth/local Provider behavior and the no-mutation-replay rule
|
|
are unchanged.
|
|
- Generated and verified the final Windows x64 NSIS from clean candidate
|
|
`34a4434cfb3b6d083259f27dde065e78d4e0054f`. The final packaged global-Main
|
|
proxy proof passed and all proof Electron/Pi processes exited.
|
|
|
|
## Commits
|
|
|
|
- `f902edefd0026fc8b003d4769c4eb1c064243880` — lazy Main Host token,
|
|
typed Provider auth mapping, retryable recovery state, focused regressions,
|
|
and the packaged global-Main proxy proof path.
|
|
- `34a4434cfb3b6d083259f27dde065e78d4e0054f` — drop Pi/Undici's
|
|
`sec-fetch-mode` transport header before Electron upstream forwarding and use
|
|
an actionable real-UI send in the packaged proof harness.
|
|
|
|
## Changed Files
|
|
|
|
- `.project-docs/30-worklog/tasks/20260824-pi-runtime-unavailable-hotfix-4e9c7a31.md`
|
|
- `electron/api/coding-composition.ts`
|
|
- `electron/api/coding-provider-auth.ts`
|
|
- `electron/api/routes/ai-proxy.ts`
|
|
- `electron/coding-runtime/pi/release-proof.ts`
|
|
- `electron/main/index.ts`
|
|
- `scripts/run-pi-subagent-packaged-smoke.mjs`
|
|
- `src/stores/coding-conversations.ts`
|
|
- `tests/unit/ai-proxy-routes.test.ts`
|
|
- `tests/unit/coding-conversations-store.test.tsx`
|
|
- `tests/unit/coding-core-routes.test.ts`
|
|
- `tests/unit/coding-provider-auth.test.ts`
|
|
- `tests/unit/pi-managed-worker-opener.test.ts`
|
|
- `tests/unit/pi-runtime-auth-recovery.test.ts`
|
|
- `tests/unit/pi-subagent-child.test.ts`
|
|
|
|
## Verification
|
|
|
|
- `corepack pnpm install --frozen-lockfile` with pinned pnpm `10.33.4`: passed,
|
|
997 packages linked from the existing store and the lockfile remained
|
|
unchanged.
|
|
- Focused Vitest run for proxy forwarding, composition, auth, Renderer recovery,
|
|
parent opener, child opener, and auth recovery: 7 files / 66 tests passed.
|
|
The initial hotfix red
|
|
run failed exactly on typed auth classification, auth-required projection,
|
|
and permanent `recovering` state.
|
|
- `corepack pnpm run typecheck`: passed after the final proof changes.
|
|
- `corepack pnpm run lint:check`: passed with 0 errors and 5 pre-existing React
|
|
warnings in `src/pages/Home/index.tsx` and `src/pages/Makelore/index.tsx`.
|
|
- `corepack pnpm test`: passed; primary run 178 files / 1512 passed / 2 skipped,
|
|
serialized pressure run 1 file / 1 passed.
|
|
- `corepack pnpm run build:vite`: passed; Renderer, Main, Preload, and release
|
|
utility bundles built. Existing dynamic-import and large-chunk warnings remain.
|
|
- `corepack pnpm run test:electron:windows`: passed; 2 files / 4 tests.
|
|
- `corepack pnpm run package:win`: passed from clean candidate
|
|
`34a4434cfb3b6d083259f27dde065e78d4e0054f`; produced
|
|
`Makelore-2.0.0-win-x64.exe`, 211,888,141 bytes, SHA-256
|
|
`3A1335A6DEFDEBE53A84EA558E6A000DBD538C568EB9AFB202893AA4D82858B2`.
|
|
- `corepack pnpm run verify:artifact:win`: passed. The unpacked product runs
|
|
Electron `43.4.0` / Node `24.18.1`; bundled Python, pip, sqlite3, SSL,
|
|
`uv 0.10.0`, npm `11.6.2`, msgpackr, and x64 canvas load from the product.
|
|
- `corepack pnpm run verify:artifact:pi -- --samples 2`: passed. Final
|
|
`app.asar`, Pi `0.84.2` CLI, all 130 expected production packages, 6 runtime
|
|
assets, 5 native assets outside ASAR, 4 managed Skills, and the materialized
|
|
extension/subagent contract are present and executable. The nested runtime
|
|
report remains `partial-pass` only for the pre-existing explicit real-
|
|
Provider/macOS/Linux waivers; the artifact verifier result is `pass`.
|
|
- `corepack pnpm run test:pi-subagent:packaged`: passed against the final
|
|
unpacked executable. The actual packaged `app.asar` Main composition used
|
|
`works_square_ai_gateway_proxy`, created exactly one first Conversation,
|
|
established its Pi binding, projected the submitted user input and
|
|
`REAL_PARENT_COMPLETE`, and settled at worker `ready` / run `idle`.
|
|
Parent and child each reached the controlled upstream through the current
|
|
authenticated Host proxy; the token was absent from argv, `models.json`,
|
|
logs, and diagnostics. The UI remained editable with neither runtime-
|
|
unavailable nor permanent-recovering state. Cleanup reported zero retained
|
|
workers, and an independent Windows process query found zero proof Electron/
|
|
Pi processes.
|
|
- Pre-final packaged attempts were not counted as passes: the first used an
|
|
unsupported optional embedded-commit assertion, and the real proxy run then
|
|
failed on `net::ERR_INVALID_ARGUMENT`; that failure directly produced the
|
|
`sec-fetch-mode` regression and the final package/proof rerun above.
|
|
|
|
## Follow-ups
|
|
|
|
- Real external Provider turn verification remains explicitly waived and its
|
|
concurrency, credential-isolation, and protocol-compatibility risk remains
|
|
accepted; the loopback Host-proxy proof must not be reported as a real
|
|
Provider pass.
|
|
- macOS and native non-WSL Linux release gates remain unchanged by this Windows
|
|
hotfix.
|
|
|
|
## Promotion Candidates
|
|
|
|
- None. This feature task records the hotfix and evidence locally; it does not
|
|
promote stale shared OpenCode-era canonical documents.
|