aw-spec-cli 0.1.23 → 0.1.25
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/ORCH-DIALECT.md +3 -3
- package/assets/.appweaver/RULE-PARTITION.md +41 -28
- package/assets/.appweaver/orchestrator/orchestrator.py +92 -14
- package/assets/.appweaver/orchestrator/rev-templates/ai-rules.reference.md +3 -3
- package/assets/.appweaver/orchestrator/rev-templates/delta-design-template.skeleton.md +19 -12
- package/assets/.appweaver/orchestrator/rev-templates/design-template.skeleton.md +25 -17
- package/assets/.appweaver/orchestrator/rev-templates/domain-requirements.skeleton.md +2 -2
- package/assets/.appweaver/orchestrator/rev-templates/domain-rule-bindings.skeleton.md +10 -10
- package/assets/.appweaver/orchestrator/rev-templates/tech-rule-bindings.skeleton.md +28 -17
- package/assets/.appweaver/orchestrator/rev-templates/technical-constitution.skeleton.md +22 -24
- package/assets/.appweaver/orchestrator/rev-templates/technical-rule-file.skeleton.md +1 -1
- package/assets/.appweaver/orchestrator/rev-templates/ui-delta-design-template.skeleton.md +29 -19
- package/assets/.appweaver/orchestrator/rev-templates/ui-design-template.skeleton.md +27 -20
- package/assets/.appweaver/orchestrator/workflows/aw-spec-adopt.orch.yaml +184 -37
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-plan-delta.orch.yaml +18 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-plan.orch.yaml +19 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-slice-delta.orch.yaml +18 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-inventory.orch.yaml +55 -29
- package/assets/.appweaver/orchestrator/workflows/aw-spec-onboard.orch.yaml +650 -205
- package/assets/.appweaver/orchestrator/workflows/aw-spec-plan.orch.yaml +19 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-select-feature.orch.yaml +5 -5
- package/assets/.appweaver/orchestrator/workflows/aw-spec-select-stack.orch.yaml +2 -2
- package/assets/.appweaver/orchestrator/workflows/aw-spec-ui-model.orch.yaml +13 -3
- package/assets/.appweaver/orchestrator/workflows/aw-spec-ui-prototype.orch.yaml +40 -1
- package/assets/.appweaver/orchestrator/workflows/aw-spec-workflow-model.orch.yaml +2 -1
- package/assets/.appweaver/scripts/bash/aw-rev-constitution.sh +1 -1
- package/assets/.appweaver/scripts/bash/aw-spec-actions.sh +69 -7
- package/assets/.appweaver/scripts/powershell/aw-rev-constitution.ps1 +1 -1
- package/assets/.appweaver/scripts/powershell/aw-spec-actions.ps1 +58 -2
- package/assets/.appweaver/scripts/python/aw-inventory.py +1809 -156
- package/assets/.appweaver/scripts/python/aw-rev-constitution.py +106 -145
- package/assets/.appweaver/scripts/python/aw-stack.py +45 -1
- package/assets/.appweaver/scripts/python/aw-xref.py +73 -2
- package/assets/.appweaver/scripts/python/validate_okf.py +10 -5
- package/assets/.appweaver/templates/okf-concept-template.md +10 -2
- package/assets/.appweaver/templates/proposed-inventory-template.md +100 -48
- package/assets/.appweaver/templates/source-map-template.md +14 -6
- package/package.json +1 -1
|
@@ -24,13 +24,25 @@
|
|
|
24
24
|
# 3. GOVERNANCE SCAFFOLD — the PROJECT-level governing tier: the split constitution
|
|
25
25
|
# (technical + domain), the guardrails/projects/brf-<domain>/domain/ rule-file set
|
|
26
26
|
# (+ domain-rule-bindings), the domain charter that set is headed by, and the
|
|
27
|
-
# activated domain.
|
|
28
|
-
#
|
|
29
|
-
#
|
|
30
|
-
#
|
|
31
|
-
#
|
|
32
|
-
#
|
|
33
|
-
#
|
|
27
|
+
# activated domain. The FIRST context to onboard AUTHORS it from the whole-repo
|
|
28
|
+
# scan. Every LATER context AMENDS it from its own code — ADDITIVELY: a rule file
|
|
29
|
+
# for a concern no existing file covers, rules for a variant an existing file does
|
|
30
|
+
# not state, a principle for a project-level trait no principle covers, and the
|
|
31
|
+
# context's entry in every map the tier keeps. It never rewords, renumbers or
|
|
32
|
+
# deletes what an earlier context wrote; where this context's code contradicts a
|
|
33
|
+
# rule, it records a Divergence note under it for /appweaver constitution to
|
|
34
|
+
# decide. Re-deriving the tier per context would be the aggregate-scoping bias the
|
|
35
|
+
# rev-constitution work removed; adding one context's evidence at project scope is
|
|
36
|
+
# not. A TIER that does not exist yet — a lane declared after an earlier onboard —
|
|
37
|
+
# is authored in full by whichever run first sees it. The document templates are
|
|
38
|
+
# written once per lane and never amended: plans already written follow them.
|
|
39
|
+
# Because nothing is adopted yet, the tier is PROVISIONAL, evidenced by the code
|
|
40
|
+
# (project identity + bounded-context map are firm; principles/rules are marked
|
|
41
|
+
# provisional); /appweaver constitution is its human amendment path.
|
|
42
|
+
#
|
|
43
|
+
# Naming a context that is ALREADY onboarded re-runs this governance pass alone —
|
|
44
|
+
# its concepts and specs tree are left as they are. That is how a lane declared
|
|
45
|
+
# after every context was onboarded gets its governance.
|
|
34
46
|
#
|
|
35
47
|
# inventory → [edit specs/proposed-inventory.md] → inventory apply
|
|
36
48
|
# → ONBOARD <Context> (once per context) ← you are here
|
|
@@ -81,18 +93,18 @@
|
|
|
81
93
|
# source (never from a greenfield UI template's content), then linted like the other
|
|
82
94
|
# halves and composed in. Parallel to the technical base, so its numbering is its own.
|
|
83
95
|
# guardrails/projects/brf-<domain>/frontend/*.md — the code-derived lane rule set, the detail
|
|
84
|
-
# layer under those UX-* principles,
|
|
85
|
-
#
|
|
86
|
-
#
|
|
96
|
+
# layer under those UX-* principles, wired into tech-rule-bindings.md under the lane's
|
|
97
|
+
# three headings: `## /aw-spec-ui-constitution` (what a later /appweaver constitution
|
|
98
|
+
# re-ratifies the UI half from), `## /aw-spec-plan-ui` and `## /aw-spec-implement-ui`
|
|
99
|
+
# (what the frontend lane of `plan` and of `implement` load).
|
|
87
100
|
# .appweaver/templates/overrides/ui-design-template.md + ui-delta-design-template.md — the
|
|
88
101
|
# lane's own document pair, reverse-engineered from the UI source the same way the
|
|
89
102
|
# service pair is reverse-engineered from the service code. The lane is governed by a
|
|
90
|
-
# different constitution half and
|
|
91
|
-
#
|
|
92
|
-
# crosses between them is the
|
|
103
|
+
# different constitution half and generated by a different lane of `implement`, so it
|
|
104
|
+
# gets its own plan document rather than a section inside the backend plan; the only
|
|
105
|
+
# thing that crosses between them is the service's published surface. Their consumers are the FRONTEND LANES
|
|
93
106
|
# of `plan` and `implement` — one command each, covering both lanes — and the templates
|
|
94
|
-
# are written here because the whole-repo evidence for them
|
|
95
|
-
# onboard.
|
|
107
|
+
# are written here because the whole-repo evidence for them is read at onboard.
|
|
96
108
|
# RUN /appweaver select-stack FIRST. It is the first command of the brownfield
|
|
97
109
|
# sequence and this workflow REFUSES to run without it, because it needs to be told three
|
|
98
110
|
# things before it can start: which lanes this project has, where each lane's source is,
|
|
@@ -132,12 +144,13 @@
|
|
|
132
144
|
# Launch: /appweaver onboard [<BoundedContext>] [; concerns: a, b, c]
|
|
133
145
|
# e.g. /appweaver onboard Clinical
|
|
134
146
|
# e.g. /appweaver onboard # the next context the map has open
|
|
147
|
+
# e.g. /appweaver onboard Clinical # already onboarded: governance pass only
|
|
135
148
|
# e.g. /appweaver onboard "Clinical; concerns: auditing, concurrency, authorization"
|
|
136
149
|
# =============================================================================
|
|
137
150
|
|
|
138
151
|
name: aw-spec-onboard
|
|
139
|
-
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/projects/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 and
|
|
140
|
-
version: 2.
|
|
152
|
+
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/projects/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-ui` and `## /aw-spec-implement-ui`; 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, never writes one. No migration content; never modifies source.
|
|
153
|
+
version: 2.3.0
|
|
141
154
|
agent_agnostic: true
|
|
142
155
|
dialect: aw-spec.orchestrator/v1
|
|
143
156
|
|
|
@@ -174,15 +187,31 @@ standards:
|
|
|
174
187
|
- { path: .appweaver/ai-rules.md } # kit-resident: the universal operating rules, every flow
|
|
175
188
|
|
|
176
189
|
vars:
|
|
177
|
-
|
|
190
|
+
# The provenance stamp every generated file carries. It names THIS workflow's version,
|
|
191
|
+
# so it moves with `version:` above — one value, never a literal repeated per prompt.
|
|
192
|
+
generated_by: "aw-spec-onboard/2.3.0"
|
|
193
|
+
bundle_present: "false" # set by the scan (the bundle holds concepts); reported, gates nothing
|
|
178
194
|
conformant: "false" # OKF conformance-gate driver
|
|
179
|
-
pack_present: "false" # project
|
|
195
|
+
pack_present: "false" # the project tier exists ⇒ repo_gov, so this context AMENDS it
|
|
180
196
|
# The governance tier — constitution halves, rule packs, document templates —
|
|
181
|
-
# is PROJECT-scoped
|
|
182
|
-
#
|
|
183
|
-
#
|
|
184
|
-
#
|
|
197
|
+
# is PROJECT-scoped: the first context to onboard authors it, and every later one
|
|
198
|
+
# amends it additively. Re-authoring project principles from one context's evidence
|
|
199
|
+
# is the scoping bias the rev-constitution work removed; this var is what switches
|
|
200
|
+
# a later run from authoring to amending.
|
|
185
201
|
repo_gov: "false" # true once the project governance exists
|
|
202
|
+
# Per-lane tier presence, from project-setup. A lane whose tier is absent is authored
|
|
203
|
+
# in full even on a later context — a lane declared after an earlier onboard.
|
|
204
|
+
service_present: "false"
|
|
205
|
+
frontend_present: "false"
|
|
206
|
+
amend_repo: "false" # the domain tier + domain half exist ⇒ amend them
|
|
207
|
+
amend_svc: "false" # the service tier exists and the lane is declared ⇒ amend it
|
|
208
|
+
amend_ui: "false" # the frontend tier exists and the lane is declared ⇒ amend it
|
|
209
|
+
# False when the named context is already onboarded: its concepts and specs tree are
|
|
210
|
+
# left as they are and the run is the governance pass alone.
|
|
211
|
+
bundle_pass: "true"
|
|
212
|
+
amended_domain_files: ""
|
|
213
|
+
amended_service_files: ""
|
|
214
|
+
amended_ui_files: ""
|
|
186
215
|
# The governance project is named from the PROJECT, never from the context.
|
|
187
216
|
# Passing the context name here would produce one rule pack per bounded
|
|
188
217
|
# context, which is the same bias by another route.
|
|
@@ -273,6 +302,11 @@ workflow:
|
|
|
273
302
|
args: ["--service-root", "{{be_root}}", "--ui-root", "{{fe_root}}"]
|
|
274
303
|
outputs:
|
|
275
304
|
- { name: inventory_json, from: "$.inventory_json" }
|
|
305
|
+
# The same substrate cut per lane. A step that authors ONE lane's governance
|
|
306
|
+
# reads its lane's view; the bundle and the lane-neutral domain steps read the
|
|
307
|
+
# whole substrate.
|
|
308
|
+
- { name: inventory_service_json, from: "$.inventory_service_json" }
|
|
309
|
+
- { name: inventory_ui_json, from: "$.inventory_ui_json" }
|
|
276
310
|
- { name: root, from: "$.root" }
|
|
277
311
|
- { name: head, from: "$.head" }
|
|
278
312
|
- { name: file_count, from: "$.file_count" }
|
|
@@ -348,6 +382,11 @@ workflow:
|
|
|
348
382
|
- { name: contexts_ordered, from: "$.contexts_ordered" }
|
|
349
383
|
- { name: feature_map, from: "$.feature_map" }
|
|
350
384
|
- { name: map_error, from: "$.error" }
|
|
385
|
+
- { name: all_onboarded, from: "$.all_onboarded" }
|
|
386
|
+
# The input's "concerns:" clause, split off the context name. Prompts quote
|
|
387
|
+
# `concerns_line`, never the raw input.
|
|
388
|
+
- { name: concerns, from: "$.concerns" }
|
|
389
|
+
- { name: concerns_line, from: "$.concerns_line" }
|
|
351
390
|
|
|
352
391
|
# 1d. No map means the boundaries were never decided. Onboarding without them
|
|
353
392
|
# is what produced a flat aggregate list with no context level at all.
|
|
@@ -362,6 +401,23 @@ workflow:
|
|
|
362
401
|
review and edit `specs/proposed-inventory.md` — it is the boundary map and
|
|
363
402
|
it is yours to change — then run `/appweaver inventory apply`.
|
|
364
403
|
|
|
404
|
+
# context-state exits non-zero on the three refusals below and still prints its
|
|
405
|
+
# verdict; `on_error: continue` binds that JSON, so each gate quotes the reason.
|
|
406
|
+
- id: all_done_gate
|
|
407
|
+
condition: "{{all_onboarded}} == true"
|
|
408
|
+
action: verify_context
|
|
409
|
+
require_value: all_onboarded
|
|
410
|
+
equals: "false"
|
|
411
|
+
on_mismatch: stop
|
|
412
|
+
on_mismatch_message: >
|
|
413
|
+
Every bounded context in the feature map is already onboarded
|
|
414
|
+
({{onboarded_contexts}}), so there is no context left to onboard. Pick a feature
|
|
415
|
+
with /appweaver select-feature and develop it — adopt it first if it exists in
|
|
416
|
+
the code. To re-run the governance pass — for instance after declaring a lane
|
|
417
|
+
with /appweaver select-stack — name a context: /appweaver onboard <Context>. To
|
|
418
|
+
onboard a context the map does not have, edit specs/proposed-inventory.md and run
|
|
419
|
+
/appweaver inventory apply.
|
|
420
|
+
|
|
365
421
|
- id: require_context
|
|
366
422
|
action: verify_context
|
|
367
423
|
require_value: context_known
|
|
@@ -369,16 +425,27 @@ workflow:
|
|
|
369
425
|
on_mismatch: stop
|
|
370
426
|
on_mismatch_message: "{{map_error}}"
|
|
371
427
|
|
|
372
|
-
# 1e. Per-context curation guard — the narrow form of the old bundle guard.
|
|
373
|
-
-
|
|
428
|
+
# 1e. Per-context curation guard — the narrow form of the old bundle guard. A context
|
|
429
|
+
# whose concepts all exist is not re-mapped: the concept author is skipped, so its
|
|
430
|
+
# curation is never overwritten. The governance pass still runs, because what it
|
|
431
|
+
# amends is project-scoped and may have moved since — a lane declared after this
|
|
432
|
+
# context was onboarded is the case that needs it.
|
|
433
|
+
- id: context_done_refresh
|
|
434
|
+
condition: "{{already_onboarded}} == true"
|
|
435
|
+
action: set
|
|
436
|
+
vars: { bundle_pass: "false" }
|
|
437
|
+
- id: context_done_note
|
|
438
|
+
condition: "{{already_onboarded}} == true"
|
|
374
439
|
action: verify_context
|
|
375
440
|
require_value: already_onboarded
|
|
376
|
-
equals: "
|
|
377
|
-
on_mismatch:
|
|
441
|
+
equals: "never"
|
|
442
|
+
on_mismatch: continue
|
|
378
443
|
on_mismatch_message: >
|
|
379
444
|
Bounded context {{bc}} is already onboarded — every aggregate its
|
|
380
|
-
{{bc_feature_count}} feature(s) act on ({{bc_aggregates}})
|
|
381
|
-
{{bundle_dir}}
|
|
445
|
+
{{bc_feature_count}} feature(s) act on ({{bc_aggregates}}) has a concept in
|
|
446
|
+
{{bundle_dir}}. Those concepts and its specs tree are left as they are; this run is
|
|
447
|
+
the GOVERNANCE pass alone: it authors any lane tier that does not exist yet and
|
|
448
|
+
amends the rest from {{bc}}'s code.
|
|
382
449
|
|
|
383
450
|
# 1f. Dependency order. A context whose dependencies are still open would be
|
|
384
451
|
# modelled against aggregates that do not exist yet. A context inside a
|
|
@@ -505,12 +572,14 @@ workflow:
|
|
|
505
572
|
# OKF format authority, and an OPTIONAL DDD vocabulary aid for naming (no
|
|
506
573
|
# migration/pipeline reference — this is development).
|
|
507
574
|
- id: ctx_author
|
|
575
|
+
condition: "{{bundle_pass}} == true"
|
|
508
576
|
action: build_context
|
|
509
577
|
context:
|
|
510
578
|
- { path: "{{inventory_json}}" } # the deterministic substrate (aggregate_signals etc.)
|
|
511
579
|
- { path: "{{feature_map}}" } # the CONFIRMED boundaries: which features belong to which bounded context, and in what order
|
|
512
580
|
- { path: .appweaver/templates/okf-concept-template.md } # OKF v0.1 format authority (frontmatter, index, log, rules) — format only, zero project content
|
|
513
581
|
- id: author_bundle
|
|
582
|
+
condition: "{{bundle_pass}} == true"
|
|
514
583
|
action: agent_generate
|
|
515
584
|
tools: "Read,Write,Edit"
|
|
516
585
|
permission_mode: acceptEdits
|
|
@@ -631,9 +700,10 @@ workflow:
|
|
|
631
700
|
group). Do NOT impose a fixed Domain/Application/UI taxonomy — the CODE's
|
|
632
701
|
folders ARE the grouping. Set `timestamp` to the latest commit time across them.
|
|
633
702
|
Then set `ui_source_files` to the FRONTEND files that serve this aggregate,
|
|
634
|
-
grouped the same way. The substrate
|
|
635
|
-
|
|
636
|
-
|
|
703
|
+
grouped the same way. The substrate proposes them per aggregate (the `ui_files`
|
|
704
|
+
of each aggregate signal, summarised in `ui_attribution`): files under a UI
|
|
705
|
+
feature folder the map names are attributed through the map, the rest by NAME —
|
|
706
|
+
confirm those against what the file actually is and move or drop one it got wrong. Keep the key and leave it EMPTY where the
|
|
637
707
|
aggregate has no UI (and on a backend-only repo, where every concept has none);
|
|
638
708
|
never fold these paths into `source_files`, which stays the service surface.
|
|
639
709
|
- `aggregates/index.md` — the BOUNDED-CONTEXT / feature map (no frontmatter beyond
|
|
@@ -652,7 +722,7 @@ workflow:
|
|
|
652
722
|
|
|
653
723
|
Provenance + safety (OKF hard rules):
|
|
654
724
|
- Stamp every concept `origin: reverse-engineered`, `generated_by:
|
|
655
|
-
|
|
725
|
+
{{generated_by}}` and `bounded_context: {{bc}}` in frontmatter. The
|
|
656
726
|
context key is what lets later commands filter features by the context they
|
|
657
727
|
belong to instead of listing every aggregate under every one.
|
|
658
728
|
- The CODE is the source of truth; capture what IS (quirks included), not what
|
|
@@ -666,16 +736,21 @@ workflow:
|
|
|
666
736
|
- { name: bundle_files, from: "$.files" }
|
|
667
737
|
|
|
668
738
|
- id: verify_authored
|
|
739
|
+
condition: "{{bundle_pass}} == true"
|
|
669
740
|
action: verify_context
|
|
670
741
|
require_non_empty: bundle_files
|
|
671
742
|
on_empty: stop
|
|
672
743
|
on_empty_message: "No feature-map files were written to {{bundle_dir}}. Ensure the substrate {{inventory_json}} has aggregate_signals and re-run."
|
|
673
744
|
|
|
674
745
|
# 4. CONFORMANCE gate — OKF v0.1 validator (errors block; warnings noted).
|
|
746
|
+
# validate exits non-zero on a non-conformant bundle; `on_error: continue` binds the
|
|
747
|
+
# verdict it prints, so the gate below names the errors instead of the run stopping
|
|
748
|
+
# on a bare script failure.
|
|
675
749
|
- id: validate_bundle
|
|
676
750
|
action: execute_script
|
|
677
751
|
script: { ref: inventory }
|
|
678
752
|
subcommand: validate
|
|
753
|
+
on_error: continue
|
|
679
754
|
args: ["--bundle", "{{bundle_dir}}", "--repo-root", "{{root}}"]
|
|
680
755
|
outputs:
|
|
681
756
|
- { name: conformant, from: "$.conformant" }
|
|
@@ -689,6 +764,30 @@ workflow:
|
|
|
689
764
|
on_false: stop
|
|
690
765
|
on_false_message: "The OKF feature map at {{bundle_dir}} is NON-CONFORMANT (errors: {{okf_errors}}). Fix the reported ERRORs (unparseable frontmatter, missing `type`, malformed index.md/log.md) and re-run."
|
|
691
766
|
|
|
767
|
+
# Did every aggregate this context acts on get its concept? The conformance gate checks
|
|
768
|
+
# the files that were written; this checks that the ones the map asked for were. Read
|
|
769
|
+
# back through context-state, the same reader that decides whether the context is
|
|
770
|
+
# onboarded, so a concept it cannot find counts as missing.
|
|
771
|
+
- id: concepts_check
|
|
772
|
+
action: execute_script
|
|
773
|
+
script: { ref: inventory }
|
|
774
|
+
subcommand: context-state
|
|
775
|
+
on_error: continue
|
|
776
|
+
args: ["--context", "{{bc}}", "--bundle", "{{bundle_dir}}"]
|
|
777
|
+
outputs:
|
|
778
|
+
- { name: concepts_complete, from: "$.already_onboarded" }
|
|
779
|
+
- { name: concepts_missing, from: "$.pending_aggregates" }
|
|
780
|
+
- id: concepts_gate
|
|
781
|
+
action: verify_context
|
|
782
|
+
require_value: concepts_complete
|
|
783
|
+
equals: "true"
|
|
784
|
+
on_mismatch: stop
|
|
785
|
+
on_mismatch_message: >
|
|
786
|
+
The bundle at {{bundle_dir}} has no concept for these aggregates of {{bc}}:
|
|
787
|
+
{{concepts_missing}}. Each needs a concept whose `type` names an aggregate and whose
|
|
788
|
+
`title` is the aggregate's name exactly as the map spells it. Re-run onboard for
|
|
789
|
+
{{bc}}; the concepts already written are left as they are.
|
|
790
|
+
|
|
692
791
|
# ═══════════ THE CONTEXT'S SPECS TREE — specs/<Context>/<Feature>/ ═══════════
|
|
693
792
|
# The concepts above say what this context CONTAINS; these two steps make that
|
|
694
793
|
# shape exist where every later command looks for it. Until now a context left
|
|
@@ -760,31 +859,31 @@ workflow:
|
|
|
760
859
|
/appweaver inventory apply, then /appweaver select-feature will offer them.
|
|
761
860
|
|
|
762
861
|
# ═══════════════ PART 2 — GOVERNANCE SCAFFOLD (project-level) ════════════════
|
|
763
|
-
#
|
|
764
|
-
#
|
|
765
|
-
#
|
|
766
|
-
#
|
|
767
|
-
#
|
|
862
|
+
# The first context AUTHORS the governing tier from the whole-repo vantage; every
|
|
863
|
+
# later context AMENDS it additively from its own code (see the flags below).
|
|
864
|
+
# project-context reads the project framing from the OKF bundle only:
|
|
865
|
+
# project_name / overview / project_context (domain evidence) and technical_context
|
|
866
|
+
# (overview + platform: the technical evidence). It never lists adopted features, so
|
|
867
|
+
# a team that re-runs onboard after adopting some still gets a tier evidenced by the
|
|
868
|
+
# code, not by those features' documents.
|
|
768
869
|
|
|
769
870
|
- id: project_ctx
|
|
770
871
|
action: execute_script
|
|
771
872
|
script: { ref: revcon }
|
|
772
|
-
subcommand:
|
|
873
|
+
subcommand: project-context
|
|
773
874
|
outputs:
|
|
774
|
-
- { name:
|
|
775
|
-
- { name: spec_context, from: "$.spec_context" } # at onboard = project_context (no specs yet)
|
|
776
|
-
- { name: design_context, from: "$.design_context" } # at onboard = overview + platform (the tech evidence)
|
|
875
|
+
- { name: technical_context, from: "$.technical_context" } # overview + platform (the tech evidence)
|
|
777
876
|
- { name: project_context, from: "$.project_context" } # overview + aggregates/index + platform + index
|
|
778
877
|
- { name: project_name, from: "$.project_name" }
|
|
779
878
|
- { name: overview, from: "$.overview" }
|
|
780
879
|
|
|
781
880
|
# Slugify + `brf-` prefix the domain name and create guardrails/projects/brf-<domain>/.
|
|
782
|
-
# Name: explicit arg → PROJECT name from the OKF overview →
|
|
783
|
-
#
|
|
881
|
+
# Name: explicit arg → the ACTIVE brf- project → PROJECT name from the OKF overview →
|
|
882
|
+
# repo basename. It reports which tiers already hold rule files, and lists them.
|
|
784
883
|
# The governance project is named from the PROJECT — `gov_name` is empty, so
|
|
785
|
-
# project-setup falls back to the project name from the OKF
|
|
786
|
-
#
|
|
787
|
-
# pack per context and split the project's constitution along context lines,
|
|
884
|
+
# project-setup falls back to the active project, then the project name from the OKF
|
|
885
|
+
# overview, then the repo basename. Passing the bounded context here would create one
|
|
886
|
+
# rule pack per context and split the project's constitution along context lines,
|
|
788
887
|
# which is the aggregate-scoping bias in a new place.
|
|
789
888
|
- id: pack_setup
|
|
790
889
|
action: execute_script
|
|
@@ -797,48 +896,62 @@ workflow:
|
|
|
797
896
|
- { name: domain_rule_bindings, from: "$.domain_rule_bindings" }
|
|
798
897
|
- { name: domain_constitution_source, from: "$.domain_constitution_source" }
|
|
799
898
|
- { name: pack_present, from: "$.pack_present" }
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
899
|
+
- { name: service_present, from: "$.service_present" }
|
|
900
|
+
- { name: frontend_present, from: "$.frontend_present" }
|
|
901
|
+
- { name: domain_files, from: "$.domain_files" }
|
|
902
|
+
- { name: service_files, from: "$.service_files" }
|
|
903
|
+
- { name: frontend_files, from: "$.frontend_files" }
|
|
904
|
+
|
|
905
|
+
# An existing project is the signal that an earlier context authored the tier and
|
|
906
|
+
# this run AMENDS it.
|
|
806
907
|
- id: repo_gov_present
|
|
807
908
|
action: set
|
|
808
909
|
condition: "{{pack_present}} == true"
|
|
809
910
|
vars: { repo_gov: "true" }
|
|
810
911
|
|
|
811
|
-
# WHAT THIS RUN AUTHORS. The engine compares one
|
|
812
|
-
# has no compound conditions, so "this lane
|
|
813
|
-
#
|
|
814
|
-
# asked at each step: default to the
|
|
815
|
-
#
|
|
912
|
+
# WHAT THIS RUN AUTHORS AND WHAT IT AMENDS, PER TIER. The engine compares one
|
|
913
|
+
# variable against one value and has no compound conditions, so "this lane is
|
|
914
|
+
# declared AND its tier does not exist yet" is computed here as ordered sets rather
|
|
915
|
+
# than asked at each step: default to authoring whatever the declaration names, then
|
|
916
|
+
# switch each tier that already exists to amending.
|
|
816
917
|
#
|
|
817
|
-
#
|
|
818
|
-
#
|
|
819
|
-
#
|
|
820
|
-
#
|
|
918
|
+
# Authoring and amending are exclusive per tier, and between them they cover every
|
|
919
|
+
# declared lane, so every constitution half this run can touch is linted below. The
|
|
920
|
+
# document templates follow the author flags only: they are written when their lane's
|
|
921
|
+
# tier is first authored and never amended, because the plans already written follow
|
|
922
|
+
# their shape.
|
|
821
923
|
#
|
|
822
|
-
#
|
|
823
|
-
#
|
|
824
|
-
#
|
|
825
|
-
#
|
|
826
|
-
#
|
|
827
|
-
#
|
|
828
|
-
#
|
|
829
|
-
#
|
|
830
|
-
#
|
|
831
|
-
# amending them ADDITIVELY from a later context — add a rule for a concern this
|
|
832
|
-
# context exhibits, never rewrite or renumber an existing one — would be more
|
|
833
|
-
# evidence at the same project scope rather than one context's bias. That
|
|
834
|
-
# additive pass is not built; author-once is what runs.
|
|
924
|
+
# AMENDING IS ADDITIVE, and that is what makes it safe to do per context. A later
|
|
925
|
+
# context adds what its own code evidences and the tier does not yet say — a rule
|
|
926
|
+
# file for a new concern, rules for a variant an existing file does not state, a
|
|
927
|
+
# principle for a project-level trait no principle covers, its entry in every map —
|
|
928
|
+
# and never rewords, renumbers or deletes what an earlier context wrote. Re-deriving
|
|
929
|
+
# the tier per context would be the aggregate-scoping bias rev-constitution v1.1.0
|
|
930
|
+
# removed; adding one context's evidence at project scope is more evidence, not bias.
|
|
931
|
+
# A contradiction is recorded as a Divergence note under the rule it contradicts, for
|
|
932
|
+
# /appweaver constitution to decide, never resolved here.
|
|
835
933
|
- id: author_flags_default
|
|
836
934
|
action: set
|
|
837
|
-
vars:
|
|
838
|
-
|
|
839
|
-
|
|
935
|
+
vars:
|
|
936
|
+
author_repo: "true"
|
|
937
|
+
author_svc: "{{svc_lane}}"
|
|
938
|
+
author_ui_flag: "{{ui_lane}}"
|
|
939
|
+
gov_mode: "authored — this run wrote the project tier"
|
|
940
|
+
- id: amend_repo_flags
|
|
840
941
|
condition: "{{repo_gov}} == true"
|
|
841
|
-
|
|
942
|
+
action: set
|
|
943
|
+
vars:
|
|
944
|
+
author_repo: "false"
|
|
945
|
+
amend_repo: "true"
|
|
946
|
+
gov_mode: "amended — an earlier context wrote the project tier and this run added {{bc}}'s evidence to it"
|
|
947
|
+
- id: amend_svc_flags
|
|
948
|
+
condition: "{{service_present}} == true"
|
|
949
|
+
action: set
|
|
950
|
+
vars: { author_svc: "false", amend_svc: "{{svc_lane}}" }
|
|
951
|
+
- id: amend_ui_flags
|
|
952
|
+
condition: "{{frontend_present}} == true"
|
|
953
|
+
action: set
|
|
954
|
+
vars: { author_ui_flag: "false", amend_ui: "{{ui_lane}}" }
|
|
842
955
|
|
|
843
956
|
# ── DOMAIN RULE SET (provisional, evidenced by the SCAN) ────────────────────
|
|
844
957
|
# Feed NEUTRAL shape skeletons (rev-templates/, zero content to leak) + the rule-
|
|
@@ -878,11 +991,10 @@ workflow:
|
|
|
878
991
|
vantage — describe the domain / bounded context AS A WHOLE, so any feature later
|
|
879
992
|
slots in without a rewrite.
|
|
880
993
|
|
|
881
|
-
CONCERNS HINT: {{
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
evidences. Ignore any non-concerns text (the domain name / scope hint).
|
|
994
|
+
CONCERNS HINT: {{concerns_line}} Treat any listed concern as a SEARCH HINT — go look
|
|
995
|
+
for it in the code — but you still DECIDE presence from evidence: include a concern's
|
|
996
|
+
rule file ONLY if the code exhibits it, drop a listed concern the code shows none of,
|
|
997
|
+
and ADD an unlisted concern the code clearly evidences.
|
|
886
998
|
|
|
887
999
|
PROVISIONAL BY CONSTRUCTION. Because no slice is adopted, you have the domain's
|
|
888
1000
|
SHAPE (its features, ubiquitous language, bounded-context map, evident concerns)
|
|
@@ -915,7 +1027,7 @@ workflow:
|
|
|
915
1027
|
- domain-requirements.md — the PROJECT overview: open with a
|
|
916
1028
|
`[DOMAIN: Bounded Contexts / Modules]` map (from the overview + aggregates
|
|
917
1029
|
index), then per-subsection pointers, platform topology, governance overrides.
|
|
918
|
-
Stamp every file `origin: reverse-engineered`, `generated_by:
|
|
1030
|
+
Stamp every file `origin: reverse-engineered`, `generated_by: {{generated_by}}`,
|
|
919
1031
|
and note the project is a provisional scaffold reconciled per slice at adopt.
|
|
920
1032
|
|
|
921
1033
|
domain-rule-bindings.md (MANDATORY — /specify's resolve-domain reads this exact filename).
|
|
@@ -947,13 +1059,17 @@ workflow:
|
|
|
947
1059
|
# ── DOMAIN CONSTITUTION SOURCE — <project>/domain/domain-constitution.md ────────────
|
|
948
1060
|
# Named and placed exactly as a greenfield industry corpus names and places its charter,
|
|
949
1061
|
# and already wired as the first `## /aw-spec-constitution` bullet by the step above.
|
|
1062
|
+
# The charter is authored from the domain rule set the step above wrote — its files,
|
|
1063
|
+
# not only the map that lists them. This step has no tools, so every file it cites is
|
|
1064
|
+
# inlined here: `pack_files` is what author_pack reported, narrowed by the engine to
|
|
1065
|
+
# the files actually on disk.
|
|
950
1066
|
- id: ctx_domain_source
|
|
951
1067
|
condition: "{{author_repo}} == true"
|
|
952
1068
|
action: build_context
|
|
953
1069
|
context:
|
|
954
1070
|
- { path: "{{domain_rule_bindings}}" }
|
|
955
1071
|
- { path: .appweaver/orchestrator/rev-templates/domain-constitution.skeleton.md, optional: true }
|
|
956
|
-
context_from: project_context
|
|
1072
|
+
context_from: [project_context, pack_files]
|
|
957
1073
|
- id: author_domain_source
|
|
958
1074
|
condition: "{{author_repo}} == true"
|
|
959
1075
|
action: agent_author
|
|
@@ -962,8 +1078,10 @@ workflow:
|
|
|
962
1078
|
task: |
|
|
963
1079
|
Author the DOMAIN CONSTITUTION SOURCE (the output target) — the human-readable
|
|
964
1080
|
charter for the WHOLE PROJECT **{{project_name}}** (domain {{domain_slug}}),
|
|
965
|
-
scaffolded from the OKF feature map (architecture/overview.md, aggregates/index.md
|
|
966
|
-
|
|
1081
|
+
scaffolded from the OKF feature map (architecture/overview.md, aggregates/index.md)
|
|
1082
|
+
and the project's generated domain rule set — domain-rule-bindings.md and every rule
|
|
1083
|
+
file it maps, all in context. The rule files were read out of the code; they are
|
|
1084
|
+
the deeper evidence, the map the shallower one. Follow the SHAPE of the
|
|
967
1085
|
neutral skeleton domain-constitution.skeleton.md (in context) — its Project-Identity
|
|
968
1086
|
+ Domain-Principle structure — so the normal /appweaver constitution can
|
|
969
1087
|
re-derive the domain half later. The skeleton carries NO content; every value
|
|
@@ -980,7 +1098,8 @@ workflow:
|
|
|
980
1098
|
- `## Domain Principles` — principles the domain embodies, TITLED by DOMAIN CONCERN
|
|
981
1099
|
(not by a feature name), each a declarative rule that would hold across features.
|
|
982
1100
|
Number with a stable "D1, D2, …" convention (the composed constitution assigns
|
|
983
|
-
exact roman numerals after the technology base). Cite the
|
|
1101
|
+
exact roman numerals after the technology base). Cite the evidence — the rule
|
|
1102
|
+
file a principle rests on, or the feature-map line;
|
|
984
1103
|
mark any principle whose exact rule ids are not yet enumerable `PROVISIONAL —
|
|
985
1104
|
reconciled at adopt`.
|
|
986
1105
|
- AS-BUILT: state the rule the code evidences; do NOT prescribe an ideal it does
|
|
@@ -996,9 +1115,9 @@ workflow:
|
|
|
996
1115
|
# EVERY setup-constitution call in this workflow, the UI one included: this command
|
|
997
1116
|
# creates the always-present halves as a side effect of whatever else it is asked to
|
|
998
1117
|
# do, so a later call without the flag silently recreates the half an earlier call
|
|
999
|
-
# was told to skip.
|
|
1118
|
+
# was told to skip. It creates only what is missing and returns every path either way,
|
|
1119
|
+
# so it runs on each pass: an amending run needs the same paths an authoring one does.
|
|
1000
1120
|
- id: setup_constitution
|
|
1001
|
-
condition: "{{author_repo}} == true"
|
|
1002
1121
|
action: execute_script
|
|
1003
1122
|
script: { ref: actions }
|
|
1004
1123
|
subcommand: setup-constitution
|
|
@@ -1007,7 +1126,91 @@ workflow:
|
|
|
1007
1126
|
- { name: constitution_technical_file, from: "$.constitution_technical_file" }
|
|
1008
1127
|
- { name: constitution_domain_file, from: "$.constitution_domain_file" }
|
|
1009
1128
|
|
|
1010
|
-
#
|
|
1129
|
+
# ── AMEND THE SERVICE TIER (a later context, the tier exists) ────────────────
|
|
1130
|
+
# One step for the lane's whole tier — its rule files, its headings in the map and
|
|
1131
|
+
# its constitution half — because a new principle is only ever the ratified line over
|
|
1132
|
+
# a rule this context's code evidences, and the two are decided together. Rules first,
|
|
1133
|
+
# principle second, from THIS context's code: the first context's author read the
|
|
1134
|
+
# whole-repo scan, so what a later context adds is the depth it brings to its own
|
|
1135
|
+
# files. Runs before the domain tier's amendment, which continues this half's
|
|
1136
|
+
# numbering. Changing nothing is a valid outcome, so nothing here gates on a result.
|
|
1137
|
+
- id: ctx_amend_service
|
|
1138
|
+
condition: "{{amend_svc}} == true"
|
|
1139
|
+
action: build_context
|
|
1140
|
+
context:
|
|
1141
|
+
- { path: "{{constitution_technical_file}}" } # the ratified half being amended
|
|
1142
|
+
- { path: "{{pack_dir}}/tech-rule-bindings.md" } # the map being amended
|
|
1143
|
+
- { path: "{{inventory_service_json}}" } # the lane's substrate — locate this context's files
|
|
1144
|
+
- { path: .appweaver/orchestrator/rev-templates/technical-rule-file.skeleton.md, optional: true } # SHAPE ONLY for a new rule file
|
|
1145
|
+
- { path: .appweaver/RULE-PARTITION.md } # which heading a new file may go under
|
|
1146
|
+
# The existing rule files, inlined, plus the overview + platform note this run's
|
|
1147
|
+
# concept author may have added this context's technology to.
|
|
1148
|
+
context_from: [technical_context, service_files]
|
|
1149
|
+
- id: amend_service_tier
|
|
1150
|
+
condition: "{{amend_svc}} == true"
|
|
1151
|
+
action: agent_generate
|
|
1152
|
+
tools: "Read,Write,Edit"
|
|
1153
|
+
permission_mode: acceptEdits
|
|
1154
|
+
task: |
|
|
1155
|
+
AMEND the SERVICE lane's governance for **{{project_name}}** (project
|
|
1156
|
+
{{domain_slug}}) with what bounded context `{{bc}}` evidences. The tier exists — an
|
|
1157
|
+
earlier context authored it — and this run ADDS to it. It never re-authors it.
|
|
1158
|
+
|
|
1159
|
+
THE EVIDENCE IS THIS CONTEXT'S CODE. Its aggregates: {{bc_aggregates}} (features:
|
|
1160
|
+
{{bc_features}}). Each has a concept under {{bundle_dir}}/aggregates/ whose `title`
|
|
1161
|
+
is the aggregate's name, and its `source_files` are this context's service code.
|
|
1162
|
+
Read those concepts, then READ the source they list — enough to see how this
|
|
1163
|
+
context handles each technology concern. {{inventory_service_json}} (in context) is
|
|
1164
|
+
the whole lane's substrate, for anything the concepts do not list.
|
|
1165
|
+
|
|
1166
|
+
WHAT EXISTS (in context): every rule file in {{pack_dir}}/service/, the map
|
|
1167
|
+
{{pack_dir}}/tech-rule-bindings.md and the technical half
|
|
1168
|
+
{{constitution_technical_file}}. Read all of it before writing anything.
|
|
1169
|
+
|
|
1170
|
+
WHAT YOU MAY ADD — and only add:
|
|
1171
|
+
- A NEW rule file `{{pack_dir}}/service/<concern>.md` for a technology concern this
|
|
1172
|
+
context's code exhibits and no existing file covers. Same shape as the existing
|
|
1173
|
+
files (frontmatter origin: reverse-engineered, generated_by: {{generated_by}},
|
|
1174
|
+
concern); every rule cites a code coordinate from this context and the numeral
|
|
1175
|
+
of the principle it details. Wire it into tech-rule-bindings.md under the
|
|
1176
|
+
headings its rules serve (RULE-PARTITION.md, in context) and give it a row in
|
|
1177
|
+
the quick-reference table. Nothing but service/domain-modelling.md ever goes
|
|
1178
|
+
under `## /aw-spec-specify`.
|
|
1179
|
+
- NEW rules appended to an EXISTING file, where this context shows a form of that
|
|
1180
|
+
concern the file does not state — each citing this context's coordinate and
|
|
1181
|
+
marked `(context: {{bc}})`.
|
|
1182
|
+
- A NEW principle in the technical half, only for a PROJECT-level technology trait
|
|
1183
|
+
this context evidences and no principle covers. Append it after the last one
|
|
1184
|
+
with the next roman numeral, citing its evidence and marked `PROVISIONAL — code
|
|
1185
|
+
coordinate reconciled at adopt` where the exact coordinate is not pinned.
|
|
1186
|
+
NEVER reword, reorder, renumber or delete an existing rule, principle, map bullet
|
|
1187
|
+
or heading, and never touch the evidence another context contributed. Add no
|
|
1188
|
+
domain-specific principle, identifier or terminology — this tier is domain-free.
|
|
1189
|
+
|
|
1190
|
+
A CONFLICT IS RECORDED, NOT RESOLVED. Where this context's code does what an
|
|
1191
|
+
existing rule or principle says the code does not do (or the reverse), leave that
|
|
1192
|
+
text as it is and add under it one line:
|
|
1193
|
+
`Divergence ({{bc}}): <what this code does> (evidence: <path>)`.
|
|
1194
|
+
Name every divergence in the half's Sync Impact Report as needing a decision
|
|
1195
|
+
through /appweaver constitution.
|
|
1196
|
+
|
|
1197
|
+
WHEN YOU CHANGE THE HALF: bump its version — MINOR for a new principle, PATCH when
|
|
1198
|
+
only a divergence note was added — set Last Amended to today and keep Ratified;
|
|
1199
|
+
replace the leading Sync Impact Report comment with one for this amendment
|
|
1200
|
+
(version old→new, what was added or noted and from which context); and if the
|
|
1201
|
+
principle count moved, update the hand-off line ("Technical principles: I–<N>;
|
|
1202
|
+
domain half continues at <N+1>").
|
|
1203
|
+
|
|
1204
|
+
CHANGING NOTHING IS A VALID OUTCOME. If the tier already covers everything this
|
|
1205
|
+
context's code shows, write no file and say so.
|
|
1206
|
+
Write ONLY inside {{pack_dir}}/service/, {{pack_dir}}/tech-rule-bindings.md and
|
|
1207
|
+
{{constitution_technical_file}} — the domain tier and the frontend lane are
|
|
1208
|
+
amended by their own steps. Modify no source. Report the files you changed (an
|
|
1209
|
+
empty list when none) and, per change, the concern and the code path evidencing it.
|
|
1210
|
+
outputs:
|
|
1211
|
+
- { name: amended_service_files, from: "$.files" }
|
|
1212
|
+
|
|
1213
|
+
# TECHNICAL HALF — from the OKF overview + platform note (technical_context), DOMAIN-FREE.
|
|
1011
1214
|
# The neutral technical shape skeleton is fed via CONTEXT (not the sticky standards
|
|
1012
1215
|
# set, which is empty), so nothing leaks into the Part-1 feature-map agent.
|
|
1013
1216
|
- id: ctx_technical
|
|
@@ -1017,7 +1220,7 @@ workflow:
|
|
|
1017
1220
|
- { path: "{{constitution_technical_file}}" }
|
|
1018
1221
|
- { path: .appweaver/orchestrator/rev-templates/technical-constitution.skeleton.md, optional: true }
|
|
1019
1222
|
- { path: .appweaver/orchestrator/rev-templates/ai-rules.reference.md, optional: true }
|
|
1020
|
-
context_from:
|
|
1223
|
+
context_from: technical_context
|
|
1021
1224
|
- id: author_technical
|
|
1022
1225
|
action: agent_author
|
|
1023
1226
|
condition: "{{author_svc}} == true"
|
|
@@ -1061,9 +1264,11 @@ workflow:
|
|
|
1061
1264
|
the technical count / domain hand-off numeral, and dependent artifacts (✅/⚠).
|
|
1062
1265
|
Return the complete updated technical constitution content only.
|
|
1063
1266
|
|
|
1267
|
+
# Authored or amended, the half is linted: with a service lane declared, one of the
|
|
1268
|
+
# two ran.
|
|
1064
1269
|
- id: technical_validation_loop
|
|
1065
1270
|
action: loop
|
|
1066
|
-
condition: "{{
|
|
1271
|
+
condition: "{{svc_lane}} == true"
|
|
1067
1272
|
while: "{{technical_ok}} != true"
|
|
1068
1273
|
max_iterations: 3
|
|
1069
1274
|
steps:
|
|
@@ -1105,10 +1310,11 @@ workflow:
|
|
|
1105
1310
|
# order the technical tier already uses in this workflow.
|
|
1106
1311
|
|
|
1107
1312
|
# Create the UI half from its template — on demand, unlike the other two. Its
|
|
1108
|
-
# ABSENCE is meaningful: a repo with no UI never gets the file at all.
|
|
1313
|
+
# ABSENCE is meaningful: a repo with no UI never gets the file at all. Where the half
|
|
1314
|
+
# exists it is left alone and its path returned, for the amending step below.
|
|
1109
1315
|
- id: setup_ui_constitution
|
|
1110
1316
|
action: execute_script
|
|
1111
|
-
condition: "{{
|
|
1317
|
+
condition: "{{ui_lane}} == true"
|
|
1112
1318
|
script: { ref: actions }
|
|
1113
1319
|
subcommand: setup-constitution
|
|
1114
1320
|
args: ["--ui", "{{setup_tech_flag}}"]
|
|
@@ -1116,12 +1322,91 @@ workflow:
|
|
|
1116
1322
|
- { name: constitution_ui_file, from: "$.constitution_ui_file" }
|
|
1117
1323
|
- { name: ui_created, from: "$.ui_created" }
|
|
1118
1324
|
|
|
1325
|
+
# ── AMEND THE FRONTEND TIER (a later context, the tier exists) ───────────────
|
|
1326
|
+
# The frontend lane's twin of the service amendment above: its rule files, its three
|
|
1327
|
+
# headings in the map and the UX-* half, from this context's UI code. A lane declared
|
|
1328
|
+
# after an earlier onboard has no tier yet, so it takes the authoring path below
|
|
1329
|
+
# instead — this step never runs for it.
|
|
1330
|
+
- id: ctx_amend_ui
|
|
1331
|
+
condition: "{{amend_ui}} == true"
|
|
1332
|
+
action: build_context
|
|
1333
|
+
context:
|
|
1334
|
+
- { path: "{{constitution_ui_file}}" } # the ratified UX-* half being amended
|
|
1335
|
+
- { path: "{{pack_dir}}/tech-rule-bindings.md" } # the map whose UI headings are amended
|
|
1336
|
+
- { path: "{{inventory_ui_json}}" } # the lane's substrate — locate this context's UI files
|
|
1337
|
+
- { path: .appweaver/orchestrator/rev-templates/frontend-rule-file.skeleton.md, optional: true } # SHAPE ONLY for a new rule file
|
|
1338
|
+
- { path: .appweaver/RULE-PARTITION.md }
|
|
1339
|
+
- { path: "{{bundle_dir}}/architecture/frontend.md", optional: true } # the shared UI surface, as the bundle records it
|
|
1340
|
+
context_from: frontend_files
|
|
1341
|
+
- id: amend_ui_tier
|
|
1342
|
+
condition: "{{amend_ui}} == true"
|
|
1343
|
+
action: agent_generate
|
|
1344
|
+
tools: "Read,Write,Edit"
|
|
1345
|
+
permission_mode: acceptEdits
|
|
1346
|
+
task: |
|
|
1347
|
+
AMEND the FRONTEND lane's governance for **{{project_name}}** (project
|
|
1348
|
+
{{domain_slug}}) with what bounded context `{{bc}}` evidences. The tier exists — an
|
|
1349
|
+
earlier context authored it — and this run ADDS to it. It never re-authors it.
|
|
1350
|
+
|
|
1351
|
+
THE EVIDENCE IS THIS CONTEXT'S UI CODE. Its aggregates: {{bc_aggregates}}
|
|
1352
|
+
(features: {{bc_features}}). Each has a concept under {{bundle_dir}}/aggregates/
|
|
1353
|
+
whose `title` is the aggregate's name, and its `ui_source_files` are the UI files
|
|
1354
|
+
serving it. Read those concepts, then READ the UI source they list — enough to see
|
|
1355
|
+
how this context's screens handle each experience concern. {{inventory_ui_json}}
|
|
1356
|
+
(in context) is the whole lane's substrate. The shared UI surface (app shell,
|
|
1357
|
+
layout, design system) belongs to no context and is already governed; amend it
|
|
1358
|
+
only where this context's screens show something the tier does not state.
|
|
1359
|
+
|
|
1360
|
+
WHAT EXISTS (in context): every rule file in {{pack_dir}}/frontend/, the map
|
|
1361
|
+
{{pack_dir}}/tech-rule-bindings.md and the UX half {{constitution_ui_file}}. Read
|
|
1362
|
+
all of it before writing anything.
|
|
1363
|
+
|
|
1364
|
+
WHAT YOU MAY ADD — and only add:
|
|
1365
|
+
- A NEW rule file `{{pack_dir}}/frontend/<concern>.md` for an experience concern
|
|
1366
|
+
this context's UI exhibits and no existing file covers. Same shape as the
|
|
1367
|
+
existing files (frontmatter origin: reverse-engineered, generated_by:
|
|
1368
|
+
{{generated_by}}, concern); every rule cites a UI code coordinate from this
|
|
1369
|
+
context and the UX numeral it details. Wire it into tech-rule-bindings.md under
|
|
1370
|
+
`## /aw-spec-plan-ui` and/or `## /aw-spec-implement-ui` as its rules serve
|
|
1371
|
+
planning or generating, and give it its table row. frontend/ui-constitution.md
|
|
1372
|
+
stays the only file under `## /aw-spec-ui-constitution` that is not also a
|
|
1373
|
+
concern file.
|
|
1374
|
+
- NEW rules appended to an EXISTING file, where this context shows a form of that
|
|
1375
|
+
concern the file does not state — each citing this context's coordinate and
|
|
1376
|
+
marked `(context: {{bc}})`.
|
|
1377
|
+
- A NEW principle in the UX half, only for a lane-wide experience trait this
|
|
1378
|
+
context evidences and no principle covers. Append it with the next UX-* numeral.
|
|
1379
|
+
NEVER reword, reorder, renumber or delete an existing rule, principle, map bullet
|
|
1380
|
+
or heading, never touch the service lane's headings or files, and add no
|
|
1381
|
+
domain-specific principle, identifier or terminology.
|
|
1382
|
+
|
|
1383
|
+
A CONFLICT IS RECORDED, NOT RESOLVED. Where this context's UI does what an
|
|
1384
|
+
existing rule or principle says the UI does not do (or the reverse), leave that
|
|
1385
|
+
text as it is and add under it one line:
|
|
1386
|
+
`Divergence ({{bc}}): <what this UI does> (evidence: <path>)`.
|
|
1387
|
+
Name every divergence in the half's Sync Impact Report as needing a decision
|
|
1388
|
+
through /appweaver constitution.
|
|
1389
|
+
|
|
1390
|
+
WHEN YOU CHANGE THE HALF: bump its version — MINOR for a new principle, PATCH when
|
|
1391
|
+
only a divergence note was added — set Last Amended to today and keep Ratified,
|
|
1392
|
+
and replace the leading Sync Impact Report comment with one for this amendment
|
|
1393
|
+
(version old→new, what was added or noted and from which context).
|
|
1394
|
+
|
|
1395
|
+
CHANGING NOTHING IS A VALID OUTCOME. If the tier already covers everything this
|
|
1396
|
+
context's UI shows, write no file and say so.
|
|
1397
|
+
Write ONLY inside {{pack_dir}}/frontend/, the UI headings and table rows of
|
|
1398
|
+
{{pack_dir}}/tech-rule-bindings.md, and {{constitution_ui_file}}. Modify no source.
|
|
1399
|
+
Report the files you changed (an empty list when none) and, per change, the
|
|
1400
|
+
concern and the code path evidencing it.
|
|
1401
|
+
outputs:
|
|
1402
|
+
- { name: amended_ui_files, from: "$.files" }
|
|
1403
|
+
|
|
1119
1404
|
- id: ctx_ui
|
|
1120
1405
|
action: build_context
|
|
1121
1406
|
condition: "{{author_ui_flag}} == true"
|
|
1122
1407
|
context:
|
|
1123
1408
|
- { path: "{{constitution_ui_file}}" } # the target half being filled
|
|
1124
|
-
- { path: "{{
|
|
1409
|
+
- { path: "{{inventory_ui_json}}" } # PRIMARY: the substrate's UI view — frontend_signals + the UI file lists to read source from
|
|
1125
1410
|
- { path: .appweaver/orchestrator/rev-templates/ui-constitution.skeleton.md, optional: true } # SHAPE ONLY: heading style, Sync-Impact-Report shape, evidence-line pattern (zero UI content)
|
|
1126
1411
|
- { path: "{{bundle_dir}}/architecture/frontend.md", optional: true } # SECONDARY (shallow): the OKF as-built frontend note — corroborate, don't rely on alone
|
|
1127
1412
|
- id: author_ui
|
|
@@ -1137,10 +1422,10 @@ workflow:
|
|
|
1137
1422
|
base it runs parallel to.
|
|
1138
1423
|
Why this lane was detected: {{ui_evidence}}
|
|
1139
1424
|
Lane declaration: {{ui_declaration_note}}
|
|
1140
|
-
|
|
1425
|
+
Concerns hint: {{concerns_line}} A hint only — the UI code decides what is present.
|
|
1141
1426
|
|
|
1142
1427
|
EVIDENCE = THE UI CODE ITSELF (deep read). Authority, in order:
|
|
1143
|
-
1. THE ACTUAL UI SOURCE (ground truth). Use {{
|
|
1428
|
+
1. THE ACTUAL UI SOURCE (ground truth). Use {{inventory_ui_json}} (in context):
|
|
1144
1429
|
`frontend_signals` lists the candidate lane roots with their kind
|
|
1145
1430
|
(spa / server-rendered / desktop), their framework markers, and their
|
|
1146
1431
|
component / route / store / style file lists. READ ENOUGH OF THOSE FILES to
|
|
@@ -1195,7 +1480,7 @@ workflow:
|
|
|
1195
1480
|
|
|
1196
1481
|
- id: ui_validation_loop
|
|
1197
1482
|
action: loop
|
|
1198
|
-
condition: "{{
|
|
1483
|
+
condition: "{{ui_lane}} == true"
|
|
1199
1484
|
while: "{{ui_ok}} != true"
|
|
1200
1485
|
max_iterations: 3
|
|
1201
1486
|
steps:
|
|
@@ -1228,14 +1513,110 @@ workflow:
|
|
|
1228
1513
|
# repo no half was created, so the run reports that rather than a bare false a reader
|
|
1229
1514
|
# would take for a half that needs a manual touch.
|
|
1230
1515
|
- id: ui_validation_state_absent
|
|
1231
|
-
condition: "{{author_repo}} == true"
|
|
1232
1516
|
action: set
|
|
1233
1517
|
vars: { ui_validation_state: "n/a — no frontend lane, no UI half authored" }
|
|
1234
1518
|
- id: ui_validation_state_present
|
|
1235
1519
|
action: set
|
|
1236
|
-
condition: "{{
|
|
1520
|
+
condition: "{{ui_lane}} == true"
|
|
1237
1521
|
vars: { ui_validation_state: "{{ui_ok}}" }
|
|
1238
1522
|
|
|
1523
|
+
# ── AMEND THE DOMAIN TIER (a later context, the tier exists) ─────────────────
|
|
1524
|
+
# The domain rule set, its map, the charter and the domain half, from this context's
|
|
1525
|
+
# domain-carrying code. It runs AFTER both lane halves are settled because the domain
|
|
1526
|
+
# half continues the technical half's numerals: a technical principle added above
|
|
1527
|
+
# moves where the domain series starts, and this is the one step allowed to shift it.
|
|
1528
|
+
# The context maps the tier keeps — the bounded-context/feature map, the requirements
|
|
1529
|
+
# overview's context list, the charter's Project Identity — must carry this context,
|
|
1530
|
+
# so a newly onboarded context always has at least that to write.
|
|
1531
|
+
- id: ctx_amend_domain
|
|
1532
|
+
condition: "{{amend_repo}} == true"
|
|
1533
|
+
action: build_context
|
|
1534
|
+
context:
|
|
1535
|
+
- { path: "{{domain_rule_bindings}}" }
|
|
1536
|
+
- { path: "{{constitution_domain_file}}" }
|
|
1537
|
+
- { path: "{{constitution_technical_file}}", optional: true } # the numerals the domain half continues (absent with no service lane)
|
|
1538
|
+
- { path: .appweaver/orchestrator/rev-templates/domain-rule-file.skeleton.md, optional: true } # SHAPE ONLY for a new rule file
|
|
1539
|
+
- { path: .appweaver/RULE-PARTITION.md }
|
|
1540
|
+
# The existing domain rule files (the charter and the requirements overview among
|
|
1541
|
+
# them), inlined, plus the bundle framing this run just extended with the context.
|
|
1542
|
+
context_from: [project_context, domain_files]
|
|
1543
|
+
- id: amend_domain_tier
|
|
1544
|
+
condition: "{{amend_repo}} == true"
|
|
1545
|
+
action: agent_generate
|
|
1546
|
+
tools: "Read,Write,Edit"
|
|
1547
|
+
permission_mode: acceptEdits
|
|
1548
|
+
task: |
|
|
1549
|
+
AMEND the DOMAIN governance of **{{project_name}}** (project {{domain_slug}}) with
|
|
1550
|
+
bounded context `{{bc}}`. The tier exists — an earlier context authored it — and
|
|
1551
|
+
this run ADDS this context to it. It never re-authors it.
|
|
1552
|
+
|
|
1553
|
+
THE EVIDENCE IS THIS CONTEXT'S CODE. Its aggregates: {{bc_aggregates}} (features:
|
|
1554
|
+
{{bc_features}}; which feature acts on which: {{bc_feature_aggregates}}). Each has
|
|
1555
|
+
a concept under {{bundle_dir}}/aggregates/ whose `title` is the aggregate's name
|
|
1556
|
+
and whose `source_files` list its code. Read those concepts, then READ the
|
|
1557
|
+
domain-carrying files among them — entities, value objects, invariant checks,
|
|
1558
|
+
validation, domain events — enough to state each rule from what the code actually
|
|
1559
|
+
enforces. The OKF overview and aggregates/index.md (in context) already carry this
|
|
1560
|
+
context.
|
|
1561
|
+
|
|
1562
|
+
WHAT EXISTS (in context): every file in {{pack_dir}}/domain/ — the rule files, the
|
|
1563
|
+
requirements overview and the charter {{domain_constitution_source}} — the map
|
|
1564
|
+
{{domain_rule_bindings}}, and the domain half {{constitution_domain_file}}. Read
|
|
1565
|
+
all of it before writing anything.
|
|
1566
|
+
|
|
1567
|
+
WHAT YOU MUST ADD — this context's place in every map the tier keeps, in each
|
|
1568
|
+
file that has one: the bounded-context / feature map and ubiquitous language
|
|
1569
|
+
(domain-model.domain.md, where it exists), the `[DOMAIN: Bounded Contexts /
|
|
1570
|
+
Modules]` map (domain-requirements.md, where it exists), the charter's Project
|
|
1571
|
+
Identity context map, and the domain half's identity / context map. Add `{{bc}}`
|
|
1572
|
+
with its aggregates, its features and the terms its code uses wherever a map does
|
|
1573
|
+
not carry it yet (a re-run for an onboarded context usually finds it there); leave
|
|
1574
|
+
every other context's entry as it is.
|
|
1575
|
+
|
|
1576
|
+
WHAT YOU MAY ADD — and only add:
|
|
1577
|
+
- A NEW rule file `{{pack_dir}}/domain/<concern>.domain.md` for a domain concern
|
|
1578
|
+
this context's code exhibits and no existing file covers, in the existing
|
|
1579
|
+
files' shape (origin: reverse-engineered, generated_by: {{generated_by}}),
|
|
1580
|
+
named after the concern the code exhibits. Wire it into
|
|
1581
|
+
domain-rule-bindings.md under `## /aw-spec-specify` and `## /aw-spec-gate`
|
|
1582
|
+
(plus `## /aw-spec-constitution` for an identity / regulatory file), as the
|
|
1583
|
+
existing files are wired. `## /aw-spec-plan` and `## /aw-spec-implement` keep
|
|
1584
|
+
loading no domain file.
|
|
1585
|
+
- NEW rules appended to an EXISTING rule file, where this context's code enforces
|
|
1586
|
+
a rule of that concern the file does not state — each citing this context's code
|
|
1587
|
+
and marked `(context: {{bc}})`. Mark unresolved specifics `PROVISIONAL —
|
|
1588
|
+
reconciled at adopt`.
|
|
1589
|
+
- A NEW principle in the charter (the next D-n) and in the domain half, only for a
|
|
1590
|
+
project-level domain trait this context evidences and no principle covers.
|
|
1591
|
+
NEVER reword, reorder or delete an existing rule, principle, map bullet or entry,
|
|
1592
|
+
and never touch another context's evidence. Never invent a rule the code does not
|
|
1593
|
+
evidence.
|
|
1594
|
+
|
|
1595
|
+
NUMBERING. The domain half continues the technical half's roman numerals: its
|
|
1596
|
+
first principle is the technical half's last numeral + 1 (the technical half is in
|
|
1597
|
+
context; with no service lane the series starts at I). If the domain half no longer
|
|
1598
|
+
starts there — a technical principle was added earlier in this run — renumber the
|
|
1599
|
+
domain principles IN ORDER to resume at the right numeral, keeping every title and
|
|
1600
|
+
text, and record the shift in its Sync Impact Report. That is the only renumbering
|
|
1601
|
+
you may do. A new domain principle takes the next numeral after the last one.
|
|
1602
|
+
|
|
1603
|
+
A CONFLICT IS RECORDED, NOT RESOLVED. Where this context's code contradicts an
|
|
1604
|
+
existing rule or principle, leave that text as it is and add under it one line:
|
|
1605
|
+
`Divergence ({{bc}}): <what this code does> (evidence: <path>)`, and name it in the
|
|
1606
|
+
domain half's Sync Impact Report as needing a decision through /appweaver
|
|
1607
|
+
constitution.
|
|
1608
|
+
|
|
1609
|
+
THE DOMAIN HALF: bump its version — MINOR for a new principle, PATCH for context-
|
|
1610
|
+
map entries, divergence notes or a numeral shift — set Last Amended to today and
|
|
1611
|
+
keep Ratified, and replace the leading Sync Impact Report comment with one for this
|
|
1612
|
+
amendment (version old→new, what was added and from which context).
|
|
1613
|
+
|
|
1614
|
+
Write ONLY inside {{pack_dir}}/domain/, {{domain_rule_bindings}} and
|
|
1615
|
+
{{constitution_domain_file}}. Modify no source. Report the files you changed and,
|
|
1616
|
+
per change, what was added and the code path evidencing it.
|
|
1617
|
+
outputs:
|
|
1618
|
+
- { name: amended_domain_files, from: "$.files" }
|
|
1619
|
+
|
|
1239
1620
|
# DOMAIN HALF — from the project + charter, principles continue the technical numbering.
|
|
1240
1621
|
- id: ctx_domain
|
|
1241
1622
|
condition: "{{author_repo}} == true"
|
|
@@ -1245,7 +1626,8 @@ workflow:
|
|
|
1245
1626
|
- { path: "{{constitution_technical_file}}" } # to CONTINUE its numbering (evidenced-only ⇒ not a fixed XV)
|
|
1246
1627
|
- { path: "{{domain_constitution_source}}" }
|
|
1247
1628
|
- { path: "{{domain_rule_bindings}}" }
|
|
1248
|
-
|
|
1629
|
+
# The domain rule files themselves, inlined: this step has no tools to read them by path.
|
|
1630
|
+
context_from: [project_context, pack_files]
|
|
1249
1631
|
- id: author_domain
|
|
1250
1632
|
condition: "{{author_repo}} == true"
|
|
1251
1633
|
action: agent_author
|
|
@@ -1254,9 +1636,9 @@ workflow:
|
|
|
1254
1636
|
task: |
|
|
1255
1637
|
Scaffold the DOMAIN ADDENDA constitution for the WHOLE PROJECT **{{project_name}}**
|
|
1256
1638
|
(domain {{domain_slug}}) — the target file in context — AS-BUILT and PROVISIONAL,
|
|
1257
|
-
from the OKF project context (overview, aggregates/index
|
|
1258
|
-
|
|
1259
|
-
|
|
1639
|
+
from the OKF project context (overview, aggregates/index) + the domain-constitution
|
|
1640
|
+
source + the project's generated domain rule set (domain-rule-bindings.md and every
|
|
1641
|
+
rule file it maps) — all in context. It is a TEMPLATE
|
|
1260
1642
|
with [ALL_CAPS] tokens; this half carries ONLY domain material.
|
|
1261
1643
|
- Name the SAME project as the technical half / charter: title / any [PROJECT_NAME]
|
|
1262
1644
|
token = {{project_name}}. This is a PROJECT constitution, not an aggregate spec —
|
|
@@ -1287,8 +1669,8 @@ workflow:
|
|
|
1287
1669
|
principles, dependent artifacts ✅/⚠ + TODOs).
|
|
1288
1670
|
Return the complete updated domain addenda content only.
|
|
1289
1671
|
|
|
1672
|
+
# The domain half is authored or amended on every run, so it is linted on every run.
|
|
1290
1673
|
- id: domain_validation_loop
|
|
1291
|
-
condition: "{{author_repo}} == true"
|
|
1292
1674
|
action: loop
|
|
1293
1675
|
while: "{{domain_ok}} != true"
|
|
1294
1676
|
max_iterations: 3
|
|
@@ -1320,7 +1702,6 @@ workflow:
|
|
|
1320
1702
|
|
|
1321
1703
|
# ── COMPOSE + ACTIVATE ───────────────────────────────────────────────────────
|
|
1322
1704
|
- id: compose_constitution
|
|
1323
|
-
condition: "{{author_repo}} == true"
|
|
1324
1705
|
action: execute_script
|
|
1325
1706
|
script: { ref: actions }
|
|
1326
1707
|
subcommand: compose-constitution
|
|
@@ -1343,7 +1724,6 @@ workflow:
|
|
|
1343
1724
|
# Ordered override — the var holds "ok" unless the check reported a problem, because
|
|
1344
1725
|
# require_non_empty reports on EMPTY.
|
|
1345
1726
|
- id: numbering_default
|
|
1346
|
-
condition: "{{author_repo}} == true"
|
|
1347
1727
|
action: set
|
|
1348
1728
|
vars: { numbering_gate: "ok" }
|
|
1349
1729
|
- id: numbering_detect
|
|
@@ -1351,7 +1731,6 @@ workflow:
|
|
|
1351
1731
|
condition: "{{numbering_ok}} == false"
|
|
1352
1732
|
vars: { numbering_gate: "" }
|
|
1353
1733
|
- id: numbering_warning
|
|
1354
|
-
condition: "{{author_repo}} == true"
|
|
1355
1734
|
action: verify_context
|
|
1356
1735
|
require_non_empty: numbering_gate
|
|
1357
1736
|
on_empty: continue
|
|
@@ -1365,9 +1744,9 @@ workflow:
|
|
|
1365
1744
|
constitution.md was still written so the clash is visible.
|
|
1366
1745
|
|
|
1367
1746
|
# Auto-activate: point .appweaver/domain.json at the scaffolded project so the forward CR
|
|
1368
|
-
# loop governs development with it from the first change.
|
|
1747
|
+
# loop governs development with it from the first change. Every pass activates it, so
|
|
1748
|
+
# the project this run authored or amended is the one the pipeline reads afterwards.
|
|
1369
1749
|
- id: activate_domain
|
|
1370
|
-
condition: "{{author_repo}} == true"
|
|
1371
1750
|
action: execute_script
|
|
1372
1751
|
script: { ref: actions }
|
|
1373
1752
|
subcommand: set-domain
|
|
@@ -1395,19 +1774,20 @@ workflow:
|
|
|
1395
1774
|
# 2. guardrails/projects/<domain>/tech-rule-bindings.md — the TECHNICAL map (resolve-tech +
|
|
1396
1775
|
# tech-select read it by that exact name), wiring the generated files per-workflow.
|
|
1397
1776
|
# Because onboard already ACTIVATED brf-<domain>, the forward pipeline's + adopt's tech_select
|
|
1398
|
-
# steps now resolve to THESE files — never another project's rules, ever. The
|
|
1399
|
-
#
|
|
1777
|
+
# steps now resolve to THESE files — never another project's rules, ever. The files live
|
|
1778
|
+
# inside pack_dir, so a later context does not author them again: service_present switches
|
|
1779
|
+
# the lane to amend_service_tier above, which only adds to them.
|
|
1400
1780
|
- id: ctx_tech_pack
|
|
1401
1781
|
action: build_context
|
|
1402
1782
|
condition: "{{author_svc}} == true"
|
|
1403
1783
|
context:
|
|
1404
|
-
- { path: "{{
|
|
1784
|
+
- { path: "{{inventory_service_json}}" } # PRIMARY: the substrate's service view — read representative SOURCE from its file lists
|
|
1405
1785
|
- { path: "{{constitution_technical_file}}" } # PRIMARY: the VALIDATED as-built technology base — the ratified principles these files detail
|
|
1406
1786
|
- { path: .appweaver/orchestrator/rev-templates/tech-rule-bindings.skeleton.md, optional: true } # SHAPE ONLY: the technical map's headings + partition + table (zero real files)
|
|
1407
1787
|
- { path: .appweaver/orchestrator/rev-templates/technical-rule-file.skeleton.md, optional: true } # SHAPE ONLY: one code-derived tech rule file's shape (zero real tech)
|
|
1408
1788
|
- { path: .appweaver/RULE-PARTITION.md } # the rule-partition authority (which command reads what)
|
|
1409
1789
|
- { path: "{{bundle_dir}}/architecture/platform.md", optional: true } # SECONDARY (shallow): the OKF as-built platform note — corroborate, don't rely on alone
|
|
1410
|
-
context_from:
|
|
1790
|
+
context_from: technical_context
|
|
1411
1791
|
- id: author_tech_pack
|
|
1412
1792
|
action: agent_generate
|
|
1413
1793
|
condition: "{{author_svc}} == true"
|
|
@@ -1418,14 +1798,14 @@ workflow:
|
|
|
1418
1798
|
{{domain_slug}}) — the CODE-DERIVED replacement for the greenfield technical rule set —
|
|
1419
1799
|
into guardrails/projects/{{domain_slug}}/service/ (create it), plus the technical map
|
|
1420
1800
|
guardrails/projects/{{domain_slug}}/tech-rule-bindings.md. This is the TECHNICAL twin of the
|
|
1421
|
-
already-generated domain set: it feeds the HOW phases (
|
|
1801
|
+
already-generated domain set: it feeds the HOW phases (plan/implement/build/…) plus
|
|
1422
1802
|
ONE modelling-methodology file for /specify (see domain-modelling below) — and nothing
|
|
1423
1803
|
else ever reaches /specify from this tier.
|
|
1424
1804
|
|
|
1425
1805
|
EVIDENCE = THE CODE ITSELF (deep read) + THE VALIDATED TECHNICAL CONSTITUTION. Authority,
|
|
1426
1806
|
in order:
|
|
1427
|
-
1. THE ACTUAL SOURCE CODE (ground truth). Use {{
|
|
1428
|
-
representative files across top_level_dirs + a few aggregate_signals, and Read enough
|
|
1807
|
+
1. THE ACTUAL SOURCE CODE (ground truth). Use {{inventory_service_json}} (in context) to
|
|
1808
|
+
locate representative files across top_level_dirs + a few aggregate_signals, and Read enough
|
|
1429
1809
|
to state each technical rule from what the code ACTUALLY does — the folder/tier/module
|
|
1430
1810
|
convention, the dependency direction, the persistence approach, concurrency handling,
|
|
1431
1811
|
testing convention, the auth/cross-cutting posture. Do NOT assert structure you have
|
|
@@ -1439,17 +1819,16 @@ workflow:
|
|
|
1439
1819
|
greenfield fixture, NOT this project's rules. Every path you write lives under
|
|
1440
1820
|
guardrails/projects/{{domain_slug}}/service/.
|
|
1441
1821
|
|
|
1442
|
-
CONCERNS HINT: {{
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
non-concerns text.
|
|
1822
|
+
CONCERNS HINT: {{concerns_line}} Treat any listed concern as a SEARCH HINT — look for it
|
|
1823
|
+
in the code — but DECIDE presence from evidence: write a tech rule file for a concern ONLY
|
|
1824
|
+
if the code exhibits it, drop a listed concern the code shows none of, and ADD an unlisted
|
|
1825
|
+
concern the code clearly evidences.
|
|
1447
1826
|
|
|
1448
1827
|
EVIDENCED-ONLY (lean). Write a `service/<concern>.md` ONLY for a technology concern the code
|
|
1449
1828
|
actually exhibits — e.g. as-built-architecture, persistence, concurrency, testing,
|
|
1450
1829
|
security-posture, api-surface, eventing, observability, hosting. Follow the SHAPE of
|
|
1451
1830
|
technical-rule-file.skeleton.md (in context): frontmatter (origin: reverse-engineered,
|
|
1452
|
-
generated_by:
|
|
1831
|
+
generated_by: {{generated_by}}, concern), a one-line framing, rules each citing a CODE
|
|
1453
1832
|
COORDINATE (real file/folder path or named type) + the constitution principle numeral where
|
|
1454
1833
|
it maps. The skeleton carries NO real technology — copy the shape only. State stubs/partials
|
|
1455
1834
|
AS-BUILT (do not upgrade a stub into a greenfield ideal); omit a concern the code shows none
|
|
@@ -1480,12 +1859,12 @@ workflow:
|
|
|
1480
1859
|
ONLY a heading you have a generated file for (an absent heading soft-continues → loads
|
|
1481
1860
|
nothing):
|
|
1482
1861
|
- `## /aw-spec-specify` — EXACTLY ONE bullet: `service/domain-modelling.md`, the modelling methodology. NEVER an architecture / persistence / codegen / security file here — specify is the domain phase and any technology rule under this heading breaks its domain purity. Omit the heading only if you did not write domain-modelling.md.
|
|
1483
|
-
- `## /aw-spec-plan` — the as-built architecture / cross-cutting rules the
|
|
1862
|
+
- `## /aw-spec-plan` — the as-built architecture / cross-cutting rules the SERVICE lane's plan author mediates the spec against.
|
|
1484
1863
|
- `## /aw-spec-implement` — the code-generation / convention set the SERVICE lane's generator builds against (from backend-plan.md).
|
|
1485
1864
|
- `## /aw-spec-implement-delta` — the same set for the service lane on the DELTA path. `implement` is one command that keys this heading when it is generating a change's delta plan and the one above when it is generating the master, so a project that wants the same rules on both paths repeats them here.
|
|
1486
1865
|
- `## /aw-spec-build` — the layering + convention rules the compile-fixer respects.
|
|
1487
|
-
- `## /aw-spec-analyze-slice` — the conformance rules the
|
|
1488
|
-
- `## /aw-spec-adopt` — the technical reference set the reversed
|
|
1866
|
+
- `## /aw-spec-analyze-slice` — the conformance rules the plan↔code gate validates against.
|
|
1867
|
+
- `## /aw-spec-adopt` — the technical reference set the reversed plan mediates against (a subset of plan's).
|
|
1489
1868
|
- `## /aw-spec-constitution` — the standards a later `/appweaver constitution` re-ratifies the TECHNICAL half from. You authored that half from code evidence before these files existed; this heading is what makes a re-run author from THIS project's rules rather than from an empty set. Ratifiable standards only, no worked `examples/` sample, no domain file.
|
|
1490
1869
|
- `## /aw-spec-run` — the runtime / execution conventions the app-run step honors (add ONLY if the code evidences a runtime/hosting concern file; NOT data-migration — migration is the deferred later phase).
|
|
1491
1870
|
Each bullet is a
|
|
@@ -1503,7 +1882,7 @@ workflow:
|
|
|
1503
1882
|
on_empty: stop
|
|
1504
1883
|
on_empty_message: "No technical rule files were written to guardrails/projects/{{domain_slug}}/service/. Ensure the scan substrate (inventory_json) + the validated technical constitution carry an as-built technology base and re-run."
|
|
1505
1884
|
- id: require_tech_rule_bindings
|
|
1506
|
-
condition: "{{
|
|
1885
|
+
condition: "{{author_svc}} == true"
|
|
1507
1886
|
action: verify_context
|
|
1508
1887
|
required_files: ["{{pack_dir}}/tech-rule-bindings.md"]
|
|
1509
1888
|
|
|
@@ -1516,7 +1895,7 @@ workflow:
|
|
|
1516
1895
|
# file, and the run's remaining work is worth keeping either way.
|
|
1517
1896
|
- id: probe_specify_wiring
|
|
1518
1897
|
action: execute_script
|
|
1519
|
-
condition: "{{
|
|
1898
|
+
condition: "{{svc_lane}} == true"
|
|
1520
1899
|
on_error: continue
|
|
1521
1900
|
script: { ref: actions }
|
|
1522
1901
|
subcommand: resolve-tech
|
|
@@ -1525,7 +1904,7 @@ workflow:
|
|
|
1525
1904
|
- { name: specify_rules, from: "$.candidates" }
|
|
1526
1905
|
- id: warn_specify_wiring
|
|
1527
1906
|
action: verify_context
|
|
1528
|
-
condition: "{{
|
|
1907
|
+
condition: "{{svc_lane}} == true"
|
|
1529
1908
|
require_non_empty: specify_rules
|
|
1530
1909
|
on_empty: continue
|
|
1531
1910
|
on_empty_message: >
|
|
@@ -1542,18 +1921,20 @@ workflow:
|
|
|
1542
1921
|
# enforceable rule ↓), exactly as service/ is the detail layer under the technical half.
|
|
1543
1922
|
#
|
|
1544
1923
|
# Runs AFTER the technical set because both write the SAME map file: the technical set
|
|
1545
|
-
# authors tech-rule-bindings.md, and this step APPENDS the lane's
|
|
1546
|
-
#
|
|
1547
|
-
#
|
|
1548
|
-
#
|
|
1549
|
-
#
|
|
1924
|
+
# authors tech-rule-bindings.md, and this step APPENDS the lane's three headings to it
|
|
1925
|
+
# (or creates the file, in a project with no service lane). `## /aw-spec-ui-constitution`
|
|
1926
|
+
# is what makes a later /appweaver constitution re-ratify the UI half from THIS project's
|
|
1927
|
+
# lane rules, and the authoritative signal that the project HAS a frontend lane.
|
|
1928
|
+
# `## /aw-spec-plan-ui` and `## /aw-spec-implement-ui` are what the frontend lane of
|
|
1929
|
+
# `plan` and of `implement` load; without them that lane plans and generates against no
|
|
1930
|
+
# project rule at all.
|
|
1550
1931
|
- id: ctx_ui_pack
|
|
1551
1932
|
action: build_context
|
|
1552
1933
|
condition: "{{author_ui_flag}} == true"
|
|
1553
1934
|
context:
|
|
1554
|
-
- { path: "{{
|
|
1935
|
+
- { path: "{{inventory_ui_json}}" } # PRIMARY: the substrate's UI view — frontend_signals + the UI file lists to read source from
|
|
1555
1936
|
- { path: "{{constitution_ui_file}}" } # PRIMARY: the VALIDATED as-built UX-* base — the ratified principles these files detail
|
|
1556
|
-
- { path: "{{pack_dir}}/tech-rule-bindings.md" }
|
|
1937
|
+
- { path: "{{pack_dir}}/tech-rule-bindings.md", optional: true } # the map to APPEND to — absent only where no service lane is declared
|
|
1557
1938
|
- { path: .appweaver/orchestrator/rev-templates/frontend-rule-file.skeleton.md, optional: true } # SHAPE ONLY: one code-derived lane rule file's shape (zero real UI tech)
|
|
1558
1939
|
- { path: .appweaver/orchestrator/rev-templates/tech-rule-bindings.skeleton.md, optional: true } # SHAPE ONLY: the technical map's headings + partition + table
|
|
1559
1940
|
- { path: .appweaver/RULE-PARTITION.md } # the rule-partition authority (which command reads what)
|
|
@@ -1573,7 +1954,7 @@ workflow:
|
|
|
1573
1954
|
|
|
1574
1955
|
EVIDENCE = THE UI CODE ITSELF (deep read) + THE VALIDATED UI CONSTITUTION. Authority,
|
|
1575
1956
|
in order:
|
|
1576
|
-
1. THE ACTUAL UI SOURCE (ground truth). Use {{
|
|
1957
|
+
1. THE ACTUAL UI SOURCE (ground truth). Use {{inventory_ui_json}} (in context):
|
|
1577
1958
|
`frontend_signals` gives the lane roots, their kind, their framework markers and
|
|
1578
1959
|
their component / route / store / style file lists. Read enough of those files to
|
|
1579
1960
|
state each rule from what the UI ACTUALLY does. Do NOT assert a convention you
|
|
@@ -1589,7 +1970,7 @@ workflow:
|
|
|
1589
1970
|
Every path you write lives under guardrails/projects/{{domain_slug}}/frontend/.
|
|
1590
1971
|
|
|
1591
1972
|
EVIDENCED-ONLY (lean). Follow the SHAPE of frontend-rule-file.skeleton.md (in context):
|
|
1592
|
-
frontmatter (origin: reverse-engineered, generated_by:
|
|
1973
|
+
frontmatter (origin: reverse-engineered, generated_by: {{generated_by}}, concern),
|
|
1593
1974
|
a one-line framing, then rules each citing a CODE COORDINATE (a real component / route /
|
|
1594
1975
|
store / stylesheet / config path) and the UX principle numeral where it maps.
|
|
1595
1976
|
- `frontend/ui-constitution.md` — ALWAYS, the lane's base file: the lane declaration
|
|
@@ -1605,24 +1986,29 @@ workflow:
|
|
|
1605
1986
|
divergence with its coordinates. Do not upgrade a partial into a greenfield ideal, and
|
|
1606
1987
|
do not create a debt/backlog sink — modernization is a separate later phase.
|
|
1607
1988
|
|
|
1608
|
-
WIRE THE MAP —
|
|
1609
|
-
|
|
1610
|
-
byte-for-byte.
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
the authoritative signal that the project has a
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1989
|
+
WIRE THE MAP — guardrails/projects/{{domain_slug}}/tech-rule-bindings.md. Where the
|
|
1990
|
+
service rule set was generated it exists and carries the technical headings: EDIT IT IN
|
|
1991
|
+
PLACE and PRESERVE every one of them byte-for-byte. Where this project has no service
|
|
1992
|
+
lane it does not exist yet: CREATE it with the skeleton's title and framing and only the
|
|
1993
|
+
headings below. Add the lane's THREE headings after the last technical heading and
|
|
1994
|
+
BEFORE the closing quick-reference table. Every bullet is a workspace-relative path
|
|
1995
|
+
`- guardrails/projects/{{domain_slug}}/frontend/<file>` naming a file you just generated:
|
|
1996
|
+
1. `## /aw-spec-ui-constitution` — the lane's RATIFIABLE standards,
|
|
1997
|
+
`frontend/ui-constitution.md` first. It is what a later /appweaver constitution
|
|
1998
|
+
re-ratifies the UI half from, and the authoritative signal that the project has a
|
|
1999
|
+
frontend lane; precede the bullets with a short HTML comment saying both.
|
|
2000
|
+
2. `## /aw-spec-plan-ui` — the files the FRONTEND lane of `plan` authors
|
|
2001
|
+
frontend-plan.md against: those whose rules decide a feature's screens, navigation,
|
|
2002
|
+
client state, interaction states, forms, accessibility and service binding.
|
|
2003
|
+
3. `## /aw-spec-implement-ui` — the files the FRONTEND lane of `implement` generates
|
|
2004
|
+
code against, on the master and the delta path alike: those whose rules govern
|
|
2005
|
+
component conventions, state and data fetching, styling, forms and UI tests.
|
|
2006
|
+
A file whose rules carry both a planning half and a generating half is listed under both
|
|
2007
|
+
2 and 3 — a rule read by only one of the two phases loses its other half. Do NOT list
|
|
2008
|
+
`frontend/ui-constitution.md` under 2 or 3: it is the source the UI half is ratified
|
|
2009
|
+
from, and both phases already read that half (constitution.ui.md) directly. No domain
|
|
2010
|
+
file, no service/ file and no example under any of the three. Give each heading its row
|
|
2011
|
+
in the quick-reference table, in the same format as the existing rows.
|
|
1626
2012
|
|
|
1627
2013
|
Write ONLY inside guardrails/projects/{{domain_slug}}/ (frontend/ + the map edit); modify
|
|
1628
2014
|
no source. Report the files written, the concerns you found present with the code paths
|
|
@@ -1634,6 +2020,7 @@ workflow:
|
|
|
1634
2020
|
action: verify_context
|
|
1635
2021
|
condition: "{{author_ui_flag}} == true"
|
|
1636
2022
|
require_non_empty: ui_pack_files
|
|
2023
|
+
required_files: ["{{pack_dir}}/frontend/ui-constitution.md", "{{pack_dir}}/tech-rule-bindings.md"]
|
|
1637
2024
|
on_empty: stop
|
|
1638
2025
|
on_empty_message: "A frontend lane was detected ({{ui_evidence}}) but no lane rule files were written to guardrails/projects/{{domain_slug}}/frontend/. Check that the scan substrate's frontend_signals carry readable UI source, then re-run."
|
|
1639
2026
|
|
|
@@ -1644,7 +2031,7 @@ workflow:
|
|
|
1644
2031
|
# it. Announce, don't stop — the rule files are on disk and the heading is one edit away.
|
|
1645
2032
|
- id: probe_ui_wiring
|
|
1646
2033
|
action: execute_script
|
|
1647
|
-
condition: "{{
|
|
2034
|
+
condition: "{{ui_lane}} == true"
|
|
1648
2035
|
on_error: continue
|
|
1649
2036
|
script: { ref: actions }
|
|
1650
2037
|
subcommand: resolve-tech
|
|
@@ -1653,7 +2040,7 @@ workflow:
|
|
|
1653
2040
|
- { name: ui_map_rules, from: "$.candidates" }
|
|
1654
2041
|
- id: warn_ui_wiring
|
|
1655
2042
|
action: verify_context
|
|
1656
|
-
condition: "{{
|
|
2043
|
+
condition: "{{ui_lane}} == true"
|
|
1657
2044
|
require_non_empty: ui_map_rules
|
|
1658
2045
|
on_empty: continue
|
|
1659
2046
|
on_empty_message: >
|
|
@@ -1664,6 +2051,48 @@ workflow:
|
|
|
1664
2051
|
project as backend-only. Add the heading after the last technical one, bulleting
|
|
1665
2052
|
frontend/ui-constitution.md first, then the rest of the frontend/ set.
|
|
1666
2053
|
|
|
2054
|
+
# The same read-back for the two headings the frontend lane's PHASES key on. Empty
|
|
2055
|
+
# means that lane of `plan` / `implement` runs with the ratified UX-* base and no
|
|
2056
|
+
# project rule file at all.
|
|
2057
|
+
- id: probe_ui_plan_wiring
|
|
2058
|
+
action: execute_script
|
|
2059
|
+
condition: "{{ui_lane}} == true"
|
|
2060
|
+
on_error: continue
|
|
2061
|
+
script: { ref: actions }
|
|
2062
|
+
subcommand: resolve-tech
|
|
2063
|
+
args: ["--command", "aw-spec-plan-ui"]
|
|
2064
|
+
outputs:
|
|
2065
|
+
- { name: ui_plan_rules, from: "$.candidates" }
|
|
2066
|
+
- id: warn_ui_plan_wiring
|
|
2067
|
+
action: verify_context
|
|
2068
|
+
condition: "{{ui_lane}} == true"
|
|
2069
|
+
require_non_empty: ui_plan_rules
|
|
2070
|
+
on_empty: continue
|
|
2071
|
+
on_empty_message: >
|
|
2072
|
+
guardrails/projects/{{domain_slug}}/tech-rule-bindings.md maps nothing under
|
|
2073
|
+
`## /aw-spec-plan-ui`, so the frontend lane of /appweaver plan will author
|
|
2074
|
+
frontend-plan.md with no project rule file. Add the heading, bulleting the
|
|
2075
|
+
frontend/ files whose rules shape a feature's screens, state and interactions.
|
|
2076
|
+
- id: probe_ui_impl_wiring
|
|
2077
|
+
action: execute_script
|
|
2078
|
+
condition: "{{ui_lane}} == true"
|
|
2079
|
+
on_error: continue
|
|
2080
|
+
script: { ref: actions }
|
|
2081
|
+
subcommand: resolve-tech
|
|
2082
|
+
args: ["--command", "aw-spec-implement-ui"]
|
|
2083
|
+
outputs:
|
|
2084
|
+
- { name: ui_impl_rules, from: "$.candidates" }
|
|
2085
|
+
- id: warn_ui_impl_wiring
|
|
2086
|
+
action: verify_context
|
|
2087
|
+
condition: "{{ui_lane}} == true"
|
|
2088
|
+
require_non_empty: ui_impl_rules
|
|
2089
|
+
on_empty: continue
|
|
2090
|
+
on_empty_message: >
|
|
2091
|
+
guardrails/projects/{{domain_slug}}/tech-rule-bindings.md maps nothing under
|
|
2092
|
+
`## /aw-spec-implement-ui`, so the frontend lane of /appweaver implement will
|
|
2093
|
+
generate UI code with no project rule file. Add the heading, bulleting the
|
|
2094
|
+
frontend/ files whose rules govern component, state, styling and test conventions.
|
|
2095
|
+
|
|
1667
2096
|
# ═══════════ LANE DECLARATION — read back, never written ═══════════════════════
|
|
1668
2097
|
# onboard does not declare lanes. It used to: before select-stack was the first
|
|
1669
2098
|
# command of this sequence, a repo could arrive here with no declaration at all, so
|
|
@@ -1681,7 +2110,6 @@ workflow:
|
|
|
1681
2110
|
# the run reports the lanes it actually scanned under rather than a second opinion
|
|
1682
2111
|
# about them.
|
|
1683
2112
|
- id: lane_readback
|
|
1684
|
-
condition: "{{author_repo}} == true"
|
|
1685
2113
|
action: execute_script
|
|
1686
2114
|
on_error: continue
|
|
1687
2115
|
script: { ref: actions }
|
|
@@ -1702,11 +2130,11 @@ workflow:
|
|
|
1702
2130
|
# DESIGN CONVENTION by REVERSE-ENGINEERING its own technical structure into a project-
|
|
1703
2131
|
# specific design + delta-design template pair, written to the PROJECT-LEVEL override slot
|
|
1704
2132
|
# (.appweaver/templates/overrides/{design,delta-design}-template.md — resolve_template
|
|
1705
|
-
# Priority-1). The
|
|
1706
|
-
#
|
|
1707
|
-
# as-built architecture, and a CHANGE authors its delta
|
|
1708
|
-
# sections (
|
|
1709
|
-
#
|
|
2133
|
+
# Priority-1). The service lane of `plan` (plan-scaffold reports override_active ⇒
|
|
2134
|
+
# be_mode == bootstrap_bf) then authors EVERY new feature's backend-plan.md against the
|
|
2135
|
+
# as-built architecture, and a CHANGE authors its delta plan against the SAME code-derived
|
|
2136
|
+
# sections (delta-plan-scaffold resolves "delta-design-template" ⇒ the override) — no adopt
|
|
2137
|
+
# required, consistent with the backend-plan.md adopt emits.
|
|
1710
2138
|
#
|
|
1711
2139
|
# THE TEMPLATE IDENTIFIERS KEEP THE `design-template` SPELLING DELIBERATELY. The DOCUMENTS
|
|
1712
2140
|
# are backend-plan.md / frontend-plan.md now; the template NAMES are not, because a repo
|
|
@@ -1728,14 +2156,15 @@ workflow:
|
|
|
1728
2156
|
# (header block, the §1.2 domain/data-model anchor, the traceability spine, the two
|
|
1729
2157
|
# deferral ledgers, Change History, the tech-agnostic authoring rules) with the layering
|
|
1730
2158
|
# removed and every structural section left as a slot the code fills. The generated
|
|
1731
|
-
# template keeps the §0–§6 shape
|
|
1732
|
-
#
|
|
2159
|
+
# template keeps the §0–§6 shape `plan`'s bootstrap_bf branch expects and the two
|
|
2160
|
+
# anchors aw-xref keys on, so no workflow change is needed to consume it.
|
|
1733
2161
|
#
|
|
1734
2162
|
# WHERE A FRONTEND LANE EXISTS the lane gets its OWN pair (ui-design-template +
|
|
1735
2163
|
# ui-delta-design-template, below), so this pair covers the SERVICE lane only and excludes
|
|
1736
2164
|
# the lane's roots from the structure it derives. One lane's template never describes the
|
|
1737
|
-
# other's code.
|
|
1738
|
-
#
|
|
2165
|
+
# other's code. The templates are authored when their lane's tier is first authored — by
|
|
2166
|
+
# the first context, or by the run that first sees a lane declared later — and are never
|
|
2167
|
+
# amended: every plan already written follows their shape.
|
|
1739
2168
|
|
|
1740
2169
|
# DESIGN template — the code-derived evidence (code + inventory + technical constitution)
|
|
1741
2170
|
# plus a NEUTRAL skeleton for the bones. No greenfield template is in context.
|
|
@@ -1743,7 +2172,7 @@ workflow:
|
|
|
1743
2172
|
action: build_context
|
|
1744
2173
|
condition: "{{author_svc}} == true"
|
|
1745
2174
|
context:
|
|
1746
|
-
- { path: "{{
|
|
2175
|
+
- { path: "{{inventory_service_json}}" } # PRIMARY: the substrate's service view (top_level_dirs, aggregate_signals' per-layer file groupings) — the OKF markdown only SUMMARISES this
|
|
1747
2176
|
- { path: "{{constitution_technical_file}}" } # PRIMARY: the VALIDATED as-built technology base (framework/persistence/concurrency/hosting/testing/cross-cutting)
|
|
1748
2177
|
- { path: .appweaver/orchestrator/rev-templates/design-template.skeleton.md } # SHAPE ONLY: the neutral bones + the pinned anchors + tech-agnostic authoring rules (zero layering, zero technology)
|
|
1749
2178
|
- { path: .appweaver/DESIGN-FORMAT.md } # the HLD contract + its Brownfield variant note (which anchors are pinned, and why)
|
|
@@ -1759,16 +2188,16 @@ workflow:
|
|
|
1759
2188
|
REVERSE-ENGINEER this repo's design convention into a PROJECT-SPECIFIC design
|
|
1760
2189
|
TEMPLATE and Write it to .appweaver/templates/overrides/design-template.md (create the
|
|
1761
2190
|
overrides/ dir if absent). It is a TEMPLATE — concrete project-derived section HEADERS
|
|
1762
|
-
with [PLACEHOLDER] tokens + authoring HTML comments the
|
|
1763
|
-
per feature — NOT a filled
|
|
2191
|
+
with [PLACEHOLDER] tokens + authoring HTML comments the service lane of `plan` fills
|
|
2192
|
+
per feature into specs/<Context>/<Feature>/backend-plan.md — NOT a filled plan.
|
|
1764
2193
|
|
|
1765
2194
|
GROUND EVERYTHING IN THE CODE + THE REVERSE-ENGINEERED FILES — not the shallow OKF map
|
|
1766
2195
|
and not any architecture you know from elsewhere. Evidence authority, in order:
|
|
1767
2196
|
1. THE ACTUAL SOURCE CODE (ground truth). Read REPRESENTATIVE source files across the
|
|
1768
|
-
repo's top_level_dirs and a few aggregate_signals (from {{
|
|
2197
|
+
repo's top_level_dirs and a few aggregate_signals (from {{inventory_service_json}}) — enough
|
|
1769
2198
|
to CONFIRM from the code the recurring folder/tier/module convention + the dependency
|
|
1770
2199
|
direction it actually follows. Do NOT assert structure you have not seen in the code.
|
|
1771
|
-
2. {{
|
|
2200
|
+
2. {{inventory_service_json}} — the deterministic scan substrate's service view (top_level_dirs, each
|
|
1772
2201
|
aggregate_signal's files grouped by layer, categories, tech stack). The OKF markdown
|
|
1773
2202
|
only SUMMARISES this, shallowly — prefer the substrate + the code over it.
|
|
1774
2203
|
3. The TECHNICAL CONSTITUTION (constitution.technical.md, in context) — the VALIDATED
|
|
@@ -1796,10 +2225,10 @@ workflow:
|
|
|
1796
2225
|
folders + the dependency rule) from evidence 1–3 — this ONE template governs every
|
|
1797
2226
|
future feature.
|
|
1798
2227
|
|
|
1799
|
-
Then AUTHOR the template on the skeleton's §0–§6 shape (the shape
|
|
1800
|
-
|
|
1801
|
-
- Keep the skeleton's header block (
|
|
1802
|
-
Status) and its TECHNOLOGY-AGNOSTIC authoring rules (behaviour as signatures +
|
|
2228
|
+
Then AUTHOR the template on the skeleton's §0–§6 shape (the shape `plan`'s
|
|
2229
|
+
bootstrap_bf branch expects — keep these section numbers + headings):
|
|
2230
|
+
- Keep the skeleton's header block (Feature / Plan home / Source spec / Source model /
|
|
2231
|
+
Version / Status) and its TECHNOLOGY-AGNOSTIC authoring rules (behaviour as signatures +
|
|
1803
2232
|
pre/post/invariant/raises, contracts as field shapes, NO code; every element traces to
|
|
1804
2233
|
a spec id). Fill [GENERATED_STRUCTURE_NOTE] with this project's convention.
|
|
1805
2234
|
- §0 Design Overview + `### Ubiquitous Language (design delta)` — carry over as-is.
|
|
@@ -1829,8 +2258,8 @@ workflow:
|
|
|
1829
2258
|
deviations, NOT "organised unlike a reference architecture" (that is the as-built
|
|
1830
2259
|
shape, §1.1).
|
|
1831
2260
|
- Change History — carry over.
|
|
1832
|
-
Keep every [PLACEHOLDER] and authoring comment so `
|
|
1833
|
-
comments DIRECT the downstream author (
|
|
2261
|
+
Keep every [PLACEHOLDER] and authoring comment so `plan` can fill it — and in those
|
|
2262
|
+
comments DIRECT the downstream author (`plan` / adopt) to GROUND each filled
|
|
1834
2263
|
section in the ACTUAL CODE + the reverse-engineered files (cite real file/folder paths and
|
|
1835
2264
|
the relevant technical-constitution principle). Do NOT invent project structure the code
|
|
1836
2265
|
does not show; where the convention is unclear, template a generic axis and flag it in a
|
|
@@ -1844,12 +2273,13 @@ workflow:
|
|
|
1844
2273
|
action: verify_context
|
|
1845
2274
|
condition: "{{author_svc}} == true"
|
|
1846
2275
|
require_non_empty: design_template_files
|
|
2276
|
+
required_files: [".appweaver/templates/overrides/design-template.md"]
|
|
1847
2277
|
on_empty: stop
|
|
1848
2278
|
on_empty_message: "No design template was written to .appweaver/templates/overrides/design-template.md. Ensure the scan substrate (inventory_json) + the technical constitution are present and re-run."
|
|
1849
2279
|
|
|
1850
2280
|
# DELTA-DESIGN template — MIRROR the just-generated master template's OWN sections so a
|
|
1851
2281
|
# change classifies ADDED/MODIFIED/REMOVED against the code-derived structure, not the
|
|
1852
|
-
# greenfield four layers. Aligns with the delta-
|
|
2282
|
+
# greenfield four layers. Aligns with the delta-plan module (classifies "per the
|
|
1853
2283
|
# master's OWN section structure").
|
|
1854
2284
|
- id: ctx_delta_design_template
|
|
1855
2285
|
action: build_context
|
|
@@ -1867,20 +2297,21 @@ workflow:
|
|
|
1867
2297
|
Author the matching PROJECT-SPECIFIC DELTA-design TEMPLATE and Write it to
|
|
1868
2298
|
.appweaver/templates/overrides/delta-design-template.md. It is a TEMPLATE (placeholders
|
|
1869
2299
|
+ authoring comments) for classifying a CHANGE to a feature as ADDED / MODIFIED /
|
|
1870
|
-
REMOVED against the master
|
|
2300
|
+
REMOVED against the master backend-plan.md.
|
|
1871
2301
|
|
|
1872
2302
|
MIRROR the just-generated master template (.appweaver/templates/overrides/design-template.md,
|
|
1873
2303
|
in context — Read it): its ADDED/MODIFIED/REMOVED tables must key off the master's OWN
|
|
1874
2304
|
code-derived sections (§1.1/§1.2, the §2.n axes it derived, §3). Use the skeleton's
|
|
1875
|
-
"Section (§ in
|
|
2305
|
+
"Section (§ in backend-plan.md)" column and fill its example rows with the ACTUAL sections of
|
|
1876
2306
|
the generated master template. Never name a layering — neither one you know nor one the
|
|
1877
2307
|
master did not derive.
|
|
1878
2308
|
- CARRY OVER the neutral parts of rev-templates/delta-design-template.skeleton.md (in
|
|
1879
2309
|
context): Change summary, Cross-section impact, Regression targets, New assumptions/
|
|
1880
|
-
deviations (DA-n / WA-n), On
|
|
2310
|
+
deviations (DA-n / WA-n), On merge — word for word: finalize-delta merges the spec and
|
|
2311
|
+
the model, never this plan, which `plan main` re-derives. Keep behaviour technology-agnostic (signatures +
|
|
1881
2312
|
contracts, no code); a shared element is MODIFIED in place, never duplicated; every
|
|
1882
2313
|
changed element serves a spec id.
|
|
1883
|
-
- This aligns with the delta-
|
|
2314
|
+
- This aligns with the delta-plan module, which classifies "per the master's OWN
|
|
1884
2315
|
section structure" — so the template MUST NOT hardcode a fixed layering.
|
|
1885
2316
|
Keep every [PLACEHOLDER] and authoring comment. Write ONLY the override file; modify no
|
|
1886
2317
|
source. Report the file written.
|
|
@@ -1891,6 +2322,7 @@ workflow:
|
|
|
1891
2322
|
action: verify_context
|
|
1892
2323
|
condition: "{{author_svc}} == true"
|
|
1893
2324
|
require_non_empty: delta_design_template_files
|
|
2325
|
+
required_files: [".appweaver/templates/overrides/delta-design-template.md"]
|
|
1894
2326
|
on_empty: stop
|
|
1895
2327
|
on_empty_message: "No delta-design template was written to .appweaver/templates/overrides/delta-design-template.md. Re-run onboard after confirming the design template override was generated."
|
|
1896
2328
|
|
|
@@ -1971,6 +2403,7 @@ workflow:
|
|
|
1971
2403
|
condition: "{{author_repo}} == true"
|
|
1972
2404
|
action: verify_context
|
|
1973
2405
|
require_non_empty: model_template_files
|
|
2406
|
+
required_files: [".appweaver/templates/overrides/domain-model-template.md"]
|
|
1974
2407
|
on_empty: stop
|
|
1975
2408
|
on_empty_message: "No domain-model template was written to .appweaver/templates/overrides/domain-model-template.md. Without it every reversed slice authors its aggregate against the kit's GREENFIELD model template, whose shape assumes a domain designed before it was built. Ensure the scan substrate (inventory_json) is present and re-run."
|
|
1976
2409
|
|
|
@@ -1984,12 +2417,13 @@ workflow:
|
|
|
1984
2417
|
# WHY THE LANE NEEDS ITS OWN PAIR rather than a section inside the service design: the
|
|
1985
2418
|
# two lanes are governed by different constitution halves and different map headings,
|
|
1986
2419
|
# they are implemented by different commands, and the ONLY thing that crosses between
|
|
1987
|
-
# them is the
|
|
1988
|
-
# structure under the service lane's rules and hand
|
|
1989
|
-
#
|
|
2420
|
+
# them is the service's published surface. A UI section inside backend-plan.md would put
|
|
2421
|
+
# the lane's structure under the service lane's rules and hand the frontend lane of `plan`
|
|
2422
|
+
# the whole backend plan to read — precisely the leak §5's published-surface boundary
|
|
2423
|
+
# exists to stop.
|
|
1990
2424
|
#
|
|
1991
2425
|
# THE SECTION LIST IS RATIFIED, THE CONTENT IS THE CODE'S. aw-spec specifies what
|
|
1992
|
-
#
|
|
2426
|
+
# frontend-plan.md contains (navigation & screen structure · client state · component
|
|
1993
2427
|
# structure · interaction & flow · contract binding · cross-cutting · traceability ·
|
|
1994
2428
|
# DA-n · WA-n); the skeleton carries exactly that, framework-free. What this step
|
|
1995
2429
|
# derives from the lane's source is what goes IN those sections — the real composition
|
|
@@ -1998,13 +2432,13 @@ workflow:
|
|
|
1998
2432
|
# THE CONSUMERS ARE BUILT: the frontend lane of `plan` scaffolds from this override when
|
|
1999
2433
|
# onboard installed one (plan-scaffold reports override_active), and the frontend lane of
|
|
2000
2434
|
# `implement` generates from the plan it produced. The templates are written HERE because
|
|
2001
|
-
# the evidence for them is
|
|
2002
|
-
#
|
|
2435
|
+
# the evidence for them is onboard's whole-repo scan, and nothing breaks for their absence
|
|
2436
|
+
# in a repo that never onboarded.
|
|
2003
2437
|
- id: ctx_ui_design_template
|
|
2004
2438
|
action: build_context
|
|
2005
2439
|
condition: "{{author_ui_flag}} == true"
|
|
2006
2440
|
context:
|
|
2007
|
-
- { path: "{{
|
|
2441
|
+
- { path: "{{inventory_ui_json}}" } # PRIMARY: the substrate's UI view — frontend_signals + the component/route/store/style file lists to read source from
|
|
2008
2442
|
- { path: "{{constitution_ui_file}}" } # PRIMARY: the VALIDATED as-built UX-* base — the ratified principles this structure must serve
|
|
2009
2443
|
- { path: .appweaver/orchestrator/rev-templates/ui-design-template.skeleton.md } # SHAPE ONLY: the ratified section list + neutral bones (zero framework, zero component library)
|
|
2010
2444
|
- { path: "{{pack_dir}}/frontend/ui-constitution.md", optional: true } # the generated lane rule set's base file — the detail layer under those principles
|
|
@@ -2018,12 +2452,12 @@ workflow:
|
|
|
2018
2452
|
REVERSE-ENGINEER this repo's FRONTEND LANE into a PROJECT-SPECIFIC UI DESIGN TEMPLATE
|
|
2019
2453
|
and Write it to .appweaver/templates/overrides/ui-design-template.md (create the
|
|
2020
2454
|
overrides/ dir if absent). It is a TEMPLATE — concrete lane-derived section content
|
|
2021
|
-
with [PLACEHOLDER] tokens + authoring HTML comments that
|
|
2022
|
-
feature into specs/<Feature>/
|
|
2455
|
+
with [PLACEHOLDER] tokens + authoring HTML comments that the frontend lane of `plan`
|
|
2456
|
+
fills per feature into specs/<Context>/<Feature>/frontend-plan.md — NOT a filled plan.
|
|
2023
2457
|
The lane: {{ui_evidence}} · roots: {{frontend_roots}}
|
|
2024
2458
|
|
|
2025
2459
|
GROUND EVERYTHING IN THE LANE'S OWN CODE. Evidence authority, in order:
|
|
2026
|
-
1. THE ACTUAL UI SOURCE (ground truth). Use {{
|
|
2460
|
+
1. THE ACTUAL UI SOURCE (ground truth). Use {{inventory_ui_json}} (in context):
|
|
2027
2461
|
`frontend_signals` gives the lane roots, their kind (spa / server-rendered /
|
|
2028
2462
|
desktop), their framework markers and their component / route / store / style
|
|
2029
2463
|
file lists. READ ENOUGH OF THOSE FILES to state each structural claim from what
|
|
@@ -2070,13 +2504,14 @@ workflow:
|
|
|
2070
2504
|
shows little. They are the two sections a backend-shaped process drops and where
|
|
2071
2505
|
most UI defects live. Where the code handles no error or empty state, template the
|
|
2072
2506
|
section so the downstream author must record that as-built — never delete it.
|
|
2073
|
-
- §5 Contract Binding — keep the lane boundary intact: the binding table
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2507
|
+
- §5 Contract Binding — keep the lane boundary intact: the binding table binds
|
|
2508
|
+
against the service's PUBLISHED SURFACE (the spec's IC- ids and the API contracts
|
|
2509
|
+
backend-plan.md states), never the service's internals. Note in the authoring
|
|
2510
|
+
comment that where the surface does not name an operation yet, the author binds
|
|
2511
|
+
against the spec's own IC-/FR- surface and logs a §8 assumption.
|
|
2077
2512
|
- §7 Traceability, §8 Assumptions (DA-n), §9 Deviations (WA-n), Change History — carry
|
|
2078
2513
|
over; the §7 Section column uses THIS template's own section refs.
|
|
2079
|
-
Keep every [PLACEHOLDER] and authoring comment so
|
|
2514
|
+
Keep every [PLACEHOLDER] and authoring comment so `plan` can fill it — and in
|
|
2080
2515
|
those comments DIRECT the downstream author to GROUND each filled section in the
|
|
2081
2516
|
ACTUAL UI CODE and the lane's governance (cite real component/route/store/stylesheet
|
|
2082
2517
|
paths and the constitution.ui.md UX numeral). Do NOT invent lane structure the code
|
|
@@ -2091,6 +2526,7 @@ workflow:
|
|
|
2091
2526
|
action: verify_context
|
|
2092
2527
|
condition: "{{author_ui_flag}} == true"
|
|
2093
2528
|
require_non_empty: ui_design_template_files
|
|
2529
|
+
required_files: [".appweaver/templates/overrides/ui-design-template.md"]
|
|
2094
2530
|
on_empty: stop
|
|
2095
2531
|
on_empty_message: "A frontend lane was detected ({{ui_evidence}}) but no UI design template was written to .appweaver/templates/overrides/ui-design-template.md. Check that the scan substrate's frontend_signals carry readable UI source, then re-run."
|
|
2096
2532
|
|
|
@@ -2112,18 +2548,19 @@ workflow:
|
|
|
2112
2548
|
Author the matching PROJECT-SPECIFIC UI DELTA-design TEMPLATE and Write it to
|
|
2113
2549
|
.appweaver/templates/overrides/ui-delta-design-template.md. It is a TEMPLATE
|
|
2114
2550
|
(placeholders + authoring comments) for classifying a CHANGE to a feature's
|
|
2115
|
-
EXPERIENCE as ADDED / MODIFIED / REMOVED against the master
|
|
2551
|
+
EXPERIENCE as ADDED / MODIFIED / REMOVED against the master frontend-plan.md.
|
|
2116
2552
|
|
|
2117
2553
|
MIRROR the just-generated lane master (.appweaver/templates/overrides/ui-design-template.md,
|
|
2118
2554
|
in context — Read it): its ADDED/MODIFIED/REMOVED tables must key off that master's OWN
|
|
2119
2555
|
sections, including whatever composition axes its §3 derived. Use the skeleton's
|
|
2120
|
-
"Section (§ in
|
|
2556
|
+
"Section (§ in frontend-plan.md)" column and fill its example rows with the ACTUAL sections
|
|
2121
2557
|
of the generated master. Never name a framework or a UI taxonomy the master did not
|
|
2122
2558
|
derive.
|
|
2123
2559
|
- CARRY OVER the neutral parts of rev-templates/ui-delta-design-template.skeleton.md
|
|
2124
2560
|
(in context): Change summary, Interaction states touched, Contract impact,
|
|
2125
2561
|
Cross-section impact, Regression targets, New assumptions/deviations (DA-n / WA-n),
|
|
2126
|
-
On
|
|
2562
|
+
On merge — word for word: finalize-delta merges the spec and the model, never this
|
|
2563
|
+
plan, which `plan main` re-derives.
|
|
2127
2564
|
- KEEP the "Interaction states touched" section whatever this lane's code shows: a new
|
|
2128
2565
|
interaction that ships without its loading, empty, error and permission-denied states
|
|
2129
2566
|
is an incomplete delta, and the template is where that is enforced.
|
|
@@ -2141,6 +2578,7 @@ workflow:
|
|
|
2141
2578
|
action: verify_context
|
|
2142
2579
|
condition: "{{author_ui_flag}} == true"
|
|
2143
2580
|
require_non_empty: ui_delta_design_template_files
|
|
2581
|
+
required_files: [".appweaver/templates/overrides/ui-delta-design-template.md"]
|
|
2144
2582
|
on_empty: stop
|
|
2145
2583
|
on_empty_message: "No UI delta-design template was written to .appweaver/templates/overrides/ui-delta-design-template.md. Re-run onboard after confirming the UI design template override was generated."
|
|
2146
2584
|
|
|
@@ -2210,4 +2648,11 @@ outputs:
|
|
|
2210
2648
|
ui_delta_design_template_files: "{{ui_delta_design_template_files}}"
|
|
2211
2649
|
technical_validation_ok: "{{technical_ok}}"
|
|
2212
2650
|
domain_validation_ok: "{{domain_ok}}"
|
|
2213
|
-
|
|
2651
|
+
# Authored (the first context, or a lane tier that did not exist) or amended (a later
|
|
2652
|
+
# context adding its evidence), and what each amendment step changed — empty when the
|
|
2653
|
+
# tier already covered this context.
|
|
2654
|
+
governance_mode: "{{gov_mode}}"
|
|
2655
|
+
amended_domain_files: "{{amended_domain_files}}"
|
|
2656
|
+
amended_service_files: "{{amended_service_files}}"
|
|
2657
|
+
amended_ui_files: "{{amended_ui_files}}"
|
|
2658
|
+
next: "Onboarded bounded context {{bc}} ({{bc_feature_count}} feature(s): {{bc_features}}). Its aggregate concepts ({{bc_aggregates}}) are in {{bundle_dir}}, each keyed `bounded_context: {{bc}}` and listing the features that act on it — the bundle is the project's knowledge, one concept per aggregate, never one per feature — and its specs tree now exists at {{bc_dir}}/ with a directory per feature ({{feature_dirs}}) — EMPTY on purpose: the directory says the feature is known, and the documents that describe it are written per feature by /appweaver adopt and per context by /appweaver specify. {{bc}} is now the ACTIVE bounded context (.appweaver/context.json), so /appweaver select-feature lists exactly these features and nothing from a neighbouring context; switch with /appweaver select-bounded-context. ONBOARD RUNS ONCE PER CONTEXT: contexts already done — {{onboarded_contexts}}; still open — {{remaining_contexts}}; the order the map gives is {{contexts_ordered}}. Run /appweaver onboard <NextContext> for each remaining one, or with no argument to take the next one automatically. GOVERNANCE — {{gov_mode}}. The project tier is the PROVISIONAL governance scaffold — the split constitution, the domain rule set at guardrails/projects/{{domain_slug}}/domain/*.domain.md + domain-rule-bindings.md, each declared LANE's rule set and constitution half, the activated domain {{active_domain}}, and the code-derived design / delta-design / domain-model template overrides in .appweaver/templates/overrides/. The first context authors it; every later context AMENDS it from its own code, additively — rules, principles and map entries its code evidences, never a rewrite, renumbering or deletion of what an earlier context wrote — and a lane tier that did not exist yet is authored in full. Files this run amended — domain: {{amended_domain_files}}; service: {{amended_service_files}}; frontend: {{amended_ui_files}}. Search them for `Divergence ({{bc}})`: each marks a rule this context's code contradicts, left as written for you to decide with /appweaver constitution, which is also how you amend the tier by hand. The templates are written once per lane and never amended. To re-run this governance pass later — after declaring a lane with /appweaver select-stack, say — name an onboarded context: /appweaver onboard <Context>. ONE HALF AND ONE RULE SET PER LANE: service_lane / ui_lane report which lanes .appweaver/stacks.json declared, and the declaration is what decided. A lane declared (none) in select-stack gets none of it, which is the correct outcome and not an omission. LANE DECLARATION: read, never written — select-stack is its sole writer, and this run scanned the source paths it named (scanned_service_root / scanned_ui_root); scanned_backend_files / scanned_ui_files report each. ui_source_evidence_found false means the UI lane's declared path held nothing a scan recognises as UI, so its governance is thin — move the source path with /appweaver select-stack and re-run. The build/test/run commands on each lane are that PROFILE's defaults and may not match a legacy layout — review them. Because the domain is activated, resolve-domain + resolve-tech route the WHOLE forward pipeline to these code-derived rules — never another project's rules as a fallback. THE BOUNDARIES CAME FROM THE MAP, not from this run: /appweaver inventory proposed them and you confirmed them in specs/proposed-inventory.md. To change a boundary, edit that file and run /appweaver inventory apply — a context whose concepts already exist is not re-mapped; naming it re-runs only its governance pass. Develop an EXISTING feature just-in-time: /appweaver adopt <Feature> reverse-engineers its spec.md + backend-plan.md + source-map.md and deepens the OKF concept of the aggregate it acts on. Develop a NEW feature straight through the forward pipeline — /appweaver select-feature FIRST (specify and every stage after it read the active feature and STOP without one), then specify → plan → analyze-plan → implement → build → analyze-slice → run. 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), and re-derive the master plans after it with /appweaver plan main → analyze-plan — finalize-delta merges a change into spec.md and domain-model.md, never into the plans. If a validation_ok is false, its constitution half needs a manual touch (see its Sync Impact Report)."
|