Files
correx/docs/decisions/adr-0000-invariants.md

242 lines
5.5 KiB
Markdown

---
name: "Adr 0000 Invariants"
description: "Foundational architectural invariants of the Correx system"
depth: 2
links: ["../index.md", "../architecture/overview.md", "../decisions/adr-0001-event-sourcing.md"]
---
# ADR 0000: architectural invariants of the correx system
**status:** accepted
**date:** 08.05.2026
**deciders:** Kami
---
## context
Correx is an event-sourced orchestration system with deterministic replay requirements, LLM-driven inference, and multi-layered execution (validation, approvals, tools, context synthesis, and transitions).
Without explicit invariants, the system risks:
* implicit coupling between modules
* nondeterministic behavior creeping into core logic
* inconsistent interpretation of event streams across bounded contexts
* broken replay guarantees under evolution of modules
This ADR defines the **hard architectural rules** that all other ADRs and implementation decisions must obey.
These invariants are not suggestions. They are constraints on system evolution.
---
## invariants
### 1. event log is the single source of truth
All system state MUST be derivable from the event stream.
* no hidden mutable state is allowed to influence execution outcomes
* all decisions, approvals, transitions, and tool executions MUST emit events
* projections are disposable and rebuildable at any time
implication:
* caching is allowed only if it is derivable from events
* any system behavior not reproducible from events is a bug
---
### 2. projections are bounded-context owned
Each bounded context owns its own projection(s).
* `sessions` owns session state projection
* `artifacts` owns artifact state projection
* `context` owns context assembly projection
* `validation` owns validation state projection
projections:
* MAY NOT mutate each other
* MAY NOT be shared as a global mutable model
* MAY be reconstructed independently from the event stream
implication:
* there is no “global system state object”
* cross-domain reasoning must go through events or read-only queries
---
### 3. deterministic core vs nondeterministic inputs separation
The system is split into two layers:
**deterministic core:**
* event handling
* state transitions
* approval logic
* validation routing decisions
* scheduling
**nondeterministic layer:**
* LLM inference
* tool output
* user input
* external system responses
rule:
* nondeterministic outputs MAY influence events
* but ONLY deterministic core may commit events
implication:
* LLMs propose; core decides
* tools suggest; core validates and records
---
### 4. no cross-module implementation dependencies inside core (outdated)
Inside `:core`, modules MAY depend only on:
* `:core:contracts` (or equivalent shared model module)
* or strictly lower-level primitives
forbidden:
* `context → validation`
* `validation → approvals`
* `router → kernel internals`
allowed:
* interaction only via:
* events
* interfaces
* explicit orchestration entrypoints
implication:
* core is a DAG, not a mesh
---
### 5. event causality is strictly linear per session
Within a single session:
* every event MUST have exactly one causation parent (except root)
* sequence ordering is total and monotonic
* correlation IDs define logical grouping but do not define ordering
implication:
* no ambiguous causality graphs
* replay is deterministic and linear
---
### 6. policy layer is absolute and non-overridable
Policy evaluation is the highest authority layer.
* approvals cannot override policy denial
* validation cannot bypass policy constraints
* tool execution cannot ignore policy results
policy failure is terminal for the operation path.
implication:
* approval system is not a security boundary; policy is
---
### 7. tool execution is sandbox-first by default
All tools:
* MUST declare execution tier
* MUST be assumed unsafe until validated
* MUST produce structured receipts
side effects:
* are only valid if captured in events
implication:
* “silent execution” is not allowed in system design
---
### 8. compression and summarization are non-authoritative
Any compressed, summarized, or derived representation:
* MUST NOT replace original events or artifacts
* MUST be reproducible from source data
* MUST be explicitly marked as derived
implication:
* no lossy compression in the source-of-truth layer
* only in read models
---
### 9. LLM outputs are untrusted until validated
Any output from inference:
* is considered a proposal
* cannot affect state unless validated and approved
* cannot bypass schema validation
implication:
* prompt injection is structurally contained, not just filtered
---
### 10. replay must be environment-independent
Replaying a session:
* MUST NOT depend on current system state
* MUST NOT depend on external services
* MUST NOT require live LLM calls (unless explicitly in “live replay mode”)
implication:
* full determinism is a first-class requirement, not a debug feature
---
## consequences
**positive:**
* system behavior remains consistent under evolution
* replay and debugging are guaranteed properties, not best-effort
* module boundaries become enforceable in code and architecture
* future distributed execution becomes feasible without redesign
**negative:**
* requires discipline in module design (especially core dependencies)
* increases upfront design overhead for new components
* forces strict separation between “thinking” and “executing” layers
---
## status
This ADR is foundational. All future ADRs are subordinate to these invariants. Any contradiction requires revision of this document before implementation proceeds.