9e6756f678
Backfills transcripts that existed only locally in ohm-infra: - 0019.1/.2/.3 - UX-polish wave subagent transcripts (driver 0019.0 never finalized) - 0026.1-.9 - security-audit-0026 subagent transcripts (driver abandoned/closed-out by 0068; audit drove published 0030 remediation) - 0073.0 - PPE/progressive-delivery + engineering-handbook session, originally drafted as a duplicate 0046.0; reassigned next free number (0072 taken by a concurrent session) sessions.json: add 0019/0073 titles, update 0026 title. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
142 lines
7.0 KiB
Markdown
142 lines
7.0 KiB
Markdown
# Session 0019.3 — Transcript
|
|
|
|
Parent: SESSION-0019.0-TRANSCRIPT-… (UX-polish wave, rfc-app v0.21.0)
|
|
Subagent ordinal: .3 — roadmap item #32 (session/transcript page
|
|
polish) + the /docs surfaces' share of #31.
|
|
|
|
## Goal
|
|
|
|
In the isolated worktree `/Users/benstull/git/rfc-app-v0.21.0-docs`
|
|
on branch `feature/v0.21.0-docs-32`:
|
|
|
|
(a) Collapse single-transcript session roots — render the transcript
|
|
inline at `/docs/sessions/:nnnn` instead of a dead-end placeholder;
|
|
multi-transcript sessions inline the `.0` driver transcript and
|
|
list the siblings.
|
|
(b) Add a transcript metadata header (title, started/ended parsed from
|
|
the filename ISO segments, derived duration, optional `tldr` from
|
|
the manifest, external view-source link).
|
|
(c) Docs-surface token polish + consistent loading/empty/error states +
|
|
aria-labels on icon-only controls.
|
|
|
|
## Pre-state
|
|
|
|
- Foundation commit carried `frontend/src/styles/tokens.css` (the #31
|
|
design-token module). Build requires `VITE_APP_NAME` (no default).
|
|
- `/docs/sessions/:nnnn` (DocsSessionIndex.jsx) rendered a
|
|
`.docs-session-overview` placeholder: "N transcript(s) in this
|
|
session. Select one from the navigation."
|
|
- DocsSessionTranscript.jsx rendered body via MarkdownPreview with a
|
|
breadcrumb but no metadata header.
|
|
- Backend `/api/docs/sessions/manifest` (api.py:177-178) returns
|
|
`result["manifest"]` verbatim — the full `sessions.json` object —
|
|
so arbitrary per-entry fields already reach the frontend.
|
|
|
|
## Turn-by-turn arc (honest)
|
|
|
|
1. Read tokens.css, SESSION-PROTOCOL.md (§1 naming + the 0017.0
|
|
folder-layout amendment + the sessions.json shape), all seven owned
|
|
docs components, api.js docs helpers, docs_sessions.py, and the
|
|
api.py manifest route.
|
|
2. Confirmed the manifest endpoint is a pass-through → **no backend
|
|
change needed** for `tldr`. The decision branch in the task was
|
|
resolved in favor of "already passes through".
|
|
3. Read the existing docs CSS block in App.css (read-only) to learn
|
|
which classes a sibling owns (.docs-article, .docs-empty,
|
|
.docs-error, .docs-source-link, .docs-session-overview, etc.) so
|
|
Docs.css would not collide.
|
|
4. Rewrote DocsSessionTranscript.jsx: exported `gitSourceUrl`,
|
|
`transcriptOrdinal`, `parseTranscriptMeta`, and `TranscriptMetaHeader`;
|
|
added a manifest fetch for title+tldr; rendered the header above the
|
|
body.
|
|
5. Rewrote DocsSessionIndex.jsx to inline-render the primary transcript
|
|
(driver `.0` preferred, else `files[0]`) and list siblings; reused
|
|
the imported header + ordinal helpers.
|
|
6. Created Docs.css (new classes only, all token-valued).
|
|
7. Brought DocsUserGuide's bare `<p className="error">` onto the shared
|
|
`.docs-error` + retry convention.
|
|
8. Build failed first run (VITE_APP_NAME unset — env requirement, not
|
|
my change); re-ran with `VITE_APP_NAME="OHM Verify" npm run build`
|
|
→ green (974 kB index chunk; >500 kB warning expected/benign).
|
|
9. Staged the four files explicitly (avoided the `frontend/node_modules`
|
|
symlink), committed.
|
|
|
|
## Design decisions
|
|
|
|
**Inline-collapse (a).** URL stays stable to the session number — the
|
|
session root fetches the index, picks a primary file, fetches its body,
|
|
and renders the same `TranscriptMetaHeader` + `philosophy-body` the
|
|
standalone route uses. No `<Navigate>`, no 301. Primary selection:
|
|
`SESSION-NNNN.0-TRANSCRIPT…` if present, else `files[0]` (backend
|
|
returns the list pre-sorted). For multi-transcript sessions, a
|
|
`.docs-session-siblings` strip lists every transcript ordinal — the
|
|
primary marked "(shown below)" with `aria-current`, the rest linking to
|
|
`/docs/sessions/:nnnn/:filename`. No empty placeholder remains on any
|
|
path that has at least one transcript.
|
|
|
|
**Metadata header (b).** `parseTranscriptMeta` regexes the
|
|
`-TRANSCRIPT-<start>--<end>.md` ISO segment (`YYYY-MM-DDTHH-MM` x2,
|
|
colons-as-dashes per protocol). Times are built as **local** Dates and
|
|
rendered as wall-clock via `toLocaleString` — the filename encodes no
|
|
timezone (PST implied), and duration is a difference of two same-basis
|
|
Dates so the implied-TZ ambiguity cancels. Legacy renamed-letter
|
|
transcripts (no segment) → all derived fields null → header shows just
|
|
the title + source link (graceful degrade). Duration omitted when
|
|
start==end or unparseable.
|
|
|
|
**tldr schema (b).** Consumed as a **string** field named `tldr` on the
|
|
per-session entry of `sessions.json`, i.e. keyed by the 4-digit session
|
|
number alongside `title`:
|
|
```json
|
|
{ "0019": { "title": "UX-polish wave …", "tldr": "One-line summary." } }
|
|
```
|
|
Read via `getSessionsManifest()` → `payload[nnnn].tldr`; rendered only
|
|
when `typeof === 'string'` and truthy. Absent ⇒ no TL;DR line.
|
|
|
|
**Polish (c).** Docs.css styles ONLY the two new element families
|
|
(`.docs-transcript-meta*`, `.docs-session-siblings*`), every value a
|
|
tokens.css custom property, to avoid racing the #31 App.css sweep for
|
|
the pre-existing docs selectors. DocsUserGuide normalized to the shared
|
|
error convention. All icon-only controls already carried aria-labels
|
|
(verified the drawer toggle `☰`, scrim) — no aria gaps found in owned
|
|
files.
|
|
|
|
## Cut state
|
|
|
|
- Branch: `feature/v0.21.0-docs-32`
|
|
- Final commit SHA: `adb5d2571532ad5992900791d295ef214ddfba0d`
|
|
- Files changed (4):
|
|
- `frontend/src/components/DocsSessionIndex.jsx` (rewrite — inline collapse)
|
|
- `frontend/src/components/DocsSessionTranscript.jsx` (rewrite — meta header + exports)
|
|
- `frontend/src/components/DocsUserGuide.jsx` (error-state normalize)
|
|
- `frontend/src/components/Docs.css` (new)
|
|
- **Backend: NOT changed.** docs_sessions.py untouched — manifest
|
|
pass-through already exposes `tldr`. (No py_compile needed.)
|
|
- Build: GREEN (`VITE_APP_NAME=… npm run build`; 974 kB chunk warning benign).
|
|
|
|
## What the driver needs to know
|
|
|
|
- **No backend coordination required** for this item — frontend renders
|
|
`tldr` when present; the field's value-backfill is the documented
|
|
out-of-scope follow-up.
|
|
- **sessions.json `tldr` schema to backfill** (driver/operator task in
|
|
`wiggleverse/ohm-session-history`): add an optional `"tldr": "<one
|
|
line>"` string to any per-session entry next to `"title"`. The
|
|
frontend already consumes it on both the inline session-root view and
|
|
the standalone transcript view. Absent ⇒ no-op.
|
|
- Inline-collapse changes the `/docs/sessions/:nnnn` semantics: it is no
|
|
longer nav-only. The left-nav transcript rows + sibling links still
|
|
point at the standalone `/docs/sessions/:nnnn/:filename` route, which
|
|
is unchanged and now also carries the metadata header.
|
|
- Build needs `VITE_APP_NAME` set (env requirement, not from this item).
|
|
|
|
## §19.2 candidates
|
|
|
|
- `parseTranscriptMeta` / `transcriptOrdinal` are filename-shape logic
|
|
that mirrors the backend `_TRANSCRIPT_FILENAME_RE` and the nav's own
|
|
`transcriptOrdinal` in DocsLayout.jsx — there are now two frontend
|
|
copies of the ordinal regex (DocsLayout owns one; I export one). A
|
|
future consolidation could lift a single `lib/transcripts.js` and have
|
|
DocsLayout import it (DocsLayout is sibling-owned, so I did not touch
|
|
it). Worth flagging for a follow-up de-dup.
|