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:
@@ -100,10 +100,21 @@ Prerequisite: you must already be in Phase 1.
|
||||
over real values) and `tht search find --kind evidence "<term>"`. The LSH exposes
|
||||
EVERY column where a value appears — it does not collapse to a single best match,
|
||||
so a value like "ablazione" may anchor on multiple columns.
|
||||
2. For each ambiguity (clinical term, population, time window, outcome), present a
|
||||
`reviewer_select` with the candidate interpretations (`recommended:true` on the
|
||||
best) + "Altro". When a clarification is settled, move on. Pass the FULL list of
|
||||
clarifications, not only the latest, when you close.
|
||||
2. For each ambiguity (clinical term, population, time window, outcome), present the
|
||||
candidate interpretations (`recommended:true` on the best) + "Altro". Pick the widget
|
||||
by the question's shape:
|
||||
- **Exactly one interpretation is correct** (mutually exclusive) → `reviewer_select`
|
||||
(single-pick; it only asks — then record the choice with a `reviewer_decide`
|
||||
`concept_clarified`).
|
||||
- **Several answers can be simultaneously true** (e.g. more than one valid population,
|
||||
procedure code, or time window) → do NOT use `reviewer_select`: single-pick buttons
|
||||
force one answer and mislead the reviewer. Use `reviewer_decide` directly (it emits a
|
||||
**multiselect checkbox** widget), one option per candidate, each carrying its own
|
||||
`concept_clarified` decision; the reviewer checks all that apply. Keep `advance:false`
|
||||
(Phase 1 still closes via the phase gate in step 3).
|
||||
|
||||
When a clarification is settled, move on. Pass the FULL list of clarifications, not
|
||||
only the latest, when you close.
|
||||
3. To close Phase 1: `reviewer_confirm kind:"phase"` (the deliberate "I'm done
|
||||
clarifying" gate). Do NOT add a separate `reviewer_confirm` after each individual
|
||||
clarification — those advance via `reviewer_decide` (`concept_clarified`), not via
|
||||
|
||||
Reference in New Issue
Block a user