incident-correlation
Walks the Kinetic Gain Protocol Suite document graph and turns an AI Incident Card into a structured remediation plan. When a tool, an agent, or a vendor's AEO disclosure misbehaves in production, the honest question is what else does this touch? This crate answers it with one BFS.
use ;
let mut g = default;
g.add_node;
g.add_node;
g.add_node;
g.add_node;
g.add_edge?;
g.add_edge?;
let incident = IncidentCard ;
let plan = default.correlate?;
for n in &plan.affected_nodes
# Ok::
What it answers
When an AI Incident Card lands, you have the names of the directly-affected docs. You don't have the things you really need to do next:
- Which agent-cards depend on the affected tool?
- Which decision-cards approved the affected vendor — and therefore which PolicyBundles are now suspect?
- Which AEO entities mention the affected entity?
- What's the right urgency for each follow-up call?
IncidentCorrelator::correlate returns a [RemediationPlan] with one [AffectedNode] per touched document, the BFS depth, a recommended [Action], and a plain-English rationale you can paste into a ticket.
How the BFS works
- Seed nodes are the ids in
incident.affected_documents(depth 0). - At each step we walk incoming edges — "what depends on this" rather than "what does this depend on" — because the propagation we care about is downstream.
- We follow
DependsOnandApprovedBy.Mentionsis informational and is NOT followed (it would over-fan the plan into the long tail of papers that quote the affected entity once).
The default urgency table follows the SRE workbook intuitions:
| severity | depth 0 | depth ≥ 1 |
|---|---|---|
| critical | Critical (page) | High |
| high | High | Normal |
| medium | Normal | Normal |
| low | Low | Low |
The action a node gets depends on its NodeKind:
| Node kind | Recommended action |
|---|---|
IncidentCard |
Page |
DecisionCard |
RecheckPolicy |
Vendor |
RequestReview |
| anything at depth 0 with severity=critical | Page |
| everything else | Revalidate |
Override the table by reading the BFS output and re-deriving your own actions; the structure is small and serde-serialisable.
Composes with
- procurement-decision-api — the Decision Cards we walk.
- policy-as-code-engine — the
RecheckPolicyaction drivesPOST /bundles/{id}/evaluatecalls against the bundles those cards produced. - aeo-validator-service —
Revalidateactions on AEO nodes turn intoPOST /watches/{id}/recheckcalls. - reliability-toolkit-rs — wrap the outbound recheck calls in a circuit breaker + retry.
Same flavour as the rest of the portfolio: small surface, composable, no surprises.
API surface
| Type | Notes |
|---|---|
SuiteGraph |
Typed graph (petgraph under the hood). add_node / add_edge are the whole API. |
SuiteNode |
{ id, kind, label }. |
SuiteEdge |
DependsOn / ApprovedBy / Mentions. |
NodeKind |
Aeo / AgentCard / ToolCard / DecisionCard / IncidentCard / Vendor. |
IncidentCard |
Trimmed view of the v0.1 spec — only the fields the correlator reads. |
IncidentCorrelator |
correlate(&graph, &incident) -> Result<RemediationPlan, _>. |
RemediationPlan |
affected_nodes: Vec<AffectedNode>, summary: String, helpers affected(kind) and has_page(). |
Action / Urgency |
enums; serde-serialised as snake_case. |
Run the example
Builds the toy graph above, walks it for a high-severity tool incident, and prints the plan.
Bench
The bundled bench builds a 1000-agent fanout off a single tool-card and times the correlator. Order-of-magnitude reference, not a vendor pitch.
Tests
CI matrix: stable, beta, 1.85.0 (MSRV).
License
MIT. See LICENSE.