fix(backend): echo Pi's RPC id so reviewer gates unblock after answer
ctx.ui.input in `pi --mode rpc` correlates extension_ui_response on its own
top-level RPC id (crypto.randomUUID), not the descriptor id the gate carries
in `title`. SessionBridge replied with the descriptor id, so Pi silently
dropped the response and the model never resumed — every reviewer widget hung
after the human answered.
SessionBridge now stores Pi's top-level m.id (pendingPiId) and replies
extension_ui_response{ id: pendingPiId, value: <uiResponse> }; value still
carries the descriptor id so the gate's internal resp.id === descriptor.id
check still holds.
The fake-pi double had masked the bug by forcing m.id == descriptor.id; it now
mirrors real Pi (distinct randomUUID, correlate on it, drop unknown ids), with
a negative regression test. SKILL.md Phase 1 also now steers multi-answer
disambiguation to reviewer_decide (multiselect).
Tests: backend 67/67, tsc clean, fake-pi contract 2/2.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+48
-4
@@ -1,6 +1,6 @@
|
||||
# ThothII — Project State
|
||||
|
||||
> Starting-point snapshot for new sessions. Last updated: 2026-06-29.
|
||||
> Starting-point snapshot for new sessions. Last updated: 2026-06-30.
|
||||
> Point a fresh session here ("read PROJECT_STATE.md") before substantial work.
|
||||
|
||||
## What ThothII is
|
||||
@@ -53,7 +53,7 @@ Opens frontend at http://localhost:5173 → backend :8787.
|
||||
- frontend: `cd frontend && npm run dev` (Vite; `VITE_BACKEND_URL` → backend)
|
||||
- harness install: `cd harness && python -m venv .venv && pip install -e ".[dev]"` → `tht` on PATH
|
||||
|
||||
## How to test (all green as of 2026-06-29: harness 248 / backend 59 / frontend 73)
|
||||
## How to test (all green as of 2026-06-29: harness 248 / backend 67 / frontend 73)
|
||||
- harness: `cd harness && .venv/bin/pytest -q` (5 L2/real-DB tests are deselected by default)
|
||||
- backend: `cd backend && npx vitest run` · typecheck `npx tsc --noEmit -p .`
|
||||
- frontend: `cd frontend && npx vitest run` · typecheck `npx tsc -b` · e2e `npm run e2e` (Playwright)
|
||||
@@ -78,6 +78,40 @@ Opens frontend at http://localhost:5173 → backend :8787.
|
||||
- Global user rules (`~/.claude/CLAUDE.md`): think before coding, simplicity first, surgical
|
||||
changes, goal-driven verification.
|
||||
|
||||
## Most recent work — F1 reviewer-widget hang fix + multiselect guidance (committed 2026-06-30; authored 2026-06-29)
|
||||
|
||||
Two fixes, **committed to `main`** (7 files):
|
||||
|
||||
1. **Bug: every reviewer widget hung "stuck with no output" after the human answered** — F1
|
||||
disambiguation (and any gate) dead-ended. Root cause, confirmed from Pi's own source
|
||||
(`@mariozechner/pi-coding-agent` `dist/modes/rpc/rpc-mode.js`, `createDialogPromise`):
|
||||
`ctx.ui.input` assigns its OWN RPC id (`crypto.randomUUID`) and correlates
|
||||
`extension_ui_response` on THAT id, silently dropping unknown ids. The gate puts a
|
||||
different id (`u${Date.now()}`) inside the descriptor carried in `title`. `SessionBridge`
|
||||
was replying with the **descriptor** id, so real Pi never resolved `ctx.ui.input` → the
|
||||
model never continued. **Fix:** `SessionBridge` now stores Pi's top-level `m.id`
|
||||
(`pendingPiId`) on the incoming request and replies `extension_ui_response{ id: pendingPiId,
|
||||
value: <uiResponse JSON> }` (value still carries the descriptor id, so the gate's internal
|
||||
`resp.id === descriptor.id` check holds). File: `backend/src/bridge/session-bridge.ts`.
|
||||
Full write-up: memory `pi-ui-input-id-correlation.md`.
|
||||
- **The test double was masking it:** `harness/tests/fake_pi/fake_pi_rpc.mjs` had forced
|
||||
`m.id == descriptor.id`. Corrected to mirror real Pi (distinct `randomUUID` top-level id,
|
||||
correlate on it, drop unknown ids); `test_fake_pi_contract.mjs` gained a negative
|
||||
regression test ("respond with descriptor id → no follow-up").
|
||||
- TDD: `backend/test/session-bridge.test.ts` (unit) + `backend/test/e2e-f1.test.ts`
|
||||
(integration — now asserts the model's follow-up arrives after the answer) went
|
||||
RED→GREEN.
|
||||
|
||||
2. **UX: multi-answer disambiguation** — `harness/.pi/skills/tht-sessione/SKILL.md` Phase 1
|
||||
now tells the model to use `reviewer_decide` (the existing multiselect/checkbox widget)
|
||||
when an ambiguity admits several simultaneously-true answers, instead of single-pick
|
||||
`reviewer_select`. Guidance-only — no new widget (`frontend MultiselectWidget` already
|
||||
exists).
|
||||
|
||||
Verified this session: backend `npx vitest run` **67/67 green**; `tsc --noEmit -p .` **OK**;
|
||||
fake-pi contract `node --test test_fake_pi_contract.mjs` **2/2 green**. Harness pytest and
|
||||
frontend NOT re-run (untouched by these changes). **NOT verified live** — see open item 4.
|
||||
|
||||
## Most recent feature — Session management (MERGED to main @ 2c21e46)
|
||||
Full session management modeled on Claude's UI, all three layers:
|
||||
- **Read-only "split view" panel** (left drawer, `SessionDocumentsPanel`) showing a session's
|
||||
@@ -102,6 +136,15 @@ Full session management modeled on Claude's UI, all three layers:
|
||||
(today gated by `load_session`); `close_session` could reuse `_save_touched` (DRY);
|
||||
delete-via-kebab integration test skipped (base-ui Menu portal not drivable in jsdom —
|
||||
the dialog itself is unit-tested); a couple of test-file lint nits.
|
||||
4. **Live-verify the F1 reviewer-widget hang fix (committed 2026-06-30).** The fix is committed
|
||||
and proven against Pi's source + a now-faithful fake, but the browser round-trip is still
|
||||
unproven. With VPN up: start the stack, drive an F1 session past the first answer, confirm
|
||||
the widget unblocks and the model continues. (On 2026-06-29 DWH REST was unreachable with
|
||||
VPN off, so the live e2e couldn't run; Ollama was reachable and `pi` present.)
|
||||
5. **Model caveat (likely "struggles to finish the task" symptom).** Settings use
|
||||
`deepseek-v4-flash` (thinking high) but the harness is tuned for GLM 5.2, and F1 needs
|
||||
many autonomous tool calls; even with the hang fixed a "flash" model may not complete F1.
|
||||
Separate config decision — try GLM 5.2 when validating live.
|
||||
|
||||
## Where design history lives
|
||||
- Specs: `docs/superpowers/specs/` · Plans: `docs/superpowers/plans/`
|
||||
@@ -110,5 +153,6 @@ Full session management modeled on Claude's UI, all three layers:
|
||||
(notes on the Pi RPC event vocabulary and the Omics Portal/GSD design system).
|
||||
|
||||
## Git
|
||||
`main` @ `2c21e46`, pushed to `origin` (github.com/mptyl/ThothII), in sync. Other local
|
||||
branches (`feat/settings-menu`, `feat/thothII-debugging`) are pre-existing, untouched.
|
||||
`main` tracks `origin` (github.com/mptyl/ThothII). The F1 hang-fix (7 files + this
|
||||
`PROJECT_STATE.md`) is **committed on `main` on top of `4f60b38`, not yet pushed**. Other
|
||||
local branches (`feat/settings-menu`, `feat/thothII-debugging`) are pre-existing, untouched.
|
||||
|
||||
Reference in New Issue
Block a user