aw-spec-cli 0.1.15 → 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 (69) 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 +78 -626
  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 +882 -464
  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 +832 -477
  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 -892
  37. package/assets/.appweaver/scripts/bash/aw-spec-actions.sh +1096 -2911
  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 +936 -2766
  41. package/assets/.appweaver/scripts/powershell/aw-xref.ps1 +1 -2
  42. package/assets/.appweaver/scripts/python/aw-payload-parity.py +174 -0
  43. package/assets/.appweaver/scripts/python/aw-stack.py +6 -2
  44. package/assets/.appweaver/scripts/python/aw-xref.py +185 -292
  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/workflows/aw-spec-analyze-delta-design.orch.yaml +0 -251
  63. package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-design.orch.yaml +0 -749
  64. package/assets/.appweaver/orchestrator/workflows/aw-spec-implement-delta.orch.yaml +0 -253
  65. package/assets/.appweaver/orchestrator/workflows/aw-spec-implement-ui.orch.yaml +0 -540
  66. package/assets/.appweaver/orchestrator/workflows/aw-spec-plan-ui.orch.yaml +0 -597
  67. package/assets/.appweaver/orchestrator/workflows/aw-spec-story-plan.orch.yaml +0 -945
  68. package/assets/.appweaver/orchestrator/workflows/aw-spec-sync-stories.orch.yaml +0 -1040
  69. package/assets/.appweaver/templates/story-template.md +0 -147
@@ -13,14 +13,14 @@ A feature's design is **one document**, living beside its spec:
13
13
  ```
14
14
  specs/<Aggregate>/
15
15
  spec.md # behaviour (tech-agnostic) — WHAT / WHY — the source of truth
16
- design.md # structure & decisions (tech-agnostic HLD) — the MEDIATOR
16
+ backend-plan.md # structure & decisions (tech-agnostic HLD) — the MEDIATOR
17
17
  changes/ # open + archived change records (delta-spec + delta-design)
18
18
  ```
19
19
 
20
- `design.md` is the **mediator** between the spec and the generated code:
20
+ `backend-plan.md` is the **mediator** between the spec and the generated code:
21
21
 
22
22
  ```
23
- spec.md ──▶ design.md ──▶ code (+ tests)
23
+ spec.md ──▶ backend-plan.md ──▶ code (+ tests)
24
24
  behaviour structure & generated by `implement`
25
25
  FR/BR/US/SC decisions (HLD) (stack bound at generation time)
26
26
  ```
@@ -37,11 +37,11 @@ FR/BR/US/SC decisions (HLD) (stack bound at generation time)
37
37
  layer (§1) follows spec.md exactly — its entities/value-objects are the spec's Key
38
38
  Entities and its invariants are the spec's Business Rules.
39
39
  - **Technology-agnostic.** Behaviour and contracts use conceptual types, never a
40
- language. The SAME design.md must be generatable on a different stack. The target
40
+ language. The SAME backend-plan.md must be generatable on a different stack. The target
41
41
  language/framework/persistence is bound only at `implement` time from the
42
42
  constitution's technology base + the active stack profile.
43
43
  - **Physical schema is out of scope.** PKs/FKs, columns, indexes, JSON shapes, and
44
- migration SQL belong to a separate technical-data-model — design.md states WHAT is
44
+ migration SQL belong to a separate technical-data-model — backend-plan.md states WHAT is
45
45
  stored and WHICH port persists it, not the schema.
46
46
  - **Two deferral ledgers are first-class:** §7 Assumptions (`DA-n`, clarify later)
47
47
  and §8 Workarounds (`WA-n`, clear later). They keep the HLD honest about what it
@@ -49,7 +49,7 @@ FR/BR/US/SC decisions (HLD) (stack bound at generation time)
49
49
  - **Solution-wide rules live elsewhere, not per feature:** the layering/dependency
50
50
  rule is the constitution's; the code-generation mechanics (folder mapping,
51
51
  file-per-element, test pairing, stack binding) are a technology-specific rule
52
- applied in the `implement` phase. `design.md` stays feature-specific and
52
+ applied in the `implement` phase. `backend-plan.md` stays feature-specific and
53
53
  technology-agnostic.
54
54
 
55
55
  ## Brownfield variant (existing codebases)
@@ -89,7 +89,7 @@ from the code.
89
89
  ## Frontend lane variant (`design-ui`)
90
90
 
91
91
  A project with a frontend lane designs it in its **own** document,
92
- `specs/<Feature>/design.ui.md`, authored by `design-ui` — not a section inside `design.md`.
92
+ `specs/<Feature>/frontend-plan.md`, authored by `design-ui` — not a section inside `backend-plan.md`.
93
93
  The lanes are governed by different constitution halves, take their rules from different
94
94
  map headings, and are implemented by different commands. A UI section inside the service
95
95
  design would put the lane's structure under the service lane's rules and hand `design-ui`
@@ -101,13 +101,13 @@ navigation & screen structure · client state · component structure · interact
101
101
  contract binding · cross-cutting · traceability · `DA-n` · `WA-n`. Technology-agnostic here
102
102
  means no framework, router, state library or component library appears: a component is
103
103
  described by its responsibility, its inputs as field shapes, the events it raises and the
104
- states it can be in, and the framework binds at `implement-ui` from `constitution.ui.md`
105
- plus that command's rule set. The authoring template is
104
+ states it can be in, and the framework binds in the FRONTEND LANE of `implement`, from
105
+ `constitution.ui.md` plus that lane's rule set. The authoring template is
106
106
  `.appweaver/templates/ui-design-template.md`.
107
107
 
108
108
  **§5 Contract Binding is the lane boundary.** The UI design reads the whole spec — the
109
109
  experience is stated there — but only the service's **published surface**: the spec's `IC-`
110
- ids and the API contracts `design.md` states. No table, handler or persistence choice
110
+ ids and the API contracts `backend-plan.md` states. No table, handler or persistence choice
111
111
  crosses that line, and an operation the experience needs that the surface does not offer is
112
112
  a contract delta raised back to the service lane, never a client workaround. ⌛ `design`
113
113
  will emit that surface as a `design-contract.md` projection; the rule does not change when
@@ -116,7 +116,7 @@ it does, only what §5 reads.
116
116
  **`UX-` lives here and only here.** The service design excludes the spec's Experience
117
117
  Standards by contract — it realises no experience standard, and a traceability row for one
118
118
  would be a fabrication. So a `UX-` that reaches neither design is a dropped requirement,
119
- and design.ui.md's §7 is the only place that is visible.
119
+ and frontend-plan.md's §7 is the only place that is visible.
120
120
 
121
121
  **Interaction & flow and cross-cutting are never omitted**, however thin the feature.
122
122
  They are the two sections a backend-shaped process silently drops, and loading, empty,
@@ -134,10 +134,10 @@ The design document and the code are **not** a byte-for-byte copy of each other.
134
134
 
135
135
  | Direction | Phase | What happens |
136
136
  |---|---|---|
137
- | **Generate** (forward) | Implement | The model reads spec + design.md and **generates** the code and tests — a reasoning step the design guides and constrains, not a transcription. |
138
- | **Reconcile** (high-level back) | Build / Run fixes | Compile/typecheck/runtime fixes happen on the **code**. Only when a fix is a **high-level technical variation** — a changed pattern, a new component, an altered contract/dependency — is that decision written back into design.md. Low-level churn stays in the code. |
137
+ | **Generate** (forward) | Implement | The model reads spec + backend-plan.md and **generates** the code and tests — a reasoning step the design guides and constrains, not a transcription. |
138
+ | **Reconcile** (high-level back) | Build / Run fixes | Compile/typecheck/runtime fixes happen on the **code**. Only when a fix is a **high-level technical variation** — a changed pattern, a new component, an altered contract/dependency — is that decision written back into backend-plan.md. Low-level churn stays in the code. |
139
139
 
140
- > **Invariant:** design.md remains a faithful **high-level** account of the built
140
+ > **Invariant:** backend-plan.md remains a faithful **high-level** account of the built
141
141
  > system — every significant technical decision is recorded — but it is a durable
142
142
  > design reference, **not** a line-by-line mirror of the code. (This retires the old
143
143
  > `docs == files` extract/reconcile invariant.)
@@ -158,13 +158,13 @@ A **feature is the largest slice whose code no other feature owns.** Because
158
158
  `implement` regenerates the whole feature's code coherently, a shared file
159
159
  (`src/Domain/Order.cs`) must have exactly **one** owning design. So for an aggregate
160
160
  with a shared entity, **feature = the aggregate** (`Order`), and individual commands
161
- (`CreateOrder`, `UpdateOrder`, …) are **user stories / deltas** on the same design.md:
161
+ (`CreateOrder`, `UpdateOrder`, …) are **user stories / deltas** on the same backend-plan.md:
162
162
 
163
163
  - `CreateOrder` = US-1; `UpdateOrder` = US-2.
164
164
  - Adding `UpdateOrder` is an additive CR: a Delta Spec (`+US-2`) and a Delta Design
165
165
  (`ADDED` new use-case/endpoint sections, `MODIFIED` the shared Order/root and
166
166
  repository sections — see `delta-design-template.md`). The design phase amends
167
- design.md doc-first, bumps the feature version (`v1.0 → v1.1`), and archives the CR;
167
+ backend-plan.md doc-first, bumps the feature version (`v1.0 → v1.1`), and archives the CR;
168
168
  `implement` regenerates the touched slice; regression re-tests the shared-file
169
169
  dependents.
170
170
 
@@ -179,9 +179,9 @@ The legacy path-tagged helpers (`design-extract` / `design-reconcile` / `design-
179
179
  are **retired and deleted** from both shells. They belonged to the four-document,
180
180
  full-code model in which `design.{domain,application,api,infra}.md` carried the source
181
181
  inside ` ```lang path=… ` fences. That convention is gone — no template emits `path=`,
182
- and `design-scaffold` writes a single `design.md` — so all three had been finding
182
+ and `design-scaffold` writes a single `backend-plan.md` — so all three had been finding
183
183
  nothing and no-op'ing at exit 0. (Their glob, `design.*.md`, could not have matched a
184
- single `design.md` even if the fences had survived: the second dot required a middle
184
+ single `backend-plan.md` even if the fences had survived: the second dot required a middle
185
185
  segment. The one legitimate remaining user of that glob, `list-features`'s informational
186
186
  `design_docs` count, is fixed to `design*.md`.)
187
187
 
@@ -48,9 +48,7 @@ transport profile (`agent.json`) and their thin `/appweaver` launcher.
48
48
  `strategy:` override): `sdk`, `sdk-apply`, `spawn`, `agent` — they only
49
49
  govern WHO fulfills a generation, never what goes into it. `agent` isolation
50
50
  is best-effort (same conversation); `sdk` / `spawn` / `sdk-apply` generation
51
- are isolated. Python scripts (`execute_script`) are deterministic only —
52
- they never MODEL-author spec or code content (a few, like `aw-inventory.py`
53
- and `aw-rev-constitution.py`, do generate documents — deterministically).
51
+ are isolated.
54
52
  3. **The checkpoint channel is strategy-independent** (D1): `ask`,
55
53
  `user_select` and `dispatch_hooks` suspend via `--checkpoint` under EVERY
56
54
  strategy, so the launching agent can relay to the human. Converted-skill
@@ -44,7 +44,7 @@ A command with **no heading** in a map loads nothing mapped for that class and
44
44
  - `.appweaver/memory/constitution.technical.md` — the technology base. Standing input to
45
45
  **design + implement**. Domain-agnostic.
46
46
  - `.appweaver/memory/constitution.ui.md` — the **frontend lane's** base, a UX-* principle series.
47
- Standing input to ⌛ **ui-design + ui-implement**. Domain-agnostic for the same reason the
47
+ Standing input to the **FRONTEND LANE of `plan` and of `implement`**. Domain-agnostic for the same reason the
48
48
  technical base is, and it exists only where a frontend lane does — a backend-only project has
49
49
  no such file.
50
50
  - `.appweaver/memory/constitution.domain.md` — the active domain's addenda. Standing input to
@@ -52,8 +52,9 @@ A command with **no heading** in a map loads nothing mapped for that class and
52
52
  - `.appweaver/memory/constitution.md` — the composed human/compatibility view. The pipeline loads
53
53
  the halves, not this file.
54
54
 
55
- One lane's constitution never governs the other lane's code: `design`/`implement` load the
56
- technical base and `ui-design`/`ui-implement` load the UI base. What they share is the spec.
55
+ One lane's constitution never governs the other lane's code. `plan` and `implement` are each
56
+ ONE command covering BOTH lanes, and the halves are loaded per lane inside them: the service
57
+ lane loads the technical base, the frontend lane loads the UI base. What they share is the spec.
57
58
 
58
59
  ---
59
60
 
@@ -79,10 +80,20 @@ technical base and `ui-design`/`ui-implement` load the UI base. What they share
79
80
  spec against.
80
81
  - Constitution: the **technical** half.
81
82
 
82
- ### `implement` / `implement-delta` — *code generation*
83
- - **Domain rule files: NEVER.** The design is the only input describing what to build.
84
- - **Technical rule files: yes** — the code-generation and convention set.
85
- - Constitution: the **technical** half.
83
+ ### `implement` — *code generation, both lanes, both paths*
84
+ - **Domain rule files: NEVER.** The lane's plan is the only input describing what to BUILD.
85
+ - **The domain MODEL: yes, and it is not a rule file.** `specs/<Context>/domain-model.md` is
86
+ spec-tier, like `spec.md` — the canonical statement of what the domain IS. It is in context
87
+ because a plan cites `BR-nnn` and never restates it, so without the model the phase is told
88
+ where to enforce a rule it was never told the content of. On the delta path that change's
89
+ `domain-model.<CR-id>.delta.md` joins it, since the master is not merged until
90
+ finalize-delta. The model is READ, never mined for work: what it holds and no plan element
91
+ realises is a planning gap, not code to invent.
92
+ - **Technical rule files: yes** — the code-generation and convention set, keyed per lane and,
93
+ for the service lane, per path: `## /aw-spec-implement` generating a master plan,
94
+ `## /aw-spec-implement-delta` generating a change's delta plan, `## /aw-spec-implement-ui`
95
+ for the frontend lane either way.
96
+ - Constitution: the **technical** half in the service lane, the **UI** half in the frontend one.
86
97
 
87
98
  ### `build` — *compile + repair*
88
99
  - **Technical rule files: yes** — the layering and convention rules the compile-fixer respects.
@@ -91,7 +102,7 @@ technical base and `ui-design`/`ui-implement` load the UI base. What they share
91
102
  ### `run` — *runtime*
92
103
  - **Technical rule files:** only if the project evidences a runtime/hosting concern.
93
104
 
94
- ### Gates — `analyze-design`, `analyze-delta-design`, `analyze-slice`, and the `/aw-spec-gate` overlay set
105
+ ### Gates — `analyze-plan`, `analyze-plan-delta`, `analyze-slice`, and the `/aw-spec-gate` overlay set
95
106
  - Load the domain **gate overlays** as a **conformance checklist**.
96
107
  - **Validation input ONLY — never authoring.** A gate may fail a document or a slice; it may
97
108
  never write a rule into one.
@@ -144,16 +155,21 @@ technical base and `ui-design`/`ui-implement` load the UI base. What they share
144
155
 
145
156
  ## Invariants
146
157
 
147
- 1. **No domain rule file is ever loaded by `design`, `implement`, `implement-delta` or `build`.**
148
- 2. **Domain reaches design and code only as spec ids.**
158
+ 1. **No domain rule file is ever loaded by `design`, `implement` or `build`** — on either
159
+ lane and on either path.
160
+ 2. **Domain reaches design and code only through the SPEC TIER** — as spec ids, and as the
161
+ bounded context's `domain-model.md` (plus a change's pending model delta) that those ids
162
+ point into. Never as a domain rule file: the rules were resolved into the model and the
163
+ spec at `specify`, and a phase downstream of that reads the resolution, never re-derives
164
+ it from the authority.
149
165
  3. **Gate overlays validate; they never author.**
150
166
  4. **A constraint not in the spec cannot be honoured downstream** — lift it first
151
167
  (`LIFT-FAILURE:` → back to `specify`).
152
168
  5. **An absent map heading loads nothing and soft-continues** — it is never a blocking error.
153
169
  6. **The constitution halves are referred to directly** and never listed in either map.
154
- 7. **A lane's constitution half governs that lane only** — `constitution.ui.md` never reaches
155
- `design` or `implement`, and `constitution.technical.md` never reaches `ui-design` or
156
- `ui-implement`.
170
+ 7. **A lane's constitution half governs that lane only** — inside the one command that covers
171
+ both, `constitution.ui.md` never reaches the service lane's payload and
172
+ `constitution.technical.md` never reaches the frontend lane's.
157
173
 
158
174
  ---
159
175
 
@@ -20,9 +20,11 @@ A lane is not a project, not a module, and not a layer. Two lanes exist when two
20
20
  toolchains do, which is why `kind` has exactly two values today (`backend`, `frontend`)
21
21
  and why nothing in the format assumes there are only two lanes.
22
22
 
23
- **Lanes get command names, never a `--lane` flag.** Rule maps are keyed on
24
- `## /aw-spec-<command>`, so a lane's phases are reached as `ui-implement`, `ui-foundation`
25
- and so on. A flag would have no heading to key on.
23
+ **Lanes get map headings, never a `--lane` flag.** Rule maps are keyed on
24
+ `## /aw-spec-<name>`, so a lane's rule set is reached under its own heading —
25
+ `## /aw-spec-implement-ui` for the frontend lane of `implement`, and so on. A flag would have
26
+ no heading to key on. Where the two lanes are folded into one command, as `plan` and
27
+ `implement` are, the heading names the lane and the command dispatches on the declaration.
26
28
 
27
29
  ---
28
30
 
@@ -55,9 +57,9 @@ and so on. A flag would have no heading to key on.
55
57
 
56
58
  ### Three properties matter more than the schema
57
59
 
58
- 1. **`root` is ownership, and it is the source path.** `implement` writes only under a
59
- backend lane's root, `ui-implement` only under a frontend lane's, `build`/`test`/`run`
60
- act on it, and `onboard` reverse-engineers out of it.
60
+ 1. **`root` is ownership, and it is the source path.** `implement`'s service lane writes only
61
+ under a backend lane's root and its frontend lane only under a frontend lane's,
62
+ `build`/`test`/`run` act on it, and `onboard` reverse-engineers out of it.
61
63
  2. **The commands are project-supplied strings.** The engine stays stdlib-only and
62
64
  stack-ignorant. This is how `build` already avoids knowing what a compiler is, and it
63
65
  is the only thing that makes "any frontend stack" tractable.
@@ -96,8 +98,7 @@ project it does not exist yet — the whole point of declaring `src/` on day one
96
98
  `implement` will create it.
97
99
 
98
100
  `lane-verify` is the check, and it runs where the path has to be real: before `implement`,
99
- `implement-delta`, `build`, `run`, and before `onboard` reverse-engineers a codebase out of
100
- it. That split is what lets one file serve a project with no code yet and a project that is
101
+ `build`, `run`, and before `onboard` reverse-engineers a codebase out of it. That split is what lets one file serve a project with no code yet and a project that is
101
102
  nothing but code.
102
103
 
103
104
  Two failure classes, deliberately distinguished:
@@ -139,7 +140,7 @@ file re-checks all three.
139
140
 
140
141
  `lane-resolve` still reports `declared: false` and exits 0 when the file is missing — reading
141
142
  is never fatal. What changed is that the phases which *act* on a lane no longer proceed
142
- without one. `constitution`, `onboard`, `implement`, `implement-delta`, `build` and `run` all
143
+ without one. `constitution`, `onboard`, `implement`, `build` and `run` all
143
144
  call `lane-verify` and stop with the fix named, because each of them needs an answer this
144
145
  file is the only place to get: which lanes to govern, which subtree to scan, where to write.
145
146
 
@@ -0,0 +1,32 @@
1
+ {
2
+ "vars": {},
3
+ "strategy": "agent",
4
+ "model": "",
5
+ "input": "",
6
+ "answers": {},
7
+ "selects": {},
8
+ "agent_profile": "",
9
+ "isolation": "bare",
10
+ "os": "posix",
11
+ "cache": {
12
+ "script_ro": {
13
+ "domains": [
14
+ "dotnet-default-project"
15
+ ]
16
+ }
17
+ },
18
+ "pending": {
19
+ "kind": "ask",
20
+ "key": "pick_mode",
21
+ "step": "pick_mode",
22
+ "prompt": "Smoke mode?",
23
+ "options": [
24
+ "fast",
25
+ "slow"
26
+ ],
27
+ "multi": false,
28
+ "instructions": "Ask the USER this question (the options are the allowed choices). Write the answer as PLAIN TEXT to response_path, then re-run the resume command.",
29
+ "response_path": ".appweaver/orchestrator/.state/smoke.state.json.response.md",
30
+ "resume": "python3 .appweaver/orchestrator/orchestrator.py .appweaver/orchestrator/workflows/_smoke.orch.yaml --checkpoint .appweaver/orchestrator/.state/smoke.state.json --json"
31
+ }
32
+ }
@@ -70,7 +70,10 @@ same) — none of which the engine knows about; it only follows the profile's
70
70
  [bin] + args
71
71
  + (model_flag model) if model_flag and --model
72
72
  + (system.flag system) if system is a {flag}
73
- + (tools_flag tools) if tools_flag
73
+ + (tools_flag tools) if tools_flag is declared — ALWAYS, even
74
+ when tools is empty: an empty allowlist is
75
+ "no tools", and omitting the flag instead
76
+ lets the CLI fall back to its default set
74
77
  + approval[permission_mode | default]
75
78
  + isolation[--isolation]
76
79
  + (budget_flag budget) if budget_flag and --budget
@@ -0,0 +1,251 @@
1
+ # =============================================================================
2
+ # delta-plan (orchestrator module) — author ONE change's LANE PLANS
3
+ #
4
+ # Included by /appweaver plan on its DELTA branch (a master plan already exists).
5
+ # It authors, inside the change's own directory beside its delta-spec:
6
+ # • changes/<cr-id>/delta-backend-plan.md when a backend lane is declared
7
+ # • changes/<cr-id>/delta-frontend-plan.md when a frontend lane is declared
8
+ # and touches NEITHER master. The change stays OPEN; `implement` generates the code from
9
+ # these documents (it asks which change, and takes the delta plans of the answer),
10
+ # finalize-delta merges the change's SPEC and MODEL halves (never a lane plan — a master
11
+ # plan is derived from those two and is re-derived from them), and close-delta archives
12
+ # these plans with the change at the end. No version bump here, no code (that is
13
+ # /appweaver implement).
14
+ #
15
+ # IT DOES NOT CHOOSE THE CHANGE — the caller already did. `plan` asks one question at the
16
+ # top of its run (which is why a re-plan of the MASTER and a delta are the same command),
17
+ # activates the answer and resolves its documents, so this module receives cr_id / cr_dir
18
+ # / delta_spec / delta_model / wave / predecessor_files already bound and is pure
19
+ # AUTHORING. The plan-only change — a refactor or architectural decision where the
20
+ # realisation of EXISTING spec ids moves with no spec delta — is the caller's NEW option
21
+ # and reaches this module as an ordinary change whose delta-spec is an unfilled stub.
22
+ #
23
+ # IT PLANS AGAINST THE EFFECTIVE MODEL, not the bare master:
24
+ # • the context's domain-model.md — what the domain IS today
25
+ # • this change's domain-model.<cr>.delta.md — what this change makes it
26
+ # • the PREDECESSOR deltas — every open model delta in a LOWER WAVE. A wave is a
27
+ # dependency level: same wave means independent and developable in parallel, higher
28
+ # wave means "after those land". So a lower-wave delta is committed to landing first
29
+ # and may be built on; a same-wave one is visible but is never assumed, because
30
+ # nothing orders the two against each other.
31
+ #
32
+ # IT READS THE CODE. The feature's real source files arrive from its OKF concept
33
+ # (concept-paths, resolved by the caller) as a PATH LIST, and the authoring steps declare
34
+ # `tools: Read` — a delta plan for an existing feature has to be written against the code
35
+ # that is actually there, not against an idealised master.
36
+ #
37
+ # Runs in the CALLER's context (include semantics): shares vars + the sticky standards
38
+ # (plan's per-lane rule sets) + the caller's scripts map + replay cache.
39
+ # EXPECTS caller vars: feature_dir, spec_file, backend_plan, frontend_plan, domain_model,
40
+ # be_existing, fe_existing, fe_lane_id, source_files, source_count, USER_INPUT,
41
+ # and — resolved by the caller from the change it chose and activated — cr_id, cr_dir,
42
+ # delta_spec, delta_model, wave, predecessor_files, predecessor_count, sibling_count.
43
+ # PRODUCES: delta_backend_plan, delta_frontend_plan, downstream_count, impact_report.
44
+ # =============================================================================
45
+
46
+ name: delta-plan
47
+ dialect: aw-spec.orchestrator/v1
48
+
49
+ # Scripts this module invokes. A module's scripts EXTEND the caller's map (setdefault, so
50
+ # the caller's refs WIN at runtime — these are inert when plan already supplies them);
51
+ # declaring both keeps the module self-contained + validatable on its own. `actions`
52
+ # mirrors the caller's ref; `xref` (the OKF cross-reference substrate) drives the advisory
53
+ # blast-radius step below.
54
+ scripts:
55
+ actions:
56
+ sh: .appweaver/scripts/bash/aw-spec-actions.sh
57
+ ps1: .appweaver/scripts/powershell/aw-spec-actions.ps1
58
+ xref:
59
+ sh: .appweaver/scripts/bash/aw-xref.sh
60
+ ps1: .appweaver/scripts/powershell/aw-xref.ps1
61
+
62
+ # Fallbacks only — every one of these is bound by the caller before the include, and is
63
+ # declared here so the module stays validatable on its own.
64
+ vars:
65
+ cr_id: "" # the change being planned — normalised by the caller's cr-paths
66
+ wave: "1"
67
+ predecessor_files: [] # every open model delta in a LOWER wave — this delta's predecessors
68
+ predecessor_count: "0"
69
+ sibling_count: "0"
70
+ delta_backend_plan: ""
71
+ delta_frontend_plan: ""
72
+
73
+ workflow:
74
+
75
+ # 1. Scaffold this change's plan document for each lane whose MASTER already exists.
76
+ # A lane whose master was scaffolded in this same run has just been authored from
77
+ # the whole spec — there is nothing for a delta to add to it — so it gets none.
78
+ - id: be_delta_scaffold
79
+ condition: "{{be_existing}} == true"
80
+ action: execute_script
81
+ script: { ref: actions }
82
+ subcommand: delta-plan-scaffold
83
+ args: ["--cr-id", "{{cr_id}}", "--lane", "backend", "--feature-dir", "{{feature_dir}}"]
84
+ outputs:
85
+ - { name: delta_backend_plan, from: "$.delta_plan" }
86
+
87
+ - id: fe_delta_scaffold
88
+ condition: "{{fe_existing}} == true"
89
+ action: execute_script
90
+ script: { ref: actions }
91
+ subcommand: delta-plan-scaffold
92
+ args: ["--cr-id", "{{cr_id}}", "--lane", "frontend", "--feature-dir", "{{feature_dir}}"]
93
+ outputs:
94
+ - { name: delta_frontend_plan, from: "$.delta_plan" }
95
+
96
+ # ═════════════════════ BACKEND LANE — the service delta plan ═════════════════
97
+ - id: ctx_backend_delta
98
+ condition: "{{be_existing}} == true"
99
+ action: build_context
100
+ context_from: predecessor_files # the open model deltas in LOWER waves — committed
101
+ # to landing first, so this plan may build on them.
102
+ # Empty for a wave-1 delta, which is the common case.
103
+ context:
104
+ - "{{delta_backend_plan}}" # the delta plan template to fill
105
+ - "{{delta_spec}}" # the spec-side change (from specify)
106
+ - { path: "{{delta_model}}", optional: true }
107
+ # this change's MODEL half — the structure the plan
108
+ # realises. Optional: a plan-only change has an
109
+ # unfilled one, and that is a valid state.
110
+ - "{{spec_file}}" # the current master spec (READ ONLY)
111
+ - "{{backend_plan}}" # the current master plan (READ ONLY — never amended here)
112
+ - { path: "{{domain_model}}", optional: true }
113
+ # the context's CANONICAL model — the aggregate root,
114
+ # its entities and its invariants live here, not in the
115
+ # spec and not in this plan.
116
+ - { path: .appweaver/DESIGN-FORMAT.md }
117
+ - id: author_backend_delta
118
+ condition: "{{be_existing}} == true"
119
+ action: agent_author # plan's technical standards stay ON (default) — correct here
120
+ tools: Read # the feature's EXISTING source arrives as {{source_files}} paths, not inlined
121
+ output_target: { type: file, path: "{{delta_backend_plan}}" }
122
+ task: |
123
+ Fill the SERVICE-LANE delta plan for change {{cr_id}} (wave {{wave}}) — the target
124
+ document in context — from the delta-spec, this change's model delta and the CURRENT
125
+ master backend plan (all in context). THE DELTA ONLY. Do NOT edit backend-plan.md —
126
+ no stage merges this delta back into it: the master is derived from the spec and the
127
+ model, which is where finalize-delta lands the change.
128
+ - READ THE CODE FIRST. {{source_count}} source file(s) currently realise this
129
+ feature: {{source_files}}. Read the ones this change touches before planning it.
130
+ The master plan says what the structure was designed to be; the code says what it
131
+ IS, and a delta that ignores the difference plans an edit to something that is not
132
+ there. Where the two disagree, plan against the code and record the divergence as
133
+ a WA-n.
134
+ - Classify every change to the plan as ADDED / MODIFIED / REMOVED against the
135
+ master, per the master's OWN section structure (whatever sections it actually has
136
+ — do not assume a fixed layering), plus the cross-section impact, the regression
137
+ targets, and any new assumption (DA-n) or workaround (WA-n) the change introduces.
138
+ A shared element (e.g. the aggregate root's realisation) is MODIFIED in place,
139
+ never duplicated.
140
+ - STRUCTURE IS NOT YOURS TO WRITE. Entities, value objects, domain events and
141
+ invariants (BR-n) live in the context's domain model and in this change's model
142
+ delta. Fill "## Model changes this plan realises" with one row per item that
143
+ model delta ADDED / MODIFIED / REMOVED, saying where it lands and WHERE the
144
+ invariant is ENFORCED. Cite ids; never restate what an invariant says. An item in
145
+ the model delta with no row here is a structural change nothing implements.
146
+ - THE EFFECTIVE MODEL IS master + this change's delta + the PREDECESSOR deltas in
147
+ context (open changes in a LOWER wave, committed to landing first). You MAY build
148
+ on a predecessor — record it under "## Depends on", which is what orders the
149
+ finalizes. You may NOT assume a same-wave delta: nothing orders it against this
150
+ one. Where one touches the same aggregate or element, say so under "Other open
151
+ deltas" and plan around it. Until merged, every one of them is a proposal.
152
+ - PUBLISH WHAT THE FRONTEND LANE NEEDS. Fill "## Contract deltas for the frontend
153
+ lane" with every addition or change to this feature's published surface, as field
154
+ shapes. That table is the only part of this document the frontend delta plan may
155
+ bind against; a contract the UI needs and this document never states becomes a
156
+ client-side workaround. "None" when the surface is unchanged.
157
+ - Stay technology-agnostic (no code) and keep the master's form: behaviour as
158
+ signatures + pre/post/invariant/raises, contracts as field shapes.
159
+ - TWO CASES — decide from the delta-spec in context:
160
+ • SPEC-DRIVEN — the delta-spec lists ADDED/MODIFIED/REMOVED spec items: realise
161
+ them; every changed plan element serves one of those spec ids.
162
+ • PLAN-ONLY — the delta-spec is an unfilled stub (no spec delta): this change
163
+ refines HOW the EXISTING spec is realised (an architectural / decision change)
164
+ driven by the guidance below. The spec is unchanged, so every changed element
165
+ MUST still trace to an EXISTING spec id (FR-/BR-/CN-/DC-/IC-/US-/SC-) — you are
166
+ changing the realisation, never inventing a requirement.
167
+ - Do NOT edit the Wave / Base version / Delta spec / Model delta headers — scripts
168
+ stamp those.
169
+ Guidance: {{USER_INPUT}}
170
+
171
+ # ═════════════════════ FRONTEND LANE — the experience delta plan ═════════════
172
+ - id: ctx_frontend_delta
173
+ condition: "{{fe_existing}} == true"
174
+ action: build_context
175
+ context_from: predecessor_files # the same lower-wave model deltas — the ubiquitous
176
+ # language and the aggregates this change assumes
177
+ context:
178
+ - "{{delta_frontend_plan}}" # the delta plan template to fill
179
+ - "{{delta_spec}}" # the spec-side change (UX-/US-/FR- items)
180
+ - { path: "{{delta_model}}", optional: true }
181
+ - "{{spec_file}}" # the current master spec (READ ONLY)
182
+ - "{{frontend_plan}}" # the current master plan (READ ONLY — never amended here)
183
+ - { path: "{{delta_backend_plan}}", optional: true }
184
+ # THE SERVICE HALF of this same change — its contract
185
+ # table is what this lane binds to. Optional: an
186
+ # experience-only change has no service delta, and a
187
+ # frontend-only project has no service lane at all.
188
+ - { path: "{{domain_model}}", optional: true }
189
+ - { path: .appweaver/memory/constitution.ui.md, optional: true }
190
+ - { path: .appweaver/DESIGN-FORMAT.md }
191
+ - id: author_frontend_delta
192
+ condition: "{{fe_existing}} == true"
193
+ action: agent_author
194
+ tools: Read # the lane's EXISTING source arrives as {{source_files}} paths, not inlined
195
+ output_target: { type: file, path: "{{delta_frontend_plan}}" }
196
+ task: |
197
+ Fill the FRONTEND-LANE delta plan for change {{cr_id}} (wave {{wave}}) — the target
198
+ document in context — from the delta-spec and the CURRENT master frontend plan (both
199
+ in context). THE DELTA ONLY. Do NOT edit frontend-plan.md — no stage merges this delta
200
+ back into it: the master is derived from the spec's UX- standards and the model, which
201
+ is where finalize-delta lands the change.
202
+ - READ THE CODE FIRST. {{source_count}} source file(s) currently realise this
203
+ feature: {{source_files}}. Read the ones this change touches — a delta that plans
204
+ an edit to a component that is not there, or that duplicates one that is, costs a
205
+ whole implementation pass to discover.
206
+ - Classify every change ADDED / MODIFIED / REMOVED against the master, per the
207
+ master's OWN sections. A shared component or a shared state container is MODIFIED
208
+ in place, never copied into the change.
209
+ - STATES ARE PART OF THE CHANGE. Fill "## Interaction states touched" with the FULL
210
+ state set of every interaction this change adds or alters — loading, empty, error,
211
+ permission-denied, in-flight. A new interaction that ships without them is an
212
+ incomplete delta, not a later refinement. A state the UI can reach that the
213
+ delta-spec does not describe is a SPEC gap: log it as a DA-n that routes back to
214
+ `specify`, never invent the requirement here.
215
+ - THE LANE BOUNDARY IS THE PUBLISHED SURFACE. Bind against the delta-spec's IC- ids
216
+ and, where the service delta is in context, its "Contract deltas for the frontend
217
+ lane" table. CITE those contracts; do not restate, re-derive or contradict them,
218
+ and introduce no server-side behaviour or persistence assumption. What the
219
+ experience needs and the surface does not offer goes under "Contract deltas
220
+ needed", raised back to the service lane — never worked around in the client.
221
+ - UX- IS THIS DOCUMENT'S TO REALISE. The service plan excludes the spec's Experience
222
+ Standards by contract, so a UX- item in the delta-spec that reaches neither plan
223
+ is a dropped requirement.
224
+ - Use the context's UBIQUITOUS LANGUAGE exactly as the domain model defines it, in
225
+ labels, states and messages — the same terms, no synonyms — and cite BR-nnn rather
226
+ than restating a rule.
227
+ - THE EFFECTIVE MODEL IS master + this change's delta + the PREDECESSOR deltas in
228
+ context (open changes in a LOWER wave). You MAY build on a predecessor — record it
229
+ under "## Depends on". You may NOT assume a same-wave delta; where one touches the
230
+ same screens or shared components, say so under "Other open deltas".
231
+ - TECHNOLOGY-AGNOSTIC: no framework, router, state library, component library or
232
+ styling approach — responsibilities, field shapes, events and states only. The
233
+ header's Lane field is `{{fe_lane_id}}`.
234
+ - Do NOT edit the Wave / Base version / Delta spec / Service delta headers — scripts
235
+ stamp those.
236
+ Guidance: {{USER_INPUT}}
237
+
238
+ # ADVISORY blast radius: who currently depends on THIS aggregate (its Cross-References in
239
+ # the OKF bundle). A change here may ripple to them — surfaced now, at planning time, and
240
+ # written to the change dir (impact.md) for the record. Read-only + on_error: continue: it
241
+ # INFORMS how to scope the change; the actual downstream-green enforcement is
242
+ # finalize-delta's job.
243
+ - id: xref_impact
244
+ action: execute_script
245
+ on_error: continue
246
+ script: { ref: xref }
247
+ subcommand: list
248
+ args: ["--feature-dir", "{{feature_dir}}", "--out", "{{cr_dir}}/impact.md"]
249
+ outputs:
250
+ - { name: downstream_count, from: "$.count" }
251
+ - { name: impact_report, from: "$.impact_report" }