fix: clarify memory selection semantics

This commit is contained in:
User
2026-07-14 13:13:59 +02:00
parent 1e3c5a1e99
commit c7d586aaf7
10 changed files with 205 additions and 24 deletions
@@ -0,0 +1,115 @@
# Memory Selection Clarity 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 Phase 2 memory checkboxes mean only “apply this memory now”, with recommended memories preselected and unselected memories left undecided.
**Architecture:** The Pi gate converts each `recommended:true` Phase 2 option into the existing multiselect descriptor’s `selected` flag. The shared React multiselect keeps its generic behavior, while Phase 2 supplies explicit Italian selection and confirmation copy through descriptor fields. Only selected IDs continue to create decisions; omitted IDs remain non-persisting.
**Tech Stack:** Pi extension JavaScript (`node:test`), React 18/TypeScript, Vitest.
## Global Constraints
- UI copy is English except workspace/document content; this Phase 2 reviewer prompt is workspace-language Italian and stays Italian.
- No unselected memory may create `memory_rejected` or any other decision.
- Keep the generic multiselect compatible with existing widgets.
---
### Task 1: Carry recommendations into checked Phase 2 options
**Files:**
- Modify: `harness/.pi/extensions/tht-gate.js:686-750`
- Test: `harness/.pi/extensions/gate/__tests__/gate_reviewer_decide.test.js`
**Interfaces:**
- Consumes: `reviewer_decide.options[].recommended?: boolean`.
- Produces: a multiselect descriptor whose recommended option IDs occur in `selected`, and whose Phase 2 title/action communicate application only.
- [ ] **Step 1: Write the failing test**
Exercise the gate with one recommended and one optional decision, capture its UI request, and assert `selected` is the recommended ID, the title asks to select memories to apply, and `confirm_label` is `Applica le memory selezionate`.
- [ ] **Step 2: Run test to verify it fails**
Run: `node --test harness/.pi/extensions/gate/__tests__/gate_reviewer_decide.test.js`
Expected: FAIL because the descriptor has no `selected` recommendation mapping or memory-specific copy.
- [ ] **Step 3: Write minimal implementation**
In `reviewer_decide`, map each recommended option to `selected: true` before calling `buildMultiselectRequest`; add optional `selection_label` and `confirm_label` fields to the descriptor only for the F2 memory title.
- [ ] **Step 4: Run the gate tests**
Run: `node --test harness/.pi/extensions/gate/__tests__/*.test.js`
Expected: PASS.
### Task 2: Render Phase 2 action copy without changing generic multiselect behavior
**Files:**
- Modify: `frontend/src/api/types.ts`
- Modify: `frontend/src/widgets/MultiselectWidget.tsx`
- Test: `frontend/src/widgets/MultiselectWidget.test.tsx`
**Interfaces:**
- Consumes: optional `WidgetDescriptor.selection_label?: string` and `WidgetDescriptor.confirm_label?: string`.
- Produces: supplied labels in the count and confirm button; absent labels retain `selected` and `Confirm`.
- [ ] **Step 1: Write the failing test**
Render a descriptor with one checked recommended memory and the custom labels. Assert the checkbox is checked, the count reads `1 / 2 memory da applicare`, and confirmation uses `Applica le memory selezionate` while emitting only checked IDs.
- [ ] **Step 2: Run test to verify it fails**
Run: `cd frontend && npx vitest run src/widgets/MultiselectWidget.test.tsx`
Expected: FAIL because the descriptor type and component ignore the custom labels.
- [ ] **Step 3: Write minimal implementation**
Add the two optional descriptor fields and use them with the existing generic strings as fallbacks. Do not alter checkbox response semantics.
- [ ] **Step 4: Run widget test and typecheck**
Run: `cd frontend && npx vitest run src/widgets/MultiselectWidget.test.tsx && npx tsc -b`
Expected: PASS.
### Task 3: Align the Phase 2 model instructions with implementation
**Files:**
- Modify: `harness/.pi/skills/tht-sessione/memoria.md`
- Modify: `harness/.pi/skills/tht-sessione/SKILL.md`
**Interfaces:**
- Consumes: selected options are applied; omitted options are not applied now.
- Produces: instructions that never ask the model to create a negative “do not use” option or a persistent rejection for unchecked memories.
- [ ] **Step 1: Update the memory checklist contract**
State that every row describes a candidate memory declaratively, `recommended:true` preselects only memories proposed for use, and unchecked candidates are not applied now and may be considered again after a reopen.
- [ ] **Step 2: Verify no obsolete rejection instruction remains**
Run: `rg -n "deselected.*memory_rejected|deselezionate.*memory_rejected|mem_id" harness/.pi/skills/tht-sessione`
Expected: no matches.
### Task 4: Full verification
**Files:**
- Verify only.
- [ ] **Step 1: Run focused gate and frontend checks**
Run: `node --test harness/.pi/extensions/gate/__tests__/*.test.js && cd frontend && npx vitest run src/widgets/MultiselectWidget.test.tsx && npx tsc -b`
Expected: all commands exit 0.
- [ ] **Step 2: Review the diff**
Run: `git diff --check && git diff -- harness/.pi/extensions/tht-gate.js frontend/src/api/types.ts frontend/src/widgets/MultiselectWidget.tsx harness/.pi/skills/tht-sessione`
Expected: no whitespace errors; changes only implement the clarified memory-selection contract.