ADR-027
Strict L0 sublayer tiers + max 3 sibling deps + cargo timings per-crate budget
accepted · 2026-04-16 · L0 L0.5 · cites 6
0ADR-027: Strict L0 sublayer tiers + cargo timings budget #
Context #
ADR-022 lays out 14 foundation crates. Without internal discipline, L0 risks becoming a flat bag of crates with arbitrary cross-dependencies. We want the strongest possible compile DAG.
Decision #
Internal L0 tiers (sublayer discipline) #
L0 has 4 internal tiers, strict downward-only:
- Tier · Constraint · Crates
- **L0-tier-0** · LEAF — zero `nika-*` deps · `nika-core`, `nika-macros`
- **L0-tier-1** · depends on tier-0 only · `nika-error`, `nika-envelope`
- **L0-tier-2** · depends on tier-0+1, single domain · `nika-event`, `nika-binding-transform`, `nika-catalog-codegen`, `nika-schema-ast`
- **L0-tier-3** · depends on lower L0 tiers · `nika-catalog`, `nika-binding`, `nika-schema`
Hard rule: max 3 sibling L0 deps per L0 crate #
Hygiene vector 28 (check-l0-dep-fanout.sh) reads docs/workspace.toml and
asserts every L0 crate's sibling_deps array length ≤ 3.
nika-schema is at the limit (4 deps including nika-catalog); admission
spec must justify each dep.
`cargo timings` per-crate budget (vector 29) #
Each crate has compile_budget_secs in docs/workspace.toml:
[crates.nika-core]compile_budget_secs = 10[crates.nika-schema]compile_budget_secs = 30Hygiene vector 29 (check-cargo-timings.sh) runs cargo build --timings and
asserts no crate exceeds budget. CI ratchet — regression caught at PR time.
`cargo deny check duplicates` strict (vector 31) #
deny.toml configured to forbid duplicate crate versions in Cargo.lock.
Single-version policy across the workspace.
`cargo doc --document-private-items` clean (vector 32) #
Internal API documented with same rigor as public. No undocumented private items.
Consequences #
- ✅ Maximum compile parallelism (independent tier-0 + tier-1 crates compile concurrently)
- ✅ Forward-compat: adding a tier-4 means promoting one tier-3 first — conscious decision
- ✅ Predictable crate placement (mechanical sort test extends to internal tiers)
- ✅
cargo timingsbudget catches O(n²) trait-resolution regressions early - ✅
cargo deny duplicatespreventstokio-util 0.7+tokio-util 0.8ecosystem split - ❌ +5 hygiene vectors (28, 29, 30, 31, 32) — implementation cost ~4h
- ❌ Initial baseline: 14
cargo timingsmeasurements committed todocs/api-baselines/timings/<crate>.toml
Vector summary (Phase B + E adds) #
- # · Name · Tier · Mode · Source ADR
- 22 · check-no-async-in-l0 · P1 · full · (planned, PRE-DIAMOND)
- 23 · check-workflow-envelope · P0 · fast · ADR-021→082
- 24 · check-model-format · P0 · fast · ADR-021→082
- 25 · check-kind-closed-set · P0 · fast · ADR-021→082
- 26 · check-status-claims-sync · P1 · fast · (this session)
- 27 · check-file-loc · P1 · full · ADR-023
- 28 · check-l0-dep-fanout · P0 · fast · ADR-027
- 29 · check-cargo-timings · P2 · full · ADR-027
- 30 · check-public-api-baseline · P1 · full · ADR-024
- 31 · check-cargo-deny-duplicates · P1 · full · ADR-027
- 32 · check-cargo-doc-private · P2 · full · ADR-027
- 33 · check-workspace-toml-sync · P0 · fast · ADR-026
Total deployed at v0.81: 21 (current) + 12 (new) = 33 vectors.
Reference #
- ADR-022 (14-crate layout)
- ADR-026 (workspace.toml SSOT — provides metadata for vectors 28+29)
~/.claude/.../memory/feedback_l0_strict_sublayer_tiers.md
read at v0.107.0 · the decision record ships with the engine