aw-spec-cli 0.1.7 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/.appweaver/DESIGN-FORMAT.md +200 -0
- package/assets/.appweaver/ORCH-DIALECT.md +156 -0
- package/assets/.appweaver/RULE-PARTITION.md +175 -0
- package/assets/.appweaver/STACK-PROFILES.md +461 -0
- package/assets/.appweaver/ai-rules.md +180 -0
- package/assets/.appweaver/domain.json +1 -0
- package/assets/.appweaver/extensions/.registry +19 -0
- package/assets/.appweaver/extensions/agent-context/README.md +57 -0
- package/assets/.appweaver/extensions/agent-context/agent-context-config.yml +4 -0
- package/assets/.appweaver/extensions/agent-context/commands/aw-spec.agent-context.update.md +26 -0
- package/assets/.appweaver/extensions/agent-context/extension.yml +37 -0
- package/assets/.appweaver/extensions/agent-context/scripts/bash/update-agent-context.sh +201 -0
- package/assets/.appweaver/extensions/agent-context/scripts/powershell/update-agent-context.ps1 +237 -0
- package/assets/.appweaver/extensions.yml +16 -0
- package/assets/.appweaver/feature.json +3 -0
- package/assets/.appweaver/init-options.json +9 -0
- package/assets/.appweaver/integration.json +15 -0
- package/assets/.appweaver/integrations/aw-spec.manifest.json +9 -0
- package/assets/.appweaver/interpreter/run-skill.py +1176 -0
- package/assets/.appweaver/memory/constitution.md +50 -0
- package/assets/.appweaver/orchestrator/.smoke-out/smoke.md +6 -0
- package/assets/.appweaver/orchestrator/AGENT-PROFILE.md +94 -0
- package/assets/.appweaver/orchestrator/README.md +300 -0
- package/assets/.appweaver/orchestrator/adapters/claude_agent_sdk.py +74 -0
- package/assets/.appweaver/orchestrator/adapters/google_antigravity.py +74 -0
- package/assets/.appweaver/orchestrator/modules/delta-design.orch.yaml +105 -0
- package/assets/.appweaver/orchestrator/modules/delta-spec.orch.yaml +101 -0
- package/assets/.appweaver/orchestrator/modules/domain-select.orch.yaml +90 -0
- package/assets/.appweaver/orchestrator/modules/lane-gate.orch.yaml +126 -0
- package/assets/.appweaver/orchestrator/modules/tech-select.orch.yaml +123 -0
- package/assets/.appweaver/orchestrator/orchestrator.py +1721 -0
- package/assets/.appweaver/orchestrator/rev-templates/ai-rules.reference.md +40 -0
- package/assets/.appweaver/orchestrator/rev-templates/delta-design-template.skeleton.md +101 -0
- package/assets/.appweaver/orchestrator/rev-templates/design-template.skeleton.md +245 -0
- package/assets/.appweaver/orchestrator/rev-templates/domain-constitution.skeleton.md +63 -0
- package/assets/.appweaver/orchestrator/rev-templates/domain-requirements.skeleton.md +48 -0
- package/assets/.appweaver/orchestrator/rev-templates/domain-rule-bindings.skeleton.md +59 -0
- package/assets/.appweaver/orchestrator/rev-templates/domain-rule-file.skeleton.md +39 -0
- package/assets/.appweaver/orchestrator/rev-templates/frontend-rule-file.skeleton.md +63 -0
- package/assets/.appweaver/orchestrator/rev-templates/tech-rule-bindings.skeleton.md +116 -0
- package/assets/.appweaver/orchestrator/rev-templates/technical-constitution.skeleton.md +106 -0
- package/assets/.appweaver/orchestrator/rev-templates/technical-rule-file.skeleton.md +54 -0
- package/assets/.appweaver/orchestrator/rev-templates/ui-constitution.skeleton.md +125 -0
- package/assets/.appweaver/orchestrator/rev-templates/ui-delta-design-template.skeleton.md +123 -0
- package/assets/.appweaver/orchestrator/rev-templates/ui-design-template.skeleton.md +294 -0
- package/assets/.appweaver/orchestrator/workflows/_smoke.orch.yaml +160 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-add-component.orch.yaml +270 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-adopt.orch.yaml +934 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-delta-design.orch.yaml +251 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-design.orch.yaml +265 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-slice.orch.yaml +437 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-build.orch.yaml +197 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-characterize.orch.yaml +475 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-close-delta.orch.yaml +181 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-constitution.orch.yaml +727 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-demo.orch.yaml +100 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-dependency-tree.orch.yaml +69 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-deploy.orch.yaml +85 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-design-ui.orch.yaml +386 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-design.orch.yaml +382 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-finalize-delta.orch.yaml +462 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-foundation.orch.yaml +265 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-implement-delta.orch.yaml +253 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-implement-ui.orch.yaml +267 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-implement.orch.yaml +287 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-inventory.orch.yaml +238 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-onboard.orch.yaml +1822 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-parity.orch.yaml +293 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-run.orch.yaml +194 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-select-domain.orch.yaml +83 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-select-feature.orch.yaml +128 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-select-stack.orch.yaml +296 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-specify.orch.yaml +439 -0
- package/assets/.appweaver/scripts/bash/aw-inventory.sh +17 -0
- package/assets/.appweaver/scripts/bash/aw-parity.sh +13 -0
- package/assets/.appweaver/scripts/bash/aw-rev-constitution.sh +13 -0
- package/assets/.appweaver/scripts/bash/aw-spec-actions.sh +2626 -0
- package/assets/.appweaver/scripts/bash/aw-xref.sh +15 -0
- package/assets/.appweaver/scripts/bash/common.sh +533 -0
- package/assets/.appweaver/scripts/powershell/aw-inventory.ps1 +17 -0
- package/assets/.appweaver/scripts/powershell/aw-parity.ps1 +13 -0
- package/assets/.appweaver/scripts/powershell/aw-rev-constitution.ps1 +13 -0
- package/assets/.appweaver/scripts/powershell/aw-spec-actions.ps1 +2232 -0
- package/assets/.appweaver/scripts/powershell/aw-xref.ps1 +15 -0
- package/assets/.appweaver/scripts/python/aw-component-catalog.py +121 -0
- package/assets/.appweaver/scripts/python/aw-inventory.py +1180 -0
- package/assets/.appweaver/scripts/python/aw-parity.py +380 -0
- package/assets/.appweaver/scripts/python/aw-rev-constitution.py +329 -0
- package/assets/.appweaver/scripts/python/aw-stack.py +1251 -0
- package/assets/.appweaver/scripts/python/aw-xref.py +1330 -0
- package/assets/.appweaver/scripts/python/validate_okf.py +352 -0
- package/assets/.appweaver/stack-profiles/angular.json +16 -0
- package/assets/.appweaver/stack-profiles/blazor-wasm.json +17 -0
- package/assets/.appweaver/stack-profiles/dotnet-webapi.json +15 -0
- package/assets/.appweaver/stack-profiles/go-chi.json +14 -0
- package/assets/.appweaver/stack-profiles/java-spring.json +16 -0
- package/assets/.appweaver/stack-profiles/nextjs.json +16 -0
- package/assets/.appweaver/stack-profiles/node-express.json +15 -0
- package/assets/.appweaver/stack-profiles/python-fastapi.json +16 -0
- package/assets/.appweaver/stack-profiles/react-vite.json +17 -0
- package/assets/.appweaver/stack-profiles/sveltekit.json +16 -0
- package/assets/.appweaver/stack-profiles/vue-vite.json +17 -0
- package/assets/.appweaver/stacks.json +3 -0
- package/assets/.appweaver/templates/constitution-domain-template.md +116 -0
- package/assets/.appweaver/templates/constitution-technical-template.md +108 -0
- package/assets/.appweaver/templates/constitution-ui-template.md +116 -0
- package/assets/.appweaver/templates/delta-design-template.md +69 -0
- package/assets/.appweaver/templates/delta-spec-template.md +63 -0
- package/assets/.appweaver/templates/design-template.md +383 -0
- package/assets/.appweaver/templates/okf-concept-template.md +114 -0
- package/assets/.appweaver/templates/parity-manifest-template.json +49 -0
- package/assets/.appweaver/templates/source-map-template.md +85 -0
- package/assets/.appweaver/templates/spec-template.md +309 -0
- package/assets/.appweaver/templates/ui-design-template.md +273 -0
- package/assets/foundations/dotnet/ModularMonolith/ModularMonolith.Reference.pack.txt +25248 -0
- package/assets/foundations/dotnet/ModularMonolith/ModularMonolith.pack.txt +5726 -0
- package/assets/foundations/dotnet/ModularMonolith/pack-foundation.ps1 +145 -0
- package/assets/foundations/dotnet/ModularMonolith/pack-foundation.sh +196 -0
- package/assets/foundations/dotnet/ModularMonolith/pack-reference-foundation.ps1 +157 -0
- package/assets/foundations/dotnet/ModularMonolith/pack-reference-foundation.sh +209 -0
- package/assets/foundations/dotnet/ModularMonolith/unpack-foundation.ps1 +126 -0
- package/assets/foundations/dotnet/ModularMonolith/unpack-foundation.sh +217 -0
- package/assets/foundations/dotnet/ModularMonolith/unpack-reference-foundation.ps1 +129 -0
- package/assets/foundations/dotnet/ModularMonolith/unpack-reference-foundation.sh +218 -0
- package/assets/foundations/dotnet/VerticalSlice/VerticalSlice.Reference.pack.txt +19318 -0
- package/assets/foundations/dotnet/VerticalSlice/VerticalSlice.pack.txt +2833 -0
- package/assets/foundations/dotnet/VerticalSlice/pack-foundation.ps1 +145 -0
- package/assets/foundations/dotnet/VerticalSlice/pack-foundation.sh +196 -0
- package/assets/foundations/dotnet/VerticalSlice/pack-reference-foundation.ps1 +157 -0
- package/assets/foundations/dotnet/VerticalSlice/pack-reference-foundation.sh +209 -0
- package/assets/foundations/dotnet/VerticalSlice/unpack-foundation.ps1 +126 -0
- package/assets/foundations/dotnet/VerticalSlice/unpack-foundation.sh +217 -0
- package/assets/foundations/dotnet/VerticalSlice/unpack-reference-foundation.ps1 +129 -0
- package/assets/foundations/dotnet/VerticalSlice/unpack-reference-foundation.sh +218 -0
- package/assets/foundations/dotnet/components/Email/README.md +119 -0
- package/assets/foundations/dotnet/components/Email/ReferenceEndpoints/SendEmailEndpoint.cs +84 -0
- package/assets/foundations/dotnet/components/Email/integration.md +300 -0
- package/assets/foundations/dotnet/components/Jobs/README.md +113 -0
- package/assets/foundations/dotnet/components/Jobs/integration.md +259 -0
- package/assets/foundations/dotnet/components/QrGenerator/README.md +85 -0
- package/assets/foundations/dotnet/components/QrGenerator/ReferenceEndpoints/GenerateQrEndpoint.cs +57 -0
- package/assets/foundations/dotnet/components/QrGenerator/integration.md +230 -0
- package/assets/foundations/dotnet/components/README.md +74 -0
- package/assets/guardrails/README.md +222 -0
- package/assets/guardrails/domain/healthcare/ai-rules.domain.md +34 -0
- package/assets/guardrails/domain/healthcare/api-versioning.domain.md +17 -0
- package/assets/guardrails/domain/healthcare/auditing.domain.md +97 -0
- package/assets/guardrails/domain/healthcare/authorization.domain.md +26 -0
- package/assets/guardrails/domain/healthcare/clinical-terms.md +20 -0
- package/assets/guardrails/domain/healthcare/coding-standards.domain.md +26 -0
- package/assets/guardrails/domain/healthcare/consent.md +19 -0
- package/assets/guardrails/domain/healthcare/cqrs.domain.md +12 -0
- package/assets/guardrails/domain/healthcare/data-classification.domain.md +28 -0
- package/assets/guardrails/domain/healthcare/dependency-policy.domain.md +11 -0
- package/assets/guardrails/domain/healthcare/dicom.md +15 -0
- package/assets/guardrails/domain/healthcare/domain-constitution.md +119 -0
- package/assets/guardrails/domain/healthcare/domain-driven-design.domain.md +28 -0
- package/assets/guardrails/domain/healthcare/eventing.domain.md +18 -0
- package/assets/guardrails/domain/healthcare/fhir.md +36 -0
- package/assets/guardrails/domain/healthcare/folder-structure.domain.md +25 -0
- package/assets/guardrails/domain/healthcare/hipaa.md +34 -0
- package/assets/guardrails/domain/healthcare/hl7.md +15 -0
- package/assets/guardrails/domain/healthcare/ihe-conformance.md +31 -0
- package/assets/guardrails/domain/healthcare/integration-terms.md +21 -0
- package/assets/guardrails/domain/healthcare/persistence.domain.md +20 -0
- package/assets/guardrails/domain/healthcare/terminology.md +30 -0
- package/assets/guardrails/domain/healthcare/testing.domain.md +15 -0
- package/assets/guardrails/domain/healthcare/ux/accessibility-standards.md +36 -0
- package/assets/guardrails/domain/healthcare/ux/content-design.md +32 -0
- package/assets/guardrails/domain/healthcare/ux/interaction-states.md +44 -0
- package/assets/guardrails/domain/healthcare/ux/journey-mapping.md +40 -0
- package/assets/guardrails/domain/healthcare/vertical-slices.domain.md +18 -0
- package/assets/guardrails/domain/healthcare/zero-trust.domain.md +12 -0
- package/assets/guardrails/domain/pharma/ai-rules.domain.md +32 -0
- package/assets/guardrails/domain/pharma/api-versioning.domain.md +20 -0
- package/assets/guardrails/domain/pharma/atc.md +22 -0
- package/assets/guardrails/domain/pharma/auditing.domain.md +90 -0
- package/assets/guardrails/domain/pharma/authorization.domain.md +25 -0
- package/assets/guardrails/domain/pharma/coding-standards.domain.md +28 -0
- package/assets/guardrails/domain/pharma/cqrs.domain.md +16 -0
- package/assets/guardrails/domain/pharma/data-classification.domain.md +24 -0
- package/assets/guardrails/domain/pharma/data-provenance.md +21 -0
- package/assets/guardrails/domain/pharma/dependency-policy.domain.md +11 -0
- package/assets/guardrails/domain/pharma/domain-constitution.md +113 -0
- package/assets/guardrails/domain/pharma/domain-driven-design.domain.md +36 -0
- package/assets/guardrails/domain/pharma/domain-requirements.sample.md +103 -0
- package/assets/guardrails/domain/pharma/eventing.domain.md +18 -0
- package/assets/guardrails/domain/pharma/fhir.md +31 -0
- package/assets/guardrails/domain/pharma/folder-structure.domain.md +26 -0
- package/assets/guardrails/domain/pharma/hl7.md +17 -0
- package/assets/guardrails/domain/pharma/idmp.md +26 -0
- package/assets/guardrails/domain/pharma/integration-terms.md +21 -0
- package/assets/guardrails/domain/pharma/ndc.md +28 -0
- package/assets/guardrails/domain/pharma/persistence.domain.md +23 -0
- package/assets/guardrails/domain/pharma/pharma-terms.md +27 -0
- package/assets/guardrails/domain/pharma/product-lifecycle.domain.md +30 -0
- package/assets/guardrails/domain/pharma/regulatory-compliance.md +19 -0
- package/assets/guardrails/domain/pharma/terminology.md +32 -0
- package/assets/guardrails/domain/pharma/testing.domain.md +19 -0
- package/assets/guardrails/domain/pharma/vertical-slices.domain.md +17 -0
- package/assets/guardrails/domain/pharma/zero-trust.domain.md +12 -0
- package/assets/guardrails/projects/dotnet-default-project/domain/domain-requirements.md +58 -0
- package/assets/guardrails/projects/dotnet-default-project/domain-rule-bindings.md +113 -0
- package/assets/guardrails/projects/dotnet-default-project/frontend/ui-requirements.md +43 -0
- package/assets/guardrails/projects/dotnet-default-project/service/technical-requirements.md +40 -0
- package/assets/guardrails/projects/dotnet-default-project/tech-rule-bindings.md +263 -0
- package/assets/guardrails/requirement-spec.txt +27 -0
- package/assets/guardrails/technology/dotnet-webapi/PACKAGING.md +184 -0
- package/assets/guardrails/technology/dotnet-webapi/api-versioning.md +44 -0
- package/assets/guardrails/technology/dotnet-webapi/auditing.md +96 -0
- package/assets/guardrails/technology/dotnet-webapi/authorization-matrix.md +14 -0
- package/assets/guardrails/technology/dotnet-webapi/authorization.md +39 -0
- package/assets/guardrails/technology/dotnet-webapi/clean-architecture.md +54 -0
- package/assets/guardrails/technology/dotnet-webapi/coding-standards.md +87 -0
- package/assets/guardrails/technology/dotnet-webapi/cqrs.md +63 -0
- package/assets/guardrails/technology/dotnet-webapi/data-classification.md +38 -0
- package/assets/guardrails/technology/dotnet-webapi/dependency-policy.md +40 -0
- package/assets/guardrails/technology/dotnet-webapi/domain-driven-design.md +91 -0
- package/assets/guardrails/technology/dotnet-webapi/eventing.md +57 -0
- package/assets/guardrails/technology/dotnet-webapi/examples/api-versioning.md +75 -0
- package/assets/guardrails/technology/dotnet-webapi/examples/auditing.md +84 -0
- package/assets/guardrails/technology/dotnet-webapi/examples/authorization.md +68 -0
- package/assets/guardrails/technology/dotnet-webapi/examples/clean-architecture.md +37 -0
- package/assets/guardrails/technology/dotnet-webapi/examples/cqrs.md +97 -0
- package/assets/guardrails/technology/dotnet-webapi/examples/domain-driven-design.md +141 -0
- package/assets/guardrails/technology/dotnet-webapi/examples/eventing.md +46 -0
- package/assets/guardrails/technology/dotnet-webapi/examples/persistence.md +207 -0
- package/assets/guardrails/technology/dotnet-webapi/examples/vertical-slices.md +151 -0
- package/assets/guardrails/technology/dotnet-webapi/examples/zero-trust.md +48 -0
- package/assets/guardrails/technology/dotnet-webapi/folder-structure.md +61 -0
- package/assets/guardrails/technology/dotnet-webapi/modular-monolith.md +47 -0
- package/assets/guardrails/technology/dotnet-webapi/persistence.md +82 -0
- package/assets/guardrails/technology/dotnet-webapi/technology-constitution.md +162 -0
- package/assets/guardrails/technology/dotnet-webapi/testing.md +55 -0
- package/assets/guardrails/technology/dotnet-webapi/vertical-slices.md +70 -0
- package/assets/guardrails/technology/dotnet-webapi/zero-trust.md +48 -0
- package/assets/guardrails/technology/java-spring/README.md +62 -0
- package/assets/guardrails/technology/nextjs/accessibility-implementation.md +56 -0
- package/assets/guardrails/technology/nextjs/api-client.md +56 -0
- package/assets/guardrails/technology/nextjs/api-integration.dotnet-webapi.md +174 -0
- package/assets/guardrails/technology/nextjs/api-integration.java-spring.md +203 -0
- package/assets/guardrails/technology/nextjs/auth-session.md +68 -0
- package/assets/guardrails/technology/nextjs/client-security.md +69 -0
- package/assets/guardrails/technology/nextjs/component-architecture.md +60 -0
- package/assets/guardrails/technology/nextjs/component-conventions.md +58 -0
- package/assets/guardrails/technology/nextjs/design-system.md +60 -0
- package/assets/guardrails/technology/nextjs/error-handling.md +72 -0
- package/assets/guardrails/technology/nextjs/forms-and-validation.md +75 -0
- package/assets/guardrails/technology/nextjs/frontend-testing.md +94 -0
- package/assets/guardrails/technology/nextjs/i18n.md +57 -0
- package/assets/guardrails/technology/nextjs/observability.md +67 -0
- package/assets/guardrails/technology/nextjs/performance-budgets.md +66 -0
- package/assets/guardrails/technology/nextjs/routing-navigation.md +52 -0
- package/assets/guardrails/technology/nextjs/state-management.md +70 -0
- package/assets/guardrails/technology/nextjs/ui-constitution.md +166 -0
- package/dist/commands/init.js +2 -2
- package/dist/commands/init.js.map +1 -1
- package/dist/utils/copy-assets.js +8 -8
- package/dist/utils/copy-assets.js.map +1 -1
- package/package.json +1 -1
- package/assets/docs/pharma-constitution.my-ref.md +0 -86
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
# Design: [AGGREGATE]
|
|
2
|
+
|
|
3
|
+
**Aggregate (feature)**: `[Aggregate]` <!-- the feature = the aggregate, e.g. Order -->
|
|
4
|
+
|
|
5
|
+
**Design home**: `specs/[Aggregate]/design.md`
|
|
6
|
+
|
|
7
|
+
**Source spec**: `specs/[Aggregate]/spec.md`
|
|
8
|
+
|
|
9
|
+
**Version**: v1.0 <!-- moves in lockstep with the spec; every applied change request bumps this — see Change History -->
|
|
10
|
+
|
|
11
|
+
**Status**: Draft
|
|
12
|
+
|
|
13
|
+
<!--
|
|
14
|
+
WHAT THIS DOCUMENT IS
|
|
15
|
+
=====================
|
|
16
|
+
The single, living High-Level Design (HLD) for ONE aggregate. It is the
|
|
17
|
+
MEDIATOR between spec.md (WHAT/WHY, tech-agnostic) and the generated code
|
|
18
|
+
(HOW, tech-specific). It is NOT code: it carries structure, contracts,
|
|
19
|
+
behaviour, and decisions — enough for ANY capable LLM to generate correct,
|
|
20
|
+
spec-satisfying code on ANY target stack, but no complete method bodies.
|
|
21
|
+
|
|
22
|
+
spec.md ──▶ design.md ──▶ code (+ tests)
|
|
23
|
+
behaviour structure & generated by `implement`
|
|
24
|
+
(FR/BR/US/SC) decisions (HLD) (stack-bound at generation time)
|
|
25
|
+
|
|
26
|
+
ANCHORING RULES
|
|
27
|
+
- Every design element traces UP to a spec id (FR-/BR-/CN-/DC-/IC-/US-/SC-) and
|
|
28
|
+
the whole spec is covered DOWN here (see §6 Traceability). No design element
|
|
29
|
+
without a spec reason; no spec requirement without a design home.
|
|
30
|
+
- THE SPEC IS THE ONLY DOMAIN INPUT. Design reads the spec + the technical/
|
|
31
|
+
architecture standards — NOT the domain rule files. The domain reached this doc
|
|
32
|
+
only as spec ids: business invariants (BR-), domain-derived constraints (CN- —
|
|
33
|
+
retention/immutability/audit/limits), data classification (DC-), and interop
|
|
34
|
+
obligations (IC-). Realise each of those; invent no domain rule the spec omits
|
|
35
|
+
(if one seems missing, record it as an Assumption in §7, never smuggle it in).
|
|
36
|
+
- Feature = aggregate. Commands (CreateOrder, UpdateOrder…) are USER STORIES,
|
|
37
|
+
not features. One aggregate = one design.md = one owning design for its code
|
|
38
|
+
files. A later requirement is a delta on THIS doc, never a new one.
|
|
39
|
+
|
|
40
|
+
WHAT LIVES ELSEWHERE (do NOT repeat it here — it is identical for every feature)
|
|
41
|
+
- The clean-architecture layering + dependency rule (API → Application → Domain
|
|
42
|
+
← Infrastructure) is a STANDING project rule in the constitution / architecture
|
|
43
|
+
standards. This doc just uses the layers as sections; it does not restate the rule.
|
|
44
|
+
- HOW to turn this design into code (folder mapping, file-per-element, test
|
|
45
|
+
pairing, stack binding) is a SOLUTION-WIDE, technology-specific rule applied in
|
|
46
|
+
the `implement` phase — NOT per feature. This doc stays technology-agnostic.
|
|
47
|
+
- Physical persistence (PKs/FKs, columns, indexes, JSON shapes, migration SQL)
|
|
48
|
+
belongs to a technical-data-model. This doc states WHAT is stored and WHICH
|
|
49
|
+
port persists it, not the schema.
|
|
50
|
+
|
|
51
|
+
TECHNOLOGY-AGNOSTIC (mandatory)
|
|
52
|
+
- Express behaviour as SIGNATURES + pre/post/invariant/raises pseudocode and
|
|
53
|
+
contracts as field shapes — NEVER language code. Use conceptual types
|
|
54
|
+
(string, int, decimal, enum, list<T>, set<T>, id<T>, money, date). The target
|
|
55
|
+
language/framework is bound only at `implement` time from the constitution's
|
|
56
|
+
technology base + the active stack profile. The SAME design must be
|
|
57
|
+
generatable on a different stack without edits.
|
|
58
|
+
|
|
59
|
+
HOW TO AUTHOR
|
|
60
|
+
- Fill every [PLACEHOLDER]. Keep the section order. Omit a LAYER subsection only
|
|
61
|
+
when the aggregate genuinely has nothing there (state why); never write "N/A".
|
|
62
|
+
- Two deferral ledgers are first-class and MANDATORY sections: §7 Assumptions
|
|
63
|
+
(things to confirm later) and §8 Workarounds (structural debt to clear later).
|
|
64
|
+
An empty ledger reads "None (as of vX.Y)", never a deletion.
|
|
65
|
+
- Delete these authoring comments as you fill each section.
|
|
66
|
+
-->
|
|
67
|
+
|
|
68
|
+
## 0. Design Overview
|
|
69
|
+
|
|
70
|
+
<!--
|
|
71
|
+
One paragraph: the architectural shape of this aggregate and the 3–5 decisions
|
|
72
|
+
that matter most (why this boundary, the lifecycle model, the hardest trade-off).
|
|
73
|
+
This is the orientation a reviewer or an LLM reads first. The standing layering /
|
|
74
|
+
dependency rule is NOT restated here — it is the project architecture standard.
|
|
75
|
+
-->
|
|
76
|
+
|
|
77
|
+
[The architectural essence of this aggregate in 3–6 sentences: its purpose, its
|
|
78
|
+
lifecycle spine, the key structural choices specific to it, and the single biggest
|
|
79
|
+
trade-off. Layering follows the project architecture standard (constitution).]
|
|
80
|
+
|
|
81
|
+
### Ubiquitous Language (design delta)
|
|
82
|
+
|
|
83
|
+
<!--
|
|
84
|
+
The terms this design introduces or sharpens beyond the spec's language. Keep it
|
|
85
|
+
short — do not restate the whole spec glossary; add only design-level terms
|
|
86
|
+
(a port name, a state, a domain-service concept). Terms here are used IDENTICALLY
|
|
87
|
+
in the generated code (type names, method names).
|
|
88
|
+
-->
|
|
89
|
+
|
|
90
|
+
| Term | Meaning in this design |
|
|
91
|
+
|---|---|
|
|
92
|
+
| [Port / concept name] | [precise definition — this becomes a code identifier] |
|
|
93
|
+
|
|
94
|
+
## 1. Domain Layer
|
|
95
|
+
|
|
96
|
+
<!--
|
|
97
|
+
FOLLOW spec.md EXACTLY. This is not a fresh model — it is the DDD elaboration of
|
|
98
|
+
what the spec already fixes:
|
|
99
|
+
• Entities & value objects = the spec's "Key Entities" (SAME names).
|
|
100
|
+
• Invariants = the spec's "Business Rules" (BR-nnn) — cite each.
|
|
101
|
+
• Aggregate boundary = the spec's "Scope & Assumptions → Aggregate Boundary"
|
|
102
|
+
(owns vs references-by-id vs out-of-scope).
|
|
103
|
+
• Lifecycle / states = the states the spec describes.
|
|
104
|
+
• Domain-derived constraints = the spec's "Constraints & NFRs" (CN-nnn) that are
|
|
105
|
+
structural here — e.g. immutability, append-only audit,
|
|
106
|
+
no-hard-delete → realised as VO immutability, a domain
|
|
107
|
+
event, or an aggregate invariant; cite the CN-. (Retention/
|
|
108
|
+
performance-as-a-limit land in §4 Infra / §5 Cross-Cutting.)
|
|
109
|
+
You MAY add design-level structure — domain events, state machines, behaviour
|
|
110
|
+
signatures — but ONLY to REALISE spec behaviour. Do NOT invent an entity, value
|
|
111
|
+
object, or rule the spec does not state, and do NOT contradict it. If a genuinely
|
|
112
|
+
new concept is unavoidable, record it as an Assumption (§7, DA-n) and flag it —
|
|
113
|
+
never smuggle it in. Pure business model: no framework, no persistence, no I/O.
|
|
114
|
+
Model this section on a rich DDD reference (entities, VOs, events, state machines,
|
|
115
|
+
invariants, behaviours). Repeat the blocks as the aggregate needs.
|
|
116
|
+
-->
|
|
117
|
+
|
|
118
|
+
### 1.1 Aggregate structure *(from the spec's Aggregate Boundary — verbatim)*
|
|
119
|
+
|
|
120
|
+
- **Aggregate root**: `[Root]` — [what it guards; the transaction boundary]
|
|
121
|
+
- **Entities (owned)**: `[Entity]` — [role]; …
|
|
122
|
+
- **Value objects (owned)**: `[VO]` — [role]; …
|
|
123
|
+
- **References (by id, not owned)**: `[OtherAggregate]Id` → [why referenced] *(ID-only; no navigable link)*
|
|
124
|
+
|
|
125
|
+
### 1.2 Domain events
|
|
126
|
+
|
|
127
|
+
<!-- Meaningful state transitions — the audit/notification/coordination mechanism. -->
|
|
128
|
+
|
|
129
|
+
| Event | Raised by | Trigger | Key payload | Serves |
|
|
130
|
+
|---|---|---|---|---|
|
|
131
|
+
| `[EntityStateChanged]` | `[Root/Entity]` | [what causes it] | `[id, key fields]` | FR-00X · US-Y |
|
|
132
|
+
|
|
133
|
+
### 1.3 Entities
|
|
134
|
+
|
|
135
|
+
<!--
|
|
136
|
+
Per entity: attributes (conceptual types), lifecycle state machine if it has one,
|
|
137
|
+
behaviours as SIGNATURE + pre/post/invariant/raises pseudocode (the most LLM-guidable,
|
|
138
|
+
stack-neutral form), and the invariants it enforces (each = a spec BR-nnn).
|
|
139
|
+
-->
|
|
140
|
+
|
|
141
|
+
#### `[Entity]` [(Aggregate Root)]
|
|
142
|
+
|
|
143
|
+
**Attributes**
|
|
144
|
+
|
|
145
|
+
| Attribute | Type (conceptual) | Notes |
|
|
146
|
+
|---|---|---|
|
|
147
|
+
| `[Id]` | `id<[Entity]>` | identity |
|
|
148
|
+
| `[field]` | `[string \| int \| enum{A\|B} \| VO \| list<[Child]>]` | [meaning, constraints] |
|
|
149
|
+
|
|
150
|
+
**State machine** *(only if the entity has a lifecycle described in the spec — else omit)*
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
[State] ──[Behaviour()]──▶ [State] ──[Behaviour()]──▶ [State]
|
|
154
|
+
```
|
|
155
|
+
<!-- A mermaid stateDiagram-v2 is welcome for non-trivial lifecycles. -->
|
|
156
|
+
|
|
157
|
+
**Behaviours** *(technology-agnostic — signatures + contract, not code)*
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
[Entity].[Behaviour]([params])
|
|
161
|
+
Pre-condition: [required state / inputs]
|
|
162
|
+
Invariant: [what must hold — maps to a spec BR-nnn]
|
|
163
|
+
Post-condition: [resulting state / outputs]
|
|
164
|
+
Raises: [DomainEvent]
|
|
165
|
+
Serves: FR-00X · US-Y · BR-00Z
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
**Invariants** *(always-true; each maps to a spec BR-nnn — do not add rules absent from the spec)*
|
|
169
|
+
|
|
170
|
+
- [Invariant statement] — **BR-00X**
|
|
171
|
+
|
|
172
|
+
### 1.4 Value objects
|
|
173
|
+
|
|
174
|
+
| Value object | Attributes | Equality | Validation / behaviour | Serves |
|
|
175
|
+
|---|---|---|---|---|
|
|
176
|
+
| `[VO]` | `[fields]` | [by value / by which fields] | [rules; `[method]() → …`] | BR-00X |
|
|
177
|
+
|
|
178
|
+
### 1.5 Domain services *(cross-entity/aggregate logic that fits no single entity — omit if none)*
|
|
179
|
+
|
|
180
|
+
```
|
|
181
|
+
[Service].[Operation]([params]) → [result]
|
|
182
|
+
Purpose: [why this can't live on one entity]
|
|
183
|
+
Steps: 1. … 2. … 3. …
|
|
184
|
+
Touches: [aggregates/ports coordinated]
|
|
185
|
+
Serves: FR-00X · US-Y
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## 2. Application Layer
|
|
189
|
+
|
|
190
|
+
<!--
|
|
191
|
+
Use-cases: one command/query per user-story action, its handler's orchestration,
|
|
192
|
+
the ports it depends on, application-level rules (authorization, input validation,
|
|
193
|
+
transaction + event publication), and the request/response DTO shapes. Consumes
|
|
194
|
+
Domain types and the PORTS the Domain/Application defines; NEVER touches
|
|
195
|
+
persistence directly. Stack-neutral (no framework/mediator specifics).
|
|
196
|
+
-->
|
|
197
|
+
|
|
198
|
+
### 2.1 Ports (interfaces the Application/Domain require)
|
|
199
|
+
|
|
200
|
+
<!-- The seams Infrastructure implements. Name them; give the contract; keep abstract. -->
|
|
201
|
+
|
|
202
|
+
| Port | Contract (operations) | Implemented in |
|
|
203
|
+
|---|---|---|
|
|
204
|
+
| `I[Aggregate]Repository` | `get(id) → [Root]?` · `add([Root])` · `[query]` | §4 Infra |
|
|
205
|
+
| `I[External]` | `[operation]([in]) → [out]` | §4 Infra |
|
|
206
|
+
|
|
207
|
+
### 2.2 Use-cases (commands / queries)
|
|
208
|
+
|
|
209
|
+
<!-- One block per use-case = one user-story action. This is the LLM's unit of work. -->
|
|
210
|
+
|
|
211
|
+
#### `[Command/Query]` — Serves US-Y · FR-00X
|
|
212
|
+
|
|
213
|
+
- **Type**: command (writes) | query (reads)
|
|
214
|
+
- **Request (DTO)**: `{ [field]: [type], … }`
|
|
215
|
+
- **Response (DTO)**: `{ [field]: [type], … }`
|
|
216
|
+
- **Authorization**: [role/policy required — maps to a spec FR]
|
|
217
|
+
- **Validation (application-level)**: [input-shape / cross-field checks before the domain]
|
|
218
|
+
- **Handler orchestration**:
|
|
219
|
+
```
|
|
220
|
+
[Command]Handler.handle(request)
|
|
221
|
+
1. [authorize / validate input]
|
|
222
|
+
2. [load aggregate via I[Aggregate]Repository]
|
|
223
|
+
3. [invoke domain behaviour — the real rules live in §1]
|
|
224
|
+
4. [persist via port] (single transaction boundary)
|
|
225
|
+
5. [publish domain events]
|
|
226
|
+
6. return [Response]
|
|
227
|
+
On failure: [which error → which API status in §3]
|
|
228
|
+
```
|
|
229
|
+
- **Emits**: `[DomainEvent]` (from §1.2)
|
|
230
|
+
|
|
231
|
+
## 3. API Layer
|
|
232
|
+
|
|
233
|
+
<!--
|
|
234
|
+
The contract other systems couple to. Describe it at PROTOCOL level (REST assumed
|
|
235
|
+
per the constitution — adapt for gRPC/GraphQL/CLI if the stack differs), NOT as
|
|
236
|
+
controller code. Pin route, verb, auth, request/response shape, status codes, and
|
|
237
|
+
the error contract. Delegates to an Application use-case; no business logic here.
|
|
238
|
+
-->
|
|
239
|
+
|
|
240
|
+
### `[VERB] [/route]` — [purpose] · Serves US-Y · FR-00X
|
|
241
|
+
|
|
242
|
+
- **Auth**: [required role/scope]
|
|
243
|
+
- **Request**: `[path/query params]` + body `{ [field]: [type], … }`
|
|
244
|
+
- **Success**: `2xx` → `{ [response shape] }`
|
|
245
|
+
- **Errors** *(the error contract)*:
|
|
246
|
+
|
|
247
|
+
| Status | When | Body shape |
|
|
248
|
+
|---|---|---|
|
|
249
|
+
| 400 | [validation failure] | `{ errors: [{ field, message }] }` |
|
|
250
|
+
| 403 | [unauthorized] | `{ error }` |
|
|
251
|
+
| 409 | [conflict / duplicate — maps to a BR] | `{ error }` |
|
|
252
|
+
|
|
253
|
+
- **Maps to**: `[Command/Query]` (§2.2)
|
|
254
|
+
|
|
255
|
+
## 4. Infrastructure Layer
|
|
256
|
+
|
|
257
|
+
<!--
|
|
258
|
+
The outer edge: which ports (from §2.1) are implemented here, WHAT each persists
|
|
259
|
+
or integrates (conceptually), and where a schema change is needed. Do NOT specify
|
|
260
|
+
physical schema (columns/keys/indexes) — that is the technical-data-model's job;
|
|
261
|
+
reference it. Infrastructure is generated/compiled LAST (it depends on inward ports).
|
|
262
|
+
-->
|
|
263
|
+
|
|
264
|
+
### 4.1 Persistence
|
|
265
|
+
|
|
266
|
+
| Port implemented | Adapter (intent) | Persists (conceptually) | Schema change? |
|
|
267
|
+
|---|---|---|---|
|
|
268
|
+
| `I[Aggregate]Repository` | `[Aggregate]Repository` | `[Root]` + owned `[Entity]`/`[VO]` | new / altered / none |
|
|
269
|
+
|
|
270
|
+
- **Physical schema**: see `technical-data-model` (out of scope here).
|
|
271
|
+
- **Concurrency / transaction**: [optimistic? boundary = aggregate?]
|
|
272
|
+
|
|
273
|
+
### 4.2 External integrations *(realises the spec's Integration Contracts — omit only if the spec has none)*
|
|
274
|
+
|
|
275
|
+
<!--
|
|
276
|
+
One row per spec Integration Contract (IC-nnn) plus any identity/messaging edge.
|
|
277
|
+
This is where an IC- obligation becomes an adapter/port — the spec named WHICH
|
|
278
|
+
standard/resources must be met; here you name the port that meets it. Cite the IC-.
|
|
279
|
+
-->
|
|
280
|
+
|
|
281
|
+
| Port implemented | External system | Operation | Failure mode | Serves |
|
|
282
|
+
|---|---|---|---|---|
|
|
283
|
+
| `I[External]` | [terminology / identity / messaging] | [what it calls] | [reject / degrade / retry] | IC-00X |
|
|
284
|
+
|
|
285
|
+
### 4.3 Wiring & migrations
|
|
286
|
+
|
|
287
|
+
- **Composition**: bind `[Port] → [Adapter]` for this aggregate.
|
|
288
|
+
- **Migrations needed**: [yes → what changes conceptually / no]. The Run phase applies them.
|
|
289
|
+
|
|
290
|
+
## 5. Cross-Cutting Concerns
|
|
291
|
+
|
|
292
|
+
<!--
|
|
293
|
+
Where the spec's constraints land structurally: security (authz/PII), data
|
|
294
|
+
protection & exposure, observability (events/logging/audit), performance/scale,
|
|
295
|
+
retention, idempotency, eventing/outbox. Design-level only; omit rows that don't
|
|
296
|
+
apply. For a SPEC-derived concern the "Serves" column MUST cite a SPEC id — the
|
|
297
|
+
domain-derived constraints arrive as CN-/DC- (design does not read the domain rule
|
|
298
|
+
files or restate the constitution here); every CN-/DC- in the spec needs a home in
|
|
299
|
+
this table or §1/§4. A CONSTITUTION-MANDATED cross-cutting concern with NO per-feature
|
|
300
|
+
spec id is legitimate but is NOT spec-derived: log it as a §7 DA-n citing the
|
|
301
|
+
mandating principle and set this row's "Serves" to that DA-n (e.g. `DA-<n> · Const.
|
|
302
|
+
§<n>`). Never fabricate a fake CN- for it, and never leave it uncited — the analyze
|
|
303
|
+
gate reads an uncited non-spec element as over-reach.
|
|
304
|
+
-->
|
|
305
|
+
|
|
306
|
+
| Concern | Design decision | Serves |
|
|
307
|
+
|---|---|---|
|
|
308
|
+
| Security / authorization | [where enforced — §2 handler / §3 auth] | FR-00X · CN-00X |
|
|
309
|
+
| Data protection & exposure | [classification handling; what MUST NOT surface in API/logs/traces] | DC-00X |
|
|
310
|
+
| Audit & immutability | [audit emission point; append-only/versioning approach] | CN-00X |
|
|
311
|
+
| Observability | [events emitted, what is logged/audited] | SC-00X |
|
|
312
|
+
| Performance / scale | [target + structural choice] | SC-00X · CN-00X |
|
|
313
|
+
| Retention | [retention window + where enforced; no-hard-delete/logical-delete] | CN-00X |
|
|
314
|
+
| Idempotency / concurrency | [approach; if mandated by the constitution rather than a spec rule, cite its §7 DA-n, not a spec id] | BR-00X / DA-n |
|
|
315
|
+
|
|
316
|
+
## 6. Traceability (the spine)
|
|
317
|
+
|
|
318
|
+
<!--
|
|
319
|
+
The two-way guarantee: every FR/BR/CN/DC/IC/US/SC has a design home, and every
|
|
320
|
+
design element has a spec reason. This is what makes impact analysis exact and lets
|
|
321
|
+
the analyze gate verify coverage. Keep it complete — EVERY CN-/DC-/IC- in the spec
|
|
322
|
+
MUST appear as a row here (that is how the analyze gate proves no lifted constraint
|
|
323
|
+
was dropped). The Domain rows MUST match the spec's Key Entities and Business Rules
|
|
324
|
+
exactly.
|
|
325
|
+
-->
|
|
326
|
+
|
|
327
|
+
| Spec id | Type | Design element(s) | Layer |
|
|
328
|
+
|---|---|---|---|
|
|
329
|
+
| FR-001 | requirement | `[Root].[Behaviour]`, `[Command]`, `[VERB /route]` | Domain·App·API |
|
|
330
|
+
| BR-001 | invariant | `[Root]` invariant / `[VO]` validation | Domain |
|
|
331
|
+
| CN-001 | constraint | [where realised — §1 invariant / §4 persistence / §5 cross-cutting] | [layer] |
|
|
332
|
+
| DC-001 | classification | [exposure enforcement — §2 projection / §5 data-protection] | App·Infra |
|
|
333
|
+
| IC-001 | contract | [adapter/port realising it — §4.2] | Infra |
|
|
334
|
+
| US-1 | story | [end-to-end elements realising it] | all |
|
|
335
|
+
| SC-001 | success | [where it is met + how verified] | [layer] |
|
|
336
|
+
|
|
337
|
+
## 7. Assumptions (to clarify later)
|
|
338
|
+
|
|
339
|
+
<!--
|
|
340
|
+
MANDATORY LEDGER. Every reasonable default or open interpretation the design
|
|
341
|
+
commits to so it can proceed WITHOUT blocking — INCLUDING (a) any domain concept
|
|
342
|
+
not explicitly in the spec, and (b) any CROSS-CUTTING element the technical
|
|
343
|
+
constitution MANDATES that has no per-feature spec id. For (b) state the mandating
|
|
344
|
+
principle as the basis ("per Const. §<n>") — this is what lets the analyze gate accept
|
|
345
|
+
a constitution-required element that is absent from the spec (rule 3 admits a logged
|
|
346
|
+
§7 DA-n; it cannot see the constitution). Each tracked with an id, the risk if wrong,
|
|
347
|
+
and who resolves it. Design-level (distinct from the spec's behavioural Assumptions).
|
|
348
|
+
Empty → "None (as of vX.Y)".
|
|
349
|
+
-->
|
|
350
|
+
|
|
351
|
+
| id | Assumption | Why deferred | Impact if wrong | Owner / resolve-by |
|
|
352
|
+
|---|---|---|---|---|
|
|
353
|
+
| DA-1 | [what we assumed] | [why we didn't clarify now] | [blast radius] | [role / phase] |
|
|
354
|
+
| DA-2 | [a cross-cutting element the constitution mandates but the spec omits] | Mandated by governance, not a per-feature FR — basis: per Const. §<n> | [blast radius] | — / standing |
|
|
355
|
+
|
|
356
|
+
## 8. Architectural Workarounds & Deferred Decisions (to clear later)
|
|
357
|
+
|
|
358
|
+
<!--
|
|
359
|
+
MANDATORY LEDGER. Structural debt KNOWINGLY taken — a shortcut, a temporary
|
|
360
|
+
coupling, a deferred split — with the proper end-state and the trigger that should
|
|
361
|
+
force the cleanup. Keeps the HLD honest about where it bends.
|
|
362
|
+
Empty → "None (as of vX.Y)".
|
|
363
|
+
-->
|
|
364
|
+
|
|
365
|
+
| id | Workaround taken | Proper end-state | Trigger to revisit | Serves / caused by |
|
|
366
|
+
|---|---|---|---|---|
|
|
367
|
+
| WA-1 | [the shortcut/coupling] | [the clean design] | [scale/CR/date that forces it] | [FR / constraint] |
|
|
368
|
+
|
|
369
|
+
## 9. Change History
|
|
370
|
+
|
|
371
|
+
<!--
|
|
372
|
+
The living-truth ledger, in lockstep with spec.md. Every applied change request
|
|
373
|
+
appends a row here, carrying the version it ships as. finalize-delta writes the row
|
|
374
|
+
when it merges the delta; close-delta then archives the CR, bumps the minor version
|
|
375
|
+
in active_version.json and stamps that same number into this document's **Version**
|
|
376
|
+
header — one mechanism, one stage, so header, row and active_version.json never
|
|
377
|
+
disagree. A change to this aggregate is a DELTA on THIS document (delta-design:
|
|
378
|
+
ADDED / MODIFIED / REMOVED sections), never a new design doc. Newest last.
|
|
379
|
+
-->
|
|
380
|
+
|
|
381
|
+
| Version | Date | Change | User stories | CR |
|
|
382
|
+
|---------|------|--------|--------------|-----|
|
|
383
|
+
| v1.0 | [DATE] | Initial design | US-1 | — |
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: aggregate
|
|
3
|
+
title: [Aggregate]
|
|
4
|
+
description: [one line — what this aggregate is and the invariant/boundary it guards]
|
|
5
|
+
origin: greenfield
|
|
6
|
+
source_files:
|
|
7
|
+
ui_source_files:
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
<!--
|
|
11
|
+
OKF CONCEPT — one aggregate's node in the shared knowledge bundle.
|
|
12
|
+
Canonical home: knowledge/<slug>/<slug>.md (dir also holds an index.md; the bundle
|
|
13
|
+
root holds index.md with okf_version + an optional log.md change journal).
|
|
14
|
+
|
|
15
|
+
This single bundle is the OKF knowledge tier for BOTH pipelines:
|
|
16
|
+
• greenfield — `implement` authors this concept (frontmatter + Overview + Depends-On)
|
|
17
|
+
as it generates the aggregate's code;
|
|
18
|
+
• brownfield — `inventory` seeds it and `adopt` enriches it.
|
|
19
|
+
|
|
20
|
+
WHO WRITES WHAT (do not cross these lanes):
|
|
21
|
+
• Frontmatter, Overview, Depends-On → THIS aggregate's implement/adopt.
|
|
22
|
+
• Cross-References → the OTHER aggregates that USE this one; each
|
|
23
|
+
writes its own row (never hand-edit them here).
|
|
24
|
+
One addition inside the first lane: `analyze-slice` MERGES (never replaces) the files its
|
|
25
|
+
fix loops touched into `source_files`, because it is the last stage that changes the
|
|
26
|
+
slice's files — a constraint test it had to add did not exist when implement wrote this
|
|
27
|
+
concept. It touches nothing else; edges and Overview stay with implement/adopt.
|
|
28
|
+
|
|
29
|
+
Keep the file frontmatter-valid: `type` (non-empty) + `title` are what validate_okf
|
|
30
|
+
(E2) and the concept resolver (aw-inventory.py concept) key on. `source_files` MUST
|
|
31
|
+
list only paths this aggregate OWNS (they drive the shared-code overlap signal and
|
|
32
|
+
the source-map fidelity check).
|
|
33
|
+
|
|
34
|
+
`source_files` is a FLAT list — every consumer keys on that shape — but it is written
|
|
35
|
+
GROUPED with YAML comment headers (which all parsers skip) BY THE CODE'S OWN FOLDERS,
|
|
36
|
+
so the listing mirrors the real architecture instead of a fixed taxonomy. Each header
|
|
37
|
+
is the path segment that VARIES across the files after their shared parent directory —
|
|
38
|
+
the layer folder of a vertical slice, OR the tier project of an n-tier / layered app:
|
|
39
|
+
|
|
40
|
+
source_files: # vertical-slice layout
|
|
41
|
+
# Domain
|
|
42
|
+
- src/<Project>/<Slice>/Domain/<Root>.cs
|
|
43
|
+
# Features
|
|
44
|
+
- src/<Project>/<Slice>/Features/<UseCase>/<UseCase>Command.cs
|
|
45
|
+
# Persistence
|
|
46
|
+
- src/<Project>/<Slice>/Persistence/<Root>Configuration.cs
|
|
47
|
+
# tests
|
|
48
|
+
- tests/<Project>/<Slice>/<Root>Tests.cs
|
|
49
|
+
|
|
50
|
+
source_files: # n-tier / layered layout
|
|
51
|
+
# Acme.DataAccess
|
|
52
|
+
- src/Acme.DataAccess/Repositories/<Root>Repository.cs
|
|
53
|
+
# Acme.BusinessLogic
|
|
54
|
+
- src/Acme.BusinessLogic/Services/<Root>Service.cs
|
|
55
|
+
# tests
|
|
56
|
+
- test/Acme.Tests/<Root>Tests.cs
|
|
57
|
+
|
|
58
|
+
The grouping is DERIVED from the paths by _group_source_files (aw-xref.py) and
|
|
59
|
+
re-derived on every write (tests → a `tests` bucket; repo-root files → `(root)`), so
|
|
60
|
+
never hand-maintain the comment headers.
|
|
61
|
+
|
|
62
|
+
`ui_source_files` is the SAME shape for the slice's FRONTEND surface — the components,
|
|
63
|
+
routes, stores and stylesheets that serve this aggregate — and it is a separate key
|
|
64
|
+
rather than more entries in `source_files` for two reasons. A separable frontend
|
|
65
|
+
shares no directory prefix with the service tree, so folding it in would collapse the
|
|
66
|
+
concept resolver's `module_dir` to the repo root; and the two lanes are reversed by
|
|
67
|
+
different steps reading different code, which is the same separation scope_to_lanes
|
|
68
|
+
keeps in the scan substrate. Leave it EMPTY on a backend-only slice — never delete the
|
|
69
|
+
key. UI files that serve no single aggregate (the app shell, layout, design system)
|
|
70
|
+
belong in the bundle's `architecture/frontend.md`, not forced into a slice.
|
|
71
|
+
-->
|
|
72
|
+
|
|
73
|
+
# [Aggregate]
|
|
74
|
+
|
|
75
|
+
## Overview
|
|
76
|
+
|
|
77
|
+
<!--
|
|
78
|
+
2–4 sentences: the aggregate root, what it guards, its transaction boundary.
|
|
79
|
+
Greenfield: distilled from design.md §1 (Domain Model). Brownfield: from the
|
|
80
|
+
reverse-engineered spec/design. Prose only — the edges live in the two tables below.
|
|
81
|
+
-->
|
|
82
|
+
|
|
83
|
+
[overview of the [Aggregate] aggregate]
|
|
84
|
+
|
|
85
|
+
## Depends-On
|
|
86
|
+
|
|
87
|
+
<!--
|
|
88
|
+
FORWARD edges — the sibling aggregates THIS one references. Derived DETERMINISTICALLY
|
|
89
|
+
from design.md §1 — the model section, "References (by id, not owned)" — plus its
|
|
90
|
+
External integrations table (Integration Contracts), kept
|
|
91
|
+
to targets that are real project aggregates (a specs/<Target>/ or an existing concept).
|
|
92
|
+
This is the PRUNE INDEX: reconcile-on-write reads it to find where this slice wrote, so
|
|
93
|
+
a dropped dependency self-heals out of the used aggregate's Cross-References.
|
|
94
|
+
Regenerated every implement/adopt — DO NOT hand-edit.
|
|
95
|
+
-->
|
|
96
|
+
|
|
97
|
+
| Target | Via | Kind |
|
|
98
|
+
| --- | --- | --- |
|
|
99
|
+
<!-- e.g. | Organization | ManufacturerId | entity-ref | -->
|
|
100
|
+
|
|
101
|
+
## Cross-References
|
|
102
|
+
|
|
103
|
+
<!--
|
|
104
|
+
REVERSE edges — the sibling aggregates that USE this one; i.e. THIS aggregate's
|
|
105
|
+
blast radius. Each row is written by the USING slice's implement/adopt
|
|
106
|
+
(reconcile-on-write, keyed by the "Using slice" column, so a using slice always
|
|
107
|
+
owns exactly its current rows). REVIEW THIS AT CR TIME: when this aggregate changes,
|
|
108
|
+
every Using slice listed here is downstream — finalize-delta runs their characterization
|
|
109
|
+
tests before the change can close. Rows are machine-maintained — DO NOT hand-add them.
|
|
110
|
+
-->
|
|
111
|
+
|
|
112
|
+
| Using slice | Uses (via) | Kind | Origin | Recorded |
|
|
113
|
+
| --- | --- | --- | --- | --- |
|
|
114
|
+
<!-- e.g. | Prescription | MedicinalProductId | entity-ref | greenfield | 2026-07-21 | -->
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_comment": "Parity manifest — the cutover-gate corpus for a brownfield slice. `cases` are authored by /appweaver parity from the spec + source-map; the two `sides` invocation targets are YOURS to supply (where the legacy + new systems run). Parity runs every case against BOTH sides and diffs observable output; the seam cuts over only when parity holds. See Brownfield-Pipeline.md.",
|
|
3
|
+
"aggregate": "AGGREGATE",
|
|
4
|
+
"baseline_commit": "REPLACE_WITH_INVENTORY_HEAD",
|
|
5
|
+
"sides": {
|
|
6
|
+
"legacy": {
|
|
7
|
+
"_comment": "The running LEGACY system (the oracle). kind: http → set base_url. kind: shell → set command (it receives a case's request JSON on stdin and must emit the observed output JSON on stdout).",
|
|
8
|
+
"kind": "http",
|
|
9
|
+
"base_url": "REPLACE_WITH_LEGACY_BASE_URL"
|
|
10
|
+
},
|
|
11
|
+
"candidate": {
|
|
12
|
+
"_comment": "The new (AppWeaver) implementation behind the seam.",
|
|
13
|
+
"kind": "http",
|
|
14
|
+
"base_url": "REPLACE_WITH_CANDIDATE_BASE_URL"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"compare": {
|
|
18
|
+
"_comment": "ignore_paths are dropped from BOTH sides before diffing — use for non-deterministic fields (generated ids, timestamps). Supports $.a.b, wildcard $.a[*].b and $.*.b. ignore_status compares bodies only.",
|
|
19
|
+
"ignore_paths": ["$.id", "$.createdAt", "$.updatedAt", "$.*.timestamp"],
|
|
20
|
+
"ignore_status": false,
|
|
21
|
+
"timeout_seconds": 30
|
|
22
|
+
},
|
|
23
|
+
"expected_deviations": [
|
|
24
|
+
{
|
|
25
|
+
"_comment": "Approved INTENDED differences. A diff matching {case, path} here is ACCEPTED, not a failure. Each one MUST be recorded as a MODIFIED spec item via the CR delta loop — parity does not let behaviour drift silently. Delete this example.",
|
|
26
|
+
"case": "PC-000-EXAMPLE",
|
|
27
|
+
"path": "$.someField",
|
|
28
|
+
"reason": "MODIFIED US-n: <why the new behaviour intentionally differs from legacy>"
|
|
29
|
+
}
|
|
30
|
+
],
|
|
31
|
+
"cases": [
|
|
32
|
+
{
|
|
33
|
+
"_comment": "EXAMPLE case — /appweaver parity replaces these with real ones derived from the spec's US/FR and the source-map's as-built quirks (each quirk MUST have a case that confirms the new code reproduces it). `request` is compared on {status, body}; optional `state_probe` is a follow-up request whose response captures RESULTING STATE (compared on body). Omit state_probe if not needed. Give real cases ids like PC-001 (ids ending EXAMPLE are ignored).",
|
|
34
|
+
"id": "PC-001-EXAMPLE",
|
|
35
|
+
"description": "Register a product with a valid NDC",
|
|
36
|
+
"spec_ids": ["US-1", "FR-001"],
|
|
37
|
+
"request": {
|
|
38
|
+
"method": "POST",
|
|
39
|
+
"path": "/product",
|
|
40
|
+
"headers": { "Content-Type": "application/json" },
|
|
41
|
+
"body": {}
|
|
42
|
+
},
|
|
43
|
+
"state_probe": {
|
|
44
|
+
"method": "GET",
|
|
45
|
+
"path": "/product/by-ndc/12345-678-90"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Source Map: [AGGREGATE]
|
|
2
|
+
|
|
3
|
+
**Aggregate (feature)**: `[Aggregate]` <!-- the feature = the aggregate, e.g. MedicinalProduct -->
|
|
4
|
+
|
|
5
|
+
**Source home**: `specs/[Aggregate]/source-map.md`
|
|
6
|
+
|
|
7
|
+
**Origin**: `reverse-engineered` <!-- greenfield | reverse-engineered | migrated -->
|
|
8
|
+
|
|
9
|
+
**Version**: v1.0 <!-- moves in lockstep with spec.md / design.md -->
|
|
10
|
+
|
|
11
|
+
**Baseline commit**: `[short-sha]` <!-- the inventory HEAD this slice was adopted from -->
|
|
12
|
+
|
|
13
|
+
<!--
|
|
14
|
+
WHAT THIS DOCUMENT IS
|
|
15
|
+
=====================
|
|
16
|
+
The SOURCE ANCHOR of the traceability spine for a slice that aw-spec ADOPTED
|
|
17
|
+
from existing code (Brownfield-Pipeline B1). It links each LEGACY ARTEFACT
|
|
18
|
+
(source file, DB table, endpoint, background job) to the spec/design section
|
|
19
|
+
that now describes it, so:
|
|
20
|
+
• strangler cutover is precise — you know exactly which code a slice owns;
|
|
21
|
+
• impact analysis is exact — a legacy change traces forward to spec ids;
|
|
22
|
+
• parity is scoped — you diff only this slice's surface.
|
|
23
|
+
|
|
24
|
+
LegacyArtefact ↔ FR/BR/US ↔ Spec-section ↔ Design-element ↔ Code ↔ Commit
|
|
25
|
+
|
|
26
|
+
This is a SIDECAR: spec.md and design.md stay clean, forward-loop documents
|
|
27
|
+
(the CR delta loop + forward pipeline consume them unchanged). The brownfield
|
|
28
|
+
provenance lives HERE and in the `origin:` frontmatter — never as extra
|
|
29
|
+
structure inside spec.md / design.md.
|
|
30
|
+
|
|
31
|
+
CONFIDENCE travels with each row: `certain` (the code states it outright) vs
|
|
32
|
+
`inferred` (reverse-engineering had to reason). Inferred rows are the Adopt
|
|
33
|
+
review (B1·R) + Fidelity worklist; unresolved ones become spec Assumptions or
|
|
34
|
+
`[NEEDS CLARIFICATION]` — never silently promoted to fact.
|
|
35
|
+
-->
|
|
36
|
+
|
|
37
|
+
## Seam
|
|
38
|
+
|
|
39
|
+
<!--
|
|
40
|
+
ACTION REQUIRED: the boundary this slice owns — what you can route traffic
|
|
41
|
+
across for a strangler cutover (interface, endpoint, queue, table owner) —
|
|
42
|
+
and whether it is CLEAN or TORN. A TORN seam (shares a transaction/table with
|
|
43
|
+
another slice) is a REMEDIATION item: introduce the seam before cutover.
|
|
44
|
+
-->
|
|
45
|
+
|
|
46
|
+
- **Boundary**: [e.g. `/product` endpoints + `PRODUCTS` table owner]
|
|
47
|
+
- **Seam quality**: [clean | torn]
|
|
48
|
+
- **Torn-seam remediation** (if torn): [what must be split first, or "n/a"]
|
|
49
|
+
|
|
50
|
+
## Artefact → spec/design map
|
|
51
|
+
|
|
52
|
+
<!--
|
|
53
|
+
ACTION REQUIRED: one row per legacy artefact this slice owns. Every source file
|
|
54
|
+
in the OKF bundle concept's `source_files` MUST appear here (Fidelity checks
|
|
55
|
+
full coverage both ways: no unmapped code, no spec id without a code anchor).
|
|
56
|
+
-->
|
|
57
|
+
|
|
58
|
+
| # | Legacy artefact | Kind | Spec ids | Design element | Confidence | Notes / quirk |
|
|
59
|
+
|---|---|---|---|---|---|---|
|
|
60
|
+
| SM-001 | `src/.../MedicinalProduct.cs` | file (aggregate root) | US-1, BR-001 | §1 Domain · MedicinalProduct | certain | |
|
|
61
|
+
| SM-002 | `PRODUCTS` | table | FR-003, DC-001 | §4 Infra · MedicinalProductRepository | inferred | NDC stored unformatted — see WA/CN |
|
|
62
|
+
| SM-003 | `POST /product` | endpoint | US-1, FR-001 | §3 API · RegisterMedicinalProduct | certain | |
|
|
63
|
+
|
|
64
|
+
## As-built quirks captured
|
|
65
|
+
|
|
66
|
+
<!--
|
|
67
|
+
ACTION REQUIRED: behaviours the code exhibits AS-IS (bugs, non-obvious
|
|
68
|
+
formatting, undocumented defaults) that were captured faithfully. Each links to
|
|
69
|
+
the spec item that records it (a MODIFIED-later candidate) or to a deviation.
|
|
70
|
+
These become characterization-test targets (B2) and deviation-register entries.
|
|
71
|
+
"None observed" if the slice is clean.
|
|
72
|
+
-->
|
|
73
|
+
|
|
74
|
+
- [e.g. NDC codes are stored without the canonical 5-4-2 hyphenation — captured as-is; candidate deviation.]
|
|
75
|
+
|
|
76
|
+
## Unmapped / open
|
|
77
|
+
|
|
78
|
+
<!--
|
|
79
|
+
Source files the reverse pass could not confidently place, and spec ids with no
|
|
80
|
+
code home found. Both are Fidelity gaps to resolve (out of band or by refining
|
|
81
|
+
the reverse spec/design). Empty when the map is complete.
|
|
82
|
+
-->
|
|
83
|
+
|
|
84
|
+
- **Unmapped code**: [files not yet placed, or "none"]
|
|
85
|
+
- **Unanchored spec ids**: [spec items with no code, or "none"]
|