322 lines
5.0 KiB
Markdown
322 lines
5.0 KiB
Markdown
---
|
||
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.
|
||
|
||
i’d 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.
|
||
|
||
that’s 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.
|