feat: redesign persisted session summaries

This commit is contained in:
2026-07-23 15:35:31 +02:00
parent 12c7a976d7
commit 0db85e4e4e
12 changed files with 1090 additions and 71 deletions
@@ -0,0 +1,172 @@
# Session Summary Layout Implementation Plan
> **For Codex:** Execute this plan with `superpowers:executing-plans` and use strict
> red-green-refactor cycles from `superpowers:test-driven-development`.
**Goal:** Reorganize every persisted session summary into the approved task-oriented
order, render human-facing text as Markdown, add reliable SQL copying, and make the
session document panel independently resizable up to 50% of the application width.
**Architecture:** The harness projects filesystem and repository snapshots through
shared pure helpers so old and new sessions receive the same read-time layout without
rewriting artifacts. The frontend renders those ordered documents and owns only UI
behavior: Markdown presentation, clipboard feedback, and a dedicated persisted resize
hook wired into `AppShell`.
**Tech Stack:** Python 3.12, Typer/Pydantic, React 18, TypeScript, TanStack Query,
Vitest/Testing Library, Tailwind CSS.
---
### Task 1: Canonical session document projection
**Files:**
- Modify: `harness/tests/test_session_documents.py`
- Modify: `harness/tht/session/store.py`
**Step 1: Write failing tests**
Add focused tests that pin:
- exact ordering: original question, SQL, preview, revised question, assumptions,
memories, remaining technical documents;
- identical projection for filesystem sessions and repository snapshots;
- preview extraction only from `## Preview / aggregato`;
- split of legacy `question` Markdown at `## Assunzioni`;
- approved memories before declined memories;
- suppression of memory decisions and `phase_approved`, `table_approved`,
`table_promoted`, `column_promoted` from generic decisions.
**Step 2: Verify RED**
Run: `../harness/.venv/bin/pytest -q harness/tests/test_session_documents.py`
Expected: failures caused by the missing projection helpers and old document order.
**Step 3: Implement minimal projection helpers**
Create pure helpers in `harness/tht/session/store.py` for question splitting, preview
extraction, effective decision grouping/filtering, and canonical document assembly.
Route both `build_documents` and `build_snapshot_documents` through the same assembly
function while preserving legacy malformed-content tolerance.
**Step 4: Verify GREEN**
Run the same focused pytest command and require zero failures.
### Task 2: SQL clipboard behavior
**Files:**
- Modify: `frontend/src/viewers/SqlViewer.test.tsx`
- Modify: `frontend/src/viewers/SqlViewer.tsx`
**Step 1: Write failing tests**
Cover an always-visible accessible copy button, exact SQL clipboard payload, success
feedback, and rejection feedback that leaves SQL visible.
**Step 2: Verify RED**
Run: `npx vitest run src/viewers/SqlViewer.test.tsx`
Expected: missing copy control and feedback assertions fail.
**Step 3: Implement minimal copy control**
Add a per-block copy button using `navigator.clipboard.writeText`, with visible and
screen-reader-compatible success/failure state.
**Step 4: Verify GREEN**
Run the same focused Vitest command and require zero failures.
### Task 3: Session summary Markdown and memories
**Files:**
- Modify: `frontend/src/api/types.ts`
- Modify: `frontend/src/shell/SessionDocumentsPanel.test.tsx`
- Modify: `frontend/src/shell/SessionDocumentsPanel.tsx`
**Step 1: Write failing tests**
Cover exact API order rendering, Markdown structure for revised question and memory
subject/detail, one unified Memories section without raw decision chips, and absence of
the suppressed decision types.
**Step 2: Verify RED**
Run: `npx vitest run src/shell/SessionDocumentsPanel.test.tsx`
Expected: new memory format/Markdown assertions fail against the existing renderer.
**Step 3: Implement minimal renderer changes**
Extend the document format union if needed and render memory entries through the
existing `MarkdownView`, keeping per-document error boundaries and generic decisions
for meaningful non-memory types.
**Step 4: Verify GREEN**
Run the same focused Vitest command and require zero failures.
### Task 4: Dedicated session-panel resizing
**Files:**
- Create: `frontend/src/shell/useSessionPanelResize.ts`
- Create: `frontend/src/shell/useSessionPanelResize.test.ts`
- Modify: `frontend/src/shell/AppShell.tsx`
- Modify: `frontend/src/shell/AppShell.session-mgmt.test.tsx`
- Modify: `frontend/src/shell/SessionDocumentsPanel.tsx`
**Step 1: Write failing tests**
Pin independent storage, exact 50% maximum, 512 px right-side minimum, pointer drag,
keyboard controls, ARIA values, and hiding the divider when the desktop split is not
usable.
**Step 2: Verify RED**
Run: `npx vitest run src/shell/useSessionPanelResize.test.ts src/shell/AppShell.session-mgmt.test.tsx`
Expected: the new hook is absent and the shell lacks the session separator.
**Step 3: Implement minimal resize hook and shell wiring**
Use a session-specific local-storage key and CSS variable. Keep its drag state and
separator independent from Model activity, and apply the computed width to
`SessionDocumentsPanel` only on usable desktop layouts.
**Step 4: Verify GREEN**
Run the same focused Vitest command and require zero failures.
### Task 5: Full verification, integration, and deployment
**Files:**
- Modify only if a verification failure exposes an implementation defect.
**Step 1: Run complete gates**
- `harness/.venv/bin/pytest -q` from `harness/`
- `harness/.venv/bin/ruff check .` from `harness/`
- `node --test .pi/extensions/gate/__tests__/*.test.js` from `harness/`
- `npx vitest run` from `frontend/`
- `npx tsc -b` from `frontend/`
- `npm run build` from `frontend/`
- `git diff --check`
**Step 2: Review the diff against the approved design**
Confirm old session artifacts are projected at read time, no persisted data is
rewritten, and the session and activity separators remain independent.
**Step 3: Commit and integrate**
Commit the implementation on `codex/session-summary-layout`, merge it into `main`, and
rerun relevant verification on the merged result.
**Step 4: Deploy Docker**
From the main worktree, run `docker compose up --build --force-recreate -d core frontend`.
Verify both running image IDs match the rebuilt tags, `core` is healthy, `/` returns
HTTP 200, and `/api/health` returns HTTP 200 with status `ok`.