aw-spec-cli 0.1.16 → 0.1.17

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.
Files changed (70) hide show
  1. package/assets/.appweaver/DESIGN-FORMAT.md +18 -18
  2. package/assets/.appweaver/ORCH-DIALECT.md +1 -3
  3. package/assets/.appweaver/RULE-PARTITION.md +29 -13
  4. package/assets/.appweaver/STACK-PROFILES.md +10 -9
  5. package/assets/.appweaver/orchestrator/.state/smoke.state.json +32 -0
  6. package/assets/.appweaver/orchestrator/AGENT-PROFILE.md +4 -1
  7. package/assets/.appweaver/orchestrator/modules/delta-plan.orch.yaml +251 -0
  8. package/assets/.appweaver/orchestrator/modules/delta-spec.orch.yaml +104 -35
  9. package/assets/.appweaver/orchestrator/orchestrator.py +5 -4
  10. package/assets/.appweaver/orchestrator/rev-templates/delta-design-template.skeleton.md +94 -36
  11. package/assets/.appweaver/orchestrator/rev-templates/design-template.skeleton.md +1 -1
  12. package/assets/.appweaver/orchestrator/rev-templates/domain-model-template.skeleton.md +115 -0
  13. package/assets/.appweaver/orchestrator/rev-templates/domain-rule-bindings.skeleton.md +2 -9
  14. package/assets/.appweaver/orchestrator/rev-templates/tech-rule-bindings.skeleton.md +16 -40
  15. package/assets/.appweaver/orchestrator/rev-templates/ui-delta-design-template.skeleton.md +38 -17
  16. package/assets/.appweaver/orchestrator/rev-templates/ui-design-template.skeleton.md +8 -8
  17. package/assets/.appweaver/orchestrator/workflows/aw-spec-adopt.orch.yaml +10 -11
  18. package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-plan-delta.orch.yaml +673 -0
  19. package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-plan.orch.yaml +535 -0
  20. package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-slice-delta.orch.yaml +643 -0
  21. package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-slice.orch.yaml +84 -701
  22. package/assets/.appweaver/orchestrator/workflows/aw-spec-build.orch.yaml +4 -4
  23. package/assets/.appweaver/orchestrator/workflows/aw-spec-characterize.orch.yaml +7 -7
  24. package/assets/.appweaver/orchestrator/workflows/aw-spec-close-delta.orch.yaml +16 -14
  25. package/assets/.appweaver/orchestrator/workflows/aw-spec-constitution.orch.yaml +2 -2
  26. package/assets/.appweaver/orchestrator/workflows/aw-spec-finalize-delta.orch.yaml +243 -144
  27. package/assets/.appweaver/orchestrator/workflows/aw-spec-implement.orch.yaml +877 -578
  28. package/assets/.appweaver/orchestrator/workflows/aw-spec-inventory.orch.yaml +4 -4
  29. package/assets/.appweaver/orchestrator/workflows/aw-spec-onboard.orch.yaml +32 -91
  30. package/assets/.appweaver/orchestrator/workflows/aw-spec-parity.orch.yaml +2 -2
  31. package/assets/.appweaver/orchestrator/workflows/aw-spec-plan.orch.yaml +836 -514
  32. package/assets/.appweaver/orchestrator/workflows/aw-spec-run.orch.yaml +2 -2
  33. package/assets/.appweaver/orchestrator/workflows/aw-spec-select-bounded-context.orch.yaml +132 -0
  34. package/assets/.appweaver/orchestrator/workflows/aw-spec-select-feature.orch.yaml +38 -5
  35. package/assets/.appweaver/orchestrator/workflows/aw-spec-select-stack.orch.yaml +3 -3
  36. package/assets/.appweaver/orchestrator/workflows/aw-spec-specify.orch.yaml +271 -979
  37. package/assets/.appweaver/scripts/bash/aw-spec-actions.sh +1085 -3385
  38. package/assets/.appweaver/scripts/bash/aw-xref.sh +1 -2
  39. package/assets/.appweaver/scripts/bash/common.sh +47 -0
  40. package/assets/.appweaver/scripts/powershell/aw-spec-actions.ps1 +914 -3220
  41. package/assets/.appweaver/scripts/powershell/aw-xref.ps1 +1 -2
  42. package/assets/.appweaver/scripts/python/aw-payload-parity.py +19 -3
  43. package/assets/.appweaver/scripts/python/aw-stack.py +6 -2
  44. package/assets/.appweaver/scripts/python/aw-xref.py +86 -350
  45. package/assets/.appweaver/templates/constitution-ui-template.md +1 -1
  46. package/assets/.appweaver/templates/delta-design-template.md +120 -30
  47. package/assets/.appweaver/templates/delta-domain-model-template.md +81 -0
  48. package/assets/.appweaver/templates/delta-spec-template.md +43 -17
  49. package/assets/.appweaver/templates/design-template.md +68 -98
  50. package/assets/.appweaver/templates/domain-model-template.md +130 -0
  51. package/assets/.appweaver/templates/okf-concept-template.md +2 -2
  52. package/assets/.appweaver/templates/source-map-template.md +3 -3
  53. package/assets/.appweaver/templates/spec-template.md +100 -122
  54. package/assets/.appweaver/templates/ui-delta-design-template.md +159 -0
  55. package/assets/.appweaver/templates/ui-design-template.md +46 -75
  56. package/assets/guardrails/projects/dotnet-default-project/domain-rule-bindings.md +7 -18
  57. package/assets/guardrails/projects/dotnet-default-project/tech-rule-bindings.md +34 -39
  58. package/assets/guardrails/requirement-spec.txt +2 -2
  59. package/assets/guardrails/technology/dotnet-webapi/testing.md +1 -1
  60. package/package.json +1 -1
  61. package/assets/.appweaver/orchestrator/modules/delta-design.orch.yaml +0 -105
  62. package/assets/.appweaver/orchestrator/modules/spec-state-gate.orch.yaml +0 -87
  63. package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-delta-design.orch.yaml +0 -251
  64. package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-design.orch.yaml +0 -813
  65. package/assets/.appweaver/orchestrator/workflows/aw-spec-implement-delta.orch.yaml +0 -253
  66. package/assets/.appweaver/orchestrator/workflows/aw-spec-implement-ui.orch.yaml +0 -663
  67. package/assets/.appweaver/orchestrator/workflows/aw-spec-plan-ui.orch.yaml +0 -600
  68. package/assets/.appweaver/orchestrator/workflows/aw-spec-story-plan.orch.yaml +0 -1147
  69. package/assets/.appweaver/orchestrator/workflows/aw-spec-sync-stories.orch.yaml +0 -1121
  70. package/assets/.appweaver/templates/story-template.md +0 -178
@@ -1,34 +1,37 @@
1
1
  # =============================================================================
2
2
  # delta-spec (orchestrator module) — author the SPEC-side DELTA of a change
3
3
  #
4
- # ORPHANED — INCLUDED BY NO WORKFLOW. specify v3.0.0 removed the delta branch this module
5
- # was written for: a later requirement is now an edit to the living spec.md plus a computed
6
- # Change History row, not a delta document merged back later. Nothing else includes it, so
7
- # NOTHING AUTHORS A DELTA-SPEC TODAY — the delta-spec.md that cr-setup still scaffolds for
8
- # every change is an untouched template copy, which is why specify's delta_open guard tests
9
- # whether one was authored rather than whether a change is open.
4
+ # Included by /appweaver specify on its DELTA branch (spec.md already exists).
5
+ # A later requirement is a new user story on the SAME aggregate. This module opens the
6
+ # change (cr-setup) and authors the change's TWO documents:
7
+ # • changes/<cr-id>/delta-spec.md — BEHAVIOUR: what the system must now do
8
+ # • <context>/domain-model.<cr-id>.delta.md — STRUCTURE: what the domain now is
9
+ # and touches NEITHER master. The change stays OPEN; finalize-delta merges both into
10
+ # spec.md and domain-model.md later in the chain, and close-delta closes it at the end.
11
+ # No version bump here, no plan (that is /appweaver plan → delta-plan).
10
12
  #
11
- # Kept, not deleted, because the sibling half is still live: /appweaver design includes
12
- # delta-design on its own delta branch, and finalize-delta / analyze-slice / close-delta
13
- # still run. Retiring this file is a decision about the delta FAMILY, not about this module.
13
+ # WHY BOTH IN ONE RUN: the aggregate root lives in the context's domain model, not in
14
+ # the spec, so a requirement that needs a new entity or invariant has a model dependency
15
+ # the same moment it is written. Authoring the model half here means the model is never
16
+ # behind the spec that relies on it, and never waits for the plan or the implementation.
14
17
  #
15
- # What follows describes it as it was written to be included by specify.
16
- #
17
- # This is the SPEC half of the former standalone `cr` capture, relocated here: a
18
- # later requirement is a new user story on the SAME aggregate. It opens the change
19
- # (cr-setup — single-active-change guarded; also scaffolds delta-spec AND delta-design)
20
- # and authors the DELTA-SPEC ONLY. It does NOT touch the master spec.md — the change
21
- # stays OPEN; finalize-delta merges the delta into spec.md later in the chain and
22
- # close-delta closes it at the end. No version bump here, no design (that is
23
- # /appweaver design → delta-design).
18
+ # WHY THE MODEL DELTA SITS BESIDE THE MASTER, not inside changes/<cr-id>/: many changes
19
+ # may be open at once, and each one's proposed model change has to be VISIBLE to the
20
+ # others while they are being authored. A delta that can see its neighbours is designed
21
+ # around them; one that cannot discovers the overlap at merge time, when the work is
22
+ # already spent. WAVE is the ordering that follows from that: same wave = independent
23
+ # and developable in parallel, higher wave = after the lower waves land.
24
24
  #
25
25
  # Runs in the CALLER's context (include semantics): shares vars + the sticky standards
26
26
  # (specify's DDD authority + the selected domain rule files) + the caller's scripts map
27
27
  # + replay cache.
28
- # EXPECTS caller vars: feature_dir, spec_file, USER_INPUT.
29
- # PRODUCES: cr_id, cr_dir, delta_spec (and, via cr-setup, an OPEN change + a scaffolded
30
- # delta-design.md for the design phase to fill). cr_dir is what lets the
31
- # caller's quality loop target THIS change (create-checklist --kind delta).
28
+ # EXPECTS caller vars: feature_dir, spec_file, USER_INPUT, domain_model,
29
+ # pending_model_files.
30
+ # PRODUCES: cr_id, cr_dir, delta_spec, delta_model, wave, open_count (and, via cr-setup,
31
+ # an OPEN change). The change's LANE PLANS are scaffolded by `plan`, per declared
32
+ # lane — the spec phase does not know which lanes exist.
33
+ # cr_dir is what lets the caller's quality loop target THIS change
34
+ # (create-checklist --kind delta).
32
35
  # =============================================================================
33
36
 
34
37
  name: delta-spec
@@ -45,23 +48,39 @@ scripts:
45
48
 
46
49
  workflow:
47
50
 
48
- # Open the change (sets active_version.json.active_change) + scaffold the two delta
49
- # docs from their templates. Refuses if a change is already open on this aggregate.
51
+ # Open the change + scaffold its THREE documents: delta-spec and delta-design under
52
+ # changes/<cr-id>/, and the model delta BESIDE the context's master model. Many
53
+ # changes may be open at once — every specify call on an established feature opens
54
+ # its own, and the wave is what orders them.
50
55
  - id: cr_setup
51
56
  action: execute_script
52
57
  script: { ref: actions }
53
58
  subcommand: cr-setup
54
59
  args: ["--feature-dir", "{{feature_dir}}", "--title", "{{USER_INPUT}}"]
55
60
  outputs:
56
- - { name: cr_id, from: "$.cr_id" }
57
- - { name: cr_dir, from: "$.cr_dir" }
58
- - { name: delta_spec, from: "$.delta_spec" }
61
+ - { name: cr_id, from: "$.cr_id" }
62
+ - { name: cr_dir, from: "$.cr_dir" }
63
+ - { name: delta_spec, from: "$.delta_spec" }
64
+ - { name: delta_model, from: "$.delta_model" }
65
+ - { name: wave, from: "$.wave" }
66
+ - { name: open_count, from: "$.open_count" }
59
67
 
60
68
  - id: ctx
61
69
  action: build_context
70
+ context_from: pending_model_files # EVERY other open delta's model change, so this
71
+ # one is authored around them rather than into a
72
+ # collision discovered at merge time. Empty on the
73
+ # first concurrent change, which is the common case.
62
74
  context:
63
75
  - "{{delta_spec}}" # the delta-spec template to fill
76
+ - "{{delta_model}}" # the model-delta template to fill
64
77
  - "{{spec_file}}" # the current master spec (READ ONLY — never amended here)
78
+ - { path: "{{domain_model}}", optional: true }
79
+ # The context's CANONICAL model — the aggregate root,
80
+ # its entities and its invariants live here, not in the
81
+ # spec. REQUIRED in spirit but declared optional: a
82
+ # feature adopted before the model existed has none yet,
83
+ # and announcing that on every delta would be noise.
65
84
  - .appweaver/memory/constitution.domain.md # the DOMAIN authority — specify's frame. Declared
66
85
  # REQUIRED (bare string, not `optional: true`) ON PURPOSE:
67
86
  # specify is the ONLY phase that reads the domain rules and
@@ -95,7 +114,7 @@ workflow:
95
114
  delta, not a code change.
96
115
  - A UX- delta states the STANDARD only — accessibility conformance, interaction-state
97
116
  coverage, content and language, journey integrity, responsiveness-as-a-limit — never
98
- a screen, page, layout or component, which the prototype and design.ui.md settle. A
117
+ a screen, page, layout or component, which the prototype and frontend-plan.md settle. A
99
118
  change to this aggregate's own interaction BEHAVIOUR is an FR- delta; only a change
100
119
  to the standard governing every such behaviour is a UX- delta. A bound the SERVICE
101
120
  must meet stays a CN-, because the service-side gates trace CN- and never read the
@@ -103,11 +122,61 @@ workflow:
103
122
  - The new operation is a NEW USER STORY — assign the next id after the highest US-n
104
123
  in the master — never a new feature/aggregate. Record the regression risk (shared
105
124
  behaviour that must still hold).
106
- - Model the delta strictly in DDD terms (→ the modelling-methodology standard + the
107
- domain's own DDD overlay, both in the sticky standards): keep the
108
- ubiquitous language, respect the aggregate boundary and its root, entities vs
109
- value objects, and aggregate-owned invariants — domain MODEL, never code.
110
- Business-facing and testable; NO implementation mechanics (an external interop
111
- OBLIGATION is a requirement → an IC- item, but never the adapter design); NO
112
- design docs (that is the design phase).
125
+ - STRUCTURE IS NOT YOURS TO WRITE HERE. A new entity or value object, a changed
126
+ aggregate boundary, a new domain event, or a new or amended invariant (BR-n) is a
127
+ MODEL change and belongs in this change's domain-model delta — the next step
128
+ authors it. In THIS document, CITE invariants by id and state BEHAVIOUR only.
129
+ Fill "## Model changes" with the aggregates touched and the ids involved, or
130
+ "None — behaviour only" when the model does not move.
131
+ - Express the delta in the context's ubiquitous language (the domain model is in
132
+ context) — the same terms, no synonyms. Business-facing and testable; NO
133
+ implementation mechanics (an external interop OBLIGATION is a requirement → an
134
+ IC- item, but never the adapter design); NO design docs (that is the design phase).
135
+ - OTHER OPEN DELTAS may be in context (their model deltas). Read them: if one
136
+ touches the same aggregate or the same FR ids, say so under "Other open deltas"
137
+ in Impact. If THIS change only makes sense after one of them lands, say so in the
138
+ Wave rationale — that is a wave dependency, and the wave must then be RAISED above
139
+ that delta's (report it; `cr-wave` applies it). Do not silently assume their
140
+ changes: until merged they are proposals, not the master.
141
+ - Do NOT edit the Wave / Created / Base version headers — scripts stamp those.
142
+ Change request: {{USER_INPUT}}
143
+
144
+ # The MODEL half of the same change, authored in the same run so the model can never
145
+ # lag the spec that depends on it. It does NOT touch domain-model.md — finalize-delta
146
+ # merges this file into the master, one `## Aggregate:` section at a time.
147
+ - id: author_model
148
+ action: agent_author
149
+ include_standards: true
150
+ output_target: { type: file, path: "{{delta_model}}" }
151
+ task: |
152
+ The MODEL half of change {{cr_id}} (wave {{wave}}). Fill the delta-domain-model
153
+ (the output target, in context) relative to the context's current domain-model.md
154
+ (in context, when it exists). Do NOT edit domain-model.md — finalize-delta merges
155
+ this delta into it one `## Aggregate:` section at a time.
156
+
157
+ This document carries STRUCTURE; the delta-spec you just wrote carries BEHAVIOUR.
158
+ - Record ONLY what the delta-spec's requirements actually need from the model: a new
159
+ aggregate, entity or value object; a changed boundary; a new domain event; a new or
160
+ amended invariant (BR-n) or cross-aggregate invariant (XBR-n). If the change needs
161
+ nothing new from the model, say so — "None — behaviour only" is a correct and
162
+ common answer, and inventing model churn to fill the template is worse than an
163
+ empty delta.
164
+ - Classify every item ADDED / MODIFIED / REMOVED, and NAME THE AGGREGATE each
165
+ belongs to. A MODIFIED item states the BEFORE and the AFTER — the merge needs both
166
+ to be unambiguous.
167
+ - List every aggregate you touched under "Aggregates touched" in the header. That
168
+ list is exactly what finalize-delta merges, so an omission silently drops a change
169
+ and an extra entry claims a section this delta never wrote.
170
+ - Model strictly in DDD terms (→ the modelling-methodology standard + the domain's
171
+ own DDD overlay, both in the sticky standards): ubiquitous language, aggregate
172
+ boundary and root, entities vs value objects, aggregate-owned invariants,
173
+ cross-aggregate references BY ID ONLY. Technology-agnostic — no types, no
174
+ persistence, no framework. WHERE an invariant is enforced is a plan concern.
175
+ - Fill "## Impact": which specs in this context reference the aggregates touched,
176
+ and which OTHER OPEN DELTAS (in context) touch the same aggregate. Two deltas on
177
+ one aggregate is the case the wave ordering exists to sequence — name it here.
178
+ - "## Depends on": other OPEN deltas whose model changes this one builds on. Every
179
+ entry MUST sit in a LOWER wave than this delta ({{wave}}). "None" when it stands
180
+ alone. Reading another delta is NOT depending on it — only assuming its changes is.
181
+ - Do NOT edit the Wave / Created / Base context version headers — scripts stamp those.
113
182
  Change request: {{USER_INPUT}}
@@ -704,9 +704,10 @@ class Orchestrator:
704
704
  return [c for c in extra if isinstance(c, (str, dict))]
705
705
 
706
706
  def _step_read_tools(self, step):
707
- """The read tools an `agent_author` / `agent_query` step declares.
707
+ """The read tools an `agent_author` / `agent_query` / `agent_review`
708
+ step declares.
708
709
 
709
- The default is NONE — those two actions are payload-only, and the
710
+ The default is NONE — those three actions are payload-only, and the
710
711
  interpreter inlines every file the workflow mapped. A step whose task
711
712
  names files by PATH rather than inlining them declares `tools:` and gets
712
713
  exactly that set. The brownfield reversals are the reason it exists:
@@ -1131,7 +1132,7 @@ class Orchestrator:
1131
1132
  for i, o in enumerate(options, 1):
1132
1133
  print(f" {i}) {o}")
1133
1134
  if multi:
1134
- print(" (pick any: numbers or names, comma-separated \u2014 "
1135
+ print(" (pick any: numbers or names, comma-separated — "
1135
1136
  "'all', or blank for none)")
1136
1137
  try:
1137
1138
  raw = input("> ").strip()
@@ -1143,7 +1144,7 @@ class Orchestrator:
1143
1144
  return raw if raw in options else None
1144
1145
  # A multi-select answer is a SET, and a set has no single-token spelling. Read by
1145
1146
  # the single-select parser, "1,3" was neither a number in range nor an option, so it
1146
- # returned None and the run stopped as "question cancelled" \u2014 leaving exactly two
1147
+ # returned None and the run stopped as "question cancelled" — leaving exactly two
1147
1148
  # reachable answers, "the first one" and "abort". act_ask splits the string it gets
1148
1149
  # back on commas, so returning one is all that is needed here.
1149
1150
  if raw.lower() in ("all", "*"):
@@ -2,85 +2,142 @@
2
2
  ═══════════════════════════════════════════════════════════════════════════
3
3
  rev-templates/delta-design-template.skeleton.md — SHAPE-ONLY reference.
4
4
 
5
- This file is the FORMAT reference for the reverse-engineered DELTA-design
5
+ This file is the FORMAT reference for the reverse-engineered DELTA BACKEND PLAN
6
6
  TEMPLATE that onboard installs at
7
7
  .appweaver/templates/overrides/delta-design-template.md. It carries the neutral
8
- bones of a change record — the classification triple, the impact and
9
- regression sections, the two ledgers, the close contract — and NOTHING ELSE.
8
+ bones of a change record — the classification triple, the model bridge, the
9
+ wave discipline, the impact and regression sections, the two ledgers, the merge
10
+ contract — and NOTHING ELSE.
10
11
 
11
12
  IT NAMES NO LAYERING AND NO TECHNOLOGY. The "Section" column below is a SLOT:
12
- it is filled with the ACTUAL sections of the master design template generated
13
+ it is filled with the ACTUAL sections of the master plan template generated
13
14
  alongside this one, whatever the code turned out to be organised into. A
14
15
  greenfield delta template's example rows name its four layers; naming any
15
16
  layer here would re-import exactly the assumption onboard exists to displace.
16
17
 
17
- MIRRORS THE MASTER, ALWAYS. The delta-design module classifies changes "per
18
- the master's OWN section structure", so this template is derived FROM the
19
- generated master design template rather than from a fixed list. If the master
20
- has axes A, B and C, the example rows here name A, B and C. That coupling is
21
- the point: a change is classified against the document it amends.
18
+ MIRRORS THE MASTER, ALWAYS. The delta-plan module classifies changes "per the
19
+ master's OWN section structure", so this template is derived FROM the generated
20
+ master plan template rather than from a fixed list. If the master has axes A, B
21
+ and C, the example rows here name A, B and C. That coupling is the point: a
22
+ change is classified against the document it amends.
22
23
 
23
24
  DISCIPLINE THIS SKELETON ENFORCES (structurally — there is no project content
24
25
  here to leak):
25
- • ONE MASTER — a change amends specs/<Aggregate>/design.md; it never opens a
26
- second design document.
26
+ • ONE MASTER PER LANE — a change amends
27
+ specs/<Context>/<Feature>/backend-plan.md; it never opens a second plan
28
+ document, and it never edits the master itself.
27
29
  • ADDED / MODIFIED / REMOVED — the complete classification. A shared element
28
30
  is MODIFIED in place, never duplicated into the change.
29
- • EVERY ROW SERVES A SPEC ID — the delta reads the spec, never the domain
30
- rule files.
31
+ • EVERY ROW SERVES A SPEC ID — the delta reads the delta-spec and the domain
32
+ model, never the domain rule files.
33
+ • STRUCTURE IS NOT PLANNED HERE — entities, events and invariants (BR-n) live
34
+ in the context's domain model. This document plans where each is ENFORCED.
35
+ • WAVE ORDERS THE OPEN CHANGES — a lower wave may be built on, a same wave is
36
+ visible but never assumed.
31
37
  • TECHNOLOGY-AGNOSTIC — signatures and field shapes, no code, exactly as in
32
38
  the master.
33
39
  ═══════════════════════════════════════════════════════════════════════════
34
40
  -->
35
- # Delta Design — [CR-ID]: [TITLE]
41
+ # Delta Backend Plan — [CR-ID]: [TITLE]
36
42
 
37
- **Feature (aggregate)**: [Aggregate]
43
+ **Feature (aggregate slice)**: [Feature]
44
+
45
+ **Lane**: backend
46
+
47
+ **Wave**: [N] <!-- script-stamped; same wave = developable in parallel, higher wave = after -->
38
48
 
39
49
  **Base version**: [vX.Y]
40
50
 
51
+ **Delta spec**: `changes/[CR-ID]/delta-spec.md`
52
+
53
+ **Model delta**: `specs/[Context]/domain-model.[CR-ID].delta.md` <!-- "none" when behaviour-only -->
54
+
41
55
  <!--
42
- This delta applies to the SINGLE master design at specs/[Aggregate]/design.md
43
- — never a new design doc. Classify every design change ADDED / MODIFIED /
44
- REMOVED against the current master, per the MASTER'S OWN SECTIONS, in the same
45
- technology-agnostic form: behaviour as signatures + pre/post/invariant/raises,
46
- contracts as field shapes, no code. A new command is a new USER STORY realised
47
- as delta elements, not a new feature. After this delta is applied,
48
- `implement-delta` regenerates the touched slice and regression re-tests the
49
- dependents of every shared element.
56
+ This delta applies to the SINGLE master plan at
57
+ specs/[Context]/[Feature]/backend-plan.md — never a new plan doc, and never the
58
+ master itself: finalize-delta merges it later in the chain.
59
+
60
+ IT PLANS AGAINST THE EFFECTIVE MODEL — the master domain-model.md, this change's
61
+ own model delta, and the PREDECESSOR deltas (the open ones in a LOWER wave,
62
+ committed to landing first). Same-wave deltas are visible but are not
63
+ predecessors: read them to avoid a collision, never assume them.
64
+
65
+ Classify every plan change ADDED / MODIFIED / REMOVED against the current
66
+ master, per the MASTER'S OWN SECTIONS, in the same technology-agnostic form:
67
+ behaviour as signatures + pre/post/invariant/raises, contracts as field shapes,
68
+ no code. A new command is a new USER STORY realised as delta elements, not a new
69
+ feature. `implement` generates the touched slice from this document and
70
+ regression re-tests the dependents of every shared element.
50
71
  -->
51
72
 
52
73
  ## Change summary
53
74
 
54
- [One paragraph: what the design change is and which user story / spec delta it serves.]
75
+ [One paragraph: what the plan change is and which delta-spec items it realises.]
76
+
77
+ ## Model changes this plan realises
78
+
79
+ <!-- One row per item the domain-model delta ADDED / MODIFIED / REMOVED, saying
80
+ WHERE the change lands in this codebase's own structure. An item in the model
81
+ delta with no row here is a structural change nothing implements.
82
+ "None — behaviour only" when this change does not move the model. -->
83
+
84
+ | Model item | Kind | Realised in | Enforced at |
85
+ |---|---|---|---|
86
+ | `[entity / event / BR-nnn]` | [added / amended / removed] | `[element]` | `[where the rule is checked]` |
87
+
88
+ ## Depends on
55
89
 
56
- ## ADDED — new design elements
90
+ <!-- Other OPEN changes this plan builds on. Every entry MUST be in a LOWER wave.
91
+ "None — stands alone" is the common and preferred answer. -->
92
+
93
+ - `[CR-ID]` (wave [N-1]) — [what this plan assumes from it]
94
+
95
+ ## ADDED — new plan elements
57
96
 
58
97
  <!-- New elements and the realisation of any new spec constraint, classification
59
- or contract. "Section" names a section of THIS project's master design —
60
- the same section titles the generated design template carries. -->
98
+ or contract. "Section" names a section of THIS project's master plan —
99
+ the same section titles the generated plan template carries. -->
61
100
 
62
- | Section (§ in design.md) | Element | Kind | Serves |
101
+ | Section (§ in backend-plan.md) | Element | Kind | Serves |
63
102
  |---|---|---|---|
64
103
  | [§ of the master's own structure] | `[element]` | [kind] | US-[n] · FR-[nnn] |
65
104
 
66
- ## MODIFIED — existing design elements
105
+ ## MODIFIED — existing plan elements
67
106
 
68
107
  <!-- Edits to elements the master already defines. A shared element is modified
69
108
  here, in place — never copied into the change. -->
70
109
 
71
- | Section (§ in design.md) | Element | What changes | Why |
110
+ | Section (§ in backend-plan.md) | Element | What changes | Why |
72
111
  |---|---|---|---|
73
112
  | [§ of the master's own structure] | `[element]` | [the edit] | US-[n] |
74
113
 
75
114
  ## REMOVED
76
115
 
77
- - [design element removed + why] — or `None`
116
+ - [plan element removed + why] — or `None`
78
117
 
79
118
  ## Cross-section impact
80
119
 
81
120
  [Which of the master's sections ripple; shared elements touched; whether a data
82
121
  migration is needed (yes/no); any contract change other systems couple to.]
83
122
 
123
+ ## Contract deltas for the frontend lane
124
+
125
+ <!-- What this change adds to or alters in the service's PUBLISHED surface — the
126
+ only part of this document the frontend lane may bind against. `None` when
127
+ the surface is unchanged. Omit the section entirely where the code has no
128
+ frontend lane. -->
129
+
130
+ | Contract | Change | Shape | Serves |
131
+ |---|---|---|---|
132
+ | `[contract]` | [added / changed] | [request → response field shapes] | IC-[nnn] |
133
+
134
+ ## Other open deltas
135
+
136
+ <!-- Which OTHER open changes touch the same elements, read from the model deltas
137
+ beside the master model. `None` when this change stands clear. -->
138
+
139
+ - `[CR-ID]` (wave [N]) — [what overlaps, and how this plan stays clear of it]
140
+
84
141
  ## Regression targets
85
142
 
86
143
  [Existing user stories / behaviours to re-verify because a shared element
@@ -89,13 +146,14 @@ changed.]
89
146
  ## New assumptions / deviations (from this change)
90
147
 
91
148
  <!-- Anything this change defers — folds into the master's DA-n / WA-n ledgers
92
- on apply. -->
149
+ on merge. -->
93
150
 
94
151
  - **DA-[n]**: [assumption to clarify later] — or `None`
95
152
  - **WA-[n]**: [deviation to clear later] — or `None`
96
153
 
97
- ## On close
154
+ ## On merge
98
155
 
99
- `finalize-delta` merges this record into the master design.md and appends the
100
- Change History row; `close-delta` bumps the version and archives the change
101
- under `changes/archive/`.
156
+ `finalize-delta` merges this record into the master backend-plan.md alongside the
157
+ spec and domain-model merges and leaves the change OPEN; `close-delta` bumps the
158
+ version, writes the Change History rows and archives the change under
159
+ `changes/archive/`.
@@ -55,7 +55,7 @@
55
55
 
56
56
  **Aggregate (feature)**: `[Aggregate]`
57
57
 
58
- **Design home**: `specs/[Aggregate]/design.md`
58
+ **Plan home**: `specs/[Context]/[Feature]/backend-plan.md`
59
59
 
60
60
  **Source spec**: `specs/[Aggregate]/spec.md`
61
61
 
@@ -0,0 +1,115 @@
1
+ <!--
2
+ ═══════════════════════════════════════════════════════════════════════════
3
+ rev-templates/domain-model-template.skeleton.md — SHAPE-ONLY reference.
4
+
5
+ This file is the FORMAT reference for the reverse-engineered DOMAIN MODEL
6
+ TEMPLATE that onboard installs at
7
+ .appweaver/templates/overrides/domain-model-template.md. It carries the neutral
8
+ bones every context domain model has — the header block, the ubiquitous
9
+ language, one repeatable `## Aggregate:` section, the cross-aggregate
10
+ invariants, the context map and the Change History — and NOTHING ELSE.
11
+
12
+ IT NAMES NO AGGREGATE, NO ENTITY AND NO TECHNOLOGY. Naming one would hand the
13
+ generator an answer to the single question it exists to ask the code. Every
14
+ [BRACKET] token is filled FROM THE CODE, never copied.
15
+
16
+ THIS IS A TEMPLATE OF A TEMPLATE. What onboard generates from it is not a
17
+ filled model — it is the project's domain-model TEMPLATE, which `specify`
18
+ (forward) and `adopt` (brownfield, per feature) then fill. So the generated
19
+ file keeps [PLACEHOLDER] tokens and authoring comments; what onboard replaces
20
+ is the STRUCTURE — which sections exist and what they are called — never the
21
+ content.
22
+
23
+ WHAT IS PINNED, AND WHY (each earns it by being something a tool or a gate
24
+ keys on):
25
+ • `## Aggregate: <Name>` is the MERGE UNIT. finalize-delta merges a delta
26
+ one such section at a time, so the heading form is machinery, not taste.
27
+ Repeat the whole block per root; never collapse two roots into one.
28
+ • `### Invariants` carries STABLE BR-nnn ids. Specs cite those ids and the
29
+ conformance gates trace them, so the id class cannot be renamed per
30
+ project.
31
+ • `**Serving specs**:` is what makes a cross-spec aggregate visible from the
32
+ model side — the reverse of each spec's Domain Model Reference.
33
+ • The Change History table is the model's version ledger; close-delta
34
+ appends to it and stamps the context version. The model never writes its
35
+ own version.
36
+
37
+ BROWNFIELD DERIVATION — where each part comes from in an existing codebase:
38
+ • Aggregate roots: the entity types other types reference by id but never
39
+ navigate into; the transaction boundaries the persistence layer commits.
40
+ • Entities vs value objects: identity. A type compared by id is an entity; a
41
+ type compared by value is a value object.
42
+ • Invariants: the guards, and the constraint checks in the persistence layer.
43
+ A rule enforced in code IS an invariant, whether or not anyone wrote it
44
+ down — record it, and record that the CODE is its current authority.
45
+ • Ubiquitous language: the names the code actually uses. Where the code and
46
+ the business disagree, record BOTH and flag it — do not silently pick one.
47
+ ═══════════════════════════════════════════════════════════════════════════
48
+ -->
49
+
50
+ # Domain Model — [BOUNDED CONTEXT]
51
+
52
+ **Bounded context**: `[Context]`
53
+
54
+ **Model home**: `specs/[Context]/domain-model.md`
55
+
56
+ **Context version**: v1.0 <!-- script-stamped -->
57
+
58
+ **Derived from**: code — [what was scanned] <!-- brownfield provenance; the code is the oracle -->
59
+
60
+ ## Ubiquitous Language
61
+
62
+ | Term | Means in this context | Not to be confused with |
63
+ |---|---|---|
64
+ | [TERM] | [meaning as the CODE uses it] | [the term it is confused with, and where] |
65
+
66
+ ## Aggregate: [Root]
67
+
68
+ **Serving specs**: [features that reference this aggregate]
69
+
70
+ **Last changed**: v1.0 · initial (reverse-engineered)
71
+
72
+ ### Boundary
73
+
74
+ - **Owns**: [types inside the consistency boundary — from the code]
75
+ - **References (by id, not owned)**: [<Other>Id fields found in the code]
76
+ - **Out of scope / non-goals**: [what the code shows this aggregate does NOT own]
77
+
78
+ ### Entities
79
+
80
+ - **[Root]** *(aggregate root)*: [what it represents; key attributes; observed lifecycle/states]
81
+ - **[Entity]**: [what it represents; relationship to the root]
82
+
83
+ ### Value objects
84
+
85
+ - **[VO]**: [what it represents; compared by value in the code]
86
+
87
+ ### Domain events
88
+
89
+ | Event | Raised by | Trigger | Key payload |
90
+ |---|---|---|---|
91
+ | [EVENT] | [type] | [what causes it] | [fields] |
92
+
93
+ ### Invariants
94
+
95
+ <!-- STABLE BR-nnn ids. In brownfield the CODE is the current authority for each rule — record what it enforces, not what it ought to. -->
96
+
97
+ - **BR-001**: [the rule as the code enforces it] *(source: [where it is enforced])*
98
+
99
+ ## Cross-Aggregate Invariants
100
+
101
+ <!-- Rules spanning two or more aggregates. "None (as of v1.0)" when there are none — never delete the section. -->
102
+
103
+ - **XBR-001**: [the rule] — or `None (as of v1.0)`
104
+
105
+ ## Context Map
106
+
107
+ | Other context | Direction | Pattern | What crosses |
108
+ |---|---|---|---|
109
+ | [CONTEXT] | [upstream/downstream] | [pattern] | [what crosses the boundary] |
110
+
111
+ ## Change History
112
+
113
+ | Context version | Date | Aggregate | Change | Feature | CR |
114
+ |---|---|---|---|---|---|
115
+ | v1.0 | [DATE] | [Root] | Initial model (reverse-engineered) | [Feature] | — |
@@ -36,20 +36,13 @@ partition; preserve it exactly.
36
36
  - guardrails/projects/[project]/domain/[each generated domain rule file].md
37
37
 
38
38
  ## /aw-spec-plan
39
- _None — the service lane's design loads no domain file. Domain reaches it only through the spec
40
- (BR-/CN-/DC-/IC-)._
41
-
42
- ## /aw-spec-plan-ui
43
- _None — the frontend lane's design loads no domain file either: domain reaches frontend-plan.md
44
- as spec ids (UX-/CN-/DC-/IC-). Written out rather than left absent, because an absent heading and
45
- an empty one behave identically and only one of them is a decision. Keep this heading even in a
46
- backend-only repo — it costs nothing and records the partition._
39
+ _None — design loads no domain file. Domain reaches design only through the spec (BR-/CN-/DC-/IC-)._
47
40
 
48
41
  ## /aw-spec-implement
49
42
  _None — implement loads no domain file. Domain reaches implement only through design.md._
50
43
 
51
44
  ## /aw-spec-gate
52
- <!-- Conformance checklist for the gates (analyze-design · analyze-slice): the domain-derived
45
+ <!-- Conformance checklist for the gates (analyze-plan · analyze-slice): the domain-derived
53
46
  constraints design/implement were NOT given as authoring input, VALIDATED against output. -->
54
47
  - guardrails/projects/[project]/domain/[each *.domain.md overlay to validate against].md
55
48