CRUMB a card from devarno-cloud

Layer Architecture L0–L6

grace intermediate 5 min read

ELI5

The STRATT codebase is a seven-floor building. Water flows down: any floor can drink from a lower floor, but no floor pumps upward. The basement (fingerprint) knows nothing about the penthouse (docs site).

Technical Deep Dive

Source: architecture/GRACE-PROTOCOL-OVERVIEW.md lines 138–151.

Layer Map

LayerPackageResponsibility
L6MERIDIANAstro documentation site (Phase 2)
L5@stratt/cli21+ commands, all orchestration entrypoints
L4@stratt/irPortable execution IR (n8n, TypeScript, langchain targets)
L3.5@stratt/n8n-exporterChain → n8n workflow compiler
L3@stratt/graphDAG, blast radius, FM-01..FM-08 CI
L2@stratt/crdtYjs-based CRDT, 7 merge strategies
L1@stratt/schemaZod validators, URI parsing, SPUH encoding
L0@stratt/fingerprintCanonical serialisation → Blake3

Dependency Direction

flowchart TB
L6[L6 MERIDIAN<br/>Astro docs]
L5[L5 cli<br/>21+ commands]
L4[L4 ir<br/>execution IR]
L35[L3.5 n8n-exporter]
L3[L3 graph<br/>DAG + CI]
L2[L2 crdt<br/>Yjs]
L1[L1 schema<br/>Zod + URI + SPUH]
L0[L0 fingerprint<br/>Blake3]
L6 --> L5
L5 --> L4
L5 --> L35
L4 --> L3
L35 --> L3
L3 --> L2
L3 --> L1
L2 --> L1
L1 --> L0

Why Strict Downward

  • L0 has zero deps: portable, can be re-implemented in Rust/Python without touching higher layers.
  • L1 owns shapes: anything that needs to validate a unit imports L1, never inverse.
  • L3 owns invariants: FM-01..FM-08 live here so a single CI binary covers all checks.
  • L5 owns orchestration: every CLI command is a thin wrapper around lower-layer functions.

Cross-Layer Anti-Pattern

If @stratt/schema imports @stratt/graph, the build cycles. The protect.ts rule for FM-07 (draft isolation) lives in graph, not schema, precisely to prevent this.

Key Terms

  • L0 minimality → Fingerprint package depends only on Blake3 + a YAML parser; no STRATT internals.
  • L3.5 → Half-step layer for the n8n exporter so it can sit beside @stratt/ir without forcing IR to depend on it.
  • L6 MERIDIAN → Documentation site, generated from lower-layer artifacts; reads only.

Q&A

Q: Why is @stratt/n8n-exporter at L3.5 instead of L4? A: It is a chain compilation target, like @stratt/ir, but it doesn’t define an IR — it consumes one. Half-step keeps L4 conceptually clean.

Q: Can @stratt/cli import @stratt/fingerprint directly? A: Yes — downward-only is permissive. It often does, e.g. stratt fingerprint --verify.

Q: Where does councils/ live in the layer map? A: It is data, not code. Council YAMLs are read by L3 (FM-04 enforcement) and L5 (gate workflow). They do not have a layer assignment.

Examples

A new “blast radius visualiser” command goes at L5 (@stratt/cli), calls into L3 (@stratt/graph’s blast.ts), which traverses the DAG built from L1-validated units, whose fingerprints come from L0. No upward edges.

neighbors on the map