Skip to content

Commit cd8bfb5

Browse files
refactor(dashboard): remove unfed dashboard surfaces
1 parent 1ee8c79 commit cd8bfb5

7 files changed

Lines changed: 30 additions & 57 deletions

File tree

dashboard/src/data/sse/connect.test.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,16 @@ describe("dashboard SSE wire bridge", () => {
9292
connection.close();
9393
});
9494

95+
it("subscribes only to server-emitted code-index activity", () => {
96+
vi.stubGlobal("EventSource", FakeEventSource);
97+
const connection = connectEvents("/api/events");
98+
const source = FakeEventSource.instances[0]!;
99+
100+
expect(source.listeners.has("code_index")).toBe(false);
101+
expect(source.listeners.has("code_index_activity")).toBe(true);
102+
connection.close();
103+
});
104+
95105
it("projects accepted events to live pulses carrying their own scope identity", () => {
96106
vi.stubGlobal("EventSource", FakeEventSource);
97107
const connection = connectEvents("/api/events");

dashboard/src/data/sse/connect.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ const DASHBOARD_EVENT_NAMES = [
55
'heartbeat',
66
'project_registry',
77
'storage_telemetry',
8-
'code_index',
98
// Live agent activity, coalesced server-side to at most 2/s per family per
109
// project. Named events are opt-in, so a new family must be listed here.
1110
'hook_activity',

dashboard/src/data/sse/reseed.dom.test.tsx

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,8 @@ async function tick(emit: () => void): Promise<void> {
154154
/** Open a canonical refresh with a revision gap and leave it in flight. */
155155
async function openRefreshWithGap(source: FakeEventSource): Promise<void> {
156156
await tick(() => {
157-
source.emit('code_index', frame('code_index', NEUTRAL_FAMILY, 1));
158-
source.emit('code_index', frame('code_index', NEUTRAL_FAMILY, 5));
157+
source.emit('code_index_activity', frame('code_index_activity', NEUTRAL_FAMILY, 1));
158+
source.emit('code_index_activity', frame('code_index_activity', NEUTRAL_FAMILY, 5));
159159
});
160160
}
161161

@@ -211,7 +211,7 @@ describe('SSE canonical refresh — signals during the window', () => {
211211
// flag, so this signal only survives if the reducer remembers it as an
212212
// epoch the in-flight refresh cannot claim to have covered.
213213
await tick(() => {
214-
source.emit('code_index', frame('code_index', NEUTRAL_FAMILY, 20));
214+
source.emit('code_index_activity', frame('code_index_activity', NEUTRAL_FAMILY, 20));
215215
});
216216
expect(refresh.spy).toHaveBeenCalledTimes(1);
217217

@@ -226,15 +226,15 @@ describe('SSE canonical refresh — signals during the window', () => {
226226
// its commit ends the chain because no newer signal arrived.
227227
for (let revision = 21; revision <= 25; revision += 1) {
228228
await tick(() => {
229-
source.emit('code_index', frame('code_index', NEUTRAL_FAMILY, revision));
229+
source.emit('code_index_activity', frame('code_index_activity', NEUTRAL_FAMILY, revision));
230230
});
231231
}
232232
expect(refresh.spy).toHaveBeenCalledTimes(2);
233233

234234
await settleRefreshes(() => refresh.resolveAll());
235235
for (let revision = 26; revision <= 30; revision += 1) {
236236
await tick(() => {
237-
source.emit('code_index', frame('code_index', NEUTRAL_FAMILY, revision));
237+
source.emit('code_index_activity', frame('code_index_activity', NEUTRAL_FAMILY, revision));
238238
});
239239
}
240240
expect(refresh.spy).toHaveBeenCalledTimes(2);
@@ -254,7 +254,7 @@ describe('SSE canonical refresh — signals during the window', () => {
254254
// The queue overflows while that refresh is still in flight.
255255
await tick(() => {
256256
for (let revision = 6; revision <= 6 + MAX_QUEUED_EVENTS; revision += 1) {
257-
source.emit('code_index', frame('code_index', NEUTRAL_FAMILY, revision));
257+
source.emit('code_index_activity', frame('code_index_activity', NEUTRAL_FAMILY, revision));
258258
}
259259
});
260260
expect(reducerStats().stale).toBe(true);
@@ -281,7 +281,7 @@ describe('SSE canonical refresh — failure is not success', () => {
281281

282282
await tick(() => {
283283
for (let revision = 1; revision <= MAX_QUEUED_EVENTS + 1; revision += 1) {
284-
source.emit('code_index', frame('code_index', NEUTRAL_FAMILY, revision));
284+
source.emit('code_index_activity', frame('code_index_activity', NEUTRAL_FAMILY, revision));
285285
}
286286
});
287287
expect(refresh.spy).toHaveBeenCalledTimes(1);
@@ -302,13 +302,13 @@ describe('SSE canonical refresh — failure is not success', () => {
302302
// Nor is a failure a retry trigger: re-issuing the identical refresh every
303303
// tick is the storm the coalescing clock exists to prevent.
304304
await tick(() => {
305-
source.emit('code_index', frame('code_index', NEUTRAL_FAMILY, MAX_QUEUED_EVENTS + 2));
305+
source.emit('code_index_activity', frame('code_index_activity', NEUTRAL_FAMILY, MAX_QUEUED_EVENTS + 2));
306306
});
307307
expect(refresh.spy).toHaveBeenCalledTimes(1);
308308

309309
// A genuinely newer signal is a new attempt, though — here a reconnect.
310310
await tick(() => {
311-
source.emit('code_index', frame('code_index', NEUTRAL_FAMILY, 1, RECONNECTED_RUN_ID));
311+
source.emit('code_index_activity', frame('code_index_activity', NEUTRAL_FAMILY, 1, RECONNECTED_RUN_ID));
312312
});
313313
expect(refresh.spy).toHaveBeenCalledTimes(2);
314314
expect(refresh.spy).toHaveBeenLastCalledWith();

dashboard/src/data/sse/throughput.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ interface Body {
4040
*/
4141
function envelope(revision: number, filler = ""): SseEventEnvelope<Body> {
4242
return {
43-
stream: { stream_id: "code_index", generation: 1 },
44-
event_id: `run-1-1700000000000000:code_index:${revision}`,
43+
stream: { stream_id: "code_index_activity", generation: 1 },
44+
event_id: `run-1-1700000000000000:code_index_activity:${revision}`,
4545
revision: { event_revision: revision, entity_revision: revision },
4646
scope: '{"project_id":"project.alpha","storage_mode":"profile_sharded"}',
4747
observation_time: String(1_700_000_000_000_000 + revision),

dashboard/src/workspaces/loom/LoomPage.dom.test.tsx

Lines changed: 9 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -230,29 +230,6 @@ const TEMPORAL = {
230230
'provider-qualified session_git_spans rows for the displayed session page',
231231
},
232232
},
233-
{
234-
id: 'delivery_outcomes',
235-
label: 'Pull request, review, CI & release outcomes',
236-
state: 'unsupported',
237-
authority: null,
238-
granularity: 'Delivery projection row',
239-
providers: [],
240-
item_count: null,
241-
reason:
242-
'the shared Delivery overview is mounted, but its outcome projections are unavailable or unsupported and do not expose session-linked rows; Loom does not duplicate them',
243-
required_authority:
244-
'GET /api/delivery/overview with session-linked pull_requests, review_comments, ci_checks, failure_localization, and releases rows',
245-
coverage: {
246-
completeness: 'unsupported',
247-
eligible: null,
248-
examined: null,
249-
matched: null,
250-
omitted: null,
251-
unit: null,
252-
reason:
253-
'coverage belongs to the shared Delivery projection once it serves session-linked rows',
254-
},
255-
},
256233
],
257234
commits: [
258235
{
@@ -334,6 +311,15 @@ afterEach(() => {
334311
});
335312

336313
describe('LoomPage', () => {
314+
it('does not present unfed Delivery outcomes as a Loom relation', async () => {
315+
renderLoom();
316+
317+
const row = await screen.findByText('Deliver Git primitive runtime');
318+
await userEvent.click(row);
319+
320+
expect(screen.queryByText('→ delivery outcomes')).toBeNull();
321+
});
322+
337323
it('draws the weave from the typed Loom temporal read', async () => {
338324
const fetchMock = serve(HAPPY);
339325
vi.stubGlobal('fetch', fetchMock);
@@ -389,11 +375,6 @@ describe('LoomPage', () => {
389375
expect(
390376
screen.queryByText(/no sessionfile or sessioncommit route/),
391377
).toBeNull();
392-
expect(
393-
screen.getAllByText(
394-
/GET \/api\/delivery\/overview with session-linked pull_requests/,
395-
).length,
396-
).toBeGreaterThanOrEqual(1);
397378
});
398379

399380
it('states which threads have no recorded extent, with the real count', async () => {
@@ -430,7 +411,6 @@ describe('LoomPage', () => {
430411
expect(screen.getByText('Session ↔ commit')).toBeTruthy();
431412
expect(screen.getByText('Session → edited file')).toBeTruthy();
432413
expect(screen.getByText('Branch & worktree spans')).toBeTruthy();
433-
expect(screen.getByText('Pull request, review, CI & release outcomes')).toBeTruthy();
434414
expect(screen.getByText(/commit_sessions/)).toBeTruthy();
435415
});
436416

dashboard/src/workspaces/loom/LoomPage.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,6 @@ export function LoomPage() {
142142
span.provider === selected.host && span.session_id === selected.sessionId,
143143
)
144144
: [];
145-
const deliveryStatus =
146-
data.source_statuses.find((source) => source.id === 'delivery_outcomes') ?? null;
147145
const commitStatus =
148146
data.source_statuses.find((source) => source.id === 'session_commit') ?? null;
149147
const branchStatus =
@@ -276,7 +274,6 @@ export function LoomPage() {
276274
branchSpans: selectedSpans,
277275
commitStatus,
278276
branchStatus,
279-
deliveryStatus,
280277
}}
281278
/>
282279
</aside>

dashboard/src/workspaces/loom/ThreadChain.tsx

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import {
2020
* This is the "selecting a thread isolates its chain" half of the Loom:
2121
* prompt → tools comes from session detail, then provider-qualified edits,
2222
* commits and branch/worktree spans continue from the Loom temporal read.
23-
* Delivery outcomes terminate in the shared route's typed dependency state.
2423
*
2524
* One further honesty point drives the whole layout: the LCM session endpoint
2625
* may omit `timestamp`, so the chain is always ordered by the store's
@@ -33,7 +32,6 @@ export interface ThreadRelations {
3332
branchSpans: readonly LoomBranchSpan[];
3433
commitStatus: LoomSourceStatus | null;
3534
branchStatus: LoomSourceStatus | null;
36-
deliveryStatus: LoomSourceStatus | null;
3735
}
3836

3937
export function ThreadChain({
@@ -267,7 +265,6 @@ function ChainTerminus({
267265
branchSpans,
268266
commitStatus,
269267
branchStatus,
270-
deliveryStatus,
271268
} = relations;
272269
return (
273270
<div className="flex flex-col gap-3">
@@ -356,16 +353,6 @@ function ChainTerminus({
356353
)}
357354
</CausalGroup>
358355

359-
<CausalGroup label="→ delivery outcomes">
360-
<StateChip
361-
kind={deliveryStatus?.state ?? 'unknown'}
362-
detail={
363-
deliveryStatus?.required_authority ??
364-
deliveryStatus?.reason ??
365-
'Loom temporal response omitted the Delivery dependency status'
366-
}
367-
/>
368-
</CausalGroup>
369356
</div>
370357
);
371358
}

0 commit comments

Comments
 (0)