aw-spec-cli 0.1.32 → 0.1.33
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 +10 -3
- package/assets/.appweaver/orchestrator/rev-templates/delta-design-template.skeleton.md +10 -6
- package/assets/.appweaver/orchestrator/rev-templates/design-template.skeleton.md +53 -3
- package/assets/.appweaver/orchestrator/workflows/aw-spec-adopt.orch.yaml +128 -22
- package/assets/.appweaver/orchestrator/workflows/aw-spec-onboard.orch.yaml +25 -8
- package/assets/.appweaver/orchestrator/workflows/aw-spec-plan.orch.yaml +6 -2
- package/assets/.appweaver/orchestrator/workflows/aw-spec-select-lane.orch.yaml +7 -4
- package/package.json +1 -1
|
@@ -82,11 +82,18 @@ same traceability spine and the two deferral ledgers — with **one difference t
|
|
|
82
82
|
are **derived from the code's own organisation** (its folders / projects / modules)
|
|
83
83
|
rather than the fixed Domain/Application/API/Infrastructure four. A component the
|
|
84
84
|
code has that fits no textbook layer (a UI tier, a worker, a host project) gets its
|
|
85
|
-
own section; a layer the code lacks does not appear.
|
|
85
|
+
own section; a layer the code lacks does not appear. Three neutral anchors are kept
|
|
86
86
|
because every system has them and the tooling keys on them: **§1 is the domain/data
|
|
87
|
-
model** (the cross-reference tool reads it for `<Other>Id` reference edges)
|
|
87
|
+
model** (the cross-reference tool reads it for `<Other>Id` reference edges), one
|
|
88
88
|
**§2 subsection is the External Integrations table** (matched by heading keyword, so
|
|
89
|
-
`aw-xref` extracts contract edges from either layout)
|
|
89
|
+
`aw-xref` extracts contract edges from either layout), and **each published endpoint
|
|
90
|
+
is an endpoint block** — the greenfield §3 form, `#### `VERB /route`` with its
|
|
91
|
+
**Operation id**, followed by the "Requests from the frontend lane" table — inside
|
|
92
|
+
whichever §2 axis publishes it. The contract scripts read exactly that form: the API
|
|
93
|
+
draft is written from the headings, and the request ledger between the two lanes reads
|
|
94
|
+
the operation ids and the table. An endpoint the code already serves keeps the id it
|
|
95
|
+
publishes; where it publishes none the plan writes `—` and records a §5 assumption,
|
|
96
|
+
never an invented id. The `debt` ledger records
|
|
90
97
|
only debt the **code itself** evidences (stubs, dead code, torn seams) — being
|
|
91
98
|
organised unlike a reference architecture is **not** debt, it is the as-built shape;
|
|
92
99
|
migrating toward a target is a separate modernization decision.
|
|
@@ -126,15 +126,19 @@ migration is needed (yes/no); any contract change other systems couple to.]
|
|
|
126
126
|
|
|
127
127
|
## Contract deltas for the frontend lane
|
|
128
128
|
|
|
129
|
-
<!-- What this change adds to
|
|
130
|
-
only part of this document the frontend lane may bind against.
|
|
131
|
-
the surface is unchanged. Omit the section entirely where the code
|
|
132
|
-
frontend lane. The operation id is the endpoint's name in the published
|
|
133
|
-
document; an endpoint that already has one keeps it.
|
|
129
|
+
<!-- What this change adds to, alters in or removes from the service's PUBLISHED
|
|
130
|
+
surface — the only part of this document the frontend lane may bind against.
|
|
131
|
+
`None` when the surface is unchanged. Omit the section entirely where the code
|
|
132
|
+
has no frontend lane. The operation id is the endpoint's name in the published
|
|
133
|
+
API document; an endpoint that already has one keeps it. A `changed` or
|
|
134
|
+
`removed` row whose operation the frontend plan binds to is reported by
|
|
135
|
+
analyze-plan-delta (contract-impact reads the Operation id and Change
|
|
136
|
+
columns) until the frontend delta of this change — or a follow-up change —
|
|
137
|
+
carries the matching change. -->
|
|
134
138
|
|
|
135
139
|
| Operation id | Contract | Change | Shape | Serves |
|
|
136
140
|
|---|---|---|---|---|
|
|
137
|
-
| `[OperationId]` | `[contract]` | [added / changed] | [request → response field shapes] | IC-[nnn] |
|
|
141
|
+
| `[OperationId]` | `[contract]` | [added / changed / removed] | [request → response field shapes] | IC-[nnn] |
|
|
138
142
|
|
|
139
143
|
## Other open deltas
|
|
140
144
|
|
|
@@ -30,6 +30,13 @@
|
|
|
30
30
|
• Exactly one §2 subsection's heading contains the word "Integration".
|
|
31
31
|
`aw-xref` matches it by keyword to extract contract edges, which is what
|
|
32
32
|
lets a derived layout and the greenfield layout be read by one tool.
|
|
33
|
+
• Each published endpoint is a `####` ENDPOINT BLOCK — the heading
|
|
34
|
+
`#### `[VERB] [/route]`` and its **Operation id** field — with the
|
|
35
|
+
"Requests from the frontend lane" table after the blocks, inside whichever
|
|
36
|
+
§2 axis publishes them. The contract scripts read exactly this form:
|
|
37
|
+
`contract-draft` drafts api-draft.json from the headings, and
|
|
38
|
+
`contract-requests` reads the operation ids and the table. The axis keeps
|
|
39
|
+
the project's own name; only the block form is fixed.
|
|
33
40
|
• The traceability spine (§4) and both ledgers (§5 DA-n, §6 WA-n) survive
|
|
34
41
|
every layout — the analyze gates read them.
|
|
35
42
|
• The §0–§6 numbering itself: `plan`'s bootstrap_bf branch names those
|
|
@@ -169,9 +176,8 @@
|
|
|
169
176
|
the titles are the code's answer — the slots below are illustrative
|
|
170
177
|
positions, not a required set. In each: the components that live there,
|
|
171
178
|
their behaviour in signature form, and the contracts they expose or
|
|
172
|
-
require.
|
|
173
|
-
|
|
174
|
-
the frontend plan cites and implement looks the endpoint up by. -->
|
|
179
|
+
require. The endpoints the service PUBLISHES take the endpoint block form
|
|
180
|
+
shown in the axis below. -->
|
|
175
181
|
|
|
176
182
|
### 2.1 [PROJECT_STRUCTURAL_AXIS_NAME]
|
|
177
183
|
|
|
@@ -186,6 +192,50 @@
|
|
|
186
192
|
|
|
187
193
|
<!-- … one per axis the code actually shows, then stop … -->
|
|
188
194
|
|
|
195
|
+
### 2.[M] [AXIS_THAT_PUBLISHES_THE_ENDPOINTS]
|
|
196
|
+
|
|
197
|
+
<!-- PINNED FORM, in whichever axis this project publishes its endpoints from. The
|
|
198
|
+
axis keeps the project's own name and its component table; what is fixed is
|
|
199
|
+
each endpoint's block below it and the requests table after the blocks,
|
|
200
|
+
because the contract scripts read exactly these: the `#### `VERB /route``
|
|
201
|
+
heading (contract-draft writes api-draft.json from it), the **Operation id**
|
|
202
|
+
field (the id the service serves, which the frontend plan binds to) and the
|
|
203
|
+
`| Request | Outcome |` table (contract-requests). A project that publishes no
|
|
204
|
+
endpoint omits both. -->
|
|
205
|
+
|
|
206
|
+
| Component | Behaviour (signature) | Pre / Post / Raises | Serves |
|
|
207
|
+
|---|---|---|---|
|
|
208
|
+
| `[Component]` | `[operation](args) -> result` | [pre / post / raises] | FR-00X · US-Y |
|
|
209
|
+
|
|
210
|
+
#### `[VERB] [/route]` — [purpose] · Serves US-Y · FR-00X
|
|
211
|
+
|
|
212
|
+
- **Operation id**: `[OperationId]` <!-- the endpoint's name in the published API document. An endpoint the code already serves keeps the id it publishes, spelled exactly as the code spells it; where it publishes none, write `—` and record a §5 DA-n saying so — never an invented id, which the service's exported document would not carry. A NEW endpoint takes an id unique across the service, and implement gives it exactly that. -->
|
|
213
|
+
- **Auth**: [required role/scope, as enforced]
|
|
214
|
+
- **Request**: `[path/query params]` + body `{ [field]: [type], … }`
|
|
215
|
+
- **Success**: `2xx` → `{ [response shape] }`
|
|
216
|
+
- **Errors** *(the error contract)*:
|
|
217
|
+
|
|
218
|
+
| Status | When | Body shape |
|
|
219
|
+
|---|---|---|
|
|
220
|
+
| [status] | [when it is returned] | [body shape] |
|
|
221
|
+
|
|
222
|
+
- **Maps to**: `[Component]` (§2.n)
|
|
223
|
+
|
|
224
|
+
#### Requests from the frontend lane
|
|
225
|
+
|
|
226
|
+
<!-- THE ANSWERS to the frontend plan's "Contract deltas needed" table, one row
|
|
227
|
+
per RQ-n it raises. PUBLISH: add the endpoint above — under the proposed
|
|
228
|
+
operation id unless it clashes with one this service already uses — and name
|
|
229
|
+
the id here. DECLINE: say why in one line; a request the spec does not
|
|
230
|
+
support is declined as a spec gap for `specify`, never published on a guess.
|
|
231
|
+
Keep every answered row; write `None` instead of the table when the frontend
|
|
232
|
+
plan raises no request — always so for a plan reversed from code, whose
|
|
233
|
+
frontend binds only to what the service already serves. -->
|
|
234
|
+
|
|
235
|
+
| Request | Outcome | Operation id | Why |
|
|
236
|
+
|---|---|---|---|
|
|
237
|
+
| RQ-[n] | published / declined | `[OperationId]` / — | [one line — required when declined] |
|
|
238
|
+
|
|
189
239
|
### 2.[N] External Integrations
|
|
190
240
|
|
|
191
241
|
<!-- PINNED ANCHOR — the heading MUST contain the word "Integration"; the
|
|
@@ -71,7 +71,18 @@
|
|
|
71
71
|
# =============================================================================
|
|
72
72
|
|
|
73
73
|
name: aw-spec-adopt
|
|
74
|
-
description: The JIT per-feature step of brownfield development — reverse-engineer ONE existing feature into a living spec.md, an aggregate section in the bounded context's shared domain-model.md, and backend-plan.md
|
|
74
|
+
description: The JIT per-feature step of brownfield development — reverse-engineer ONE existing feature into a living spec.md, an aggregate section in the bounded context's shared domain-model.md, and its lane plans — backend-plan.md where a backend lane is declared and the slice has service code, frontend-plan.md where a frontend lane is declared and this slice owns part of its surface — + source-map.md (origin reverse-engineered, per-item confidence, code-derived plan template), then COMPLETE its shallow OKF concept (deepen it to the reversed reality + link the deep artifacts) and record its cross-slice edges. The spec cites BR-nnn by id and the model defines them, exactly as on the greenfield path, so a reversed slice is checkable by the same gates as any other. Fidelity gate is spec + model + plans vs code, and an invented entity, boundary or invariant is a fabrication exactly as an invented FR- is; the review is reported for out-of-band closure. Every reverse step is scoped to the feature's own operations from the confirmed boundary map, so two features over one aggregate never claim the same operation, and the spec continues the context's BR-nnn numbering from its domain model. Where a frontend lane is declared and this slice owns none of its surface, the feature records lanes=backend so later phases neither author nor demand a frontend plan for it. The governance reconcile — carrying this feature's real evidence into the provisional rule files + constitution onboard wrote — is HELD (reconcile_governance=false), so an ordinary run does not touch the governance tier. A NEW feature is authored via the forward pipeline instead. Output is a normal feature for the CR + forward loop.
|
|
75
|
+
# 2.3.0 — the SERVICE half is reversed only where the slice has one (svc_lane: a backend lane
|
|
76
|
+
# is declared and the slice has service files), the twin of ui_lane. A frontend-only
|
|
77
|
+
# project gets no backend plan and no cross-slice edges, and its model is read from
|
|
78
|
+
# the UI files; a UI-only slice in a repo with both lanes records lanes=[frontend].
|
|
79
|
+
# A failed fidelity check names the two ways to resolve it — re-adopt, or correct
|
|
80
|
+
# the documents by hand — and what each leaves behind.
|
|
81
|
+
# 2.2.0 — the reversed plans take part in the API ledger between the lanes: the backend plan
|
|
82
|
+
# writes each endpoint the slice publishes as an endpoint block (`#### `VERB /route``
|
|
83
|
+
# + **Operation id**, the id the code publishes — `—` and a DA-n where it publishes
|
|
84
|
+
# none, never an invented one) with a "Requests from the frontend lane" table, and the
|
|
85
|
+
# frontend plan's Contract Binding rows cite those ids.
|
|
75
86
|
# 2.1.0 — every reverse step is scoped to the FEATURE, not its aggregate: the boundary map's
|
|
76
87
|
# operation list (and a sibling feature's operations, which are not this one's)
|
|
77
88
|
# reaches the spec, model, plan, UI plan, source-map and fidelity steps. The spec step
|
|
@@ -87,7 +98,7 @@ description: The JIT per-feature step of brownfield development — reverse-engi
|
|
|
87
98
|
# 1.3.0 — reverse design scaffolds from the DEFAULT `design-template` (onboard's code-derived
|
|
88
99
|
# override) instead of the never-shipped `brownfield-design-template`, unifying the
|
|
89
100
|
# whole brownfield pipeline on one code-derived template.
|
|
90
|
-
version: 2.
|
|
101
|
+
version: 2.3.0
|
|
91
102
|
agent_agnostic: true
|
|
92
103
|
dialect: aw-spec.orchestrator/v1
|
|
93
104
|
|
|
@@ -128,8 +139,12 @@ vars:
|
|
|
128
139
|
be_declared: "false"
|
|
129
140
|
fe_no_surface: "false" # a frontend lane is declared, this slice owns none of its surface, and a backend lane carries it
|
|
130
141
|
feature_lanes: "" # what record_lanes wrote — empty when the feature follows every declared lane
|
|
142
|
+
xref_edge_count: "0" # xref_record runs only where the slice has a service half
|
|
131
143
|
fe_root: ""
|
|
132
144
|
ui_lane: "false" # THIS slice reverses a UI half: a frontend lane is declared AND the slice owns UI files
|
|
145
|
+
svc_lane: "false" # THIS slice reverses a SERVICE half: a backend lane is declared AND the slice has service files
|
|
146
|
+
be_no_surface: "false" # a backend lane is declared, this slice has no service code, and a frontend lane carries it
|
|
147
|
+
model_files: "" # what the model is reversed from: the service files, or the UI files on a slice with none
|
|
133
148
|
ui_count: "0" # how many UI files the concept attributes to this aggregate (aw-inventory ui_source_files)
|
|
134
149
|
ui_source_files: ""
|
|
135
150
|
frontend_plan: ""
|
|
@@ -424,14 +439,6 @@ workflow:
|
|
|
424
439
|
outputs:
|
|
425
440
|
- { name: domain_model, from: "$.domain_model" }
|
|
426
441
|
|
|
427
|
-
- id: scaffold_plan
|
|
428
|
-
action: execute_script
|
|
429
|
-
script: { ref: actions }
|
|
430
|
-
subcommand: plan-scaffold
|
|
431
|
-
args: ["--feature-dir", "{{feature_dir}}", "--lane", "backend"] # `design-template` = onboard's code-derived override (greenfield base if onboard has not run)
|
|
432
|
-
outputs:
|
|
433
|
-
- { name: backend_plan, from: "$.plan_doc" }
|
|
434
|
-
|
|
435
442
|
- id: version_init
|
|
436
443
|
action: execute_script
|
|
437
444
|
script: { ref: actions }
|
|
@@ -502,6 +509,69 @@ workflow:
|
|
|
502
509
|
outputs:
|
|
503
510
|
- { name: feature_lanes, from: "$.lanes" }
|
|
504
511
|
|
|
512
|
+
# 2d. DOES THIS SLICE HAVE A SERVICE HALF? The twin of 2b: a backend lane must be DECLARED
|
|
513
|
+
# and this aggregate must have service files (the concept's source_files). A
|
|
514
|
+
# frontend-only project declares no backend lane, and its concepts list every file as
|
|
515
|
+
# ui_source_files, so a backend plan there would describe code that does not exist and
|
|
516
|
+
# the fidelity gate would score it as fabricated. Three ordered sets, as in 2b.
|
|
517
|
+
- id: svc_lane_off
|
|
518
|
+
action: set
|
|
519
|
+
vars: { svc_lane: "false" }
|
|
520
|
+
- id: svc_lane_on
|
|
521
|
+
action: set
|
|
522
|
+
condition: "{{be_declared}}"
|
|
523
|
+
vars: { svc_lane: "true" }
|
|
524
|
+
- id: svc_lane_no_code
|
|
525
|
+
action: set
|
|
526
|
+
condition: "{{source_count}} == 0"
|
|
527
|
+
vars: { svc_lane: "false" }
|
|
528
|
+
|
|
529
|
+
# 2e. RECORD A UI-ONLY SLICE in a repo that declares both lanes — the twin of 2c, so plan
|
|
530
|
+
# and the analyze gates do not demand a backend plan for a slice with no service code.
|
|
531
|
+
- id: be_no_surface_off
|
|
532
|
+
action: set
|
|
533
|
+
vars: { be_no_surface: "false" }
|
|
534
|
+
- id: be_no_surface_declared
|
|
535
|
+
action: set
|
|
536
|
+
condition: "{{be_declared}}"
|
|
537
|
+
vars: { be_no_surface: "true" }
|
|
538
|
+
- id: be_no_surface_has_code
|
|
539
|
+
action: set
|
|
540
|
+
condition: "{{source_count}} != 0"
|
|
541
|
+
vars: { be_no_surface: "false" }
|
|
542
|
+
- id: be_no_surface_no_frontend
|
|
543
|
+
action: set
|
|
544
|
+
condition: "{{ui_lane}} != true"
|
|
545
|
+
vars: { be_no_surface: "false" }
|
|
546
|
+
- id: record_lanes_frontend
|
|
547
|
+
condition: "{{be_no_surface}} == true"
|
|
548
|
+
action: execute_script
|
|
549
|
+
script: { ref: actions }
|
|
550
|
+
subcommand: feature-lanes
|
|
551
|
+
args: ["--feature-dir", "{{feature_dir}}", "--set", "frontend"]
|
|
552
|
+
outputs:
|
|
553
|
+
- { name: feature_lanes, from: "$.lanes" }
|
|
554
|
+
|
|
555
|
+
# What the domain model is reversed FROM. The service files where the slice has them; a
|
|
556
|
+
# slice with none keeps its domain in the UI code — the types, states and rules a
|
|
557
|
+
# frontend-only app holds — so the model is read from those.
|
|
558
|
+
- id: model_files_service
|
|
559
|
+
action: set
|
|
560
|
+
vars: { model_files: "{{source_files}}" }
|
|
561
|
+
- id: model_files_ui
|
|
562
|
+
condition: "{{svc_lane}} != true"
|
|
563
|
+
action: set
|
|
564
|
+
vars: { model_files: "{{ui_source_files}}" }
|
|
565
|
+
|
|
566
|
+
- id: scaffold_plan
|
|
567
|
+
condition: "{{svc_lane}} == true"
|
|
568
|
+
action: execute_script
|
|
569
|
+
script: { ref: actions }
|
|
570
|
+
subcommand: plan-scaffold
|
|
571
|
+
args: ["--feature-dir", "{{feature_dir}}", "--lane", "backend"] # `design-template` = onboard's code-derived override (greenfield base if onboard has not run)
|
|
572
|
+
outputs:
|
|
573
|
+
- { name: backend_plan, from: "$.plan_doc" }
|
|
574
|
+
|
|
505
575
|
# Scaffold the LANE's plan from ITS template pair (--lane frontend resolves
|
|
506
576
|
# ui-design-template -> frontend-plan.md), the twin of scaffold_plan above. onboard
|
|
507
577
|
# GENERATED that override from this repo's own UI source, so the reversed frontend plan
|
|
@@ -734,7 +804,8 @@ workflow:
|
|
|
734
804
|
- Add `origin: reverse-engineered` near the identity block. Do NOT write the Context
|
|
735
805
|
version or the Change History version column — scripts stamp those.
|
|
736
806
|
|
|
737
|
-
Source files to read (the slice's code
|
|
807
|
+
Source files to read (the slice's code — its UI files where it has no service code,
|
|
808
|
+
the one place a frontend-only app keeps its types, states and rules): {{model_files}}
|
|
738
809
|
|
|
739
810
|
# ═══════════ REVERSE BACKEND PLAN — from the SPEC + MODEL + CODE, AS-BUILT ═══
|
|
740
811
|
# Anchored to the reversed spec's ids (§4 Traceability → forward-compatible),
|
|
@@ -744,6 +815,7 @@ workflow:
|
|
|
744
815
|
# backend-plan.md IS onboard's code-derived `design-template` override — its §2
|
|
745
816
|
# component sections follow the code's own folders/modules, not a fixed layering.
|
|
746
817
|
- id: ctx_reverse_plan
|
|
818
|
+
condition: "{{svc_lane}} == true"
|
|
747
819
|
action: build_context
|
|
748
820
|
context:
|
|
749
821
|
- { path: "{{backend_plan}}" } # the scaffolded code-derived template = structure + embedded guidance
|
|
@@ -754,6 +826,7 @@ workflow:
|
|
|
754
826
|
- { path: "{{bundle_dir}}/architecture/overview.md", optional: true } # the as-built architecture (inventory) — cite, don't re-derive
|
|
755
827
|
- { path: .appweaver/memory/constitution.technical.md, optional: true } # technology base ONLY — no domain
|
|
756
828
|
- id: reverse_plan
|
|
829
|
+
condition: "{{svc_lane}} == true"
|
|
757
830
|
action: agent_author
|
|
758
831
|
include_standards: true # the technical/architecture sticky set (reference only — the CODE wins)
|
|
759
832
|
tools: Read # grounded in the CODE, which arrives as {{source_files}} paths
|
|
@@ -798,6 +871,21 @@ workflow:
|
|
|
798
871
|
the EXTERNAL INTEGRATIONS table (heading contains "Integration") realising the
|
|
799
872
|
spec's IC-. Realise CN- (structural → §1.2 invariants/events; retention/audit →
|
|
800
873
|
§2 persistence / §3 cross-cutting), DC- (§3 + projection surface).
|
|
874
|
+
- EVERY ENDPOINT THIS FEATURE PUBLISHES IS AN ENDPOINT BLOCK, in the §2 axis that
|
|
875
|
+
publishes it: the heading `#### `VERB /route` — <purpose> · Serves <US/FR ids>`, then
|
|
876
|
+
**Operation id**, Auth, Request, Success, the Errors table and Maps to, exactly as
|
|
877
|
+
the template's endpoint block — never a row in a table of endpoints. The contract
|
|
878
|
+
scripts read this form: the API draft is written from the headings, and the request
|
|
879
|
+
ledger between the lanes reads the operation ids. The **Operation id** is the id the
|
|
880
|
+
code publishes the endpoint under, spelled exactly as the code spells it; the
|
|
881
|
+
boundary map records each operation's published id where the code declares one
|
|
882
|
+
("published as …" above). Where the code publishes none, write `—` and record a §5
|
|
883
|
+
DA-n saying the endpoint has no published operation id — never invent one: the
|
|
884
|
+
service's exported API document would not carry it, so nothing could bind to it.
|
|
885
|
+
- After the endpoint blocks, a `#### Requests from the frontend lane` heading with
|
|
886
|
+
`None` under it: a frontend reversed from the same code binds only to what the
|
|
887
|
+
service already serves, so no request is open yet. Later plans answer requests
|
|
888
|
+
there.
|
|
801
889
|
- AS-BUILT DEBT, not architecture drift. §6 records ONLY debt the CODE ITSELF
|
|
802
890
|
evidences — stubs/no-ops, dead or duplicate code, torn seams (shared table/
|
|
803
891
|
transaction), TODOs, hard-coded values. The code being organised differently
|
|
@@ -835,7 +923,7 @@ workflow:
|
|
|
835
923
|
context:
|
|
836
924
|
- { path: "{{frontend_plan}}" } # the scaffolded code-derived lane template = structure + embedded guidance
|
|
837
925
|
- { path: "{{spec_file}}" } # the reversed spec — UX- + the user stories this surface serves
|
|
838
|
-
- { path: "{{backend_plan}}" }
|
|
926
|
+
- { path: "{{backend_plan}}", optional: true } # the backend plan — the contracts the UI consumes, never re-specified here; absent with no service lane
|
|
839
927
|
- { path: "{{domain_model}}", optional: true } # the ubiquitous language labels and states must use — READ, never written
|
|
840
928
|
- { path: .appweaver/memory/constitution.ui.md, optional: true } # the lane's UX-* base, reversed by onboard from this same UI
|
|
841
929
|
- { path: "{{bundle_dir}}/architecture/frontend.md", optional: true } # the as-built UI architecture + the SHARED surface no slice owns
|
|
@@ -863,9 +951,17 @@ workflow:
|
|
|
863
951
|
- STAY IN THE LANE. Realise the spec's Experience Standards (UX-) and the
|
|
864
952
|
interaction its User Stories imply. The backend plan (in context) supplies
|
|
865
953
|
the CONTRACTS this surface consumes — cite them; do NOT restate, re-derive or
|
|
866
|
-
contradict them, and introduce no server-side behaviour here.
|
|
954
|
+
contradict them, and introduce no server-side behaviour here. With no backend plan
|
|
955
|
+
in context the service is outside this repo: bind against the routes the UI code
|
|
956
|
+
calls and the spec's IC-, as an external contract. Where the domain
|
|
867
957
|
model is in context, use its UBIQUITOUS LANGUAGE exactly in labels, states and
|
|
868
958
|
messages, and cite BR-nnn rather than restating a rule.
|
|
959
|
+
- CONTRACT BINDING CITES OPERATION IDS. Each row of the Contract Binding table names,
|
|
960
|
+
in its Operation id column, the **Operation id** backend-plan.md gives the endpoint
|
|
961
|
+
the UI code calls — `—` where the backend plan records none. The id is how
|
|
962
|
+
implement finds the endpoint, and how a later change that alters or removes it is
|
|
963
|
+
reported to this lane. The "Contract deltas needed" table reads `None`: the UI calls
|
|
964
|
+
only what the service already serves.
|
|
869
965
|
- STRUCTURE FOLLOWS THE UI CODE. Fill each section from the lane's real shape —
|
|
870
966
|
its actual routes and screens, its own composition axes (however it groups
|
|
871
967
|
components), where client state and server data-fetching really live, its
|
|
@@ -890,7 +986,7 @@ workflow:
|
|
|
890
986
|
context:
|
|
891
987
|
- { path: .appweaver/templates/source-map-template.md } # the sidecar structure
|
|
892
988
|
- { path: "{{spec_file}}" }
|
|
893
|
-
- { path: "{{backend_plan}}" }
|
|
989
|
+
- { path: "{{backend_plan}}", optional: true } # the service lane's plan, where this slice has one
|
|
894
990
|
- { path: "{{frontend_plan}}", optional: true } # the lane's design, where this slice has one
|
|
895
991
|
- { path: "{{concept_path}}" } # both file lists to map
|
|
896
992
|
- id: source_map
|
|
@@ -945,7 +1041,7 @@ workflow:
|
|
|
945
1041
|
context:
|
|
946
1042
|
- "{{spec_file}}"
|
|
947
1043
|
- "{{domain_model}}"
|
|
948
|
-
- "{{backend_plan}}"
|
|
1044
|
+
- { path: "{{backend_plan}}", optional: true } # the service lane's plan, where this slice has one
|
|
949
1045
|
- { path: "{{frontend_plan}}", optional: true } # the lane's plan, where this slice has one
|
|
950
1046
|
- "{{feature_dir}}/source-map.md"
|
|
951
1047
|
- "{{concept_path}}"
|
|
@@ -1006,7 +1102,12 @@ workflow:
|
|
|
1006
1102
|
condition: "{{report_needed}} == true"
|
|
1007
1103
|
action: agent_author
|
|
1008
1104
|
include_standards: false
|
|
1009
|
-
context:
|
|
1105
|
+
context:
|
|
1106
|
+
- "{{spec_file}}"
|
|
1107
|
+
- "{{domain_model}}"
|
|
1108
|
+
- { path: "{{backend_plan}}", optional: true }
|
|
1109
|
+
- { path: "{{frontend_plan}}", optional: true }
|
|
1110
|
+
- "{{feature_dir}}/source-map.md"
|
|
1010
1111
|
output_target: { type: file, path: "{{feature_dir}}/adopt-review-report.md" }
|
|
1011
1112
|
task: |
|
|
1012
1113
|
Write an Adopt Review report (the target) for the feature '{{feature_name}}' (acting on {{aggregates_csv}}) —
|
|
@@ -1014,8 +1115,10 @@ workflow:
|
|
|
1014
1115
|
- "# Adopt Review — {{feature_name}}" + today's date + "origin: reverse-engineered".
|
|
1015
1116
|
- "verdict:" line — "BLOCKING ✗ · <n>" if blocking gaps exist, else "REVIEW ○ · <m> item(s)".
|
|
1016
1117
|
- "## Blocking gaps" (if any): table | # | kind | artefact | detail | — MUST be
|
|
1017
|
-
resolved before the slice is trustworthy
|
|
1018
|
-
|
|
1118
|
+
resolved before the slice is trustworthy, one of two ways: re-adopt — remove
|
|
1119
|
+
{{feature_dir}} and run /appweaver adopt {{feature_name}} again, which reverses
|
|
1120
|
+
the documents afresh from the code, so edits made to them by hand are not kept —
|
|
1121
|
+
or correct the documents by hand and keep them.
|
|
1019
1122
|
Blocking gaps: {{blocking_gaps}}
|
|
1020
1123
|
- "## Review items" (close out of band): table | # | kind | where | confirm |.
|
|
1021
1124
|
These are inferred-vs-certain calls, as-built quirks, and missing-invariant
|
|
@@ -1034,7 +1137,7 @@ workflow:
|
|
|
1034
1137
|
action: verify_context
|
|
1035
1138
|
require_true: fidelity_ok
|
|
1036
1139
|
on_false: stop
|
|
1037
|
-
on_false_message: "Fidelity FAILED for {{feature_name}} — the reversed documents do not match the code (blocking gaps: {{blocking_gaps}}). See {{feature_dir}}/adopt-review-report.md.
|
|
1140
|
+
on_false_message: "Fidelity FAILED for {{feature_name}} — the reversed documents do not match the code (blocking gaps: {{blocking_gaps}}). See {{feature_dir}}/adopt-review-report.md. Resolve it one of two ways. RE-ADOPT: remove {{feature_dir}} and run /appweaver adopt {{feature_name}} again; the documents are reversed afresh from the code, so edits made to them first are not kept. Removing the folder leaves what this run added to {{domain_model}} (git diff shows it), and a re-adopt extends it, so remove that first. CORRECT BY HAND: re-read the source and refine spec.md, {{domain_model}}, the lane plans this slice has (backend: {{backend_plan}}; frontend: {{frontend_plan}}) and source-map.md — map the unmapped code, remove what is fabricated. This run stopped before it completed the OKF concept {{aggregate_primary}} and recorded cross-slice edges, so on this path both stay as onboard left them. A `fabricated-model` gap means the reverse gave this slice structure its code does not have — an entity, a boundary, a lifecycle state or a BR-nnn nothing enforces; the fix is to record the domain as thin as the code really is, never to leave it flattering. A `foreign-operation` gap means a document claims an operation the boundary map gives only to another feature; remove it here — it belongs to that feature's adopt."
|
|
1038
1141
|
|
|
1039
1142
|
# ═══════════ OKF CONCEPT — COMPLETE the shallow scan concept (deep reverse) ═══
|
|
1040
1143
|
# onboard wrote this aggregate's OKF concept SHALLOW (a discovery stub — enough to pick the
|
|
@@ -1051,7 +1154,8 @@ workflow:
|
|
|
1051
1154
|
- { path: "{{concept_path}}" } # the shallow onboard concept to complete
|
|
1052
1155
|
- { path: "{{spec_file}}" } # the deep reversed spec (entities, US, BR/CN/DC/IC)
|
|
1053
1156
|
- { path: "{{domain_model}}" } # the deep reversed model (entities, boundary, invariants)
|
|
1054
|
-
- { path: "{{backend_plan}}" }
|
|
1157
|
+
- { path: "{{backend_plan}}", optional: true } # the deep reversed service plan (components, ports, integrations), where the slice has one
|
|
1158
|
+
- { path: "{{frontend_plan}}", optional: true } # the deep reversed UI plan, where the slice has one
|
|
1055
1159
|
- { path: "{{feature_dir}}/source-map.md" } # the source anchor (files, seam, quirks)
|
|
1056
1160
|
- { path: .appweaver/templates/okf-concept-template.md } # OKF v0.1 format authority
|
|
1057
1161
|
- id: complete_concept
|
|
@@ -1109,6 +1213,7 @@ workflow:
|
|
|
1109
1213
|
# reconcile-on-write helper as forward implement, stamped origin reverse-engineered,
|
|
1110
1214
|
# additive to the inventory bundle. Runs only after fidelity passes.
|
|
1111
1215
|
- id: xref_record
|
|
1216
|
+
condition: "{{svc_lane}} == true" # edges are read off the service plan, as forward implement records them
|
|
1112
1217
|
action: execute_script
|
|
1113
1218
|
script: { ref: xref }
|
|
1114
1219
|
subcommand: record
|
|
@@ -1331,9 +1436,10 @@ outputs:
|
|
|
1331
1436
|
frontend_plan: "{{frontend_plan}}" # empty where this slice has no UI half
|
|
1332
1437
|
domain_model: "{{domain_model}}" # the CONTEXT's, shared — this run ADDED an aggregate section to it
|
|
1333
1438
|
bounded_context: "{{context}}"
|
|
1439
|
+
svc_lane: "{{svc_lane}}"
|
|
1334
1440
|
ui_lane: "{{ui_lane}}"
|
|
1335
1441
|
ui_count: "{{ui_count}}"
|
|
1336
|
-
feature_lanes: "{{feature_lanes}}" # empty = every declared lane; [backend] = a service-only slice in a repo with a frontend
|
|
1442
|
+
feature_lanes: "{{feature_lanes}}" # empty = every declared lane; [backend] = a service-only slice in a repo with a frontend; [frontend] = a UI-only slice in a repo with a service
|
|
1337
1443
|
operations: "{{operations_csv}}" # this feature's operations, from the boundary map
|
|
1338
1444
|
baseline_commit: "{{baseline_commit}}"
|
|
1339
1445
|
source_map: "{{feature_dir}}/source-map.md"
|
|
@@ -1352,4 +1458,4 @@ outputs:
|
|
|
1352
1458
|
composed_file: "{{composed_file}}"
|
|
1353
1459
|
technical_reconcile_ok: "{{technical_ok}}"
|
|
1354
1460
|
domain_reconcile_ok: "{{domain_ok}}"
|
|
1355
|
-
next: "Adopted {{feature_name}} (spec.md
|
|
1461
|
+
next: "Adopted {{feature_name}} (spec.md, source-map.md and the lane plans this slice has — backend: {{backend_plan}}; frontend: {{frontend_plan}} — v1.0) and wrote {{aggregate_sections}} — the model section(s) for the aggregate(s) it acts on, resolved from the {{aggregate_source}} — in the bounded context `{{context}}`'s shared {{domain_model}}. The spec cites BR-nnn by id, the model carries their text, so this slice is checkable by the same gates as a greenfield one and analyze-plan's check 4 now has a model to check against. A section another feature over the same aggregate wrote first was EXTENDED, never duplicated; every other section is untouched. COMPLETED the OKF concept of {{aggregate_primary}} (deepened + linked the deep artifacts; {{xref_edge_count}} cross-slice edge(s) recorded). UI HALF: ui_lane={{ui_lane}} — where it is true this slice also has frontend-plan.md, reversed from the {{ui_count}} UI file(s) the feature map attributes to it; where it is false the repo declared no frontend lane, or this aggregate owns no part of its surface, and a service-only adoption is the correct outcome rather than a gap. In the second case, where a frontend lane IS declared, the feature records lanes=[backend] in its active_version.json (feature_lanes shows it), so plan and the analyze gates treat the frontend lane as absent for THIS feature; run `aw-spec-actions feature-lanes --clear` if it later gains a UI. SERVICE HALF: svc_lane={{svc_lane}} — false where the repo declares no backend lane (a frontend-only project: no backend plan, no cross-slice edges, and the model was read from the UI code) or this slice has no service code; in the second case, where a frontend lane carries it, the feature records lanes=[frontend] the same way. The SHARED UI surface (app shell, layout, design system) belongs to no slice and stays in {{bundle_dir}}/architecture/frontend.md. NOTE — governance reconcile is currently HELD (reconcile_governance=false): this run did NOT modify the constitution halves or the guardrails/{{gov_domain}}/ rule set, so they keep onboard's provisional scaffold. Close any items in {{feature_dir}}/adopt-review-report.md out of band. The slice is now a NORMAL feature: refine via /appweaver analyze-plan, then drive every change through the CR delta loop (/appweaver specify → plan → analyze-plan-delta → implement → build → analyze-slice-delta → finalize-delta → analyze-slice → close-delta). If a change edits untested legacy behaviour with blast radius, characterize just that surface first (optional on-touch fence). To restore governance reconcile, set reconcile_governance to 'true' in the workflow vars."
|
|
@@ -152,7 +152,7 @@
|
|
|
152
152
|
|
|
153
153
|
name: aw-spec-onboard
|
|
154
154
|
description: Onboard an existing codebase for brownfield DEVELOPMENT — a deterministic whole-repo scan produces a high-level OKF feature map (folders/concepts) PLUS the project-level governance scaffold (split constitution + guardrails/brf-<domain>/ with its DOMAIN rule files at domain/ + domain-rule-bindings + code-derived TECHNICAL rule files at service/ + tech-rule-bindings + activated domain), all provisional-from-scan. The first context authors that tier; every later context amends it additively from its own code (new rules, principles and map entries — never a rewrite, renumbering or deletion; a contradiction is recorded as a Divergence note), and a tier that does not exist yet, such as a lane declared after an earlier onboard, is authored in full. Naming an already-onboarded context re-runs that governance pass alone. Where the scan finds a frontend lane in the CODE, it also authors that lane's half — constitution.ui.md (UX-*) — and its code-derived rule files at brf-<domain>/frontend/, mapped under `## /aw-spec-ui-constitution`, `## /aw-spec-plan-frontend` and `## /aw-spec-implement-frontend`; a backend-only repo gets none of it. Every rule tier is reverse-engineered from the CODE alone (never a greenfield rule file), evidenced-only, and WIRED per-workflow so the whole forward pipeline AND adopt govern against THIS codebase — never a greenfield fallback. It also reverse-engineers the repo's own technical structure into a project-specific design + delta-design template pair, installed as the project template overrides, and — where the lane exists — the frontend lane's own pair from the UI source. Every authoring step is shaped by a NEUTRAL rev-templates skeleton; no greenfield constitution, rule file or document template is ever placed in context. Accepts an optional concerns list to look for (onboard decides which are actually present). Reads any declared lane whose folder exists, never writes one; a lane declared before it is built is governed as absent and its governance left to the developer. No migration content; never modifies source.
|
|
155
|
-
version: 2.
|
|
155
|
+
version: 2.5.0
|
|
156
156
|
agent_agnostic: true
|
|
157
157
|
dialect: aw-spec.orchestrator/v1
|
|
158
158
|
|
|
@@ -191,7 +191,7 @@ standards:
|
|
|
191
191
|
vars:
|
|
192
192
|
# The provenance stamp every generated file carries. It names THIS workflow's version,
|
|
193
193
|
# so it moves with `version:` above — one value, never a literal repeated per prompt.
|
|
194
|
-
generated_by: "aw-spec-onboard/2.
|
|
194
|
+
generated_by: "aw-spec-onboard/2.5.0"
|
|
195
195
|
bundle_present: "false" # set by the scan (the bundle holds concepts); reported, gates nothing
|
|
196
196
|
conformant: "false" # OKF conformance-gate driver
|
|
197
197
|
pack_present: "false" # the project tier exists ⇒ repo_gov, so this context AMENDS it
|
|
@@ -332,11 +332,13 @@ workflow:
|
|
|
332
332
|
- { name: bundle_dir, from: "$.bundle_dir" }
|
|
333
333
|
- { name: bundle_present, from: "$.bundle_present" }
|
|
334
334
|
- { name: bundle_md_count, from: "$.bundle_md_count" }
|
|
335
|
-
# The frontend lane, as the CODE evidences it. `
|
|
335
|
+
# The frontend lane, as the CODE evidences it. `frontend_evidenced` is true only
|
|
336
336
|
# where a candidate root reached lane strength (a frontend build config, or a
|
|
337
337
|
# real set of component/view files) — loose scripts and stylesheets under a
|
|
338
|
-
# wwwroot/ are reported in the substrate but are NOT a lane.
|
|
339
|
-
|
|
338
|
+
# wwwroot/ are reported in the substrate but are NOT a lane. It is the code's
|
|
339
|
+
# answer, kept apart from `frontend_present` (the UI rule tier exists, from
|
|
340
|
+
# pack_setup); which lanes this run governs is the declaration's answer, ui_lane.
|
|
341
|
+
- { name: frontend_evidenced, from: "$.frontend_present" }
|
|
340
342
|
- { name: frontend_separable, from: "$.frontend_separable" }
|
|
341
343
|
- { name: frontend_roots, from: "$.frontend_roots" }
|
|
342
344
|
- { name: frontend_root_count, from: "$.frontend_root_count" }
|
|
@@ -2303,6 +2305,16 @@ workflow:
|
|
|
2303
2305
|
signature form + the ports/contracts. Keep exactly one subsection whose heading
|
|
2304
2306
|
contains the word "Integration" (the External Integrations table — one port/adapter row
|
|
2305
2307
|
per IC-): aw-xref matches it by keyword, so it is pinned regardless of layout.
|
|
2308
|
+
- THE PUBLISHED SURFACE IS A PINNED FORM. In the §2 axis this project publishes its
|
|
2309
|
+
endpoints from (titled with the project's own name for it), keep the skeleton's
|
|
2310
|
+
endpoint block exactly — the heading `#### `[VERB] [/route]` — [purpose] · Serves …`,
|
|
2311
|
+
then **Operation id**, Auth, Request, Success, the Errors table and Maps to — and the
|
|
2312
|
+
`#### Requests from the frontend lane` table after the blocks. The contract scripts
|
|
2313
|
+
read exactly this form: the API draft is written from the headings and the request
|
|
2314
|
+
ledger between the lanes reads the operation ids and the table, so endpoints listed
|
|
2315
|
+
in a table instead leave both empty. Keep the Operation id comment: an endpoint the
|
|
2316
|
+
code already serves keeps the id it publishes, `—` with a §5 DA-n where it publishes
|
|
2317
|
+
none, never an invented one. Omit both only where the code publishes no endpoint.
|
|
2306
2318
|
- §3 Cross-Cutting Concerns — one row per concern THIS project's governance carries, read
|
|
2307
2319
|
from the technical constitution (Serves = a spec id or a §5 DA-n). Do not import a
|
|
2308
2320
|
standard concern list the constitution does not evidence.
|
|
@@ -2361,9 +2373,14 @@ workflow:
|
|
|
2361
2373
|
the generated master template. Never name a layering — neither one you know nor one the
|
|
2362
2374
|
master did not derive.
|
|
2363
2375
|
- CARRY OVER the neutral parts of rev-templates/delta-design-template.skeleton.md (in
|
|
2364
|
-
context): Change summary,
|
|
2365
|
-
|
|
2366
|
-
|
|
2376
|
+
context): Change summary, Model changes this plan realises, Depends on, Cross-section
|
|
2377
|
+
impact, Contract deltas for the frontend lane, Other open deltas, Regression targets,
|
|
2378
|
+
New assumptions/deviations (DA-n / WA-n), On merge — word for word: finalize-delta
|
|
2379
|
+
merges the spec and the model, never this plan, which `plan main` re-derives. Keep
|
|
2380
|
+
the contract table's Operation id and Change columns and its added / changed /
|
|
2381
|
+
removed values: analyze-plan-delta reads them to warn when a change alters or
|
|
2382
|
+
removes an operation the frontend binds to. Omit that section only where the code
|
|
2383
|
+
has no frontend lane. Keep behaviour technology-agnostic (signatures +
|
|
2367
2384
|
contracts, no code); a shared element is MODIFIED in place, never duplicated; every
|
|
2368
2385
|
changed element serves a spec id.
|
|
2369
2386
|
- This aligns with the delta-plan module, which classifies "per the master's OWN
|
|
@@ -117,7 +117,7 @@
|
|
|
117
117
|
|
|
118
118
|
name: aw-spec-plan
|
|
119
119
|
description: "Author the feature's lane plans from the spec and the bounded context's domain model — backend-plan.md when a backend lane is declared, frontend-plan.md when a frontend lane is, both when both are. Lanes come from .appweaver/stacks.json, so one command covers backend-only, frontend-only and full-stack projects; the former separate design-ui command is folded in. It ASKS what it is planning, the way implement asks what it is building: the master (`main`), one of the OPEN CHANGES, or a new plan-only change for a refactor with no spec delta — the argument doubles as the answer, and the menu appears only once a master exists, so a first run bootstraps with no prompt. `main` on a feature that already has masters RE-DERIVES them from the merged spec.md + domain-model.md — the operation finalize-delta's contract assumes when it merges a change's spec and model halves and no lane plan — and is confirmed before it rewrites anything. A change instead gets delta-backend-plan.md / delta-frontend-plan.md inside changes/<CR-id>/ while the masters stay untouched, written against the effective model (the master model, the change's own model delta, and the pending model deltas of LOWER waves, which are its predecessors) and against the feature's real source files from its OKF concept. Master authoring is template-driven: the kit's templates by default, or the code-derived as-built structure when onboard installed an override. Authoring only — a master gates at analyze-plan; a change ships through the CR chain."
|
|
120
|
-
version: 5.5.
|
|
120
|
+
version: 5.5.1
|
|
121
121
|
agent_agnostic: true
|
|
122
122
|
dialect: aw-spec.orchestrator/v1
|
|
123
123
|
|
|
@@ -880,7 +880,11 @@ workflow:
|
|
|
880
880
|
- NAME EVERY ENDPOINT with its route, verb and operation id — its name in the
|
|
881
881
|
service's published API document, unique across the service. Where the code
|
|
882
882
|
already gives the endpoint one, record THAT id exactly as the code spells it; the
|
|
883
|
-
frontend plan cites it and implement finds the endpoint by it.
|
|
883
|
+
frontend plan cites it and implement finds the endpoint by it. An endpoint the code
|
|
884
|
+
already serves under no id keeps `—`, with a §5 DA-n saying so — never an invented
|
|
885
|
+
id. Write each endpoint as the template's endpoint block — the heading
|
|
886
|
+
`#### `VERB /route` — …` with its **Operation id** field — never as a row in a table
|
|
887
|
+
of endpoints: the API draft and the request ledger between the lanes read that form.
|
|
884
888
|
- ANSWER THE FRONTEND LANE'S CONTRACT REQUESTS. Still open in the frontend plan's
|
|
885
889
|
"Contract deltas needed" table: {{req_backend_text}}. Answer each one in a
|
|
886
890
|
"Requests from the frontend lane" table beside this feature's endpoints (| Request
|
|
@@ -16,7 +16,10 @@
|
|
|
16
16
|
# still READ the other lane where they need it: a frontend plan binds to the backend
|
|
17
17
|
# plan's published surface, which the backend developer owns. specify, finalize-delta and
|
|
18
18
|
# close-delta do NOT follow it: the spec is written whole, from its rules and standards,
|
|
19
|
-
# and a change merges and closes with whatever its lanes have delivered.
|
|
19
|
+
# and a change merges and closes with whatever its lanes have delivered. Brownfield adopt
|
|
20
|
+
# does not follow it either: it reverses a feature once, every half its code has, because
|
|
21
|
+
# it cannot run a second time for the other lane, so the other lane's developer finds
|
|
22
|
+
# their plan already written.
|
|
20
23
|
#
|
|
21
24
|
# THE OPTIONS COME FROM stacks.json. Both lanes declared → backend, frontend and both.
|
|
22
25
|
# One lane declared → that lane only, picked without a question (there is nothing to
|
|
@@ -32,8 +35,8 @@
|
|
|
32
35
|
# =============================================================================
|
|
33
36
|
|
|
34
37
|
name: aw-spec-select-lane
|
|
35
|
-
description: Choose the lane this developer works on — backend, frontend or both — and store it in .appweaver/lane.json, which is not committed, so each developer keeps their own. The options come from the stacks declared in .appweaver/stacks.json, all three when both lanes are declared and only the declared one otherwise. plan, analyze-plan, implement, build and analyze-slice then write only that lane while still reading the other; specify, finalize-delta
|
|
36
|
-
version: 1.0.
|
|
38
|
+
description: Choose the lane this developer works on — backend, frontend or both — and store it in .appweaver/lane.json, which is not committed, so each developer keeps their own. The options come from the stacks declared in .appweaver/stacks.json, all three when both lanes are declared and only the declared one otherwise. plan, analyze-plan, implement, build and analyze-slice then write only that lane while still reading the other; specify, finalize-delta, close-delta and brownfield adopt do not follow it. select-stack writes the default (every declared lane); run this to narrow it.
|
|
39
|
+
version: 1.0.1
|
|
37
40
|
agent_agnostic: true
|
|
38
41
|
dialect: aw-spec.orchestrator/v1
|
|
39
42
|
|
|
@@ -100,5 +103,5 @@ outputs:
|
|
|
100
103
|
working_lane: "{{working_lane}}"
|
|
101
104
|
working_kinds: "{{working_kinds}}"
|
|
102
105
|
lane_file: "{{lane_file}}"
|
|
103
|
-
note: "Working lane `{{working_lane}}` stored in {{lane_file}}. The file is not committed — it is this developer's choice, and another developer on the same repository keeps their own. From now on plan, analyze-plan, implement, build and analyze-slice write only the working lane: they plan it, gate it with its own receipt, generate it, compile it and test it. They still READ the other lane where they need it — a frontend plan binds to the operation ids the backend plan publishes. specify writes the whole spec whatever lane is chosen, and finalize-delta and close-delta merge and close a change with whatever its lanes have delivered. Re-running /appweaver select-stack resets the working lane to every declared lane."
|
|
106
|
+
note: "Working lane `{{working_lane}}` stored in {{lane_file}}. The file is not committed — it is this developer's choice, and another developer on the same repository keeps their own. From now on plan, analyze-plan, implement, build and analyze-slice write only the working lane: they plan it, gate it with its own receipt, generate it, compile it and test it. They still READ the other lane where they need it — a frontend plan binds to the operation ids the backend plan publishes. specify writes the whole spec whatever lane is chosen, and finalize-delta and close-delta merge and close a change with whatever its lanes have delivered. Brownfield adopt reverses a feature once, every half its code has, whatever lane is chosen, so the other lane's developer finds their plan already written. Re-running /appweaver select-stack resets the working lane to every declared lane."
|
|
104
107
|
next: "Run the lane's flow on the active feature: /appweaver plan → analyze-plan → implement → build → analyze-slice. Switch lanes any time with /appweaver select-lane backend | frontend | both."
|
package/package.json
CHANGED