aw-spec-cli 0.1.16 → 0.1.18
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
|
@@ -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
|
-
|
|
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
|
-
`
|
|
20
|
+
`backend-plan.md` is the **mediator** between the spec and the generated code:
|
|
21
21
|
|
|
22
22
|
```
|
|
23
|
-
spec.md ──▶
|
|
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
|
|
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 —
|
|
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. `
|
|
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>/
|
|
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
|
|
105
|
-
plus that
|
|
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 `
|
|
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
|
|
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 +
|
|
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
|
|
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:**
|
|
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
|
|
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
|
-
|
|
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 `
|
|
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 `
|
|
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.
|
|
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
|
|
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
|
|
56
|
-
|
|
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`
|
|
83
|
-
- **Domain rule files: NEVER.** The
|
|
84
|
-
- **
|
|
85
|
-
-
|
|
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-
|
|
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
|
|
148
|
-
|
|
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** —
|
|
155
|
-
|
|
156
|
-
`
|
|
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
|
|
24
|
-
`## /aw-spec-<
|
|
25
|
-
and so on. A flag would have
|
|
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
|
|
59
|
-
backend lane's root
|
|
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
|
-
`
|
|
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`, `
|
|
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" }
|