Dependency DAG & Blast Radius
stratt advanced 7 min read
ELI5
The graph layer keeps a map of who-imports-whom. When you change a unit, blast radius is everyone downstream — found by walking the import arrows backwards. Cycles are illegal and detected before publish.
Technical Deep Dive
Dag Shape
flowchart LR subgraph Dag N["nodes: Map<uri, Unit>"] E["edges: Map<uri, Set<uri>>"] R["reverseEdges: Map<uri, Set<uri>>"] end BD["buildDag(registry)"] --> N BD --> E BD --> R R --> BR["blastRadius(uri) — reverse BFS"] E --> TS["topologicalSort — Kahn"] E --> DC["detectCycles — Kahn + DFS"]Operations (packages/graph/src/)
| Function | File | Purpose |
|---|---|---|
buildDag(registry, options?) | dag.ts | Async; builds nodes + forward + reverse edges |
detectCycles(dag) | dag.ts | Kahn’s algorithm; falls back to DFS for path reporting |
topologicalSort(dag) | dag.ts | Stable order for CI gate execution |
blastRadius(dag, uri) | blast.ts | Reverse BFS over reverseEdges |
resolveCrossSchemeImport(uri, resolvers) | choco-resolver.ts | IC-02 bridge dispatch |
runCi(dag, gates) | ci.ts | FM-01..FM-08 gate runner |
Cross-Scheme Imports (IC-02)
When buildDag encounters a non-strat:// URI it walks the optional BridgeResolver[] — first match resolves; an unmatched URI raises FM-02 (unresolved import). Resolved units are inserted as nodes like any other but flagged with their source scheme.
Failure Modes (Phase 1)
FM-01 cycle, FM-02 unresolved import, FM-03 schema invalid, FM-04 fingerprint mismatch, FM-05 lifecycle violation, FM-06 namespace collision, FM-07 draft-isolation breach. FM-08 is deferred.
Key Terms
- Reverse edge → an entry mapping a unit to the set of units that import it; the source of truth for blast radius.
- Kahn’s algorithm → in-degree-driven topological sort used both for ordering and primary cycle detection.
- FM-02 → the failure mode raised when a
BridgeResolverchain cannot resolve a non-strat://URI.
Q&A
Q: Why is buildDagSync deprecated?
A: BridgeResolver resolution is async (it can hit network, R2, or another registry); a sync builder forced fake-sync wrappers and was removed.
Q: Does blast radius include deprecated consumers?
A: Yes — they are still importing the unit. Filtering by status is the caller’s job.
Examples
Changing strat://core/rule/no-secrets@1.0.0 returns a 47-URI blast radius via reverse BFS; runCi schedules verification of those 47 in topological order before approving the new release.
neighbors on the map
- Unit Schema Types authoring a new prompt unit
- NATS Event Bridge subscribing a Choco service to STRATT lifecycle events