# 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`.