From a4a24de83670c9c0cb2ef5dd19e006b60c916ae9 Mon Sep 17 00:00:00 2001 From: Shay Date: Thu, 28 May 2026 07:58:44 -0700 Subject: [PATCH] docs(workbench): add wave-1 brief pack for Phase 1 polish Four parallel-safe briefs covering Chat/Proposals/Replay/Evals polish, each with operator assignment, dispatch line, doctrine refs, owned-files scope, acceptance criteria, and validation commands. Operator assignment: - 1a Chat polish -> Opus 4.6 (surface contract sensitive) - 1b Proposals polish-> Sonnet 4.6 (tight-scope lifecycle) - 1c Replay polish -> Gemini 3.1 Pro (cross-file presentation) - 1d Evals polish -> GPT-OSS-120B / Copilot (mechanical) All four are dispatchable simultaneously. No order dependency. --- .../workbench-ui/wave-1/1a-chat-polish.md | 112 +++++++++++++++++ .../wave-1/1b-proposals-polish.md | 111 +++++++++++++++++ .../workbench-ui/wave-1/1c-replay-polish.md | 111 +++++++++++++++++ .../workbench-ui/wave-1/1d-evals-polish.md | 114 ++++++++++++++++++ docs/handoff/workbench-ui/wave-1/README.md | 110 +++++++++++++++++ 5 files changed, 558 insertions(+) create mode 100644 docs/handoff/workbench-ui/wave-1/1a-chat-polish.md create mode 100644 docs/handoff/workbench-ui/wave-1/1b-proposals-polish.md create mode 100644 docs/handoff/workbench-ui/wave-1/1c-replay-polish.md create mode 100644 docs/handoff/workbench-ui/wave-1/1d-evals-polish.md create mode 100644 docs/handoff/workbench-ui/wave-1/README.md diff --git a/docs/handoff/workbench-ui/wave-1/1a-chat-polish.md b/docs/handoff/workbench-ui/wave-1/1a-chat-polish.md new file mode 100644 index 00000000..2ae2766e --- /dev/null +++ b/docs/handoff/workbench-ui/wave-1/1a-chat-polish.md @@ -0,0 +1,112 @@ +# Brief 1a — Chat route polish + +> **Operator:** Opus 4.6 (foundations / surface-contract sensitive) +> **Branch:** `workbench/wave-1a-chat-polish` +> **Base:** `feat/workbench-ui-continuation` @ `685aaae` +> **Estimated diff:** ~150–300 lines, UI only +> **Why this operator:** Chat is the one Phase 1 brief that touches the +> Runtime Surface Contract (`surface` / `walk_surface` / `articulation_surface`). +> Distinguishing those correctly under the addendum §2 is high-stakes. + +--- + +## Dispatch line + +```bash +git fetch origin && \ +git worktree add /Users/kaizenpro/Projects/core-w1a-chat \ + -b workbench/wave-1a-chat-polish origin/feat/workbench-ui-continuation && \ +cd /Users/kaizenpro/Projects/core-w1a-chat/workbench-ui && \ +pnpm install +``` + +Then open the worktree in your editor and start. + +--- + +## Doctrine refs (read before touching code) + +- `docs/plans/workbench-ui-continuation.md` §Phase 1a +- `docs/plans/workbench-ui-continuation-addendum.md` §1 (Chat trust class), + §2 (Trace surface contract — applies to Chat's trace drawer), §7 (PR checklist) +- `docs/runtime_contracts.md` — surface distinction and `trace_hash` stability + +## Scope (owned files) + +- `src/app/chat/**` — everything in this folder +- Test files colocated with the above + +## May read (no edits) + +- `src/types/api.ts` (append-only at the bottom of the chat section if + new types are needed) +- `src/api/queries.ts` (no edits; this brief does not add hooks) + +## Off-limits + +- `src/design/**` +- `src/app/Shell.tsx`, `App.tsx`, `LeftNav.tsx`, `TopBar.tsx`, `StatusFooter.tsx` +- Any backend Python file +- Any placeholder file in `src/routes/` + +## Tasks + +- [ ] **State audit.** Walk every async surface in `src/app/chat/` and confirm + it has loading, empty, and error states. Where missing, add them using + `EmptyState` from `src/design/`. +- [ ] **Surface distinction.** Inspect the trace drawer / evidence panel. The + three surfaces — `surface`, `walk_surface`, `articulation_surface` — + must render as three distinct UI elements with labels the operator can + tell apart at a glance. If currently conflated, separate them. +- [ ] **Navigation hardening.** From a turn response: + - clicking `trace_hash` opens the trace drawer at that turn, + - any proposal candidate links to its detail in the Proposals route + (use the existing route path; do not invent a new one). +- [ ] **⌘K commands.** Confirm or add palette entries for `New chat session` + and `Jump to proposal `. Entries belong to chat; do not edit other + features' entries. +- [ ] **Trace-hash stability test.** Add a test asserting that mounting the + trace drawer, navigating nodes, and unmounting does not mutate any + `trace_hash` value held in component state. This is the addendum §2 + proof obligation. +- [ ] **Tests for new interaction paths.** Use the existing `Shell.test.tsx` + pattern: render under MemoryRouter + QueryClientProvider, drive + interactions through `@testing-library/react`. + +## Acceptance criteria + +- Every async surface in `src/app/chat/` has loading + empty + error states. +- Trace drawer labels `surface` / `walk_surface` / `articulation_surface` + distinctly. A reviewer should be able to point at each on screen. +- `trace_hash` stability test exists and passes. +- ⌘K entries for `New chat session` and `Jump to proposal` are present and + keyboard-activatable. +- No edits to off-limits files. `git diff --stat` shows only `src/app/chat/` + and (optionally) `src/types/api.ts` append-only. +- `pnpm test` and `pnpm test:enum-coverage` green. + +## Validation + +```bash +cd workbench-ui +pnpm install +pnpm test +pnpm test:enum-coverage +git diff --stat $(git merge-base HEAD origin/feat/workbench-ui-continuation)..HEAD +``` + +The diff-stat output must include only `src/app/chat/**` and optionally +appended lines in `src/types/api.ts`. Anything else is out of scope. + +## PR + +Title: `feat(workbench/chat): polish states, surface distinction, ⌘K (wave 1a)` + +Body uses the template in `docs/handoff/workbench-ui/wave-1/README.md`. + +## When done + +- [ ] PR open against `feat/workbench-ui-continuation` +- [ ] CI green +- [ ] Mark this brief complete by checking the box in this file in a follow-up + commit on the same PR (single source of truth: this file) diff --git a/docs/handoff/workbench-ui/wave-1/1b-proposals-polish.md b/docs/handoff/workbench-ui/wave-1/1b-proposals-polish.md new file mode 100644 index 00000000..6b48ccec --- /dev/null +++ b/docs/handoff/workbench-ui/wave-1/1b-proposals-polish.md @@ -0,0 +1,111 @@ +# Brief 1b — Proposals route polish + +> **Operator:** Sonnet 4.6 (tight-scope route work) +> **Branch:** `workbench/wave-1b-proposals-polish` +> **Base:** `feat/workbench-ui-continuation` @ `685aaae` +> **Estimated diff:** ~150–250 lines, UI only +> **Why this operator:** Proposals has a well-defined lifecycle +> (pending / accepted / rejected / withdrawn) and clear color tokens +> already in `src/design/`. Tight contract, no surface-contract surprises. + +--- + +## Dispatch line + +```bash +git fetch origin && \ +git worktree add /Users/kaizenpro/Projects/core-w1b-proposals \ + -b workbench/wave-1b-proposals-polish origin/feat/workbench-ui-continuation && \ +cd /Users/kaizenpro/Projects/core-w1b-proposals/workbench-ui && \ +pnpm install +``` + +--- + +## Doctrine refs + +- `docs/plans/workbench-ui-continuation.md` §Phase 1b +- `docs/plans/workbench-ui-continuation-addendum.md` §1 (Proposals is + proposal-only — no direct accept/reject endpoints introduced; UI only + calls existing API), §7 (PR checklist) + +## Scope (owned files) + +- `src/app/proposals/**` +- Test files colocated with the above + +## May read (no edits) + +- `src/api/queries.ts` — observe existing `useProposals` / `useProposal` shapes +- `src/design/tokens.css` — read review-lifecycle tokens; do not edit +- `src/types/api.ts` — append-only at the bottom of proposals section if needed + +## Off-limits + +- `src/design/**` (including tokens) +- Shell / TopBar / LeftNav / StatusFooter / App.tsx +- Any backend Python file +- Any placeholder file +- Any new proposal-mutation endpoint or hook (proposal-only discipline) + +## Tasks + +- [ ] **State audit.** Confirm queue list and proposal detail handle loading, + empty, and error consistently. Wire `EmptyState` from `src/design/` + where missing. +- [ ] **Lifecycle color consistency.** The four states (`pending`, + `accepted`, `rejected`, `withdrawn`) must render with the same color + tokens in both list and detail. Verify each token is referenced via + CSS custom property — no hex literals. +- [ ] **Cross-route links.** From proposal detail: + - link to the source artifact (use existing Runs/artifact route path + if present; otherwise the artifact route Phase 2 will introduce — + for now link to the Replay-comparison entry-point if that exists), + - link to the replay-comparison view for the proposal if applicable. + Document any link that cannot land because the target route is a + placeholder; leave a TODO with the route name. +- [ ] **Suggested-CLI block.** Make the suggested-CLI snippet block + `user-select: text` (or a copy button) so the operator can copy it. +- [ ] **⌘K command entries.** Add `Open proposal ` palette entry + driven by the existing `useProposals` query. Only proposals entries — + do not touch other features'. +- [ ] **Route tests.** Cover at least: + - queue renders with loading → success transition, + - empty state when zero proposals returned, + - error state when query errors, + - lifecycle color class applied per state. + +## Acceptance criteria + +- Loading / empty / error covered everywhere in `src/app/proposals/`. +- All four lifecycle states render with the documented tokens, no hex + literals anywhere in this brief's diff (`grep -E '#[0-9a-fA-F]{3,6}'` + returns nothing in the diff). +- Suggested-CLI block is selectable or has a copy button. +- ⌘K entries for proposals are present and keyboard-activatable. +- No backend changes. No off-limits files touched. +- `pnpm test` and `pnpm test:enum-coverage` green. + +## Validation + +```bash +cd workbench-ui +pnpm install +pnpm test +pnpm test:enum-coverage +git diff --stat $(git merge-base HEAD origin/feat/workbench-ui-continuation)..HEAD +# Verify no hex literals introduced +git diff $(git merge-base HEAD origin/feat/workbench-ui-continuation)..HEAD -- 'src/app/proposals/**' | grep -E '^\+.*#[0-9a-fA-F]{3,6}' && echo "FAIL: hex literal introduced" || echo "ok: no hex literals" +``` + +## PR + +Title: `feat(workbench/proposals): polish states, lifecycle colors, links (wave 1b)` + +Body uses the template in `docs/handoff/workbench-ui/wave-1/README.md`. + +## When done + +- [ ] PR open against `feat/workbench-ui-continuation` +- [ ] CI green +- [ ] This brief checked complete on the PR diff --git a/docs/handoff/workbench-ui/wave-1/1c-replay-polish.md b/docs/handoff/workbench-ui/wave-1/1c-replay-polish.md new file mode 100644 index 00000000..90245cf5 --- /dev/null +++ b/docs/handoff/workbench-ui/wave-1/1c-replay-polish.md @@ -0,0 +1,111 @@ +# Brief 1c — Replay route polish + +> **Operator:** Gemini 3.1 Pro (survey + cross-file presentation work) +> **Branch:** `workbench/wave-1c-replay-polish` +> **Base:** `feat/workbench-ui-continuation` @ `685aaae` +> **Estimated diff:** ~150–250 lines, UI only +> **Why this operator:** Replay polish requires reading divergence +> rendering across multiple files and improving clarity of metadata +> presentation. Gemini's strength is cross-file survey + presentation +> reasoning over a moderate diff surface. + +--- + +## Dispatch line + +```bash +git fetch origin && \ +git worktree add /Users/kaizenpro/Projects/core-w1c-replay \ + -b workbench/wave-1c-replay-polish origin/feat/workbench-ui-continuation && \ +cd /Users/kaizenpro/Projects/core-w1c-replay/workbench-ui && \ +pnpm install +``` + +--- + +## Doctrine refs + +- `docs/plans/workbench-ui-continuation.md` §Phase 1c +- `docs/plans/workbench-ui-continuation-addendum.md` §1 (Replay = read-only; + no "fix" buttons, no artifact writes), §7 (PR checklist) +- The Replay route should never present an affordance to mutate an + artifact. Read + render + link out only. + +## Scope (owned files) + +- `src/app/replay/**` +- Test files colocated with the above + +## May read (no edits) + +- `src/api/queries.ts` — observe `useReplayComparison`, `useArtifacts`, `useArtifact` +- `src/design/tokens.css` — divergence-severity tokens +- `src/types/api.ts` — append-only at the bottom of replay section if needed + +## Off-limits + +- `src/design/**` +- Shell / TopBar / LeftNav / StatusFooter / App.tsx +- Any backend Python file +- Any placeholder file +- **No mutating affordances of any kind** — no "rerun", "save", "fix", + "accept divergence" buttons. Read-only doctrine. + +## Tasks + +- [ ] **Survey current state.** Read every file in `src/app/replay/` and + produce a short comment block at the top of the route (or in this + brief's PR description) summarizing what each component does. This + forces a complete read before edits. +- [ ] **State audit.** Artifact-selector and comparison view: loading, + empty (no artifacts available; selection invalid), error states. +- [ ] **Divergence-severity clarity.** Currently the divergence severity + may be coded via color alone. Add a textual severity label next to + the color band (e.g. `low`, `material`, `breaking`) so the meaning + is unambiguous without the color legend. +- [ ] **Metadata presentation.** Artifact metadata (timestamp, trace_hash, + run id, lane) should be presented in a key-value table or definition + list with consistent alignment. No "wall of text" rendering. +- [ ] **Back-link to proposal.** When the comparison view is reached from + a proposal, show a "Back to proposal #N" link. When reached directly, + do not show the link. Drive this from URL state, not props. +- [ ] **Route tests.** Cover: + - artifact selection populating comparison view, + - empty state when no artifacts, + - error state when comparison query fails, + - severity label rendering for each severity bucket. + +## Acceptance criteria + +- Every async surface in `src/app/replay/` has loading + empty + error. +- Divergence severity is conveyed by **both** color **and** text label. +- Artifact metadata renders as a structured key-value layout. +- Back-link to proposal appears only when route was entered from a proposal. +- No mutating affordances anywhere in the diff. +- No backend changes. No off-limits files touched. +- `pnpm test` and `pnpm test:enum-coverage` green. + +## Validation + +```bash +cd workbench-ui +pnpm install +pnpm test +pnpm test:enum-coverage +git diff --stat $(git merge-base HEAD origin/feat/workbench-ui-continuation)..HEAD + +# Confirm no write paths introduced (no new mutation hooks) +git diff $(git merge-base HEAD origin/feat/workbench-ui-continuation)..HEAD -- 'src/app/replay/**' | grep -E '^\+.*(useMutation|fetch\(|axios\.(post|put|patch|delete))' && echo "FAIL: mutation introduced" || echo "ok: read-only preserved" +``` + +## PR + +Title: `feat(workbench/replay): polish states, severity labels, metadata layout (wave 1c)` + +Body uses the template in `docs/handoff/workbench-ui/wave-1/README.md`. + +## When done + +- [ ] PR open against `feat/workbench-ui-continuation` +- [ ] CI green +- [ ] This brief checked complete on the PR diff --git a/docs/handoff/workbench-ui/wave-1/1d-evals-polish.md b/docs/handoff/workbench-ui/wave-1/1d-evals-polish.md new file mode 100644 index 00000000..09e6db9e --- /dev/null +++ b/docs/handoff/workbench-ui/wave-1/1d-evals-polish.md @@ -0,0 +1,114 @@ +# Brief 1d — Evals route polish + +> **Operator:** GPT-OSS-120B or GitHub Copilot cloud agent (mechanical) +> **Branch:** `workbench/wave-1d-evals-polish` +> **Base:** `feat/workbench-ui-continuation` @ `685aaae` +> **Estimated diff:** ~120–200 lines, UI only +> **Why this operator:** Evals polish is mostly mechanical: state audits, +> numeric column alignment, route tests. Clear acceptance criteria, narrow +> file scope, no surface-contract subtlety. Ideal for a local or +> cloud-mechanical operator. + +--- + +## Dispatch line + +```bash +git fetch origin && \ +git worktree add /Users/kaizenpro/Projects/core-w1d-evals \ + -b workbench/wave-1d-evals-polish origin/feat/workbench-ui-continuation && \ +cd /Users/kaizenpro/Projects/core-w1d-evals/workbench-ui && \ +pnpm install +``` + +--- + +## Doctrine refs + +- `docs/plans/workbench-ui-continuation.md` §Phase 1d +- `docs/plans/workbench-ui-continuation-addendum.md` §1 (Evals = read-only; + no lane mutation, no "suppress failing case" affordance), §7 (PR checklist) +- Evals UI must not hide or suppress failing cases. Filters that change + view are fine; filters that remove failing cases from the underlying + count are not. + +## Scope (owned files) + +- `src/app/evals/**` +- Test files colocated with the above + +## May read (no edits) + +- `src/api/queries.ts` — `useEvalLanes`, `useEvalLane`, `useEvalExecution` +- `src/design/tokens.css` — read; do not edit +- `src/types/api.ts` — append-only at the bottom of evals section if needed + +## Off-limits + +- `src/design/**` +- Shell / TopBar / LeftNav / StatusFooter / App.tsx +- Any backend Python file +- Any placeholder file +- Any affordance that mutates a lane definition or hides a failing case + +## Tasks + +- [ ] **State audit.** Lane list and eval-run view: loading, empty + (no lanes; no runs for selected lane), error states. +- [ ] **Numeric column alignment.** Wherever numeric metrics render in a + list or table, they must be right-aligned, monospace-numeric, and + use tabular-nums for consistent digit width. Use existing tokens. +- [ ] **Metric readability.** Where a metric is shown alongside a target, + render `actual / target` with the actual value emphasized. If a + metric is failing (actual < target where higher-is-better, or + actual > target where lower-is-better), apply the existing + failure color token. No new tokens. +- [ ] **Lane selection persistence.** Selected lane should be reflected in + the URL (query string is fine). Reloading the page should restore the + selection. +- [ ] **⌘K command entry.** Add `Open eval lane ` palette entries + driven by the existing `useEvalLanes` query. Only evals entries. +- [ ] **Route tests.** Cover: + - lane list loading → success, + - empty state when no lanes, + - run view rendering metrics with correct alignment, + - failure color applied when metric does not meet target. + +## Acceptance criteria + +- Every async surface in `src/app/evals/` has loading + empty + error. +- All numeric metric columns are right-aligned with `tabular-nums`. +- Failing metrics use the existing failure token, no hex literals. +- Lane selection survives reload via URL state. +- ⌘K `Open eval lane` entries present and keyboard-activatable. +- No backend changes. No off-limits files touched. No affordance that + suppresses or hides failing cases. +- `pnpm test` and `pnpm test:enum-coverage` green. + +## Validation + +```bash +cd workbench-ui +pnpm install +pnpm test +pnpm test:enum-coverage +git diff --stat $(git merge-base HEAD origin/feat/workbench-ui-continuation)..HEAD + +# No hex literals in the diff +git diff $(git merge-base HEAD origin/feat/workbench-ui-continuation)..HEAD -- 'src/app/evals/**' | grep -E '^\+.*#[0-9a-fA-F]{3,6}' && echo "FAIL: hex literal introduced" || echo "ok: no hex literals" + +# No mutation hooks introduced +git diff $(git merge-base HEAD origin/feat/workbench-ui-continuation)..HEAD -- 'src/app/evals/**' | grep -E '^\+.*useMutation' && echo "FAIL: mutation introduced" || echo "ok: read-only preserved" +``` + +## PR + +Title: `feat(workbench/evals): polish states, numeric alignment, lane URL state (wave 1d)` + +Body uses the template in `docs/handoff/workbench-ui/wave-1/README.md`. + +## When done + +- [ ] PR open against `feat/workbench-ui-continuation` +- [ ] CI green +- [ ] This brief checked complete on the PR diff --git a/docs/handoff/workbench-ui/wave-1/README.md b/docs/handoff/workbench-ui/wave-1/README.md new file mode 100644 index 00000000..a791f21b --- /dev/null +++ b/docs/handoff/workbench-ui/wave-1/README.md @@ -0,0 +1,110 @@ +# Workbench UI — Wave 1 Brief Pack + +> **Parent plan:** `docs/plans/workbench-ui-continuation.md` +> **Binding addendum:** `docs/plans/workbench-ui-continuation-addendum.md` +> **Base branch:** `feat/workbench-ui-continuation` @ `685aaae` +> **Scope:** Phase 1 only — polish the four implemented routes + +## What this wave does + +Polish Chat, Proposals, Replay, and Evals so they are cohesive, +cross-linked, and handle loading/empty/error states consistently — +before any new route lands. All four routes are already implemented; +this is hardening, not feature work. + +## Parallel safety + +| Operator brief | Owns | Read-only touches | +|-----------------------|-----------------------------------|----------------------------------| +| 1a — Chat polish | `src/app/chat/**` | `src/types/api.ts` (append only) | +| 1b — Proposals polish | `src/app/proposals/**` | `src/types/api.ts` (append only) | +| 1c — Replay polish | `src/app/replay/**` | `src/types/api.ts` (append only) | +| 1d — Evals polish | `src/app/evals/**` | `src/types/api.ts` (append only) | + +**Off-limits to every brief:** +- `src/design/**` (protected substrate — plan constraint) +- `src/app/Shell.tsx`, `LeftNav.tsx`, `TopBar.tsx`, `StatusFooter.tsx` +- `src/app/App.tsx` route table (no swaps in Wave 1) +- Any placeholder file in `src/routes/` (those belong to Phase 2+) +- `workbench-ui/src/design/tokens.css` and friends +- Backend Python (this is a UI-only wave) + +**Coordinated surface:** +- CommandPalette entries: each brief adds **only** entries for its + own feature; no brief edits another's entries. If a conflict appears + at merge, the second-merging brief rebases additively. +- `src/types/api.ts`: append-only additions to the bottom of the + matching section. No edits to existing types. + +## Dispatch DAG + +``` + ┌── 1a Chat polish (Opus 4.6) ───────┐ +main ──>│ │── merge any order + │── 1b Proposals polish (Sonnet 4.6)─│ (all four parallel-safe) + │ │ + │── 1c Replay polish (Gemini 3.1) ───│ + │ │ + └── 1d Evals polish (GPT-OSS/Copilot)┘ +``` + +All four briefs are dispatchable simultaneously. No order dependency. + +## Doctrine that applies to every brief + +From `docs/plans/workbench-ui-continuation-addendum.md`: + +- **§1 trust classification.** Chat = read + turn-submit; Proposals = proposal-only; + Replay = read-only; Evals = read-only. No brief introduces a write path. +- **§2 surface contract (Chat brief only).** `surface`, `walk_surface`, and + `articulation_surface` rendered distinctly; `trace_hash` stability test required. +- **§7 per-PR checklist.** Every PR answers the four CLAUDE.md §PR Checklist + questions in its description. +- **§8 proof obligations.** New TS unions must have a test that fails under + their named violation, or the type is decoration. + +## Validation each brief must run + +```bash +cd workbench-ui +pnpm install # if first time on this worktree +pnpm test # all green +pnpm test:enum-coverage +``` + +Backend-touching changes are **out of scope** for Wave 1 and must be +rejected at review. Any "while I'm here" backend edit means the PR +fails the trust-classification check. + +## PR template (every brief uses this) + +```markdown +## Wave 1 brief: <1a|1b|1c|1d> — polish + +### Trust classification + + +### CLAUDE.md §PR Checklist +- Capability/property/boundary added: +- Invariant preserved: +- CLI/test lane that proves it: pnpm test + pnpm test:enum-coverage (UI-only) +- Trust boundary enforced: + +### Diff scope +- Owned: +- Read-only touched: +- Off-limits respected: yes + +### Tests +- Added: +- Passing: pnpm test green; pnpm test:enum-coverage green +``` + +## Done criteria for the wave + +- [ ] All four PRs merged to `feat/workbench-ui-continuation` +- [ ] No off-limits files modified across the merged set +- [ ] No backend changes across the merged set +- [ ] `pnpm test` and `pnpm test:enum-coverage` green on the merged tip +- [ ] CommandPalette has entries for the new interactions added by each brief +- [ ] All four briefs in this folder marked done in their respective files