1 architecture guardrails and module tree tests
forgejo-actions edited this page 2026-07-11 12:38:13 +00:00

Architecture Guardrails And Module Tree Tests

Purpose

Architecture guardrails keep module boundaries, ownership rules, cleanup budgets, generated tokens, and forbidden call sites from drifting while the engine grows.

How It Works

Module-tree tests inspect the Rust module graph and named guard contracts. The JSON contract file describes expected roots, exports, imports, symbols, owner boundaries, and forbidden call sites. xtask and engine-health surfaces reuse the same ideas when reporting architecture drift.

The goal is not to freeze the codebase. The goal is to make boundary changes intentional and reviewable.

Steps

When adding a subsystem, decide whether it needs a guard before it spreads across modules. Prefer contract predicates over brittle string searches. If a guard fails, first decide whether the code crossed the boundary accidentally or whether the boundary itself should change.

Update contracts only when the new structure is the intended architecture.

Expected Outputs

A successful pass leaves module-tree tests green, architecture contracts aligned with intended ownership, and any changed guard documented through the contract rather than accidental imports.

Invariants

Guards should describe ownership boundaries, not implementation trivia. Cleanup budgets should be tied to actionable debt. Generated token expectations should fail when generated artifacts drift, not because a human edited output by hand.

Common Mistakes

Common mistakes include adding exceptions for convenience, encoding fragile string checks, updating contracts before checking whether the violation is real, or treating cleanup budgets as optional.

Recovery Paths

Failures usually name the guard and offending module, symbol, or call site. For module root or export failures, inspect the public re-export path. For forbidden call sites, move the dependency behind the owning API rather than adding another exception.