DUNIN7 · LOOMWORKS · RECORD
record.dunin7.com
Status Current
Path phases/phase-33-engagement-activity-observability/phase-33-cr-engagement-activity-observability-v0_1.md

Loomworks — Phase 33: Engagement activity observability — CR

Version. 0.1 Date. 2026-05-03 CR number. CR-2026-045 Provenance. Claude.ai CR drafting session. Operator: Marvin Percival. Status. Working draft. Awaiting Operator approval. Scoping note. loomworks-activity-observability-scoping-note-v0_1.md (2026-05-02).


1. What this builds

The engagement has no central view of what's in flight. To discover that a shape is producing or a render is running, the Operator must open each room, expand each card, and look for status messages. This is untenable with real activity across three rooms.

This CR adds engagement activity observability in three layers:

Layer 1 — Room tab activity indicators. The RoomSwitcher gains pulsing dots: green for running jobs, amber for items awaiting Operator action. One new substrate endpoint, one 10-second poll.

Layer 2 — Room-level activity banners. Inside each room, above content, a banner names running and pending items with elapsed time. Links to or scrolls to the relevant card. Collapses to nothing when idle.

Layer 3 — Event detail drill-down. Click any shape event card, render event card, or assertion to expand a detail panel showing its full birth certificate — trigger, lineage, versions, content, state transitions.


2. Scope decisions consumed

From scoping note v0.1:

N1 — Engagement-scoped single endpoint (Position A). One activity-summary endpoint returns counts for all rooms. The RoomSwitcher needs all rooms' data. One poll, not four.

N2 — 10-second polling interval. Responsive enough for "is something running" without hammering the server.

N3 — Inline expansion (Position A). Detail panels expand inline on click, consistent with existing "Show content" and "Shaping details" patterns. Not separate pages.

N4 — Phase number. This is Phase 33.


3. Substrate changes

3.1 Activity summary endpoint

Add to the engagements router:


GET /engagements/{eid}/activity-summary

Response:
{
  "shaping": { "running": 2, "pending_confirmation": 9 },
  "rendering": { "running": 1, "pending_action": 0 },
  "memory": { "pending_commit": 3 }
}

Query logic:

The endpoint reads existing tables and views. No new migrations. No new MemoryObject types.

Response schema: ActivitySummaryResponse with nested RoomActivitySchema per room.

3.2 Response schema additions for detail panels

The detail panels specified in Layer 3 require fields that may not be on current response schemas. CC audits at pre-flight and adds any missing fields.

Shape event response — check and add if missing:

Render event response — check and add if missing:

Assertion response — check and add if missing:

CC should audit each response schema against the corresponding detail panel field list (§5.3) and add any fields that are stored but not surfaced. Fields that are not stored at all should be noted in the implementation notes as future additions, not invented.

3.3 Activity summary tests

New test file tests/test_activity_summary.py:

  1. test_activity_summary_empty_engagement — no jobs, no pending shapes, no held assertions. All counts zero.
  2. test_activity_summary_running_shaping_job — create a shaping job with status queued. Verify shaping.running == 1.
  3. test_activity_summary_pending_confirmation — create a shape event in pending state. Verify shaping.pending_confirmation == 1.
  4. test_activity_summary_running_render_job — create a render job with status queued. Verify rendering.running == 1.
  5. test_activity_summary_held_assertions — create a held assertion (contribute without commit). Verify memory.pending_commit == 1.
  6. test_activity_summary_mixed_states — running shaping + pending shapes + held assertions in same engagement. Verify all counts.
  7. test_activity_summary_excludes_completed — completed jobs and committed assertions do not appear in counts.
  8. test_activity_summary_wrong_engagement — activity in engagement A does not appear in engagement B's summary.

8 tests.


4. Frontend changes — Layer 1: Room tab activity indicators

4.1 Activity polling hook

Create a useActivitySummary hook:

4.2 RoomSwitcher dot indicators

The RoomSwitcher component (the tab bar showing Memory 14 · Manifestation v1 · Shaping 3 · Rendering 10) consumes useActivitySummary.

Pulsing green dot: appears next to the count badge on a room tab when that room has running > 0. CSS animation: opacity pulse between 1.0 and 0.4 on a 1.5-second cycle. The dot is small (6px diameter), positioned to the right of the room's existing count badge.

Static amber dot: appears next to the count badge when the room has items awaiting Operator action (pending_confirmation > 0 for Shaping, pending_commit > 0 for Memory). Amber dot takes precedence visually only when there is no green dot — if both running and pending, show the green pulsing dot (running is the higher-priority signal).

No dot: when all counts for a room are zero.

Manifestation room: no activity indicator. Manifestation derivation is synchronous (no background jobs).


5. Frontend changes — Layer 2: Room-level activity banners

5.1 Banner pattern

Each room gains a banner component rendered above the room's content, below the room heading (and below the room explanation toggle if present). The banner is a light-background strip that shows running and pending items.

When empty: the banner component renders nothing (no empty-state message, no placeholder).

Banner ground: var(--lw-color-background-subtle) or the room's environment tint at low opacity, with left border accent in the room tint color. Caption-weight type (Inter, 13px).

5.2 Per-room banner content

Shaping room banner:

Derives from the room's existing shape and shaping job data. Two sections:

Each named item links to or scrolls to the relevant card.

Rendering room banner:

Derives from the room's existing render and render job data. One section:

Memory room banner:

Derives from the room's existing assertion data. One section:

5.3 Data source

The banners derive from data already fetched by each room page. No additional API calls. The activity-summary endpoint (Layer 1) provides the counts for the tab dots; the room's own data provides the names and detail for the banners.


6. Frontend changes — Layer 3: Event detail panels

6.1 Interaction pattern

Clicking a shape event card, render event card, or assertion card expands a detail panel below the card's existing content. The panel uses the same inline-expansion pattern as "Show content" and "Shaping details" — click to expand, click to collapse, pushing cards below down.

The detail panel is separate from the existing "Show content" toggle. Both can be open simultaneously. The detail toggle label is "Details" (or "Birth certificate" if the Operator prefers — CC should use "Details" as the default label).

6.2 Detail panel layout

Consistent two-column label/value layout across all three panel types:

Panel background: var(--lw-color-background-subtle) (same as banner). Left border accent in room tint.

6.3 Shape event detail panel

| Field | Label | Value source | |---|---|---| | Title | Title | title (Operator-entered or auto-derived) | | State | State | state with colored dot (green=confirmed, amber=pending, gray=retired) | | Produced at | Produced | produced_at formatted timestamp | | Triggered by | Triggered by | triggered_by actor display_name and kind | | Trigger type | Trigger | trigger value | | Against Manifestation | Manifestation | manifestation_object_id · version manifestation_version | | Shaping | Shaping | shaping slug · version shaping_version | | Executor | Executor | agent display_name · instruction version | | Seed version | Seed version | seed_version_at_production | | Engagement version | Engagement version | engagement_version_at_production | | Selection criterion | Selection | selection_criterion | | Selected memory refs | Selected memory | List with display labels | | Excluded but considered | Excluded | List with reasons (collapsible if >3 items) | | Confirmation | Confirmation | who confirmed, when, terminal state | | Content | expandable | produced_shape_content in MarkdownPanel |

Fields that are null or absent on the response: omit the row entirely. Do not show empty rows.

6.4 Render event detail panel

| Field | Label | Value source | |---|---|---| | Source shape | Source shape | source_shape_title with shape event reference | | Render type | Render type | name and consumer declaration | | Format | Format | render_format badge | | Specialist | Specialist | name · instruction version | | Triggered by | Triggered by | actor display_name and kind | | Trigger type | Trigger | trigger value | | Produced at | Produced | timestamp | | State | State | produced / retired / invalidated with colored dot | | Retirement reason | Reason | if applicable (only shown when retired/invalidated) | | Content | expandable | render_content in MarkdownPanel | | Download | button | DOWNLOAD button (reuses existing download infrastructure) |

6.5 Assertion detail panel

| Field | Label | Value source | |---|---|---| | Display number | # | display_number | | Content | Content | assertion text (already visible, but included for completeness in panel) | | State | State | held / committed / redirected with colored dot | | Contributor | Contributed by | who, when | | Committer | Committed by | who, when (if committed) | | Contribution mode | Contributed via | text / voice / image / pdf | | Relationships | Related to | list of linked concept identifiers | | Redirect target | Redirected to | engagement name (if redirected) |

6.6 Component reuse

Create a shared DetailPanel component that takes a list of { label, value, type? } entries and renders the two-column layout. Each detail panel (shape, render, assertion) composes this shared component with its specific field list. The type field allows special rendering: "badge" for format badges, "dot" for state dots, "list" for memory ref lists, "expandable" for content sections, "button" for action buttons.


7. Frontend tests

7.1 Layer 1 tests

  1. test_activity_dot_green_when_running — mock activity-summary with shaping.running: 1. Verify green pulsing dot on Shaping tab.
  2. test_activity_dot_amber_when_pending — mock with memory.pending_commit: 3, memory.running: 0. Verify amber dot on Memory tab.
  3. test_activity_dot_green_priority — mock with shaping.running: 1, shaping.pending_confirmation: 5. Verify green dot (not amber) on Shaping tab.
  4. test_no_dot_when_idle — mock with all zeros. Verify no dots on any tab.

7.2 Layer 2 tests

  1. test_shaping_banner_running — render Shaping room with a running shaping job in the data. Verify banner shows "1 shape producing" with elapsed time.
  2. test_shaping_banner_pending — render with pending shapes. Verify banner shows pending count.
  3. test_rendering_banner_running — render Rendering room with a running render job. Verify banner shows running render.
  4. test_memory_banner_held — render Memory room with held assertions. Verify banner shows held count.
  5. test_banner_empty_no_render — render any room with no running/pending activity. Verify banner renders nothing.

7.3 Layer 3 tests

  1. test_shape_detail_panel_expands — click "Details" on a shape card. Verify the detail panel appears with Title, State, Produced at fields.
  2. test_render_detail_panel_expands — click "Details" on a render card. Verify panel appears with Source shape, Format, Specialist fields.
  3. test_assertion_detail_panel_expands — click "Details" on an assertion. Verify panel appears with Display number, State, Contributor fields.
  4. test_detail_panel_null_fields_hidden — render a shape detail panel where selected_memory_refs is null. Verify that row is not rendered.
  5. test_detail_panel_collapse — expand a detail panel, click "Details" again. Verify it collapses.

14 tests.


8. Order of operations

Step 0 — Pre-flight and CR archive.

Archive this CR to docs/phase-crs/phase-33-cr-engagement-activity-observability-v0_1.md.

Audit the current response schemas against the detail panel fields in §6.3, §6.4, §6.5:

Record which fields are present, which need adding, and which are not stored at all (noted for implementation notes, not invented).

Also audit the shaping_jobs and render_jobs tables/views to confirm the status field values and query patterns for the activity-summary endpoint.

Commit: Phase 33 step 0: CR archive and schema audit.

Step 1 — Activity summary endpoint and response schema additions.

Create the activity-summary endpoint per §3.1. Add the ActivitySummaryResponse and RoomActivitySchema schemas. Add any missing response fields identified in Step 0 per §3.2.

Verification: manual curl to the endpoint returns expected shape.

Commit: Phase 33 step 1: activity summary endpoint and schema additions.

Step 2 — Substrate tests.

Write the 8 tests per §3.3.

Verification: uv run pytest -v green. All existing tests still pass.

Commit: Phase 33 step 2: activity summary tests.

Step 3 — Room tab activity indicators (frontend).

Create useActivitySummary hook per §4.1. Update RoomSwitcher with dot indicators per §4.2. CSS for pulsing green dot and static amber dot.

Verification: lint + tsc + build clean.

Commit (frontend repo): Phase 33 step 3: room tab activity indicators.

Checkpoint A — Operator sees dots on room tabs. Produce a shape or trigger a render. Verify pulsing green dot appears on the relevant tab while the job runs. Verify amber dot for pending items.

Step 4 — Room-level activity banners (frontend).

Create banner components for Shaping, Rendering, and Memory rooms per §5. Banners derive from existing room data. No new API calls.

Verification: lint + tsc + build clean.

Commit (frontend repo): Phase 33 step 4: room-level activity banners.

Step 5 — Event detail panels (frontend).

Create shared DetailPanel component per §6.6. Create shape, render, and assertion detail panels per §6.3–§6.5. Add "Details" toggle to each card type. Wire up content expansion within detail panels.

Verification: lint + tsc + build clean.

Commit (frontend repo): Phase 33 step 5: event detail panels.

Step 6 — Frontend tests.

Write the 14 tests per §7. Update any affected existing tests.

Verification: lint + tsc + build + test clean.

Commit (frontend repo): Phase 33 step 6: frontend tests.

Step 7 — Implementation notes.

Write implementation notes to docs/phase-impl-notes/phase-33-implementation-notes-v0_1.md. Record any findings, schema gaps noted but not filled, and construction decisions made during execution.

Commit: Phase 33 step 7: implementation notes.

Checkpoint B — Final. Both repos green. Operator walks the full flow:

  1. Trigger a shape production. See green dot on Shaping tab. See banner in Shaping room with shape name and elapsed time. Click "Details" on the produced shape and inspect the birth certificate.
  2. Trigger a render. See green dot on Rendering tab. See banner in Rendering room. Click "Details" on the render.
  3. Contribute an assertion without committing. See amber dot on Memory tab. See banner in Memory room. Click "Details" on the assertion.

On acceptance: tag both repos as phase-33-engagement-activity-observability. Write implementation notes if not done at Step 7.


9. Acceptance gate

This CR is accepted when:

  1. Substrate: all tests pass (~1282+, 2 skips).
  2. Frontend: lint + tsc + build + test clean (~260+ vitest).
  3. Activity summary endpoint returns correct counts for running jobs, pending shapes, and held assertions.
  4. Green pulsing dot appears on room tabs during job execution.
  5. Amber dot appears on Memory tab when assertions are held.
  6. Shaping room banner shows running shape with name and elapsed time.
  7. Rendering room banner shows running render with specialist name.
  8. Memory room banner shows held assertion count.
  9. All three banners collapse to nothing when idle.
  10. Shape event "Details" panel shows birth certificate fields.
  11. Render event "Details" panel shows source shape, specialist, and trigger.
  12. Assertion "Details" panel shows contributor, mode, and relationships.
  13. Null/absent fields are omitted from detail panels (no empty rows).
  14. The DOWNLOAD button in the render detail panel works (reuses existing infrastructure).

10. Post-CR state


11. What this CR does not build


12. Kickoff prompt for the Claude Code session


Read the Change Request document at the path I supply below. This is
CR-2026-045 v0.1, the Phase 33 Change Request. You are the executing
agent named in the CR.

CR path: ~/Downloads/phase-33-cr-engagement-activity-observability-v0_1.md

Phase 33 adds engagement activity observability in three layers:
room tab indicators (pulsing dots), room-level activity banners
(named running items), and event detail drill-down (birth certificate
panels on shape, render, and assertion cards).

Key points:
  - One new substrate endpoint: activity-summary. Queries existing
    tables. No migrations.
  - Response schema audit at Step 0 — check shape, render, and
    assertion responses for detail panel fields. Add what's stored
    but not surfaced. Note what's not stored.
  - useActivitySummary hook with 10-second polling.
  - RoomSwitcher dots: green pulsing for running, amber for pending.
  - Banners derive from existing room data, no new API calls.
  - DetailPanel shared component, three specialized panels.
  - "Details" toggle on cards, separate from existing "Show content".

Substrate baseline: 1274 tests, 2 skips.
Frontend baseline: 246 vitest, lint + tsc + build + test clean.

Step 0: archive CR + schema audit. Steps 1–3 auto.
Checkpoint A halts for Operator to see dots on tabs.
Steps 4–7 auto. Checkpoint B halts for final smoke-test and tagging.

Implementation notes at Step 7:
docs/phase-impl-notes/phase-33-implementation-notes-v0_1.md

DUNIN7 — Done In Seven LLC — Miami, Florida Phase 33: Engagement Activity Observability — CR v0.1 — 2026-05-03