--- 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.