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

Loomworks — Engagement activity observability — Scoping note

Version. 0.1 Date. 2026-05-02 Provenance. Claude.ai scoping session. Operator: Marvin Percival. Status. Working draft. Noted for next session.


The problem

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. With real activity across three rooms — shapes producing, renders running, confirmations pending — this is untenable. The Operator's observation: "you really have to hunt around to see what is happening."

Additionally, once the Operator finds an event (a shape, a render, an assertion), there is no way to inspect its full history — what triggered it, what version of what it ran against, when each state transition happened, the raw content. Events are first-class objects in the methodology. They should be inspectable.


Three layers

Layer 1 — Room tab activity indicators

The room switcher bar (Memory 14 · Manifestation v1 · Shaping 3 · Rendering 10) gains a pulsing dot on any room tab where jobs are currently running.

Data source. New substrate endpoint:


GET /engagements/{eid}/activity-summary
Returns:
{
  "shaping": { "running": 2, "pending_confirmation": 9 },
  "rendering": { "running": 1, "pending_action": 0 },
  "memory": { "pending_commit": 3 }
}

Queries shaping_jobs and render_jobs for status IN ('queued', 'dispatched'), and shape_events_view/current_memory_objects for pending states.

Frontend. The RoomSwitcher component fetches activity-summary on load and on a 10-second polling interval. A pulsing green dot appears next to the count badge on any room with running > 0. A static amber dot for rooms with items awaiting Operator action (pending_confirmation > 0, pending_commit > 0).

No new pages. No modals. Just dots on tabs the Operator is already looking at.

Layer 2 — Room-level activity banner

Inside each room, above the content, a banner summarizes running and pending activity for that room. Not a generic message — named items with elapsed time.

Shaping room banner examples:

> 1 shape producing — "Goosey Finds the Lost Duckling - Beni,Cata,Luca" via lost-duckling-story-pages · started 45s ago > 9 shapes awaiting confirmation across 2 shapings

Rendering room banner examples:

> 1 render producing — "Animated Story AAA" · Storybook rule specialist · started 2 min ago

Memory room banner examples:

> 3 assertions in held state — awaiting commit

Each named item links to or scrolls to the relevant card in the room. The banner collapses to nothing when there's no activity — no empty-state message.

Data source. The room pages already fetch their data (shapes, renders, assertions). The banner derives from the same data — filter by running/pending state, format for display. The activity-summary endpoint from Layer 1 provides the counts; the room's own data provides the names.

Layer 3 — Event detail drill-down

Click any shape event card, render event card, or assertion to expand a detail panel showing the full birth certificate.

Shape event detail panel:

| Field | Source | |---|---| | Title | title (Operator-entered) | | State | state with colored dot | | Produced at | produced_at timestamp | | Triggered by | triggered_by actor name and kind | | Trigger type | trigger (contributor_request / agent_request) | | Against Manifestation | manifestation_object_id · version manifestation_version | | Shaping | shaping slug · version shaping_version | | Executor | agent display_name · instruction version | | Seed version at production | seed_version_at_production | | Engagement version at production | engagement_version_at_production | | Selection criterion | selection_criterion (from the shape type) | | Selected memory refs | List of version-pinned memory refs with display labels | | Excluded but considered | List with reasons | | Confirmation | who confirmed, when, terminal (attest/no_change/amend/retire) | | Content | expandable "Show content" revealing produced_shape_content in a MarkdownPanel |

Render event detail panel:

| Field | Source | |---|---| | Source shape | source_shape_title with shape event ref | | Render type | name and consumer declaration | | Format | render_format badge | | Specialist | name · instruction version | | Triggered by | actor name and kind | | Trigger type | explicit_request / declared_auto | | Produced at | timestamp | | State | produced / retired / invalidated | | Retirement/invalidation reason | if applicable | | Content | expandable "Show content" revealing render_content in a MarkdownPanel | | Download | DOWNLOAD button (reuses existing download infrastructure) |

Assertion detail panel:

| Field | Source | |---|---| | Display number | display_number | | Content | assertion text | | State | held / committed / redirected | | Contributor | who contributed, when | | Committer | who committed, when | | Contribution mode | text / voice / image | | Relationships | list of linked concepts | | Redirect target | if redirected, which engagement |

UI pattern. Expanding a card pushes down the cards below (same pattern as "Show content" and "Shaping details"). The detail panel uses a consistent two-column label/value layout in caption-weight type. The content section is a separate expandable within the detail panel.

Data source. Most fields are already on the response schemas. Some may need additions:

CC should audit the current response schemas against the detail panel fields at Step 0 and add any missing fields.


Scope calls

N1 — Should the activity-summary endpoint be engagement-scoped or engagement-and-room-scoped?

Position A (engagement-scoped, single endpoint). One call returns counts for all rooms. Frontend distributes to tabs. Simpler. One poll instead of four.

Position B (room-scoped, per-room endpoint). Each room fetches its own activity. More targeted. But the room tabs need all rooms' data, so the switcher would still need to call all four.

Recommendation: Position A. The switcher needs all rooms' data. One endpoint, one poll.

N2 — Polling interval for tab indicators

10 seconds is responsive enough for "is something running" without hammering the server. The room-level banners can poll faster (or derive from the room's own data refresh).

N3 — Should the detail panel be a separate page or an inline expansion?

Position A (inline expansion). Same page. Click to expand, click to collapse. Consistent with existing "Show content" and "Shaping details" patterns.

Position B (separate detail page). /engagement/[id]/shapes/[shape_id] etc. Full page for the event. More room for content. Linkable.

Recommendation: Position A for now. The inline pattern is established. A separate page is a future extension if the detail panel gets too large.

N4 — Phase number or untagged?

This is a significant UX addition (new endpoint, polling infrastructure, detail panels across three rooms). Probably warrants a phase number. But the Operator should decide.


What this does not build


Estimated shape

Substrate: 1 new endpoint (activity-summary), response schema additions for missing detail fields (~5–10 fields across shape/render/assertion responses). ~8 tests.

Frontend: RoomSwitcher polling + dots, 3 room-level banners, 3 detail panel components (shape, render, assertion). ~12 component tests.

Medium-sized CR. 6–8 steps.


DUNIN7 — Done In Seven LLC — Miami, Florida Engagement activity observability — Scoping note — v0.1 — 2026-05-02