Version. 0.1
Date. 2026-04-30
Author. Marvin Percival (DUNIN7), prepared via Claude.
Target. /Users/dunin7/loomworks-ui (frontend only). DUNIN7-M4 (MacMini).
Priority. Standard.
Confidential. Internal.
Companion to. Phase 27 scoping note v0.1, Phase 23 CR v0.1 (Shaping Room Redesign — the template), Phase 22 CR v0.1 (Rendering Room original build), methodology v0.19.
Status. First draft. Six scoping decisions (S1–S6). Three design questions resolved (N1–N3).
Phase 27 redesigns the Rendering room from flat sections to a status-first card layout — the same treatment Phase 23 applied to the Shaping room. The current layout (Phase 22) presents thirteen DeclaredRenderTypes as subsections within Build and Commons groups. Thirteen subsections with heading, metadata, and render cards is verbose and hard to scan. The redesign replaces flat subsections with compact expandable cards under retained group headings, letting the Operator scan all render types at a glance and drill into detail on demand.
This is a frontend-only phase. No substrate changes. The Rendering room data is already served by existing endpoints. All existing functionality — Request Render, inline content viewer, retire confirmation, invalidation display, retired/invalidated collapsible toggles, async production with job polling — is preserved. Only visual placement changes.
Layer 1 — Methodology document v0.19. Rendering produces the final artifact that the reader receives. The room's job is to make the Operator's relationship with Renders clear: what is produced, for whom, from what source, and what is the current state.
Layer 2 — Phase 23 CR v0.1. The card-layout template. Collapsed/expanded states, typography hierarchy, brand enforcement, "What is shaping?" toggle, "What is this?" on empty cards. This CR adapts the same pattern to the Rendering room's different structure (thirteen types in two groups, content viewer, format badges).
Layer 3 — Phase 22 CR v0.1. The current Rendering room. Group structure, DeclaredRenderType subsections, Render cards with metadata, Request Render modal, retire/invalidate flows, async production and job polling, content viewer.
Design decisions resolved in scoping. N1: group headings carry a count ("Build · 11 render types"). N2: all cards collapse on each page load (no localStorage persistence, matching Phase 23). N3: empty groups are hidden per "only show what is available."
phase-25-engagement-creation-ui. 1170 tests, 2 skips.phase-25-engagement-creation-ui. 113 component tests, 6 E2E (1 skipped). Lint + tsc + build + test clean. Fourteen surfaces.Phase 27 is frontend-only. The substrate is unchanged. All data the card layout needs is already served by existing endpoints (DeclaredRenderType list, Render list, render jobs, retire).
Archive this CR to docs/phase-crs/phase-27-cr-rendering-room-redesign-v0_1.md in the substrate repo.
Commit (substrate repo): Phase 27 step 0: CR archival.
The current Rendering room layout:
Replaced by:
Cards within each group stack vertically with {spacing.s-4} (1rem) gap. The order follows the DeclaredRenderTypes as they appear in the engagement's seed within each group.
The room page background remains env-rendering (#E6DCCA). Cards sit on {colors.bleached} (#FFFCF5) — raised above the room's atmospheric ground per the brand's paper hierarchy. Render rows inside expanded cards sit on {colors.cartridge} (#F2EDE0).
DeclaredRenderTypes are grouped by their category metadata from the seed. The Loomworks engagement has two groups: Build (eleven render types) and Commons (two render types).
Each group heading appears as {typography.h3} with a count suffix: "Build · 11 render types" and "Commons · 2 render types" in {colors.ink-faint} for the count portion. The count is dynamic — it reflects the actual number of DeclaredRenderTypes in the group.
Spacing between the group heading and its first card: {spacing.s-3} (0.75rem). Spacing between groups: {spacing.s-6} (1.5rem).
If a group has zero DeclaredRenderTypes, its heading does not appear. Per "only show what is available." The component filters groups before rendering — only groups with at least one DeclaredRenderType produce output.
If a future engagement's DeclaredRenderTypes carry no category metadata, the room falls back to a flat card list with no group headings. The card layout itself is unchanged — only the grouping layer is absent.
Each DeclaredRenderType is a card ({components.card}) in the collapsed state by default.
Layout: two-column. Left column (flex: 1) carries the content. Right column (flex-shrink: 0, right-aligned) carries the status.
Left column content:
{typography.h3} (IBM Plex Serif, 1.5rem, weight 500).{typography.display-italic} (IBM Plex Serif italic, 1.2rem, weight 400) with {colors.ink-faint}. Who this render type serves.{typography.caption} with {colors.brass}. Format: "From [source shape type name]" where the shape type name is in {colors.type-metal}. This is the inverse of Phase 23's "Produces" line — here each render type points back to the shape type it draws from.{typography.label} (IBM Plex Mono, uppercase, 0.18em tracking). The render format (e.g., .md, .docx) displayed as a small label badge with {colors.cartridge} background and {colors.type-metal} text. Positioned below the source line.Right column content:
{typography.label} (IBM Plex Mono, uppercase, 0.18em tracking). Produced Renders: {colors.state-attest} dot + "N PRODUCED". No Renders: {colors.rule} dot + "NO RENDERS".{typography.mono} with {colors.brass}. Relative time of the most recent produced Render (e.g., "2 days ago"). Absent when no Renders exist.
Interaction: the entire card is clickable. Cursor pointer. On hover, subtle elevation change per {components.card} hover state.
Clicking a collapsed card expands it. Clicking again collapses it. Only one card per group may be expanded at a time — expanding a card in a group collapses any other expanded card in that group.
The expanded card retains the collapsed header content at the top. Below it, a divider ({colors.rule}, 1px), then the card body containing Render rows (§9).
All cards default to collapsed on page load. No localStorage persistence (matching Phase 23).
Each active (produced) Render is a row on {colors.cartridge} (#F2EDE0) background with {spacing.s-3} padding and {spacing.s-2} gap between rows.
Row content:
{colors.state-attest} dot for produced state.{typography.body}.{typography.mono} with {colors.brass}. Resolved from the confirmed shape event reference. If resolution is unavailable, show "Shape [id-prefix]".{typography.caption} with {colors.ink-faint}.{typography.caption} with {colors.ink-faint}.Action button (produced Renders only):
{components.button-ghost} at the right edge of the row. Triggers the existing inline retirement confirmation (§9.3). Per "only show what is available" — no action buttons on retired or invalidated Render rows.Active Renders appear first, newest at top. This matches Phase 22's ordering within subsections.
Unchanged from Phase 22. Clicking "Retire" on a produced Render row expands an inline confirmation below the row (not a modal):
> Retire this Render? It will no longer be current. The Render content is preserved for reference.
Reason — text input. Required.
"Confirm retirement" — {components.button-ghost}. "Cancel" — text link.
On success: the Render moves to the retired section. State dot changes.
Below active Render rows, within the expanded card:
{colors.ink-faint} dot + "Retired" label, specialist, source, timestamp, reason. No action buttons.{colors.state-amend} dot + "Invalidated" label, specialist, source, timestamp, invalidation reason from drift detection metadata if available. No action buttons.Collapsible toggles are absent when their count is zero (not "Show retired · 0" — the toggle does not appear).
At the bottom of the expanded card, below Render rows and retired/invalidated sections:
{components.button-secondary} with type-metal border (§10). Visible when render candidates exist for this DeclaredRenderType (at least one confirmed Shape exists for the source shape type). Triggers the existing Request Render modal from Phase 22 — the modal is unchanged, only its trigger location moves from the subsection to the card's action row.The button is absent when no confirmed Shapes exist for the source shape type. Per "only show what is available."
Render rows sit on {colors.cartridge} (#F2EDE0). The Phase 23 contextual color rules apply:
{colors.type-metal} border, {colors.type-metal} text, transparent background. On hover: {colors.type-metal} background, {colors.bleached} text.{colors.type-metal} text, no border. On hover: subtle {colors.bleached} background.These rules ensure buttons remain visible against the warm cartridge tone — the same problem Phase 23 solved for Shaping rows.
A DeclaredRenderType card with no Renders (active, retired, or invalidated) shows in collapsed state:
{typography.body} with {colors.ink-faint}:> No Renders have been produced for this type.
"What is rendering?" expandable toggle positioned between the room header and the first group heading.
Collapsed state (default): a single clickable line — "What is rendering?" in {typography.body} with {colors.brass}, styled as a toggle with a chevron indicator.
Expanded state: the full explanation text on {colors.bleached} background with {spacing.s-4} padding. The text is derived from assertion #15 (the Rendering room explanation contributed in the operational work):
> Rendering produces the final artifact that the reader actually receives. > > Memory accumulates knowledge. Manifestation organizes it. Shaping selects and arranges it for a specific reader. Rendering produces the thing they hold in their hands — the document, the report, the guide, the reference, whatever form the reader needs. > > The distinction from Shaping: a Shaping says "here is the knowledge this reader needs, organized for them." A Render says "here is the actual document, in the actual format, ready to use." The Shaping is the organized material; the Render is the produced artifact. > > A render specialist produces the Render. The specialist knows how to turn shaped material into the right format — a methodology document, a contributor guide, a change request, a concept reference. Different specialists produce different formats from the same shaped material. > > Every Render records what it was produced from: which Shape, which specialist, what configuration was in force. If the specialist's instructions change, or the Shape changes, or the underlying Memory grows and a new Manifestation is derived, the lineage is visible. The Operator can always see what any Render was built from. > > Rendering is the end of the pipeline. Memory is knowledge. Manifestation is organization. Shaping is selection. Rendering is production. The reader receives the Render.
This is static text. Phase 28 replaces it with the live explains assertion from Memory.
The toggle collapses the explanation on second click.
DeclaredRenderType cards with no Renders show a "What is this?" expandable link inside the expanded card body, below the empty-state message.
Collapsed state: "What is this?" as a text link in {typography.caption} with {colors.brass}.
Expanded state: the DeclaredRenderType's consumer_declaration field, rendered in {typography.body} with {colors.ink-faint}.
When the explains pattern extends to DeclaredRenderTypes (Phase 28), this link reads from Memory instead of the consumer_declaration field.
The toggle collapses on second click.
The Phase 22 async production flow (§11 of that CR) is preserved, repositioned into the card layout:
After a Render is requested via the modal:
{typography.caption} with {colors.ink-faint}).
Poll GET /render-jobs/{jobid} at 3-second intervals. Unchanged from Phase 22.
On success: the new Render row appears in the card body. The collapsed card's status badge updates ("N PRODUCED" increments). Polling stops.
On failure: an error message appears inline in the card body. Polling stops.
If polling exceeds 120 seconds, stop polling and show: "Render production is taking longer than expected. Refresh the page to check for results." Unchanged from Phase 22.
Update existing Rendering room component tests to reflect the new layout. CC writes or updates tests to cover:
Existing modal tests (Request Render) should still pass — the modal is unchanged.
Auto-mode posture: Step 0 auto. Steps 1–2 auto, Checkpoint A. Steps 3–4 auto, Checkpoint B (final).
Step 0 — CR archival.
Archive this CR to docs/phase-crs/phase-27-cr-rendering-room-redesign-v0_1.md.
Commit (substrate repo): Phase 27 step 0: CR archival.
Step 1 — Group headings, card layout, collapsed state.
Replace the flat-section layout with grouped card stacks. Implement group headings with count (§6). Implement collapsed card state (§7) with name, consumer declaration, source line, format badge, status badge, latest timestamp. Remove the old subsection-based components.
Verification: lint + tsc + build clean. Room renders with two groups and thirteen cards in collapsed state.
Commit (frontend repo): Phase 27 step 1: group headings and collapsed card state.
Step 2 — Expanded state, Render rows, action buttons, empty state, async production.
Implement expanded card state (§8). Render rows (§9) with content viewer toggle, retire confirmation, retired/invalidated collapsible sections. Action button contextual color rules (§10). Empty-state cards (§11). Async production within cards (§14). "Request render" button in action row with candidate-existence gate.
Verification: lint + tsc + build + test clean. Operator can expand cards, see Renders, retire, request new Renders.
Commit (frontend repo): Phase 27 step 2: expanded state, render rows, actions, async production.
Checkpoint A — Card layout functional. All existing operations work. Content viewer works within Render rows. Action buttons visible on cartridge ground. Operator confirms before explanation toggles and tests.
Step 3 — Room explanation toggle, "What is this?" toggle, component tests.
Implement "What is rendering?" toggle (§12). Implement "What is this?" on empty cards (§13). Write/update component tests (§15).
Verification: lint + tsc + build + test clean.
Commit (frontend repo): Phase 27 step 3: explanation toggles and component tests.
Step 4 — Implementation notes and tagging.
Create docs/phase-impl-notes/phase-27-implementation-notes-v0_1.md.
Commit (substrate repo): Phase 27 step 4: implementation notes.
Checkpoint B — Final. Both repos green. Tag both repos as phase-27-rendering-room-redesign.
Phase 27 is accepted when:
On acceptance: tag both repos as phase-27-rendering-room-redesign. Write implementation notes.
explains relationship pattern. Phase 28.explains assertions. Each DeclaredRenderType gets its own explanation from Memory. Phase 28.
Read the Change Request document at the path I supply below. This is
CR-2026-040 v0.1, the Phase 27 Change Request. You are the executing
agent named in the CR.
CR path: ~/Downloads/phase-27-cr-rendering-room-redesign-v0_1.md
Phase 27 redesigns the Rendering room from flat sections to a
status-first card layout. Same treatment as Phase 23 (Shaping room),
adapted for the Rendering room's structure (13 render types in 2
groups, content viewer, format badges).
Key design requirements:
- Each DeclaredRenderType is a compact card, not a subsection.
- Cards are grouped under Build and Commons headings with count
("Build · 11 render types").
- Cards expand on click to show Render rows within.
- Render rows sit on cartridge ground. Action button contextual
color rules per §10: secondary buttons get type-metal border,
ghost buttons get type-metal text.
- "Show content" toggle on Render rows (existing MarkdownPanel
viewer, repositioned).
- "Request render" button in expanded card action row — only when
confirmed Shapes exist for the source shape type.
- All cards collapse on page load (no localStorage persistence).
- Empty groups hidden. Format badge on collapsed cards.
- "What is rendering?" expandable toggle below room heading.
- "What is this?" expandable link on empty cards.
Frontend-only. No substrate changes. Substrate baseline: 1170 tests,
2 skips. Frontend baseline: 113 component tests, 6 E2E (1 skip).
Run Step 0: archive CR in substrate repo.
Steps 1–2 auto, Checkpoint A halts for smoke-test.
Steps 3–4 auto, Checkpoint B halts for tagging.
Brand enforcement: env-rendering (#E6DCCA) on outer frame. Bleached
(#FFFCF5) card backgrounds. Cartridge (#F2EDE0) Render rows.
No pure white. IBM Plex Serif for card names and room heading.
Inter for body. IBM Plex Mono for labels, status badges, format
badges. Audit before tagging.
Implementation notes at Step 4:
docs/phase-impl-notes/phase-27-implementation-notes-v0_1.md
DUNIN7 — Done In Seven LLC — Miami, Florida Phase 27: Rendering Room Redesign — CR v0.1 — 2026-04-30