feat(graph): record + surface suppressed-repeat activity at repeat time (Feature A) (#43)
Codex review fix. The earlier approach synthesized a 'suppressed' beat from every dismissed OUTCOME, which is wrong: a dismissal is not a later suppressed repeat, and the old dismissal timestamp sank below the 12-row activity cap (invisible). Now the negative-feedback loop is recorded WHEN IT HAPPENS. When shouldIntervene() returns false specifically because a signature was dismissed before (agent/podman.ts), the agent writes a durable SuppressionDoc to a new `suppressions` collection, timestamped at the repeat. graph/live.ts materializes those into kind:'suppressed' activity (recent -> surfaces at the top). The suppressed collision is never written to `collisions` (agent returns before recordCollision), so this is its own record. Verified end-to-end: a transient demo-pod suppression renders at the TOP of the activity stream; cleaned up after. shared build + backend/frontend typecheck + eslint pass. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -457,6 +457,31 @@ export async function materializePodGraph(podId: string): Promise<PodGraph | nul
|
||||
);
|
||||
}
|
||||
|
||||
// 7. Suppressed repeats: PodMan stayed quiet on a recurring collision because
|
||||
// the signature was dismissed before — the negative-feedback loop made visible
|
||||
// (Feature A). Stamped at repeat time, so it sorts as recent activity.
|
||||
const suppressionDocs = await c.suppressions
|
||||
.find({ podId })
|
||||
.sort({ suppressedAt: -1 })
|
||||
.limit(20)
|
||||
.toArray();
|
||||
for (const s of suppressionDocs) {
|
||||
const sFile = normalizeFile(s.file);
|
||||
if (!isFilePath(sFile)) continue;
|
||||
const sEngs = (s.engineers ?? []).join(' + ') || 'teammates';
|
||||
pushActivity(
|
||||
activity,
|
||||
{
|
||||
id: `suppressed:${s.id}`,
|
||||
at: s.suppressedAt,
|
||||
kind: 'suppressed',
|
||||
title: `Suppressed — ${shortLabel(sFile)} repeat silenced`,
|
||||
detail: `${sEngs} on ${sFile} recurred, but it was dismissed before — PodMan stayed quiet.`,
|
||||
},
|
||||
activityIds,
|
||||
);
|
||||
}
|
||||
|
||||
// Prune test-artifact engineers, then anything left orphaned by that.
|
||||
const dropNode = (id: string) => {
|
||||
b.nodes.delete(id);
|
||||
|
||||
Reference in New Issue
Block a user