Skip to content

Project grammar v3 items to presentation-driven rows (WS3 layer 1) - #2192

Closed
SawyerHood wants to merge 1 commit into
mainfrom
ws3-l1-projection-presentation
Closed

Project grammar v3 items to presentation-driven rows (WS3 layer 1)#2192
SawyerHood wants to merge 1 commit into
mainfrom
ws3-l1-projection-presentation

Conversation

@SawyerHood

@SawyerHood SawyerHood commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

WS3 layer 1 of 5 (projection + renderers + mobile). Stack base: main. Do not merge — the coordinator reviews, Sawyer merges the stack.

What was wrong

The v3 stack (#2124#2136#2153#2148#2121#2164#2178#2179) made every bridge persist a presentation on each item and emit fileRead, search, delegation, planSteps and extension items. The projection still rendered from the legacy path: fileRead/search were bridged onto tool rows with a synthesized intent, planSteps only fed the todo banner, extension items fell through the dispatch loop and were dropped, item/delegation/progress was unhandled, and no TimelineRow carried the presentation (the canary's observations in STUB-INVENTORY: "extension rows do not render; row labels ignore presentation"). Two server gaps came with it: the delegated-child fetch and parent closure in the timeline service were keyed on itemKind = 'toolCall', so a v3 delegation item whose child turn fell outside the window lost its children, and the todo head-state backfill queried TodoWrite/Task* by tool name only, so a budgeted window could drop a v3 planSteps banner.

What changed

  • Contract (packages/server-contract/src/thread-timeline.ts): every work row projected from a provider item has an optional presentation (TimelineRowPresentation = the persisted ThreadEventItemPresentation); new file-read, search, plan-steps and extension work rows (extension requires presentation); delegation rows carry childRef and background.
  • Projection (packages/thread-view): web-activity-lifecycle is now the begin/end item family for web research plus the four new kinds, each settling with its own terminal status; delegation items take item/delegation/progress and revise their label; shouldSuppressLowValueToolCall honours presentation.suppress on every kind (failed/interrupted items always render; a suppressed planSteps still drives the banner); timelineRowActivityIntents derives the legacy read/search/list intent from a file-read/search row so bundles, dedupe, counts and compact rendering treat a v3 read like a legacy Read. Titles: a row with a presentation renders label[pending|completed] + its structured content (path, query, child description, or the bridge's title); pre-presentation rows keep the legacy derivation, so old threads render unchanged.
  • Server/db: listStoredDelegatingItemRowsByItemIds and the child fetch cover toolCall and delegation parents (two queries so the partial tool-call index stays in use; delegation rows walk the thread/type/kind index); listTodoSnapshotEventRowsForThread adds the latest planSteps snapshot by kind; CROSS_TURN_TOOL_ITEM_KINDS includes the v3 kinds.
  • client-core / app / mobile: render signatures include the presentation fields and the new rows; exhaustive switches know the new kinds. Rows are title-only here; layer 2 (web) and layer 3 (mobile) add the renderers.
  • Corpus harness: BB_PROVIDER_CORPUS_ALLOWLIST merges a repo-carried allowlist after the shared file; BB_PROVIDER_CORPUS_SNAPSHOT_DIR redirects write/compare to a shadow rows dir. This PR's allowlist: apps/server/test/provider-corpus/allowlists/ws3-projection-rows.json. Docs + script header updated.
  • No daemon wire change: projection is server → app; HOST_DAEMON_PROTOCOL_VERSION unchanged. No Drizzle change in this layer (layer 5 carries migration 0107).

Deferred to layer 5 with its migration: hasParentedEventCrossingSequence still probes toolCall parents only (the partial index predicate); a mid-delegation in-turn cut is correct but rereads descendants.

How you verified

  • packages/thread-view/test/v3-item-projection.test.ts rewritten: file-read/search rows equal legacy Read/Grep/Glob intents, bundle grouping, presentation-labelled tool rows (pending/completed/failed), presentation over statusLabels, planSteps row + banner, extension rows (completed + pending), v3 delegation fields, suppression across kinds. Harness gains planSteps/extension factories and presentation on every v3 factory. turbo test --filter=@bb/thread-view: 397 passed.
  • turbo typecheck --filter=...@bb/server-contract (48 packages) clean. turbo test for @bb/db, @bb/client-core, @bb/mobile, @bb/server-contract, @bb/provider-parity green; @bb/server 1896 passed, 1 failed = the known local umask 0002 internal-skill-trees mode 0644/0664 case (passes in CI).
  • A4 corpus against a baseline minted from origin/main 15f21ad (private shadow dir, not the shared baseline): 307 threads, 93,534 rows, 0 unlisted diffs, 566 allowed in one class — legacy delegation rows gain childRef: null / background: false. Perf gate green: walk 0.93–1.00× of baseline, latest 0.74–1.13× (load 3.3/16 cores).
  • A2 parity (pnpm parity --old ~/.bb/parity-old-main@15f21ade7 --new .): 39 passed, 0 failed, 13 skipped (pi in-process, model-list process-scoped). 29 allowlist entries under Project grammar v3 items to presentation-driven rows (WS3 layer 1) #2192: the presentation field on every presented row, childRef/background on delegation rows, and the claude plan-mode Read calls projecting as file-read rows.
  • G1 ratchet: 148 → 148 (flat; the drop is layer 5). G11 unhandled: unchanged per cell in the parity output (unhandled N→N).

AGENT GENERATED: by Claude Opus 5

The bridges now persist a presentation on every item and emit fileRead,
search, delegation, planSteps and extension items, but the projection
rendered from the legacy path: fileRead/search were bridged onto tool rows,
planSteps only fed the todo banner, extension items were dropped, and no
row carried the presentation.

- TimelineRow: every work row projected from a provider item carries the
  persisted `presentation`; new `file-read`, `search`, `plan-steps` and
  `extension` work rows; delegation rows carry `childRef` and `background`.
- thread-view: the begin/end item family (web-activity-lifecycle) covers
  the four new kinds with their own terminal status; delegation items take
  `item/delegation/progress`; suppression honours `presentation.suppress`
  on every kind (failed items always render); titles use the bridge label
  first and fall back to the legacy derivation for pre-presentation rows;
  exploration bundles, dedupe and counts treat a v3 read/search like a
  legacy Read/Grep through `timelineRowActivityIntents`.
- server/db: delegated-child fetch and parent closure cover v3 delegation
  items (children were orphaned when the parent fell outside the window);
  the todo head-state backfill includes the latest planSteps snapshot by
  kind.
- client-core/app/mobile: render signatures and exhaustive switches know
  the new kinds (title-only until the renderer layers land).
- Corpus harness: a PR carries its allowlist in the repo
  (BB_PROVIDER_CORPUS_ALLOWLIST) and snapshots into a shadow dir
  (BB_PROVIDER_CORPUS_SNAPSHOT_DIR); the shared baseline stays main-minted.

Corpus A4 vs a baseline minted from origin/main: one diff class, legacy
delegation rows gain `childRef: null` / `background: false`. Parity A2:
39 passed, 0 failed, 13 skipped; 29 entries for the presentation field,
the delegation fields and the file-read rows.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant