Skip to content

Architecture Decision Records

The Design Invariants document captures what is true about Heddle's architecture and how it fails when violated. These ADRs capture the why — what alternatives were considered, what they would have cost, and why we rejected them.

ADRs are written once at decision time and not revised. If a decision changes, write a new ADR that supersedes the old one rather than editing the old text. This preserves the historical record of how the architecture evolved.

Format

Each ADR follows this skeleton:

  • Status — Accepted (the default for everything here), Superseded by ADR-NNN, or Deprecated.
  • Context — what problem the decision solves and what constraints shape it.
  • Decision — the chosen approach, stated as a single declarative sentence.
  • Alternatives considered — each option that was on the table, with the reason it lost.
  • Consequences — what this decision enables and what it costs.

Index

ID Title Pairs with
ADR-001 Stateless workers, no process-local cache Invariant 1
ADR-002 Deterministic router, no LLM in routing path Invariant 2
ADR-003 Shallow JSON Schema for I/O contracts Invariant 5
ADR-004 Skip-and-log on malformed messages, not crash Invariant 8
ADR-005 Subscribe before publish for request-reply Invariant 17
ADR-006 Tri-state synthesizer partition (succeeded / failed / in_flight) commit 15a9af4
ADR-007 Council synthesis budget and 5s per-turn floor council-howto
ADR-008 Council execution paths share one budget helper ADR-007
ADR-009 Per-goal state isolation, lockless concurrency Invariant 7
ADR-010 Condition-evaluation defaults — fail-closed by default, env-gated legacy Invariant 10
ADR-011 Pipeline parallel levels use FIRST_COMPLETED, not gather Invariant 16
ADR-012 Drop message-level retry fields Invariant 1
ADR-013 NATS auth model — multi-user, single account runbook: nats-acl-configuration

When to write a new ADR

Add an ADR when a design decision:

  • Was non-obvious — a reasonable person could have picked differently.
  • Will be revisited — future contributors will ask "why didn't we just X?" and need to find a real answer.
  • Touches a load-bearing invariant — something that, if reversed, would break the framework's value proposition.

Don't write ADRs for matters of style, library choice that could go either way, or implementation details below the invariant level. Those belong in code comments or the Coding Guide.