aw-spec-cli 0.1.26 → 0.1.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/assets/.agents/skills/appweaver/SKILL.md +7 -47
  2. package/assets/.appweaver/ORCH-DIALECT.md +13 -9
  3. package/assets/.appweaver/RULE-PARTITION.md +3 -3
  4. package/assets/.appweaver/STACK-PROFILES.md +188 -101
  5. package/assets/.appweaver/domain.json +1 -1
  6. package/assets/.appweaver/orchestrator/AGENT-PROFILE.md +38 -10
  7. package/assets/.appweaver/orchestrator/LAUNCHER.md +88 -0
  8. package/assets/.appweaver/orchestrator/README.md +120 -53
  9. package/assets/.appweaver/orchestrator/adapters/claude_agent_sdk.py +1 -1
  10. package/assets/.appweaver/orchestrator/modules/domain-select.orch.yaml +6 -4
  11. package/assets/.appweaver/orchestrator/modules/foundation-lane.orch.yaml +237 -0
  12. package/assets/.appweaver/orchestrator/modules/foundation-pack.orch.yaml +349 -0
  13. package/assets/.appweaver/orchestrator/modules/foundation-spec.orch.yaml +381 -0
  14. package/assets/.appweaver/orchestrator/modules/lane-gate.orch.yaml +4 -4
  15. package/assets/.appweaver/orchestrator/modules/tech-select.orch.yaml +3 -3
  16. package/assets/.appweaver/orchestrator/orchestrator.py +162 -63
  17. package/assets/.appweaver/orchestrator/rev-templates/domain-constitution.skeleton.md +2 -2
  18. package/assets/.appweaver/orchestrator/rev-templates/domain-requirements.skeleton.md +2 -2
  19. package/assets/.appweaver/orchestrator/rev-templates/domain-rule-bindings.skeleton.md +5 -5
  20. package/assets/.appweaver/orchestrator/rev-templates/frontend-rule-file.skeleton.md +1 -1
  21. package/assets/.appweaver/orchestrator/rev-templates/tech-rule-bindings.skeleton.md +14 -14
  22. package/assets/.appweaver/orchestrator/rev-templates/technical-constitution.skeleton.md +2 -2
  23. package/assets/.appweaver/orchestrator/rev-templates/technical-rule-file.skeleton.md +1 -1
  24. package/assets/.appweaver/orchestrator/rev-templates/ui-constitution.skeleton.md +3 -3
  25. package/assets/.appweaver/orchestrator/workflows/_smoke.orch.yaml +41 -3
  26. package/assets/.appweaver/orchestrator/workflows/aw-spec-add-component.orch.yaml +1 -1
  27. package/assets/.appweaver/orchestrator/workflows/aw-spec-adopt.orch.yaml +13 -13
  28. package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-slice-delta.orch.yaml +3 -3
  29. package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-slice.orch.yaml +3 -3
  30. package/assets/.appweaver/orchestrator/workflows/aw-spec-build.orch.yaml +4 -4
  31. package/assets/.appweaver/orchestrator/workflows/aw-spec-characterize.orch.yaml +2 -2
  32. package/assets/.appweaver/orchestrator/workflows/aw-spec-constitution.orch.yaml +61 -12
  33. package/assets/.appweaver/orchestrator/workflows/aw-spec-foundation.orch.yaml +172 -293
  34. package/assets/.appweaver/orchestrator/workflows/aw-spec-implement.orch.yaml +29 -28
  35. package/assets/.appweaver/orchestrator/workflows/aw-spec-onboard.orch.yaml +53 -53
  36. package/assets/.appweaver/orchestrator/workflows/aw-spec-parity.orch.yaml +2 -2
  37. package/assets/.appweaver/orchestrator/workflows/aw-spec-plan.orch.yaml +3 -3
  38. package/assets/.appweaver/orchestrator/workflows/aw-spec-run.orch.yaml +4 -4
  39. package/assets/.appweaver/orchestrator/workflows/aw-spec-select-bounded-context.orch.yaml +26 -2
  40. package/assets/.appweaver/orchestrator/workflows/aw-spec-select-domain.orch.yaml +21 -15
  41. package/assets/.appweaver/orchestrator/workflows/aw-spec-select-stack.orch.yaml +14 -14
  42. package/assets/.appweaver/orchestrator/workflows/aw-spec-specify.orch.yaml +2 -2
  43. package/assets/.appweaver/orchestrator/workflows/aw-spec-ui-model.orch.yaml +3 -3
  44. package/assets/.appweaver/orchestrator/workflows/aw-spec-ui-prototype.orch.yaml +6 -6
  45. package/assets/.appweaver/scripts/bash/aw-spec-actions.sh +284 -128
  46. package/assets/.appweaver/scripts/powershell/aw-spec-actions.ps1 +224 -70
  47. package/assets/.appweaver/scripts/python/aw-foundation.py +809 -20
  48. package/assets/.appweaver/scripts/python/aw-inventory.py +28 -21
  49. package/assets/.appweaver/scripts/python/aw-plan-coverage.py +2 -2
  50. package/assets/.appweaver/scripts/python/aw-rev-constitution.py +6 -6
  51. package/assets/.appweaver/scripts/python/aw-stack.py +195 -89
  52. package/assets/.appweaver/stack-profiles/angular.json +2 -1
  53. package/assets/.appweaver/stack-profiles/blazor-wasm.json +2 -1
  54. package/assets/.appweaver/stack-profiles/dotnet-webapi.json +16 -3
  55. package/assets/.appweaver/stack-profiles/go-chi.json +6 -1
  56. package/assets/.appweaver/stack-profiles/java-spring.json +12 -5
  57. package/assets/.appweaver/stack-profiles/nextjs.json +2 -1
  58. package/assets/.appweaver/stack-profiles/node-express.json +8 -2
  59. package/assets/.appweaver/stack-profiles/python-fastapi.json +9 -2
  60. package/assets/.appweaver/stack-profiles/react-vite.json +2 -1
  61. package/assets/.appweaver/stack-profiles/sveltekit.json +2 -1
  62. package/assets/.appweaver/stack-profiles/vue-vite.json +2 -1
  63. package/assets/.appweaver/stacks.json +37 -1
  64. package/assets/.appweaver/templates/constitution-ui-template.md +2 -2
  65. package/assets/.claude/skills/appweaver/SKILL.md +7 -46
  66. package/assets/foundations/dotnet/ModularMonolith/ModularMonolith.Reference.rules.json +31 -0
  67. package/assets/foundations/dotnet/VerticalSlice/VerticalSlice.Reference.rules.json +16 -0
  68. package/assets/foundations/foundation.spec.template.txt +73 -0
  69. package/assets/foundations/java/Hexagonal/Hexagonal.pack.txt +1 -1
  70. package/assets/foundations/java/Hexagonal/unpack-foundation.sh +4 -5
  71. package/assets/foundations/node/NextAppRouter/NextAppRouter.spec.txt +68 -0
  72. package/assets/guardrails/README.md +31 -17
  73. package/assets/guardrails/{projects/dotnet-default-project → project-specific}/domain-rule-bindings.md +5 -5
  74. package/assets/guardrails/{projects/dotnet-default-project → project-specific}/tech-rule-bindings.md +151 -114
  75. package/assets/guardrails/technology/dotnet-webapi/PACKAGING.md +58 -4
  76. package/assets/guardrails/technology/dotnet-webapi/coding-standards.md +1 -1
  77. package/assets/guardrails/technology/dotnet-webapi/dependency-policy.md +1 -1
  78. package/assets/guardrails/technology/dotnet-webapi/folder-structure.md +1 -1
  79. package/assets/guardrails/technology/dotnet-webapi/framework-api-map.md +1 -1
  80. package/assets/guardrails/technology/dotnet-webapi/testing.md +1 -1
  81. package/assets/guardrails/technology/nextjs/api-client.md +1 -1
  82. package/assets/guardrails/technology/nextjs/component-architecture.md +1 -1
  83. package/assets/guardrails/technology/nextjs/component-conventions.md +2 -2
  84. package/assets/guardrails/technology/nextjs/design-system.md +1 -1
  85. package/assets/guardrails/technology/nextjs/frontend-testing.md +1 -1
  86. package/assets/guardrails/technology/nextjs/routing-navigation.md +1 -1
  87. package/assets/guardrails/technology/nextjs/ui-constitution.md +3 -3
  88. package/package.json +1 -1
  89. package/assets/.agents/skills/appweaver-demo/SKILL.md +0 -59
  90. package/assets/.appweaver/orchestrator/.smoke-out/smoke.md +0 -6
  91. package/assets/.appweaver/orchestrator/workflows/aw-spec-demo.orch.yaml +0 -100
  92. package/assets/.claude/skills/appweaver-demo/SKILL.md +0 -59
  93. package/assets/.kilocode/agent.json +0 -28
  94. package/assets/.kilocode/workflows/appweaver-demo.md +0 -59
  95. package/assets/.kilocode/workflows/appweaver.md +0 -55
  96. /package/assets/guardrails/{projects/dotnet-default-project → project-specific}/domain/domain-requirements.md +0 -0
  97. /package/assets/guardrails/{projects/dotnet-default-project → project-specific}/frontend/ui-requirements.md +0 -0
  98. /package/assets/guardrails/{projects/dotnet-default-project → project-specific}/service/technical-requirements.md +0 -0
@@ -5,13 +5,15 @@
5
5
  # Exercises every extended construct in one run: inputs, set (raw object),
6
6
  # execute_script (read-only subcommand), verify_context gates, ask
7
7
  # (non-interactive default), foreach + while loops + break, agent_query
8
- # (mock:), agent_author (mock content), build_context, include
9
- # (domain-select module), dispatch_hooks (empty).
8
+ # (mock:), agent_author (mock content), build_context, agent_generate (the
9
+ # mock writes SmokeGenerated.cs), agent_review (mock: pass when the files
10
+ # exist), include (domain-select module), dispatch_hooks (empty).
10
11
  #
11
12
  # Run:
12
13
  # python3 .appweaver/orchestrator/orchestrator.py \
13
14
  # .appweaver/orchestrator/workflows/_smoke.orch.yaml --non-interactive --json
14
- # Expected: status ok, echo=hello, sum of foreach passes, smoke.md written.
15
+ # Expected: status ok, echo=hello, sum of foreach passes, smoke.md and
16
+ # SmokeGenerated.cs written, review_pass=true.
15
17
  # =============================================================================
16
18
 
17
19
  name: orch-smoke
@@ -138,6 +140,40 @@ workflow:
138
140
  action: verify_context
139
141
  required_files: ["{{out_dir}}/smoke.md"]
140
142
 
143
+ # agent_generate — the edit step: the agent writes the file itself and reports
144
+ # files[]. The mock names the file after the task's first `backtick` word and
145
+ # writes it under out_dir; a reported path not on disk is dropped before binding,
146
+ # so the non-empty gate proves the file was written.
147
+ - id: gen_file
148
+ action: agent_generate
149
+ tools: "Read,Write,Edit"
150
+ permission_mode: acceptEdits
151
+ task: |
152
+ Write exactly one file, {{out_dir}}/SmokeGenerated.cs, holding the single
153
+ line `SmokeGenerated` and nothing else. Write nothing outside {{out_dir}}.
154
+ outputs:
155
+ - { name: gen_files, from: "$.files" }
156
+ - id: gate_gen
157
+ action: verify_context
158
+ require_non_empty: gen_files
159
+ on_empty: stop
160
+ on_empty_message: "agent_generate wrote nothing, or files[] binding is broken"
161
+
162
+ # agent_review — read-only review of the files the generation reported; the
163
+ # mock passes when every reviewed file exists
164
+ - id: review_file
165
+ action: agent_review
166
+ review_of_var: gen_files
167
+ task: Check that the file holds the single line SmokeGenerated. Decide pass/fail.
168
+ outputs:
169
+ - { name: review_pass, from: "$.pass" }
170
+ - { name: review_issues, from: "$.issues" }
171
+ - id: gate_review
172
+ action: verify_context
173
+ require_true: review_pass
174
+ on_false: stop
175
+ on_false_message: "agent_review result binding is broken"
176
+
141
177
  # F9: include — the shared domain-select module (read-only script + asks;
142
178
  # non-interactive: gate→continue, mode→all)
143
179
  - id: domain
@@ -156,5 +192,7 @@ outputs:
156
192
  mode: "{{mode}}"
157
193
  seen: "{{seen}}"
158
194
  q_items: "{{q_items}}"
195
+ generated: "{{gen_files}}"
196
+ review_pass: "{{review_pass}}"
159
197
  domain: "{{domain}}"
160
198
  note: "all engine constructs exercised"
@@ -141,7 +141,7 @@ workflow:
141
141
  on_false: stop
142
142
  on_false_message: >
143
143
  No .NET host/startup project found — nothing named Program.cs under `{{host_search}}`,
144
- the source path the backend lane declares, nor elsewhere in this repository. Wiring a
144
+ the lane root folder the backend lane declares, nor elsewhere in this repository. Wiring a
145
145
  component means editing a host project's startup registration, so there has to be one
146
146
  to edit. If this is a .NET repository, scaffold it first with /appweaver foundation.
147
147
  If it is not — this lane's ecosystem is `{{host_eco}}` — then this catalogue's runbooks
@@ -37,7 +37,7 @@
37
37
  # active_version.json (v1.0) so the CR loop works immediately after.
38
38
  #
39
39
  # GOVERNANCE RECONCILE (the JIT contract, gap-fix #1) — ⏸ HELD, OFF BY DEFAULT.
40
- # onboard established the PROJECT constitution + guardrails/projects/<project>/ rule set
40
+ # onboard established the PROJECT constitution + guardrails/<project>/ rule set
41
41
  # from the whole-repo SCAN, with per-feature specifics marked PROVISIONAL. The reconcile
42
42
  # block below carries this feature's real evidence (BR-/CN-/DC-/IC- ids, code coordinates)
43
43
  # INTO that scaffold — upgrading provisional → evidenced. It RECONCILES, never re-authors:
@@ -55,7 +55,7 @@
55
55
  #
56
56
  # Adopt does NOT generate code and does NOT modify source — writes land under
57
57
  # specs/<Context>/<Feature>/, in the context's specs/<Context>/domain-model.md, and in the
58
- # aggregate's OKF concept; the constitution halves and guardrails/projects/<project>/ are
58
+ # aggregate's OKF concept; the constitution halves and guardrails/<project>/ are
59
59
  # written only when the reconcile block below is enabled.
60
60
  # Fidelity checks spec/design ↔ CODE; the Adopt review is REPORTED for out-of-band
61
61
  # closure — it blocks only on structural failures (unmapped code / fabricated spec/design).
@@ -111,7 +111,7 @@ scripts:
111
111
  # Sticky standards seed = the UNIVERSAL always-on rule only (ai-rules). The TECHNICAL/
112
112
  # architecture set for the reversed DESIGN step (mirrors aw-spec-design) is no longer
113
113
  # hardcoded here — it is now CONFIGURATION, loaded per-command from
114
- # guardrails/projects/<project>/tech-rule-bindings.md under "## /aw-spec-adopt" by the
114
+ # guardrails/<project>/tech-rule-bindings.md under "## /aw-spec-adopt" by the
115
115
  # tech-select module (see the tech_select step below). The reversed SPEC step runs
116
116
  # include_standards:false and takes its domain frame from constitution.domain.md via
117
117
  # build_context — so design never sees a domain rule file (rule partition preserved); the
@@ -335,7 +335,7 @@ workflow:
335
335
  on_false_message: "No concept for the aggregate '{{aggregate_primary}}' — the one feature '{{feature_name}}' acts on — in the onboard bundle under {{bundle_dir}}. If its bounded context has not been onboarded, run /appweaver onboard <Context> first; {{bundle_dir}}/aggregates/index.md lists each aggregate with the features that act on it. If '{{feature_name}}' is a NEW feature (no existing code), do NOT adopt it — author it through the forward pipeline (/appweaver specify → plan → implement), which onboard already made brownfield-ready."
336
336
 
337
337
  # Governance prerequisite: the reverse steps below are authored AGAINST the project
338
- # onboard established (the constitution halves + guardrails/projects/<project>/ rule set).
338
+ # onboard established (the constitution halves + guardrails/<project>/ rule set).
339
339
  # Resolve the active domain now and require its rule map to exist — without it there is
340
340
  # no code-derived rule set for tech_select to load, no domain frame for the reversed
341
341
  # spec, and nothing for the reconcile block to upgrade when it is enabled. Reconciling
@@ -363,10 +363,10 @@ workflow:
363
363
  action: verify_context
364
364
  require_true: rulemap_exists
365
365
  on_false: stop
366
- on_false_message: "No active governance for adopt to work against — run /appweaver onboard first. onboard establishes the PROJECT constitution + guardrails/projects/<project>/ rule set (provisional-from-scan) and activates it. Reversing '{{feature_name}}' without that scaffold would author the spec and design against no code-derived rules at all, and leave them with no governance home."
366
+ on_false_message: "No active governance for adopt to work against — run /appweaver onboard first. onboard establishes the PROJECT constitution + guardrails/<project>/ rule set (provisional-from-scan) and activates it. Reversing '{{feature_name}}' without that scaffold would author the spec and design against no code-derived rules at all, and leave them with no governance home."
367
367
 
368
368
  # TECHNICAL rule files → sticky standards (configuration, not hardcoded). tech-select
369
- # reads guardrails/projects/<project>/tech-rule-bindings.md under "## /aw-spec-adopt" and
369
+ # reads guardrails/<project>/tech-rule-bindings.md under "## /aw-spec-adopt" and
370
370
  # loads that reference set into the sticky standards for reverse_plan
371
371
  # (include_standards:true) — the reversed SPEC and MODEL steps turn it off
372
372
  # (include_standards:false), keeping them free of architecture (rule partition). No domain
@@ -1119,7 +1119,7 @@ workflow:
1119
1119
  # ═══════════ GOVERNANCE RECONCILE — upgrade onboard's PROVISIONAL scaffold ═══
1120
1120
  # ⏸ HELD 2026-07-29: every step in this block is gated on `reconcile_governance`
1121
1121
  # (default "false"), so adopt currently does NOT touch the constitution halves
1122
- # or the guardrails/projects/<project>/ rule set — onboard's provisional scaffold
1122
+ # or the guardrails/<project>/ rule set — onboard's provisional scaffold
1123
1123
  # is left as-is. Flip the var to "true" (workflow vars) to restore the behaviour.
1124
1124
  # Now that this feature is reversed to a TRUSTWORTHY spec (real BR-/CN-/DC-/IC- ids)
1125
1125
  # + design (real code coordinates), reconcile that evidence INTO the governance
@@ -1145,7 +1145,7 @@ workflow:
1145
1145
  - { path: "{{spec_file}}" } # the feature's real BR-/CN-/DC-/IC-
1146
1146
  - { path: "{{backend_plan}}" }
1147
1147
  - { path: "{{feature_dir}}/source-map.md" }
1148
- - { path: "guardrails/projects/{{gov_domain}}/domain-rule-bindings.md", optional: true }
1148
+ - { path: "guardrails/{{gov_domain}}/domain-rule-bindings.md", optional: true }
1149
1149
  - { path: .appweaver/RULE-PARTITION.md } # the rule-partition authority (which command reads what)
1150
1150
  - id: reconcile_pack
1151
1151
  condition: "{{reconcile_governance}} == true" # HELD — governance reconcile paused (see vars)
@@ -1153,12 +1153,12 @@ workflow:
1153
1153
  tools: "Read,Write,Edit"
1154
1154
  permission_mode: acceptEdits
1155
1155
  task: |
1156
- RECONCILE the domain rule-file set in guardrails/projects/{{gov_domain}}/domain/ with the
1156
+ RECONCILE the domain rule-file set in guardrails/{{gov_domain}}/domain/ with the
1157
1157
  newly-adopted feature '{{feature_name}}'. onboard authored these rule files from the
1158
1158
  whole-repo scan with per-feature specifics marked `PROVISIONAL — reconciled at
1159
1159
  adopt`. READ this feature's reversed spec.md + backend-plan.md + source-map.md (in
1160
1160
  context — the real evidence) and the EXISTING rule files under
1161
- guardrails/projects/{{gov_domain}}/.
1161
+ guardrails/{{gov_domain}}/.
1162
1162
 
1163
1163
  RECONCILE, do NOT re-author:
1164
1164
  - UPGRADE the provisional entries this feature now evidences: replace a
@@ -1174,7 +1174,7 @@ workflow:
1174
1174
  - Preserve the RULE PARTITION in domain-rule-bindings.md (constitution / specify / gate get
1175
1175
  the domain files; design / implement get None). Keep each file's frontmatter and
1176
1176
  note in `generated_by` that adopt reconciled '{{feature_name}}'.
1177
- Write ONLY inside guardrails/projects/{{gov_domain}}/. Report the files changed/added.
1177
+ Write ONLY inside guardrails/{{gov_domain}}/. Report the files changed/added.
1178
1178
  outputs:
1179
1179
  - { name: pack_reconciled, from: "$.files" }
1180
1180
 
@@ -1250,7 +1250,7 @@ workflow:
1250
1250
  - { path: "{{constitution_domain_file}}" }
1251
1251
  - { path: "{{constitution_technical_file}}" }
1252
1252
  - { path: "{{spec_file}}" }
1253
- - { path: "guardrails/projects/{{gov_domain}}/domain-rule-bindings.md", optional: true }
1253
+ - { path: "guardrails/{{gov_domain}}/domain-rule-bindings.md", optional: true }
1254
1254
  - id: reconcile_domain
1255
1255
  condition: "{{reconcile_governance}} == true" # HELD — governance reconcile paused (see vars)
1256
1256
  action: agent_author
@@ -1351,4 +1351,4 @@ outputs:
1351
1351
  composed_file: "{{composed_file}}"
1352
1352
  technical_reconcile_ok: "{{technical_ok}}"
1353
1353
  domain_reconcile_ok: "{{domain_ok}}"
1354
- next: "Adopted {{feature_name}} (spec.md + backend-plan.md + source-map.md, v1.0) and wrote {{aggregate_sections}} — the model section(s) for the aggregate(s) it acts on, resolved from the {{aggregate_source}} — in the bounded context `{{context}}`'s shared {{domain_model}}. The spec cites BR-nnn by id, the model carries their text, so this slice is checkable by the same gates as a greenfield one and analyze-plan's check 4 now has a model to check against. A section another feature over the same aggregate wrote first was EXTENDED, never duplicated; every other section is untouched. COMPLETED the OKF concept of {{aggregate_primary}} (deepened + linked the deep artifacts; {{xref_edge_count}} cross-slice edge(s) recorded). UI HALF: ui_lane={{ui_lane}} — where it is true this slice also has frontend-plan.md, reversed from the {{ui_count}} UI file(s) the feature map attributes to it; where it is false the repo declared no frontend lane, or this aggregate owns no part of its surface, and a service-only adoption is the correct outcome rather than a gap. In the second case, where a frontend lane IS declared, the feature records lanes=[backend] in its active_version.json (feature_lanes shows it), so plan and the analyze gates treat the frontend lane as absent for THIS feature; run `aw-spec-actions feature-lanes --clear` if it later gains a UI. The SHARED UI surface (app shell, layout, design system) belongs to no slice and stays in {{bundle_dir}}/architecture/frontend.md. NOTE — governance reconcile is currently HELD (reconcile_governance=false): this run did NOT modify the constitution halves or the guardrails/projects/{{gov_domain}}/ rule set, so they keep onboard's provisional scaffold. Close any items in {{feature_dir}}/adopt-review-report.md out of band. The slice is now a NORMAL feature: refine via /appweaver analyze-plan, then drive every change through the CR delta loop (/appweaver specify → plan → analyze-plan-delta → implement → build → analyze-slice-delta → finalize-delta → analyze-slice → close-delta). If a change edits untested legacy behaviour with blast radius, characterize just that surface first (optional on-touch fence). To restore governance reconcile, set reconcile_governance to \"true\" in the workflow vars."
1354
+ next: "Adopted {{feature_name}} (spec.md + backend-plan.md + source-map.md, v1.0) and wrote {{aggregate_sections}} — the model section(s) for the aggregate(s) it acts on, resolved from the {{aggregate_source}} — in the bounded context `{{context}}`'s shared {{domain_model}}. The spec cites BR-nnn by id, the model carries their text, so this slice is checkable by the same gates as a greenfield one and analyze-plan's check 4 now has a model to check against. A section another feature over the same aggregate wrote first was EXTENDED, never duplicated; every other section is untouched. COMPLETED the OKF concept of {{aggregate_primary}} (deepened + linked the deep artifacts; {{xref_edge_count}} cross-slice edge(s) recorded). UI HALF: ui_lane={{ui_lane}} — where it is true this slice also has frontend-plan.md, reversed from the {{ui_count}} UI file(s) the feature map attributes to it; where it is false the repo declared no frontend lane, or this aggregate owns no part of its surface, and a service-only adoption is the correct outcome rather than a gap. In the second case, where a frontend lane IS declared, the feature records lanes=[backend] in its active_version.json (feature_lanes shows it), so plan and the analyze gates treat the frontend lane as absent for THIS feature; run `aw-spec-actions feature-lanes --clear` if it later gains a UI. The SHARED UI surface (app shell, layout, design system) belongs to no slice and stays in {{bundle_dir}}/architecture/frontend.md. NOTE — governance reconcile is currently HELD (reconcile_governance=false): this run did NOT modify the constitution halves or the guardrails/{{gov_domain}}/ rule set, so they keep onboard's provisional scaffold. Close any items in {{feature_dir}}/adopt-review-report.md out of band. The slice is now a NORMAL feature: refine via /appweaver analyze-plan, then drive every change through the CR delta loop (/appweaver specify → plan → analyze-plan-delta → implement → build → analyze-slice-delta → finalize-delta → analyze-slice → close-delta). If a change edits untested legacy behaviour with blast radius, characterize just that surface first (optional on-touch fence). To restore governance reconcile, set reconcile_governance to \"true\" in the workflow vars."
@@ -158,7 +158,7 @@ workflow:
158
158
  with: { command: aw-spec-analyze-slice }
159
159
 
160
160
  # 1. WHICH LANES EXIST. Declaration only — this gate reads code, it does not write it, so
161
- # it has no reason to require a source path on disk.
161
+ # it has no reason to require a lane root folder on disk.
162
162
  - id: lane_resolve
163
163
  action: execute_script
164
164
  on_error: continue
@@ -448,7 +448,7 @@ workflow:
448
448
  the pre-existing slice.
449
449
 
450
450
  CHECK 7 — PLACEMENT. Every file this change added or edited sits under the lane that
451
- owns it: this lane's production code under its source path `{{be_source_path}}`, its
451
+ owns it: this lane's production code under its lane root folder `{{be_source_path}}`, its
452
452
  tests under its test path `{{be_test_path}}`. A service-lane element written into the
453
453
  frontend lane's subtree — or outside every lane's paths — is a HIGH `placement` gap.
454
454
  One edit outside them is allowed: registering a test project this change created in
@@ -542,7 +542,7 @@ workflow:
542
542
  gap. Judge it only over what this change touched.
543
543
 
544
544
  CHECK 7 — PLACEMENT. Every file this change added or edited sits under this lane's
545
- source path, `{{fe_source_path}}`, or — for a test — its test path, `{{fe_test_path}}`.
545
+ lane root folder, `{{fe_source_path}}`, or — for a test — its test path, `{{fe_test_path}}`.
546
546
  A file written into the service lane's subtree is a HIGH `placement` gap — a gap in the
547
547
  service surface is a contract delta raised back to that lane, never a client-side edit
548
548
  to it. The one edit allowed outside them is the test setup this change had to create,
@@ -85,7 +85,7 @@ scripts:
85
85
 
86
86
  # No hardcoded technical standards seed. The technical rule files the code/conformance
87
87
  # passes check against (testing + coding-standards) are now CONFIGURATION, loaded per-
88
- # command from guardrails/projects/<project>/tech-rule-bindings.md under "## /aw-spec-analyze-slice"
88
+ # command from guardrails/<project>/tech-rule-bindings.md under "## /aw-spec-analyze-slice"
89
89
  # by the tech-select module (see the tech_select step below). The DOMAIN gate overlays are
90
90
  # still loaded separately, as before (resolve_gate_overlays → load_gate_overlays). This gate
91
91
  # does not reference constitution.technical.md. The seed below is behaviour-only — the kit's
@@ -149,7 +149,7 @@ vars:
149
149
  workflow:
150
150
 
151
151
  # 0. TECHNICAL rule files → sticky standards (configuration, not hardcoded).
152
- # tech-select reads guardrails/projects/<project>/tech-rule-bindings.md under
152
+ # tech-select reads guardrails/<project>/tech-rule-bindings.md under
153
153
  # "## /aw-spec-analyze-slice" and loads that set (testing + coding-standards) into
154
154
  # the sticky standards the conformance query reads (include_standards: true). The
155
155
  # DOMAIN gate overlays are loaded separately below. No blocking gate: an unconfigured
@@ -559,7 +559,7 @@ workflow:
559
559
  mock: { ok: true, unbound: [], notes: [] }
560
560
  task: |
561
561
  WOULD THIS SLICE RUN? Check the service lane's composition against its code.
562
- The lane is `{{be_lane_id}}` and its source path is `{{be_source_path}}`; the
562
+ The lane is `{{be_lane_id}}` and its lane root folder is `{{be_source_path}}`; the
563
563
  backend plan is in context, and its §2.1 Ports, §4.1 Persistence and §4.3 Wiring
564
564
  say what has to be bound.
565
565
 
@@ -26,7 +26,7 @@
26
26
  # compiled by its own build command, so what this stage needs is a declaration to compile
27
27
  # from, not a particular kind of one; requiring the service lane blocked a frontend-only
28
28
  # project that `plan` and `implement` both accept. The rest of the gate is unchanged: no
29
- # lane declared, a lane with no source path, a source path that is not on disk, and two
29
+ # lane declared, a lane with no lane root folder, a lane root folder that is not on disk, and two
30
30
  # lanes claiming overlapping subtrees all still stop the run.
31
31
  #
32
32
  # Launch: /appweaver build [strategy]
@@ -48,7 +48,7 @@ scripts:
48
48
 
49
49
  # Sticky standards seed = the UNIVERSAL always-on rule only (ai-rules). The technical
50
50
  # rule files (the compile/fix reference set) are CONFIGURATION, loaded per-command from
51
- # guardrails/projects/<project>/tech-rule-bindings.md by the tech-select module (see the
51
+ # guardrails/<project>/tech-rule-bindings.md by the tech-select module (see the
52
52
  # tech_select step below). Technical rules ONLY — build loads no domain rules and does
53
53
  # not reference constitution.technical.md. A required file that is missing is reported
54
54
  # at assembly time (`[system] MISSING (required)`), an `optional:` one is skipped.
@@ -61,7 +61,7 @@ vars:
61
61
  workflow:
62
62
 
63
63
  # Rule files → sticky standards: TECHNICAL only, via tech-select, read from
64
- # guardrails/projects/<project>/tech-rule-bindings.md under "## /aw-spec-build".
64
+ # guardrails/<project>/tech-rule-bindings.md under "## /aw-spec-build".
65
65
  # NO domain-select here — see the header: build repairs compile errors, a purely
66
66
  # technical job, and the domain never reaches this stage anyway (specify is its sole
67
67
  # carrier; build reads code and design intent, not spec).
@@ -90,7 +90,7 @@ workflow:
90
90
  # project compiles the one it has, whichever kind that is. A frontend-only project is a
91
91
  # legal project: `plan` and `implement` both accept one, so refusing it here stopped it
92
92
  # at the first stage that had no reason to care. Passing no required kind leaves every
93
- # other check armed — no lane declared at all, a lane with no source path, a source path
93
+ # other check armed — no lane declared at all, a lane with no lane root folder, a lane root folder
94
94
  # that is not on disk, and two lanes claiming overlapping subtrees.
95
95
  - id: lane_gate
96
96
  action: include
@@ -58,7 +58,7 @@ scripts:
58
58
  # Sticky standards seed = the UNIVERSAL always-on rule only (ai-rules). The FRAMEWORK /
59
59
  # test-generation set (same as implement/analyze-slice — HOW to write + place tests) is no
60
60
  # longer hardcoded here — it is now CONFIGURATION, loaded per-command from
61
- # guardrails/projects/<project>/tech-rule-bindings.md under "## /aw-spec-characterize" by the
61
+ # guardrails/<project>/tech-rule-bindings.md under "## /aw-spec-characterize" by the
62
62
  # tech-select module (see the tech_select step below). No domain files: the behaviour to
63
63
  # fence comes from the CODE + the adopted spec/design/source-map (constitution.technical.md
64
64
  # is referred to directly as context), not from domain rules — the tech map lists only
@@ -79,7 +79,7 @@ vars:
79
79
  workflow:
80
80
 
81
81
  # 0. TECHNICAL rule files → sticky standards (configuration, not hardcoded). tech-select
82
- # reads guardrails/projects/<project>/tech-rule-bindings.md under "## /aw-spec-characterize"
82
+ # reads guardrails/<project>/tech-rule-bindings.md under "## /aw-spec-characterize"
83
83
  # and loads that test-generation set into the sticky standards the agent_generate steps
84
84
  # ALWAYS prepend. No domain rule file is loaded here — the tech map lists only technical
85
85
  # files. No blocking gate: an unconfigured project soft-continues (the golden-master is
@@ -2,7 +2,7 @@
2
2
  # aw-spec-constitution (orchestrator) — create/update the SPLIT project constitution
3
3
  #
4
4
  # Authors up to THREE files. Each ratifies its own MAPPED rule set. The two maps live in
5
- # the ACTIVE PROJECT (guardrails/projects/<project>/); the files they list live in the
5
+ # the ACTIVE PROJECT (guardrails/<project>/); the files they list live in the
6
6
  # shared corpora (guardrails/technology/<stack>/, guardrails/domain/<industry>/), except
7
7
  # the three the project's own team authors:
8
8
  # .appweaver/memory/constitution.technical.md ← "## /aw-spec-constitution" in
@@ -72,6 +72,13 @@
72
72
  # a bounded self-correction loop (max 3) — so the whole skill works under every
73
73
  # strategy (sdk/sdk-apply/spawn/agent), --checkpoint, or headless.
74
74
  #
75
+ # THE DEFAULT SCOPE. On a project with no specs yet the run ends by creating the bounded
76
+ # context MainContext and its feature CoreFeature (specs/MainContext/CoreFeature/) and
77
+ # making both active, so a simple project goes from constitution straight to specify.
78
+ # Any other state is left alone. A developer who wants other names runs
79
+ # select-bounded-context and select-feature, which re-point both pointer files; the empty
80
+ # default folders can then be deleted.
81
+ #
75
82
  # NOT part of the per-feature pipeline. Project-level, run-once / amend-on-change.
76
83
  #
77
84
  # Launch: /appweaver constitution [strategy] [principles or values…]
@@ -79,8 +86,8 @@
79
86
  # =============================================================================
80
87
 
81
88
  name: aw-spec-constitution
82
- description: Create or update the split project constitution — constitution.technical.md (technology base) + constitution.ui.md (the frontend lane's base, only where a lane exists) + constitution.domain.md (active domain addenda), each version-bumped with a Sync Impact Report, then composed into constitution.md. Project-level, run-once/amend — not a per-feature phase.
83
- version: 2.5.0
89
+ description: Create or update the split project constitution — constitution.technical.md (technology base) + constitution.ui.md (the frontend lane's base, only where a lane exists) + constitution.domain.md (active domain addenda), each version-bumped with a Sync Impact Report, then composed into constitution.md. On a project with no specs yet it also creates and activates the default bounded context MainContext and its feature CoreFeature. Project-level, run-once/amend — not a per-feature phase.
90
+ version: 2.6.0
84
91
  agent_agnostic: true
85
92
  dialect: aw-spec.orchestrator/v1
86
93
 
@@ -97,7 +104,7 @@ scripts:
97
104
 
98
105
  # Sticky standards seed = the UNIVERSAL always-on rule only (ai-rules). The technology-
99
106
  # constitution base the TECHNICAL half ratifies is no longer hardcoded here — it is now
100
- # CONFIGURATION, loaded per-command from guardrails/projects/<project>/tech-rule-bindings.md
107
+ # CONFIGURATION, loaded per-command from guardrails/<project>/tech-rule-bindings.md
101
108
  # under "## /aw-spec-constitution" by the tech-select module (see the tech_select step
102
109
  # below). tech_select runs BEFORE the technical half AND before domain-select, so the
103
110
  # technical author still sees only the technology base + ai-rules — NO domain file: the
@@ -112,6 +119,11 @@ vars:
112
119
  domain_ok: "false" # domain-half validation-loop guard, flipped by constitution-verify
113
120
  ui_ok: "false" # UI-half validation-loop guard, flipped by constitution-verify
114
121
  ui_lane: "false" # set by the three-signal probe below; gates the whole UI block
122
+ default_context: "MainContext" # the bounded context a project with no specs yet starts in
123
+ default_feature: "CoreFeature" # the feature created inside it and made active
124
+ scope_created: "false" # default-scope: whether this run created the pair
125
+ scope_skipped: "" # default-scope: why it did not, when it did not
126
+ active_feature_dir: "" # default-scope: the active feature after the step
115
127
 
116
128
  workflow:
117
129
 
@@ -121,7 +133,7 @@ workflow:
121
133
  # what makes `(none)` in select-stack a real declaration rather than a shrug.
122
134
  #
123
135
  # --allow-missing-root because nothing here reads the subtree: constitution
124
- # ratifies rules, and a greenfield project's source path does not exist until
136
+ # ratifies rules, and a greenfield project's lane root folder does not exist until
125
137
  # implement creates it. The on-disk check belongs to the phases that read code.
126
138
  - id: lane_model
127
139
  action: execute_script
@@ -179,7 +191,7 @@ workflow:
179
191
  vars: { svc_lane: "true", setup_tech_flag: "" }
180
192
 
181
193
  # 0. TECHNICAL rule files → sticky standards (configuration, not hardcoded). tech-select
182
- # reads guardrails/projects/<project>/tech-rule-bindings.md under "## /aw-spec-constitution"
194
+ # reads guardrails/<project>/tech-rule-bindings.md under "## /aw-spec-constitution"
183
195
  # and loads the technology-constitution base into the sticky standards the TECHNICAL
184
196
  # half ratifies. Placed FIRST — before the technical half AND before domain-select — so
185
197
  # the technical author sees only technical files: the seam that keeps it domain-free is
@@ -376,7 +388,7 @@ workflow:
376
388
  vars:
377
389
  ui_lane: "true"
378
390
  ui_stack: "{{fe_lane_profile}}"
379
- ui_evidence: "lane '{{fe_lane_id}}' ({{fe_lane_profile}}) is declared in .appweaver/stacks.json, owning the source path {{fe_lane_root}}"
391
+ ui_evidence: "lane '{{fe_lane_id}}' ({{fe_lane_profile}}) is declared in .appweaver/stacks.json, owning the lane root folder {{fe_lane_root}}"
380
392
 
381
393
  # 9. A mapped UI rule set with no lane to govern. Not fatal and not a reason to
382
394
  # author the half — the declaration decides that — but worth saying out loud,
@@ -405,8 +417,8 @@ workflow:
405
417
  No frontend lane in .appweaver/stacks.json — skipping the UI constitution half
406
418
  (constitution.ui.md is not created). This is the expected path for a backend-only
407
419
  project. To author it, run `/appweaver select-stack`, pick a UI stack and give
408
- it a source path, then re-run `/appweaver constitution`. Mapping
409
- `## /aw-spec-ui-constitution` in guardrails/projects/<project>/tech-rule-bindings.md
420
+ it a lane root folder, then re-run `/appweaver constitution`. Mapping
421
+ `## /aw-spec-ui-constitution` in guardrails/<project>/tech-rule-bindings.md
410
422
  supplies the rules that half ratifies, but no longer creates the lane on its own —
411
423
  a lane exists because the project declared it.
412
424
 
@@ -693,7 +705,41 @@ workflow:
693
705
  removed automatically. Delete that file by hand if the lane is gone for good and
694
706
  re-run; otherwise restore the lane's signal.
695
707
 
696
- # 21. Post-execution hooks.
708
+ # 21. THE DEFAULT SCOPE. A project with no specs yet gets the bounded context named by
709
+ # default_context and the feature named by default_feature inside it, both made
710
+ # active, so /appweaver specify can run next with no select command in between.
711
+ # default-scope acts only when specs/ holds no directory and no feature is active;
712
+ # every other state is reported as skipped and left untouched, so amending the
713
+ # constitution never moves the active feature and an onboarded brownfield tree is
714
+ # never added to.
715
+ - id: default_scope
716
+ action: execute_script
717
+ script: { ref: actions }
718
+ subcommand: default-scope
719
+ args: ["--context", "{{default_context}}", "--feature", "{{default_feature}}"]
720
+ outputs:
721
+ - { name: scope_created, from: "$.created" }
722
+ - { name: scope_skipped, from: "$.skipped_reason" }
723
+ - { name: active_feature_dir, from: "$.feature_dir" }
724
+
725
+ # 21b. Say what was created and how to choose other names. The never-satisfiable
726
+ # `equals` is the engine's announce-only idiom: the step is entered only when the
727
+ # pair was created, and the comparison always misses, so the message is emitted
728
+ # and the run continues.
729
+ - id: default_scope_notice
730
+ action: verify_context
731
+ condition: "{{scope_created}} == true"
732
+ require_value: scope_created
733
+ equals: "never"
734
+ on_mismatch: continue
735
+ on_mismatch_message: >
736
+ Created the default bounded context {{default_context}} and its feature
737
+ {{default_feature}} at {{active_feature_dir}}/ and made both active, so
738
+ /appweaver specify <what it does> can run next. To use your own names instead, run
739
+ /appweaver select-bounded-context <Name> and then /appweaver select-feature <Name>;
740
+ the empty default folders can then be deleted.
741
+
742
+ # 22. Post-execution hooks.
697
743
  - id: resolve_post_hooks
698
744
  action: execute_script
699
745
  script: { ref: actions }
@@ -723,5 +769,8 @@ outputs:
723
769
  ui_rule_files: "{{ui_rule_files}}"
724
770
  ui_validation_ok: "{{ui_ok}}"
725
771
  ui_validation_issues: "{{ui_issues}}"
726
- note: "Split constitution authored, one half per LANE the project declared in .appweaver/stacks.json. service_lane / ui_lane report which lanes were found there, and the declaration is the ONLY signal read: a half is a lane's standing governance, so a lane declared `(none)` in select-stack gets no half AND no file. constitution.technical.md is the service lane's base (standing input to the SERVICE lane of plan + implement); constitution.ui.md is the UI lane's UX-* base (standing input to their FRONTEND lane); constitution.domain.md is the domain addenda (standing input to specify + a gate checklist), and it is always authored because domain is not a lane — it addends whichever halves exist. All are composed into constitution.md, which now tolerates an absent technical half: a UI-only project's domain half opens the roman-numeral sequence at I instead of continuing one, and numbering_checked reports false because that check has no subject rather than because it silently passed. Mapping ## /aw-spec-ui-constitution supplies the rules the UI half ratifies but no longer creates the lane on its own — a mapped rule set with no declared lane produces a warning naming both fixes. ui_lane false with ui_included true means a lane was retired after its half was authored: the file is left alone and the log says so, because a ratified governance file is never deleted automatically. If a validation_ok is false, the matching validation_issues lists what still needs a manual touch. See each half's Sync Impact Report for its version bump. Suggested commit: 'docs: amend split constitution'."
727
- next: "/appweaver select-feature → specify. select-feature picks the feature to build and every stage from specify onward reads that active feature and stops without it; on a brownfield workspace pick the bounded context first with /appweaver select-bounded-context. From specify the greenfield sequence runs plan → analyze-plan → implement → build → analyze-slice → run → deploy. THE HALVES ARE LOADED PER CONCERN, not all at once — /appweaver specify loads constitution.domain.md; the SERVICE lane of plan + implement loads constitution.technical.md; their FRONTEND lane loads constitution.ui.md. Re-run /appweaver constitution to amend, including to pick up a lane declared or dropped after this run — re-run /appweaver select-stack first to change which lanes exist."
772
+ default_scope_created: "{{scope_created}}"
773
+ default_scope_skipped: "{{scope_skipped}}"
774
+ active_feature: "{{active_feature_dir}}"
775
+ note: "Split constitution authored, one half per LANE the project declared in .appweaver/stacks.json. service_lane / ui_lane report which lanes were found there, and the declaration is the ONLY signal read: a half is a lane's standing governance, so a lane declared `(none)` in select-stack gets no half AND no file. constitution.technical.md is the service lane's base (standing input to the SERVICE lane of plan + implement); constitution.ui.md is the UI lane's UX-* base (standing input to their FRONTEND lane); constitution.domain.md is the domain addenda (standing input to specify + a gate checklist), and it is always authored because domain is not a lane — it addends whichever halves exist. All are composed into constitution.md, which now tolerates an absent technical half: a UI-only project's domain half opens the roman-numeral sequence at I instead of continuing one, and numbering_checked reports false because that check has no subject rather than because it silently passed. Mapping ## /aw-spec-ui-constitution supplies the rules the UI half ratifies but no longer creates the lane on its own — a mapped rule set with no declared lane produces a warning naming both fixes. ui_lane false with ui_included true means a lane was retired after its half was authored: the file is left alone and the log says so, because a ratified governance file is never deleted automatically. If a validation_ok is false, the matching validation_issues lists what still needs a manual touch. See each half's Sync Impact Report for its version bump. DEFAULT SCOPE: on a project with no specs yet this run created the bounded context {{default_context}} and its feature {{default_feature}} and made both active (default_scope_created true); any other state is left untouched and default_scope_skipped says why. active_feature is the feature specify will write to. Suggested commit: 'docs: amend split constitution'."
776
+ next: "/appweaver specify <what the feature does> when active_feature is set — on a project with no specs yet that is the default {{default_context}}/{{default_feature}} this run created. To use your own names, run /appweaver select-bounded-context <Name> and then /appweaver select-feature <Name> first; the empty default folders can then be deleted. When no feature is active, run /appweaver select-feature first — every stage from specify onward reads the active feature and stops without it; if the repo uses bounded contexts, pick one with /appweaver select-bounded-context before it, since once any context exists select-feature refuses to run without one. From specify the greenfield sequence runs plan → analyze-plan → implement → build → analyze-slice → run → deploy. THE HALVES ARE LOADED PER CONCERN, not all at once — /appweaver specify loads constitution.domain.md; the SERVICE lane of plan + implement loads constitution.technical.md; their FRONTEND lane loads constitution.ui.md. Re-run /appweaver constitution to amend, including to pick up a lane declared or dropped after this run — re-run /appweaver select-stack first to change which lanes exist."