Files
correx/docs/modules/modules-and-spec.md
T

5.0 KiB
Raw Blame History

name, description, depth, links
name description depth links
Modules And Spec Guide to module organisation and documentation standards 2
../index.md
./core-module-spec.md
../design/structure.md

yes. and good catch — consistency matters here because the structure itself becomes architecture documentation.

id standardize on nested gradle modules only:

:apps
:apps:cli
:apps:server

:core
:core:events
:core:context
:core:validation
:core:transitions
:core:orchestration
:core:artifacts
:core:sessions
:core:approvals
:core:policies
:core:tools
:core:inference

:infrastructure
:infrastructure:persistence
:infrastructure:providers
:infrastructure:tools

:interfaces
:interfaces:api
:interfaces:cli

i would add:

  • :core:orchestration
  • :core:artifacts
  • :core:sessions

immediately.

because those are foundational. without them, responsibilities leak everywhere.

and yes — writing specs/design docs module-by-module is the correct approach.

BUT: you need two document types per module:

  1. contract/spec defines:
  • responsibilities
  • invariants
  • boundaries
  • public interfaces
  • forbidden dependencies
  • event ownership
  • lifecycle guarantees
  1. implementation/design defines:
  • concrete architecture
  • classes
  • flow
  • persistence
  • threading
  • algorithms
  • data structures

this separation matters a lot.

recommended documentation structure

docs/
├── architecture/
│   ├── system-overview.md
│   ├── event-model.md
│   ├── replay-model.md
│   ├── context-layers.md
│   └── security-boundaries.md
│
├── modules/
│   ├── core-events/
│   │   ├── spec.md
│   │   └── design.md
│   │
│   ├── core-context/
│   │   ├── spec.md
│   │   └── design.md
│   │
│   ├── core-validation/
│   │   ├── spec.md
│   │   └── design.md
│   │
│   └── ...
│
└── decisions/
    ├── adr-0001-event-sourcing.md
    ├── adr-0002-kotlin-choice.md
    └── ...

VERY important: use ADRs from the beginning.

Architecture Decision Records

because you WILL forget later:

  • why replay works this way
  • why approvals are append-only
  • why projections are disposable
  • why router is isolated

future-you will otherwise rewrite old mistakes.

recommended order for specs

this order minimizes architectural drift:

:core:events

first because: everything depends on event semantics.

must define:

  • event contracts
  • causation/correlation ids
  • append guarantees
  • replay guarantees
  • snapshotting
  • versioning

:core:sessions

defines:

  • lifecycle FSM
  • ownership boundaries
  • session projections
  • cancellation semantics

:core:transitions

defines:

  • graph execution
  • rule evaluation
  • deadlock/cycle handling
  • retry semantics

:core:artifacts

defines:

  • artifact contracts
  • lineage
  • validation ownership
  • immutability guarantees

:core:validation

defines:

  • layered validation pipeline
  • semantic validators
  • policy interaction
  • approval interaction

:core:context

probably hardest subsystem after validation.

must define:

  • layering
  • token budgeting
  • compression contracts
  • dedup semantics
  • rebuild rules

:core:approvals

must be isolated and heavily specified.

:core:orchestration

only AFTER the primitives exist.

because orchestration composes:

  • events
  • transitions
  • approvals
  • context
  • inference

:core:inference

provider abstraction.

:core:tools

tool contracts + receipts.

infrastructure modules

ONLY after contracts stabilize.

this is important: do NOT start with providers/tools/ui.

thats how orchestration architectures rot early.

for each module spec, define these sections

mandatory template:

1. purpose
2. responsibilities
3. non-responsibilities
4. invariants
5. public contracts
6. owned events
7. consumed events
8. state model
9. threading/concurrency model
10. failure semantics
11. replay semantics
12. persistence requirements
13. observability requirements
14. security boundaries
15. extension points
16. forbidden dependencies
17. open questions

this will massively reduce ambiguity later.

especially: “non-responsibilities” and “forbidden dependencies”

those prevent architecture erosion.

example:

:core:context

non-responsibilities:
- model execution
- persistence
- tool execution

forbidden dependencies:
- infrastructure modules
- websocket interfaces
- provider implementations

that sounds bureaucratic now. it becomes life-saving later.

one more recommendation: define module dependency rules EARLY.

example:

core modules may depend on:
- contracts
- lower-level core modules

core modules may never depend on:
- infrastructure
- interfaces
- apps

enforce this automatically eventually with:

  • archunit
  • detekt custom rules
  • dependency analysis plugin

because modular architectures silently decay otherwise.