Files
podman/shared/src/graph.ts
T
sb-iam 65764f0a1c 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>
2026-06-28 09:35:56 -07:00

108 lines
2.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Continual-learning graph: PodMan's visible "it learned" surface. A render of
* the per-pod team_model — who owns/edits which files, where work collides, and
* what PodMan learned from accepted interventions (the `learned_from` edges).
*
* Served embedded in the `team_model` document; mirrored into `graph_nodes` /
* `graph_edges` collections so the model can be walked with MongoDB
* `$graphLookup`. See docs/cont_learning.md.
*/
export type PodGraphNodeKind = 'engineer' | 'feature' | 'file' | 'collision' | 'intervention';
export type PodGraphEdgeKind =
'owns' | 'editing' | 'touches' | 'collides' | 'warns' | 'learned_from';
/** `learned` marks a node PodMan retained from a past accepted intervention. */
export type PodGraphNodeStatus = 'stable' | 'active' | 'risk' | 'learned';
export interface PodGraphNode {
/** Stable graph id, e.g. "engineer:karti" or "file:auth.ts". */
id: string;
kind: PodGraphNodeKind;
label: string;
summary: string;
/** 01 relative importance — drives node size in the viz. */
weight: number;
status: PodGraphNodeStatus;
/** Layout position on the SVG canvas (viewBox 0..720 x 0..472). */
x: number;
y: number;
}
export interface PodGraphEdge {
id: string;
/** Source node id. */
source: string;
/** Target node id. */
target: string;
kind: PodGraphEdgeKind;
label: string;
/** 01 confidence/strength — drives edge thickness. */
strength: number;
}
export interface PodGraphMetric {
label: string;
value: string;
detail: string;
}
export type PodLearningLoopStepKey = 'observe' | 'store' | 'predict' | 'outcome' | 'adapt';
export type PodLearningLoopStepStatus = 'quiet' | 'active' | 'complete' | 'planned';
export interface PodLearningLoopStep {
key: PodLearningLoopStepKey;
label: string;
value: string;
detail: string;
status: PodLearningLoopStepStatus;
}
export interface PodLearningLoop {
activeStep: PodLearningLoopStepKey;
steps: PodLearningLoopStep[];
}
export type PodGraphActivityKind =
| 'editing'
| 'collision'
| 'intervention'
| 'outcome'
| 'learned'
| 'suppressed'
| 'agent';
export interface PodGraphActivity {
id: string;
at: string;
kind: PodGraphActivityKind;
title: string;
detail: string;
nodeId?: string;
edgeId?: string;
}
/** A point-in-time render of a pod's team_model. */
export interface PodGraph {
podId: string;
/** ISO timestamp the snapshot was generated. */
generatedAt: string;
nodes: PodGraphNode[];
edges: PodGraphEdge[];
metrics: PodGraphMetric[];
loop?: PodLearningLoop;
activity?: PodGraphActivity[];
}
/** One node as a standalone document in the `graph_nodes` collection. */
export interface GraphNodeDoc extends PodGraphNode {
podId: string;
}
/** One edge as a standalone document in the `graph_edges` collection (for $graphLookup). */
export interface GraphEdgeDoc extends PodGraphEdge {
podId: string;
}