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:
@@ -8,6 +8,7 @@ import {
|
||||
recordObservation,
|
||||
recordCollision,
|
||||
recordIntervention,
|
||||
recordSuppression,
|
||||
updateInterventionStatus,
|
||||
} from '../memory/store.js';
|
||||
import { getGitStates, type GitState } from '../memory/db.js';
|
||||
@@ -144,7 +145,22 @@ export class PodMan {
|
||||
if (prior?.priorOutcome?.accepted && prior?.priorOutcome?.wasRealCollision) {
|
||||
collision.severity = 'critical';
|
||||
}
|
||||
if (!shouldIntervene(collision, prior)) return; // Loop B: policy gate
|
||||
if (!shouldIntervene(collision, prior)) {
|
||||
// Feature A — make the negative-feedback loop VISIBLE. If we stayed quiet
|
||||
// *specifically* because this signature was DISMISSED before, record a
|
||||
// durable suppressed-repeat event (timestamped now, at the repeat) so the
|
||||
// activity stream shows the learning instead of nothing.
|
||||
if (prior?.priorOutcome && !prior.priorOutcome.accepted) {
|
||||
void recordSuppression(
|
||||
collision,
|
||||
prior.priorOutcome.interventionId,
|
||||
prior.priorOutcome.recordedAt,
|
||||
).catch((err) =>
|
||||
console.error(`[memory] suppression record failed: ${(err as Error).message}`),
|
||||
);
|
||||
}
|
||||
return; // Loop B: policy gate
|
||||
}
|
||||
|
||||
this.activeConflicts.add(key); // claim now we're alerting; re-armed in onScreenFrame on resolution
|
||||
await recordCollision(collision);
|
||||
|
||||
Reference in New Issue
Block a user