242 lines
5.5 KiB
Markdown
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.
|