Commit graph

12 commits

Author SHA1 Message Date
Shay
ebb95a0541 feat(workbench): Vault route — fail-closed epistemic memory evidence (Wave R2)
Replaces VaultRoutePlaceholder with the real route over the R2-B
/vault read substrate (#712).

- TS mirrors VaultSummary/VaultEntry; both removed from NOT_YET_MIRRORED.
  Also fixes a latent ErrorCode drift: adds 'evidence_unavailable' to the
  TS union (present in Python schemas, missing in TS) — the route branches
  on it.
- fail-closed is the design: a missing/unpersisted vault (the 501
  evidence_unavailable signal, or persisted=false / entry_count=0) renders
  the honest absence card as the PRIMARY state, naming the opt-in
  RuntimeConfig.persist_session_state pointer — not a generic error, no
  skeleton theater
- with data: summary strip (entry_count, store_count, reproject_interval,
  max_entries, source_path) + VirtualizedList of entries with
  epistemic_status / epistemic_state pills and versor_digest DigestBadge
- exact-recall doctrine: renders only backend fields; never computes or
  displays a similarity/relevance proxy (runtime recall is exact cga_inner)
- selection publishes the vault_entry subject (inspect-param only, via
  setSubject + setInspectorOpen; EvidenceUrlSync writes ?inspect=vault:N);
  a URL-restored identity-only subject is hydrated once entries load
- Vault row added to routeConformance MOUNT_ROUTES — the fail-closed
  absence asserted as the primary contract
- tests: fail-closed card (not error), summary+entries, no-similarity-score
  doctrine, vault_entry subject publication, j/k spine

Token-only styling (hexScan green).
2026-06-12 21:29:18 -07:00
Shay
cfcd7dc9ec feat(workbench): Packs route + TreeView primitive — manifest & checksum evidence (Wave R2)
Replaces PacksRoutePlaceholder with the real triad route over the R2-B
/packs read substrate (#712).

- TS mirrors PackSource/PackSummary/PackDetail; PackSummary/PackDetail
  removed from NOT_YET_MIRRORED (drift gate now enforces them)
- new design primitive TreeView (src/design/components/TreeView): a
  deterministic, keyboard-driven JSON tree — object keys sorted, array
  indices in order, no animation; ←/→ collapse/expand, ↑/↓ + j/k move,
  Home/End jump, Enter toggles; registers its shortcuts only while focused
  (KeyboardHelp never advertises tree controls when no tree is on screen)
- list pane: VirtualizedList + useListNavigation (j/k) + SearchInput; rows
  show pack_id, source, version, language/modality, determinism_class pill
- detail pane: Panel + TabBar (Manifest / Checksums / Raw); Manifest renders
  via TreeView; Checksums is the verify affordance — manifest_digest and
  declared checksum as DigestBadges plus the per-field manifest checksums
  table (the checksum-hashes-the-bytes-on-disk doctrine made visible); Raw
  collapsed by default
- selection publishes the pack subject (R2-S), records /packs/<packId>
  (replace), pushRecentItem on visit
- Packs row added to routeConformance MOUNT_ROUTES (loading 'Loading
  packs...', error 'No packs mutation occurred.', empty 'No packs
  discovered.' + core pack validate <path>)
- tests: TreeView (sorted/collapsed/expand/collapse/focus/click/empty) +
  PacksRoute (list, replace-mode select + manifest tree, checksum verify
  affordance, j/k spine)

Token-only styling (hexScan green).
2026-06-12 21:14:13 -07:00
Shay
2b13feab24 feat(workbench): Runs route — session evidence with trace cross-links (Wave R2)
Replaces the RunsRoutePlaceholder with the real triad route over the
R2-B /runs read substrate (#712).

- TS mirrors RunSource/RunSummary/RunTurnRef/RunDetail; all three classes
  removed from NOT_YET_MIRRORED (drift gate now enforces them)
- list pane: VirtualizedList + useListNavigation (j/k) + SearchInput;
  rows show source, session_id, turn_count, relative timestamp, a
  checkpoint badge (present + revision vs 'no checkpoint'), and any
  evidence_gap rendered honestly in-row (never hidden)
- detail pane: Panel + TabBar (Turns / Manifest / Raw); every turn row
  is an anchor to /trace/<turn_id> (backend-provided trace_path) with the
  trace_hash as a DigestBadge — the cross-link is the point of this route;
  turn list pages via turn_limit ('Load more turns')
- selection publishes the run subject (R2-S) and records /runs/<sessionId>
  in the URL (replace), pushRecentItem on visit
- Runs row added to routeConformance MOUNT_ROUTES (loading 'Loading
  runs...', error 'No runs mutation occurred.', empty 'No runs recorded
  yet.' + core chat)
- RunsRoute.test.tsx: list evidence, in-row gap, replace-mode URL select,
  trace cross-link hrefs, manifest tab, j/k keyboard spine

Token-only styling (hexScan green); full vitest 339 green.
2026-06-12 20:58:55 -07:00
Shay
f6a03a8c14 feat(workbench): evidence subject extension and proposals wrinkles (Wave R2-S) 2026-06-12 17:13:59 -07:00
Shay
d48d040467 feat(workbench): Audit route — event timeline with mutation-boundary weighting (Wave R2-A) 2026-06-12 16:53:03 -07:00
Shay
aa6fb8ba90 feat(workbench): add trace route journal timeline 2026-06-12 16:30:34 -07:00
Shay
41f4435dc1 feat(workbench): evidence addresses — deep-linkable subjects + inspector URL state
URL = subject: one codec (evidenceAddress.ts) owns the address grammar for
every EvidenceSubject kind, including kinds whose routes are placeholders.
urlToSubject is a total inverse — malformed input yields null, never throws.

- Route params: /trace/:turnId?, /proposals/:proposalId?, /evals/:laneId?,
  /replay/:artifactId? (placeholders keep flat paths)
- ?inspect= carries inspector subject + open state; EvidenceUrlSync restores
  deep links and write-through syncs with replace (selection churn never
  pollutes history); malformed values are dropped from the URL
- Proposals/Evals/Replay restore selection from their param on load, write it
  on selection change (replace), and publish the selected subject to the
  evidence context (identity at once, detail when the query resolves)
- EvidenceSubject.data now optional; inspectors render an honest
  'detail not loaded' state for identity-only subjects
- Cmd+Shift+C copies origin + subjectToUrl(subject); no-op without subject;
  input-focus guard; transient inline 'Copied' on the inspector header
- Fix pre-existing unbounded re-render loop in RightInspector.test.tsx
  (render-phase setSubject); subjects now set from effects
2026-06-12 12:17:57 -07:00
Shay
30972e184e
feat(workbench/W-029): proposal queue (#329) 2026-05-26 21:08:36 -07:00
Shay
19506e9f60
feat(workbench/W-031): replay theater (ADR-0160 §Phase 6, deterministic-evidence UX) (#328) 2026-05-26 20:56:31 -07:00
Shay
00f5056209
feat(workbench/W-030): eval center (safe lanes only, ADR-0160 §Phase 5) (#327) 2026-05-26 20:39:30 -07:00
Shay
a612038d41
feat(W-028): chat surface + trace drawer (#303) 2026-05-26 13:22:11 -07:00
Shay
cdead696ed
feat(W-027): Workbench frontend shell — five-region grid + ten empty routes + live StatusFooter (ADR-0160 / ADR-0162) (#299)
- Five-region CSS grid shell (TopBar, LeftNav, Main, StatusFooter; Inspector collapsed)
- Ten placeholder routes with EmptyState cli/string variants and ApiErrorBoundary
- Extended EmptyState API: nextAction accepts string (button) | { kind: "cli", command }
- Updated CommandPalette: real fuzzy search over three commands (Chat, Proposals, Evals)
  with ↑/↓/Enter keyboard nav and useInRouterContext degradation for Branch 1 preview
- TanStack Query hooks for all W-026 endpoints; 30s polling on runtime/status
- TypeScript mirror of workbench/schemas.py at src/types/api.ts
- StatusFooter: mutation_mode badge, git_revision (copy on click), checkpoint_revision
  with amber warning + ADR-0157/ADR-0158 expansion note
- TopBar: CORE Workbench wordmark, ⌘K palette trigger, connection pill
- ApiErrorBoundary (class component) catches WorkbenchApiError → ErrorState
- scripts/dump-api-schemas.py: AST-based Python dataclass field extractor
- workbench-ui/api-schema-snapshot.json: checked-in drift sentinel
- 51 tests across 10 files (0 failures); enum-coverage 4/4; clean vite build
2026-05-26 12:09:12 -07:00