fix: use Pi user auth and handle startup failures
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
# Pi User Authentication and Startup Error Handling Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** Make Dockerized Pi consume the configured user auth store, expose four approved models, fail session startup cleanly, and remove three incomplete attempts.
|
||||
|
||||
**Architecture:** Compose mounts only the host Pi `auth.json` into the container while repository-owned Pi settings define the model policy. The backend validates the persisted model before creating a session and converts post-persistence runtime-construction errors into a failed session plus a sanitized 503.
|
||||
|
||||
**Tech Stack:** Docker Compose, Pi 0.80.3, Fastify/TypeScript, Vitest, shell deployment-contract tests.
|
||||
|
||||
## Global Constraints
|
||||
|
||||
- Never copy or log provider keys.
|
||||
- Mount the auth file read-only.
|
||||
- Enabled model order is ZAI, DeepSeek Flash, DeepSeek Pro, local Qwen.
|
||||
- UI error strings remain English.
|
||||
- Preserve the question in the frontend retry composer.
|
||||
- Delete only the three explicitly approved incomplete session IDs.
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Container Pi auth and model policy
|
||||
|
||||
**Files:**
|
||||
- Modify: `compose.yaml`
|
||||
- Modify: `.env.example`
|
||||
- Modify: `deploy/pi/settings.json`
|
||||
- Modify: `docker/core.Dockerfile`
|
||||
- Test: `scripts/test-default-compose.sh`
|
||||
- Test: `scripts/test-container-deployment.sh`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: `PI_AUTH_FILE`, an absolute readable host path.
|
||||
- Produces: `/home/thoth/.pi/agent/auth.json` read-only and a four-entry `enabledModels` policy.
|
||||
|
||||
- [ ] Add failing deployment-contract assertions for the auth mount, four enabled models, and Pi 0.80.3.
|
||||
- [ ] Run the focused shell tests and confirm the expected failures.
|
||||
- [ ] Add the configurable auth mount, model policy, environment documentation, and Pi version alignment.
|
||||
- [ ] Re-run the focused shell tests and confirm they pass.
|
||||
|
||||
### Task 2: Pre-persistence model availability guard
|
||||
|
||||
**Files:**
|
||||
- Modify: `backend/src/app.ts`
|
||||
- Modify: `backend/src/routes/sessions.ts`
|
||||
- Test: `backend/test/routes-sessions.test.ts`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: the existing `ListModelsFn` used by model/settings routes.
|
||||
- Produces: a sanitized 503 before `sessionNew` when saved settings are unavailable.
|
||||
|
||||
- [ ] Add a failing route test proving an unavailable model returns 503 and never calls `sessionNew`.
|
||||
- [ ] Run the single Vitest test and confirm the expected failure.
|
||||
- [ ] Inject the model-list dependency into session routes and implement the minimal guard.
|
||||
- [ ] Re-run the focused test and confirm it passes.
|
||||
|
||||
### Task 3: Post-persistence runtime-construction failure
|
||||
|
||||
**Files:**
|
||||
- Modify: `backend/src/routes/sessions.ts`
|
||||
- Test: `backend/test/routes-sessions.test.ts`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: `ThtRunner.failSession(id, workspace)` and `PiProcessManager.createFor`.
|
||||
- Produces: failed persisted state plus sanitized 503 when runtime construction throws.
|
||||
|
||||
- [ ] Add a failing route test for a throwing `createFor` after `sessionNew`.
|
||||
- [ ] Run the single test and confirm it fails because the route currently returns 500 and leaves the session open.
|
||||
- [ ] Catch runtime construction/binding failures, persist `failed`, and return the startup error.
|
||||
- [ ] Re-run the focused test and confirm it passes.
|
||||
|
||||
### Task 4: Cleanup and full verification
|
||||
|
||||
**Files:**
|
||||
- Modify: external PSD session store only through `tht session delete`.
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: the three approved session IDs.
|
||||
- Produces: no corresponding directories or API rows.
|
||||
|
||||
- [ ] Run backend Vitest and TypeScript typecheck.
|
||||
- [ ] Run deployment-contract tests and render Compose with the real auth path.
|
||||
- [ ] Rebuild/recreate the core container and verify health.
|
||||
- [ ] Verify `/models` returns all four enabled models in order.
|
||||
- [ ] Start a uniquely named DeepSeek smoke and observe the first reviewer gate; clean up only the smoke.
|
||||
- [ ] Delete the three approved incomplete sessions and verify they are absent.
|
||||
- [ ] Run `git diff --check` and inspect the final diff for secret leakage.
|
||||
@@ -0,0 +1,46 @@
|
||||
# Pi User Authentication and Startup Error Handling
|
||||
|
||||
## Goal
|
||||
|
||||
Make the Dockerized ThothII runtime use the same provider authentication that Pi stores for
|
||||
the host user, expose only the explicitly enabled model set (including DeepSeek V4 Pro), and
|
||||
avoid leaving apparently healthy `open` sessions when model startup cannot begin.
|
||||
|
||||
## Runtime configuration
|
||||
|
||||
- Keep the container user `thoth` and `HOME=/home/thoth`; those are valid container-local
|
||||
identities and must not be changed to a macOS path.
|
||||
- Bind-mount a configurable host Pi auth file, `PI_AUTH_FILE`, to
|
||||
`/home/thoth/.pi/agent/auth.json` read-only. The default local value is
|
||||
`${HOME}/.pi/agent/auth.json`; deployments may override it with another absolute path.
|
||||
- Keep `deploy/pi/settings.json` as the non-secret runtime policy. It must enable, in order:
|
||||
`zai/glm-5.2`, `deepseek/deepseek-v4-flash`, `deepseek/deepseek-v4-pro`, and
|
||||
`aritmolab/qwen3.6-35b-a3b`.
|
||||
- Keep `deploy/pi/models.json` for custom provider definitions only. Provider credentials stay
|
||||
exclusively in Pi's user auth file and are never copied into the repository.
|
||||
- Run Pi 0.80.3 in the core image, matching the audited backend provider contract.
|
||||
|
||||
## Session-start behavior
|
||||
|
||||
The settings write endpoint remains the main model-validation boundary. Session creation adds a
|
||||
defense-in-depth availability check before persistence: if the saved provider/model is absent
|
||||
from Pi's current enabled and authenticated model list, return a sanitized 503 and do not call
|
||||
`tht session new`.
|
||||
|
||||
If runtime construction fails after persistence despite that check (for example a race or local
|
||||
process limit), catch the error, mark the just-created session failed, and return the same
|
||||
sanitized startup error. Never expose provider credentials or raw Pi errors to the browser.
|
||||
Asynchronous bootstrap failures continue to emit `session_failed` and persist failed state.
|
||||
|
||||
## Cleanup and verification
|
||||
|
||||
Delete only these incomplete sessions:
|
||||
|
||||
- `a390c8b8-0a91-4a37-967b-ce7ff9be9797`
|
||||
- `a2f974b2-4c48-4967-b4b6-afdbc2b2d541`
|
||||
- `f66e1959-3c71-4b10-8aa1-606992046b7e`
|
||||
|
||||
Verify configuration contracts, backend tests and typecheck, rendered Compose mounts, `/models`
|
||||
containing all four configured models, and a live DeepSeek startup reaching its first reviewer
|
||||
gate. The auth file must remain read-only and no secret value may appear in rendered Compose,
|
||||
logs, tests, or source control.
|
||||
Reference in New Issue
Block a user