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.
- package/assets/.appweaver/DESIGN-FORMAT.md +18 -18
- package/assets/.appweaver/ORCH-DIALECT.md +1 -3
- package/assets/.appweaver/RULE-PARTITION.md +29 -13
- package/assets/.appweaver/STACK-PROFILES.md +10 -9
- package/assets/.appweaver/orchestrator/.state/smoke.state.json +32 -0
- package/assets/.appweaver/orchestrator/AGENT-PROFILE.md +4 -1
- package/assets/.appweaver/orchestrator/modules/delta-plan.orch.yaml +251 -0
- package/assets/.appweaver/orchestrator/modules/delta-spec.orch.yaml +104 -35
- package/assets/.appweaver/orchestrator/orchestrator.py +5 -4
- package/assets/.appweaver/orchestrator/rev-templates/delta-design-template.skeleton.md +94 -36
- package/assets/.appweaver/orchestrator/rev-templates/design-template.skeleton.md +1 -1
- package/assets/.appweaver/orchestrator/rev-templates/domain-model-template.skeleton.md +115 -0
- package/assets/.appweaver/orchestrator/rev-templates/domain-rule-bindings.skeleton.md +2 -9
- package/assets/.appweaver/orchestrator/rev-templates/tech-rule-bindings.skeleton.md +16 -40
- package/assets/.appweaver/orchestrator/rev-templates/ui-delta-design-template.skeleton.md +38 -17
- package/assets/.appweaver/orchestrator/rev-templates/ui-design-template.skeleton.md +8 -8
- package/assets/.appweaver/orchestrator/workflows/aw-spec-adopt.orch.yaml +10 -11
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-plan-delta.orch.yaml +673 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-plan.orch.yaml +535 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-slice-delta.orch.yaml +643 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-slice.orch.yaml +84 -701
- package/assets/.appweaver/orchestrator/workflows/aw-spec-build.orch.yaml +4 -4
- package/assets/.appweaver/orchestrator/workflows/aw-spec-characterize.orch.yaml +7 -7
- package/assets/.appweaver/orchestrator/workflows/aw-spec-close-delta.orch.yaml +16 -14
- package/assets/.appweaver/orchestrator/workflows/aw-spec-constitution.orch.yaml +2 -2
- package/assets/.appweaver/orchestrator/workflows/aw-spec-finalize-delta.orch.yaml +243 -144
- package/assets/.appweaver/orchestrator/workflows/aw-spec-implement.orch.yaml +877 -578
- package/assets/.appweaver/orchestrator/workflows/aw-spec-inventory.orch.yaml +4 -4
- package/assets/.appweaver/orchestrator/workflows/aw-spec-onboard.orch.yaml +32 -91
- package/assets/.appweaver/orchestrator/workflows/aw-spec-parity.orch.yaml +2 -2
- package/assets/.appweaver/orchestrator/workflows/aw-spec-plan.orch.yaml +836 -514
- package/assets/.appweaver/orchestrator/workflows/aw-spec-run.orch.yaml +2 -2
- package/assets/.appweaver/orchestrator/workflows/aw-spec-select-bounded-context.orch.yaml +132 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-select-feature.orch.yaml +38 -5
- package/assets/.appweaver/orchestrator/workflows/aw-spec-select-stack.orch.yaml +3 -3
- package/assets/.appweaver/orchestrator/workflows/aw-spec-specify.orch.yaml +271 -979
- package/assets/.appweaver/scripts/bash/aw-spec-actions.sh +1085 -3385
- package/assets/.appweaver/scripts/bash/aw-xref.sh +1 -2
- package/assets/.appweaver/scripts/bash/common.sh +47 -0
- package/assets/.appweaver/scripts/powershell/aw-spec-actions.ps1 +914 -3220
- package/assets/.appweaver/scripts/powershell/aw-xref.ps1 +1 -2
- package/assets/.appweaver/scripts/python/aw-payload-parity.py +19 -3
- package/assets/.appweaver/scripts/python/aw-stack.py +6 -2
- package/assets/.appweaver/scripts/python/aw-xref.py +86 -350
- package/assets/.appweaver/templates/constitution-ui-template.md +1 -1
- package/assets/.appweaver/templates/delta-design-template.md +120 -30
- package/assets/.appweaver/templates/delta-domain-model-template.md +81 -0
- package/assets/.appweaver/templates/delta-spec-template.md +43 -17
- package/assets/.appweaver/templates/design-template.md +68 -98
- package/assets/.appweaver/templates/domain-model-template.md +130 -0
- package/assets/.appweaver/templates/okf-concept-template.md +2 -2
- package/assets/.appweaver/templates/source-map-template.md +3 -3
- package/assets/.appweaver/templates/spec-template.md +100 -122
- package/assets/.appweaver/templates/ui-delta-design-template.md +159 -0
- package/assets/.appweaver/templates/ui-design-template.md +46 -75
- package/assets/guardrails/projects/dotnet-default-project/domain-rule-bindings.md +7 -18
- package/assets/guardrails/projects/dotnet-default-project/tech-rule-bindings.md +34 -39
- package/assets/guardrails/requirement-spec.txt +2 -2
- package/assets/guardrails/technology/dotnet-webapi/testing.md +1 -1
- package/package.json +1 -1
- package/assets/.appweaver/orchestrator/modules/delta-design.orch.yaml +0 -105
- package/assets/.appweaver/orchestrator/modules/spec-state-gate.orch.yaml +0 -87
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-delta-design.orch.yaml +0 -251
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-design.orch.yaml +0 -813
- package/assets/.appweaver/orchestrator/workflows/aw-spec-implement-delta.orch.yaml +0 -253
- package/assets/.appweaver/orchestrator/workflows/aw-spec-implement-ui.orch.yaml +0 -663
- package/assets/.appweaver/orchestrator/workflows/aw-spec-plan-ui.orch.yaml +0 -600
- package/assets/.appweaver/orchestrator/workflows/aw-spec-story-plan.orch.yaml +0 -1147
- package/assets/.appweaver/orchestrator/workflows/aw-spec-sync-stories.orch.yaml +0 -1121
- 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
|
-
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
#
|
|
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
|
-
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
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
|
-
#
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
# and
|
|
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
|
-
#
|
|
30
|
-
#
|
|
31
|
-
#
|
|
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
|
|
49
|
-
#
|
|
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,
|
|
57
|
-
- { name: cr_dir,
|
|
58
|
-
- { name: 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
|
|
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
|
-
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
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`
|
|
707
|
+
"""The read tools an `agent_author` / `agent_query` / `agent_review`
|
|
708
|
+
step declares.
|
|
708
709
|
|
|
709
|
-
The default is NONE — those
|
|
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
|
|
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"
|
|
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
|
|
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
|
|
9
|
-
regression sections, the two ledgers, the
|
|
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
|
|
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-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
|
26
|
-
second
|
|
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
|
|
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
|
|
41
|
+
# Delta Backend Plan — [CR-ID]: [TITLE]
|
|
36
42
|
|
|
37
|
-
**Feature (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
|
|
43
|
-
— never a new
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
60
|
-
the same section titles the generated
|
|
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
|
|
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
|
|
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
|
|
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
|
-
- [
|
|
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
|
|
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
|
|
154
|
+
## On merge
|
|
98
155
|
|
|
99
|
-
`finalize-delta` merges this record into the master
|
|
100
|
-
|
|
101
|
-
under
|
|
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/`.
|
|
@@ -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 —
|
|
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-
|
|
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
|
|