Status: Accepted Date: 2026-04-04 Decision Level: Constitutional (SOUL Law #4) Context: TDD-Inside-Spec Implementation
Trinity follows spec-first philosophy where .t27/.tri files are the single source of truth. Zig, C, and Verilog are generated backends only.
Prior to this ADR, there was ambiguity about when Zig could be written directly:
- Some agents wrote CLI logic directly in
src/**/*.zig - Runtime layer had domain logic in handwritten Zig
- No clear enforcement mechanism for spec-first workflow
This violated the core Trinity principle and created technical debt.
No new Trinity business logic handwritten in Zig.
- Source of truth: All new Trinity logic (CLI, runtime, numeric, physics, graph, agents) is specified only in
.t27/.tri.- Backends only: Zig, C, Verilog, and Rust exist only as generated backends from
.t27/.triviatri gen.- Temporary bootstrap: New
.zigfiles are allowed only as temporary bootstrap (I/O, process startup). Domain logic in Zig is forbidden.- Migration debt: Any existing handwritten Zig with domain logic must have an explicit migration task into
.t27/.tri. Do not add new debt.- Enforcement:
tri lintfails if new.zigfiles appear without ageneratedmarkertri git push --strictblocks push if Zig diffs undersrc/fail checks
Zig files are ONLY permitted in these cases:
-
Generated backends - Files with the mandatory header:
// This file is generated from <spec_path> // DO NOT EDIT - Changes will be overwritten on next tri gen // Generated at: <timestamp> // Source spec: <spec_path>
-
Bootstrap layer - Temporary I/O and process startup code:
src/bootstrap/*.zig- OS integration, file I/O basics- No domain logic (no Trinity-specific algorithms, math, physics, etc.)
-
Legacy quarantine - Existing Zig being migrated:
contrib/backend/zig/legacy/*.zig- Handwritten code awaiting migration- Each file must have
TODO: migrate to .t27 speccomment
-
Hardware bridge - FPGA bindings and external system interfaces:
contrib/backend/bridges/*.zig- Foreign function interfaces only (if present)
Writing Zig directly is FORBIDDEN for:
- CLI commands and routing
- Runtime domain logic (beyond basic I/O)
- Numeric/mathematical operations
- Sacred physics formulas
- Graph algorithms
- Agent orchestration
- Test frameworks
- Any Trinity-specific business logic
# CORRECT: Spec-first
1. Write spec in .t27
$ vim specs/numeric/gf16.t27
# (include test blocks!)
2. Generate backend
$ tri gen specs/numeric/gf16.t27
# Generates: src/numeric/gf16.zig with DO NOT EDIT header
3. Use generated code
$ zig build test
# INCORRECT: Writing Zig directly
$ vim src/numeric/gf16.zig # FORBIDDENtri lint enforces:
$ tri lint src/numeric/gf16.zig
error: Zig file lacks generated header
Expected: "// This file is generated from..."
File: src/numeric/gf16.zig
Hint: Write spec in .t27 first, then run tri gen
$ tri lint src/bootstrap/main.zig
ok: bootstrap file (no domain logic detected)
$ tri lint contrib/backend/zig/legacy/old_code.zig
warning: legacy file detected
Status: awaiting migration to .t27
Hint: Create migration task for this filetri git push --strict blocks:
$ tri git push --strict
error: strict mode violation
Modified Zig files without generated header:
- src/cli/commands.zig (handwritten)
- src/runtime/executor.zig (handwritten)
Action required:
1. Write .t27 specs for this logic
2. Run 'tri gen' to generate Zig
3. Commit generated files (with DO NOT EDIT header)GitHub Actions reject:
- PRs with new handwritten Zig in
src/(outsidebootstrap/) - PRs modifying generated Zig without corresponding
.t27changes - PRs with legacy Zig lacking migration task
- Single source of truth - All logic lives in
.t27specs - Multi-target codegen - Same spec generates Zig, C, Verilog
- AI agent alignment - Agents always check
.tricontext first - Clear boundaries - No ambiguity about where logic belongs
- Initial migration cost - Existing handwritten Zig needs migration
- Bootstrap complexity - Temporary layer adds indirection
- Toolchain dependency - Requires functional
tri genfor all work
All existing handwritten Zig with domain logic must be migrated:
- Create
.t27spec describing the logic - Add test blocks to spec (TDD-Inside-Spec)
- Run
tri gento produce Zig - Delete handwritten Zig (move to
legacy/if needed for reference) - Update imports and build system
- Rejected: Too easy to ignore warnings, defeats the purpose
- Rejected: Fragmentation, makes single-source-of-truth unclear
- Rejected: CLI has significant domain logic (validation, routing)
- ADR accepted
- SOUL Law #4 added to SOUL.md
- Linter implementation
- Git push --strict implementation
- CI/CD gate implementation
- Legacy Zig audit and migration plan
- ADR-001: De-Zigfication (original high-level principle)
- SOUL.md: Constitutional Laws
- docs/nona-03-manifest/GENERATED-HEADER-POLICY.md: Header specification
- compiler/runtime/runtime.t27: CLI runtime specification (source of truth)