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

322 lines
5.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: "Modules And Spec"
description: "Guide to module organisation and documentation standards"
depth: 2
links: ["../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:
```text id="bllgjv"
: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
2. implementation/design
defines:
* concrete architecture
* classes
* flow
* persistence
* threading
* algorithms
* data structures
this separation matters a lot.
recommended documentation structure
```text id="3ktksg"
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:
1.
`:core:events`
first because:
everything depends on event semantics.
must define:
* event contracts
* causation/correlation ids
* append guarantees
* replay guarantees
* snapshotting
* versioning
2.
`:core:sessions`
defines:
* lifecycle FSM
* ownership boundaries
* session projections
* cancellation semantics
3.
`:core:transitions`
defines:
* graph execution
* rule evaluation
* deadlock/cycle handling
* retry semantics
4.
`:core:artifacts`
defines:
* artifact contracts
* lineage
* validation ownership
* immutability guarantees
5.
`:core:validation`
defines:
* layered validation pipeline
* semantic validators
* policy interaction
* approval interaction
6.
`:core:context`
probably hardest subsystem after validation.
must define:
* layering
* token budgeting
* compression contracts
* dedup semantics
* rebuild rules
7.
`:core:approvals`
must be isolated and heavily specified.
8.
`:core:orchestration`
only AFTER the primitives exist.
because orchestration composes:
* events
* transitions
* approvals
* context
* inference
9.
`:core:inference`
provider abstraction.
10.
`:core:tools`
tool contracts + receipts.
11.
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:
```text id="n9z2y6"
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:
```text id="a1qoqm"
: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:
```text id="2vwe0o"
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.