docs: design central live log and compact CTE plan

This commit is contained in:
User
2026-07-15 11:27:39 +02:00
parent 9554379916
commit d5ec7686a0
@@ -0,0 +1,155 @@
# Central Live Log and Compact CTE Plan Design
**Date:** 2026-07-15
## Goal
Remove duplicated workflow narration from both the left **Model activity** panel and the central
body, leaving the central surface focused on one compact scrolling model-stream log plus the
current reviewer form or artifact. At the same time, make F6 CTE plan cards substantially denser
vertically without making their lateral spacing cramped.
This design supersedes the panel visibility contract in
`2026-07-15-model-activity-signal-filter-design.md`; the complete in-memory activity timeline and
all backend/SSE contracts remain unchanged.
## Current behavior and duplication
`sessionStore` deliberately keeps several independent projections of the live session:
- `lastUserEntry` is rendered centrally as **You asked** or **You chose**, while the same value is
also stored as a `prompt` activity row;
- `stepMessages` are rendered centrally, while the same `info` events are stored as `status`
activity rows;
- `pendingWidget` is rendered by `WidgetHost`, while its title is also stored as a `gate` activity
row;
- `transcript` contains assistant streaming text and currently supplies the five-line mini-log;
- `activityLog` remains the complete chronological prompt, thinking, assistant, tool, gate,
status, and lifecycle fold.
The resulting screen repeats user input, status text, and gate titles. The current mini-log is not
actually scrollable: it keeps only five lines from the latest transcript entry and applies
`overflow-hidden` plus truncation. F6 CTE cards are structurally sound, but 16/20 px vertical and
horizontal padding is applied uniformly to headers, content, table rows, and filter rows, making a
data-dense plan unnecessarily tall.
## Chosen information architecture
### Central body
While the model is working, `CentralStatus` renders only one compact live-log box. It no longer
renders:
- **You asked** / **You chose**;
- the elapsed timer, spinner, or working label;
- `stepMessages`, including informational, warning, and error text outside the log.
`WidgetHost`, reviewer gates, artifact viewers, the finalized-session card, and the composer remain
owned by `AppShell` and continue to render exactly as today. When a widget is pending, `working` is
false and the live log leaves the central body so the form is the clear focal point.
The compact log consumes the existing assistant `transcript`, not raw tool or lifecycle events. It
flattens every non-blank transcript line in chronological order so the scrollable history covers
the whole live session rather than only the latest five lines. It is present only while `working`
is true and at least one transcript line exists; no synthetic waiting or status copy is added.
The log uses a bounded height with vertical overflow, exposes log semantics to assistive
technology, wraps long content instead of truncating it, and follows appended text only while the
reader is already near the bottom. A reader who scrolls upward keeps their position. The existing
48 px near-bottom threshold is reused so the two activity surfaces behave consistently.
### Left Model activity panel
The panel keeps a strict, default-deny allowlist:
| Activity kind | Visible | Reason |
| --- | --- | --- |
| `thinking` | Yes | Genuine reasoning is not rendered in the central assistant-stream log. |
| `status` | Yes | Central `stepMessages` are removed, so status and severity remain available here. |
| `prompt` | No | The user explicitly requested that prompts leave the panel. |
| `gate` | No | The current reviewer form and its title already appear centrally. |
| `assistant` | No | Assistant streaming text belongs to the central live log. |
| `tool` | No | Low-level tool activity remains implementation noise. |
| `lifecycle` | No | Turn/process lifecycle remains implementation noise. |
| unknown future kinds | No | Default-deny behavior prevents accidental exposure. |
Filtering remains exclusively at the panel rendering boundary. `activityLog`, `transcript`, store
folds, SSE/replay behavior, tool correlation, workflow state, and persistence are not changed.
Panel empty state and bottom-follow still depend only on the visible `thinking`/`status`
projection.
## Compact CTE spacing
The change is local to `CtePlanViewer`; the shared `Card` component and the rest of the design
system do not change.
All values stay on the existing 4 px Tailwind spacing scale:
- CTE header: 8 px vertical, 12 px lateral below `sm`, 16 px lateral from `sm` upward;
- CTE content: 8 px vertical, 12 px lateral below `sm`, 16 px lateral from `sm` upward;
- table rows: 8 px vertical, 12/16 px responsive lateral padding;
- filter rows: 8 px vertical, 12/16 px responsive lateral padding;
- filter description/rationale divider and CTE rationale divider: 8 px top padding.
In Tailwind terms, these surfaces use `px-3 py-2 sm:px-4`; the bordered header additionally uses
`[&.border-b]:pb-2` to override `CardHeader`'s shared 16 px bottom-padding rule. Responsive `sm:p-5`
and the header's special 20 px bottom padding are removed. Divider sections use `pt-2`. Existing
inter-section gaps, responsive grids, borders, headings, badges, chips, line wrapping, `min-w-0`,
semantic ordered steps, roles, and ARIA labels remain unchanged. This makes the containers denser
without squeezing long SQL identifiers laterally.
The Impeccable layout pre-scan reported no arbitrary spacing or z-index classes. The qualitative
assessment found a coherent but inverted rhythm: a single CTE had 20 px internal padding/gaps while
distinct CTE steps were separated by only 12 px. The selected change corrects the excessive
container padding without introducing a new spacing system or unrelated visual refactor.
## Error and edge-case behavior
- Status warnings and errors are no longer repeated centrally; they remain visible as labeled rows
in the left panel. Existing toast and widget error handling is unchanged.
- A provider that emits no assistant transcript shows no empty live-log shell. Its genuine
`thinking` and status events can still appear in the left panel.
- A provider that emits no `thinking` can still show status rows in the left panel and assistant
stream lines in the central log.
- Unknown activity kinds remain hidden from the panel.
- Hidden prompt/gate updates cannot change panel scroll position.
- Long transcript lines and long CTE identifiers wrap without horizontal overflow.
- Closing/reopening the panel does not mutate the complete log. Resume behavior remains unchanged.
## Testing
Frontend RED/GREEN tests must prove:
1. A mixed activity sequence renders only `thinking` and `status` in the left panel; prompt, gate,
assistant, tool, lifecycle, and unknown kinds remain hidden while the complete store fold is
preserved.
2. Prompt- or gate-only activity produces the panel's `No activity yet.` state and cannot trigger
bottom-follow; visible thinking/status updates retain the existing 48 px behavior.
3. `CentralStatus` omits last-user echo, timer/spinner/label, and step messages, and renders only the
assistant transcript log while working.
4. The central log includes chronological non-blank lines across multiple transcript entries,
wraps rather than truncates, uses accessible log semantics, auto-follows near the bottom, and
preserves manual scroll position away from the bottom.
5. The central log is absent when not working or before transcript content exists; `WidgetHost`
integration remains intact.
6. CTE headers, content, tables, filters, and rationale dividers use the exact compact responsive
spacing classes while semantic structure and long-value wrapping remain covered.
Run the focused panel, central-status, AppShell, and CTE viewer tests, then the complete frontend
suite, `npx tsc -b`, `npm run build`, the Impeccable layout detector, and `git diff --check`.
## Deployment
Only the frontend is affected. Build and force-recreate only the `frontend` Compose service. If and
only if the Vite entry hash changes, restart `omics_portal-web-1` to invalidate its manifest cache.
Do not restart the core or terminate an unrelated active Pi session. Verify the running frontend
image and entry, core start timestamp/health, panel projection tests, central live-log behavior, and
compact CTE classes.
## Out of scope
- Removing data from `activityLog`, `transcript`, `lastUserEntry`, or `stepMessages` in the store.
- Changing backend, SSE, replay, persistence, workflow, or model-provider contracts.
- Showing raw tool arguments/results, lifecycle events, or assistant text in the left panel.
- Moving reviewer forms or artifact viewers out of the central body.
- Changing CTE typography, colors, content schema, grid topology, or the shared `Card` component.