Document: cr-seed-viewer-v0_1
Version: v0.1
Date: 2026-06-28
Type: Phase change request — frontend only (Operator Layer loomworks repo). No engine change — the read endpoint already exists.
Consumer: Claude Code (executor).
Branch base: feat-companion-surface @ 9667d60 (current OL HEAD after the create-restore build this session — NOT dac9fec).
Governing scoping note: loomworks-seed-viewer-scoping-note-v0_1.
Grounding: loomworks-seed-model-grounding-inspection-v0_1 + the CR-drafting grounding pass (the GET …/seed route, SeedPayloadResponse, InEngagementHeader.tsx, DraftSpecification.tsx, the projects client — engine @ 5ccc3d7, OL @ 9667d60).
When you create an engagement, the Companion builds its seed with you and you watch it take shape. After you commit, that seed vanishes from view — the in-engagement screen shows the four rooms, the title, and the focus chip, but nowhere to see the engagement's own foundation document. This adds a way to view the committed seed: what the work is, who it's for, the voice, the constraints, the success conditions — the engagement's commitments, readable any time, with its version. View only — no editing (that's the separate seed editor, which builds on this). The engine already serves the seed; this is purely surfacing it.
5ccc3d7 / OL 9667d60)The engine is done — better than the scoping note assumed:
GET /engagements/{engagement_id}/seed (seed_view.py:34-47, mounted app.py:687) returns SeedPayloadResponse. It resolves both states (active via seed_ref; candidate via candidate_seed_id) and scopes across the ADMIN-commons + engagement homes. Errors: 404 (engagement/seed-ref missing), 500 (ref present, seed not in log).SeedPayloadResponse (schemas.py:2234) returns named fields, and the schema Field(title=…) labels are already Operator vocabulary: what_the_work_is ("What the work is"), who_consumes_the_work ("Who consumes the work"), voice_of_the_work ("Voice of the work"), constraints ("Constraints"), success_conditions ("Success conditions"), plus seed_version ("Seed version") and engagement_title. Also carries initial_contributors/initial_agents (UUID lists, R-A10), additional_assertions (dict, R-A11), and is_divergent/divergence_rationale (R-A16.3).get_current_contributor (engagement-scoped, same model as GET /engagements/{id} — dual cookie/bearer path, 403 on non-membership, with the Phase-25 candidate special-case letting the creator read a candidate). The CR inherits this — no new auth.The frontend has nothing:
fetchSeed client method. SubstrateRow.seed_id exists on the wire (projects.ts:22) but the mappers drop it; ProjectSummary (types.ts:312) carries no seed field. No fetchSeed/getSeed anywhere in src/lib. (The seed_id on the list row is only the pointer; the full payload comes from the GET-seed route.)DraftSpecification.tsx is NOT reusable. It's create-bound — takes a single pre-formatted string blob + a readiness label and renders it in a <pre>, consuming the creation-time draft_specification string. The committed viewer needs a new structured field/value renderer (the endpoint returns fields, not a blob). Its vellum-Card / expandable pattern is a visual reference to match, not a reuse.InEngagementHeader.tsx shows only name + identifier/chip. Desktop right cluster (:126-163): focus chip + sort-order toggle + Avatar. Mobile (:73-103): back chevron + name/context + Avatar. The seed has no seat — this is the gap. The sort-toggle button styling (:148-161 — h-[26px] w-[26px] rounded-lg border border-rule bg-surface-1) is the affordance template to match.Net: frontend-only, three pieces. The substrate (versioning, retention, the read route, auth, the structured response) is entirely done.
Aligned — the seed is the engagement's foundation document; an Operator should be able to see the commitments they work against. "Only show what is available" applies: the seed is available (served, structured, auth-scoped); its absence from the surface is the surface failing to show it. Read-only respects Operator-authority cleanly — viewing changes nothing, so there is no state-transition concern in this piece (that arrives with the editor).
DraftSpecification (which is create-bound and blob-based). Match DraftSpecification's vellum-Card / expandable visual pattern so it reads native."Foundation document · version N" from seed_version). Version history browsing is deferred (pairs with the editor, which produces new versions worth browsing).InEngagementHeader — desktop right cluster (a button beside the sort toggle, matching its styling), mobile near the name. Opens the viewer.Render the Operator-facing commitments, in the schema's plain-terms labels:
what_the_work_is)who_consumes_the_work)voice_of_the_work)constraints — a list)success_conditions)seed_version)
Deferred / not rendered in this piece (named): initial_contributors/initial_agents (UUID lists — need name resolution to be Operator-legible, a separate concern), additional_assertions (dict — render shape TBD), is_divergent/divergence_rationale (a divergence-state concept that wants its own treatment). Lean: render the five core commitments + version now; the others are a follow-on once their display is designed. Confirm — if you want contributors/agents shown, that's a name-resolution add; flag it rather than dump UUIDs (which would violate "never show the UUID").
Per-step commits, suite green at each, halt-before-push. Frontend only; no engine, no migration.
Confirm against feat-companion-surface @ 9667d60:
9667d60.InEngagementHeader desktop right cluster (:126-163) and mobile header (:73-103) — confirm the seat for the open-affordance and the sort-toggle styling template.src/lib/api/ — how a sibling read method is shaped (e.g. fetchConversationHistory, the projects fetchers) so fetchSeed follows it.SeedPayloadResponse field names as the client type — mirror the engine schema exactly (snake_case wire → the client maps as the codebase does elsewhere).Report findings, then build.
fetchSeed client method + type
Add to src/lib/api/ (a seed.ts or the natural home per the Step-0 idiom):
SeedPayload client interface mirroring SeedPayloadResponse's rendered fields (seed_id, seed_version, engagement_title, what_the_work_is, who_consumes_the_work, voice_of_the_work, constraints, success_conditions, and the deferred fields typed but not necessarily rendered).fetchSeed(engagementId): Promise<SeedPayload> → GET /engagements/{engagementId}/seed, following the existing client-fetch idiom (error handling consistent with siblings — a 404/500 surfaces as a load error the viewer shows, not a crash).Suite expectation: new client method; add a unit test mirroring sibling fetch-method tests (success maps fields; error surfaces).
A new structured field/value renderer (SeedViewer.tsx or similar) in the in-engagement surface directory:
SeedPayload (or fetches via fetchSeed on open — Step-0 decides fetch-on-open vs. passed-in)."Foundation document · version {seed_version}").DraftSpecification's vellum-Card / expandable treatment so it reads as native chrome (reference, not reuse).
Suite expectation: component test — renders the fields from a SeedPayload, shows the version line, handles loading + error. New tests; existing unaffected.
In InEngagementHeader.tsx:
:126-163, beside the sort toggle), matching the sort-toggle styling (h-[26px] w-[26px] rounded-lg border border-rule bg-surface-1). Label/icon: a "view foundation document" affordance (a document/seed glyph or a "Foundation" control — plain-terms, per the Step-0 vocabulary check).:73-103).SeedViewer per the Step-0 open-mechanism (panel/overlay/expandable).Suite expectation: header test — the affordance renders (both layouts) and opens the viewer; existing header tests unaffected.
Note: Steps 2 and 3 may share a commit if the open-mechanism couples them tightly; per-step is preferred but CC's call if the seam is cleaner combined.
GET …/seed (proven against a real engagement with a committed seed; e.g. one of the existing engagements — Goosey/E0007 has a committed seed).TagChipArea.test.tsx tsc errors confirmed at 9667d60 baseline are not this CR's — leave them.)revise_seed/considerations machinery) is the next piece and depends on this one.main — lands on feat-companion-surface; merge is a separate authorization.DUNIN7 — Done In Seven LLC — Miami, Florida Change Request — Seed viewer (in-engagement) — v0.1 — 2026-06-28 A read-only viewer of the committed seed (the five core commitments + version) opened from the in-engagement header, over the existing GET /engagements/{id}/seed route. Frontend-only — the engine serves a structured, plain-terms, auth-scoped response already. A new field/value renderer (DraftSpecification is create-bound, not reusable). Read-only — the prerequisite for the seed editor. Base 9667d60.