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

5.5 KiB

name, description, depth, links
name description depth links
Adr 0000 Invariants Foundational architectural invariants of the Correx system 2
../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.