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
@@ -28,7 +28,7 @@
28
28
  #
29
29
  # EACH LANE IS GATED ON ITS OWN, AND A LANE'S GAP IS NOT THE RUN'S. A declared lane needs
30
30
  # two things before it can generate: the plan for THIS run (its master plan, or this
31
- # change's delta plan) and a scaffolded project under the source path it declares. A lane
31
+ # change's delta plan) and a scaffolded project under the lane root folder it declares. A lane
32
32
  # that is missing either is REPORTED with the fix named and SKIPPED — the other lane still
33
33
  # runs. Failing the whole command for the frontend's sake is how a backend that was ready
34
34
  # goes unbuilt; failing silently is how a frontend that was never generated reports green.
@@ -87,9 +87,10 @@
87
87
  # • FRONTEND — `## /aw-spec-implement-ui`, both paths. There was never a delta heading
88
88
  # for this lane because the delta half of it was never built; it is built here.
89
89
  #
90
- # TWO PATHS PER LANE. Each lane owns the source path stacks.json declares for it and the
91
- # test path lane-verify resolves beside it — `tests/` next to a .NET `src/`, the source
92
- # path itself for a stack that keeps its tests inside — and writes nothing outside them.
90
+ # TWO PATHS PER LANE. Each lane owns the lane root folder stacks.json declares for it and the
91
+ # test path lane-verify resolves for it — `backend/tests/` inside a new lane root folder,
92
+ # `tests/` next to a classic .NET `src/`, the lane root folder itself for a stack that keeps
93
+ # its tests inside — and writes nothing outside them.
93
94
  # The one exception is registering a test project the lane had to create, in whatever
94
95
  # file the lane's test command discovers tests through (a .NET solution file). A file
95
96
  # written elsewhere belongs to the other lane or to no lane at all, and the project gate
@@ -99,35 +100,35 @@
99
100
  #
100
101
  # A FILE LIST IS NOT A FINISHED LANE. Each generating lane is handed its plan's element
101
102
  # list and reports every element back as done or blocked; `plan-coverage` then checks the
102
- # code under the lane's source path for every identifier the plan introduces. Whatever
103
+ # code under the lane root folder for every identifier the plan introduces. Whatever
103
104
  # either check leaves open gets one completion pass, and anything still open after it
104
105
  # stops the run once both lanes have generated — so a pass that stopped at five use-cases
105
106
  # of seven is reported, not shipped.
106
107
  #
107
108
  # A LANE'S GAP DISABLES THAT LANE, NOT THE RUN. Three things a lane needs are checked per
108
- # lane and reported per lane: its source path is on disk, its plan is there, and a project
109
+ # lane and reported per lane: its lane root folder is on disk, its plan is there, and a project
109
110
  # is scaffolded under it. Any of them missing skips that lane with the command that fixes
110
111
  # it named, and every other declared lane still generates; only when NOTHING can run does
111
112
  # the run stop, with all the reasons printed. The whole-run stop is reserved for states
112
113
  # with no correct lane to fall back on — no lane declared at all, a lane declaring no
113
- # source path, and two lanes claiming overlapping subtrees.
114
+ # lane root folder, and two lanes claiming overlapping subtrees.
114
115
  #
115
116
  # WHAT IT DOES NOT DO. It never writes spec.md, a master plan or the domain model, and it
116
117
  # never closes a change — finalize-delta merges the change's spec and model halves,
117
118
  # analyze-slice verifies the slice, and close-delta archives it and bumps the version.
118
119
  #
119
120
  # Prereqs: /appweaver plan (+ analyze-plan, or analyze-plan-delta for a change), and a
120
- # project scaffolded under each lane's source path — this phase GENERATES into that tree,
121
- # so with no project there is nowhere to place the files. /appweaver foundation unpacks one
122
- # where a bundle ships for the stack; a stack with no bundle scaffolds with its own tooling
123
- # instead, and the gate accepts either, since it tests for a project rather than a bundle.
121
+ # project scaffolded under each lane root folder — this phase GENERATES into that tree,
122
+ # so with no project there is nowhere to place the files. /appweaver foundation scaffolds one,
123
+ # from a pack or from a spec; a team may also scaffold with the stack's own tooling, and the
124
+ # gate accepts any of them, since it tests for a project rather than for how it got there.
124
125
  #
125
126
  # Launch: /appweaver implement [guidance]
126
127
  # /appweaver implement CR-20260910-… (implement THAT open change, no prompt)
127
128
  # =============================================================================
128
129
 
129
130
  name: aw-spec-implement
130
- description: "Generate the aggregate's source files and paired tests from its lane plans — the backend lane from backend-plan.md when a backend stack is declared, the frontend lane from frontend-plan.md when a frontend stack is, both when both are. One command covers backend-only, frontend-only and full-stack projects and absorbs the former implement-ui and implement-delta. Self-detecting off the changes on disk — with none open it generates from the master plans; with one or more open it ASKS which change and generates only what that change's delta plans mark ADDED or MODIFIED, leaving the masters untouched. Every lane is gated on its own source path, its own plan and its own scaffolded project, and a lane missing any of them is reported and skipped rather than failing the other lane; each runnable lane confirms before it writes. Model-driven, and it does not read the spec — analyze-plan already conformed the plans to it. The plan says WHAT to build; the bounded context's domain-model.md, in context alongside it, says what the domain IS — the entity names, the boundary and the text of every invariant the plan cites by id — joined on the delta path by that change's own model delta, since the master is not merged until finalize-delta. The stack binds here from the lane declaration and the constitution halves; the plans stay technology-agnostic."
131
+ description: "Generate the aggregate's source files and paired tests from its lane plans — the backend lane from backend-plan.md when a backend stack is declared, the frontend lane from frontend-plan.md when a frontend stack is, both when both are. One command covers backend-only, frontend-only and full-stack projects and absorbs the former implement-ui and implement-delta. Self-detecting off the changes on disk — with none open it generates from the master plans; with one or more open it ASKS which change and generates only what that change's delta plans mark ADDED or MODIFIED, leaving the masters untouched. Every lane is gated on its own lane root folder, its own plan and its own scaffolded project, and a lane missing any of them is reported and skipped rather than failing the other lane; each runnable lane confirms before it writes. Model-driven, and it does not read the spec — analyze-plan already conformed the plans to it. The plan says WHAT to build; the bounded context's domain-model.md, in context alongside it, says what the domain IS — the entity names, the boundary and the text of every invariant the plan cites by id — joined on the delta path by that change's own model delta, since the master is not merged until finalize-delta. The stack binds here from the lane declaration and the constitution halves; the plans stay technology-agnostic."
131
132
  version: 3.10.0
132
133
  agent_agnostic: true
133
134
  dialect: aw-spec.orchestrator/v1
@@ -148,7 +149,7 @@ scripts:
148
149
 
149
150
  # Sticky standards seed = the UNIVERSAL always-on rule only (ai-rules). Each lane's
150
151
  # FRAMEWORK / code-generation rule files are CONFIGURATION, loaded per-lane from
151
- # guardrails/projects/<project>/tech-rule-bindings.md by the tech-select module (see the
152
+ # guardrails/<project>/tech-rule-bindings.md by the tech-select module (see the
152
153
  # tech_select steps below). Per the rule-partition this phase loads NO domain rule file —
153
154
  # everything domain reached the code through spec → plan. The architecture and UX bases
154
155
  # arrive via constitution.technical.md / constitution.ui.md (referred to directly, as-is —
@@ -272,15 +273,15 @@ workflow:
272
273
  # kind: a backend-only and a frontend-only project are both correct states, and which
273
274
  # lanes exist is exactly what it is here to find out.
274
275
  #
275
- # --allow-missing-root, because a lane whose source path is not on disk is THAT LANE'S
276
+ # --allow-missing-root, because a lane whose lane root folder is not on disk is THAT LANE'S
276
277
  # gap, not the run's. This phase is per-lane throughout — a missing plan or a missing
277
278
  # project is reported at step 5 and the other lane still generates — and a missing root
278
279
  # is the same kind of gap, most often a declared frontend that `foundation` has not
279
- # unpacked yet. With the check left on it arrives here instead, as a whole-run stop
280
+ # scaffolded yet. With the check left on it arrives here instead, as a whole-run stop
280
281
  # that takes the ready lane down with it. It is re-checked per lane at step 5 from
281
282
  # `*_root_exists`, which lane-verify reports whether or not the on-disk half is armed.
282
283
  #
283
- # What still stops the run: no lane declared at all, a lane declaring no source path,
284
+ # What still stops the run: no lane declared at all, a lane declaring no lane root folder,
284
285
  # and two lanes claiming overlapping subtrees. Those are declaration errors with no
285
286
  # correct lane to fall back to, and none of them is a state any phase can work around.
286
287
  - id: lane_verify
@@ -539,8 +540,8 @@ workflow:
539
540
  # detect-project searches the LANE'S OWN subtree for an ecosystem manifest (.sln/
540
541
  # .csproj, pom.xml, build.gradle, package.json, go.mod, Cargo.toml, pyproject.toml),
541
542
  # falls back to the whole repo, and reports which scope answered. How the project got
542
- # there is not asked — `foundation` unpacked it, or the team scaffolded it with the
543
- # stack's own tooling.
543
+ # there is not asked — `foundation` unpacked or built it, or the team scaffolded it with
544
+ # the stack's own tooling.
544
545
  - id: be_detect_project
545
546
  condition: "{{be_declared}} == true"
546
547
  action: execute_script
@@ -555,7 +556,7 @@ workflow:
555
556
  # in a two-lane project is the service lane's manifest, and generating this lane's code
556
557
  # against it is exactly the failure the lane model exists to prevent — a frontend that
557
558
  # was never scaffolded, generated into anyway, reporting green. The service lane accepts
558
- # either scope, because the layout that keeps a manifest beside the lane root rather than
559
+ # either scope, because the layout that keeps a manifest beside the lane root folder rather than
559
560
  # inside it is a normal one for it.
560
561
  - id: fe_detect_project
561
562
  condition: "{{fe_declared}} == true"
@@ -586,13 +587,13 @@ workflow:
586
587
  action: verify_context
587
588
  require_true: be_root_exists
588
589
  on_false: continue
589
- on_false_message: "BACKEND LANE SKIPPED — lane `{{be_lane_id}}` ({{be_title}}) declares source path `{{be_source_path}}` in .appweaver/stacks.json, and that path is not a directory in this repository. A lane owns its subtree and this phase writes into it, so there is nothing to generate into: unpack a project there with /appweaver foundation <FoundationName> <AppName> where a bundle ships for {{be_profile}}, create one with the stack's own tooling, or re-run /appweaver select-stack and point the lane at the directory that really holds its source. Nothing is generated for this lane; any other declared lane still runs."
590
+ on_false_message: "BACKEND LANE SKIPPED — lane `{{be_lane_id}}` ({{be_title}}) declares lane root folder `{{be_source_path}}` in .appweaver/stacks.json, and that path is not a directory in this repository. A lane owns its subtree and this phase writes into it, so there is nothing to generate into: scaffold a project there with /appweaver foundation (a pack or a spec for {{be_profile}}, or a spec you give it), create one with the stack's own tooling, or re-run /appweaver select-stack and point the lane at the directory that really holds its source. Nothing is generated for this lane; any other declared lane still runs."
590
591
  - id: warn_be_project
591
592
  condition: "{{be_declared}} == true"
592
593
  action: verify_context
593
594
  require_true: be_project_ok
594
595
  on_false: continue
595
- on_false_message: "BACKEND LANE SKIPPED — no project found under the {{be_lane_id}} lane's source path `{{be_source_path}}`, nor anywhere else in this repository. This phase GENERATES into an existing project tree, so one has to be scaffolded first: run /appweaver foundation <FoundationName> <AppName> where a foundation bundle ships for {{be_profile}}, or create the project with the stack's own tooling under that path. Any ecosystem manifest marks it — .sln/.csproj, pom.xml, build.gradle(.kts), package.json, go.mod, Cargo.toml or pyproject.toml."
596
+ on_false_message: "BACKEND LANE SKIPPED — no project found under the {{be_lane_id}} lane root folder `{{be_source_path}}`, nor anywhere else in this repository. This phase GENERATES into an existing project tree, so one has to be scaffolded first: run /appweaver foundation, which scaffolds it from a pack or from a spec (one it ships for {{be_profile}}, or one you give it), or create the project with the stack's own tooling under that path. Any ecosystem manifest marks it — .sln/.csproj, pom.xml, build.gradle(.kts), package.json, go.mod, Cargo.toml or pyproject.toml."
596
597
  - id: warn_fe_plan
597
598
  condition: "{{fe_declared}} == true"
598
599
  action: verify_context
@@ -604,15 +605,15 @@ workflow:
604
605
  action: verify_context
605
606
  require_true: fe_root_exists
606
607
  on_false: continue
607
- on_false_message: "FRONTEND LANE SKIPPED — lane `{{fe_lane_id}}` ({{fe_title}}) declares source path `{{fe_source_path}}` in .appweaver/stacks.json, and that path is not a directory in this repository. A lane owns its subtree and this phase writes into it, so there is nothing to generate into: unpack a project there with /appweaver foundation <FoundationName> <AppName> where a bundle ships for {{fe_profile}}, create one with the stack's own tooling, or re-run /appweaver select-stack and point the lane at the directory that really holds its source. Nothing is generated for this lane; any other declared lane still runs."
608
+ on_false_message: "FRONTEND LANE SKIPPED — lane `{{fe_lane_id}}` ({{fe_title}}) declares lane root folder `{{fe_source_path}}` in .appweaver/stacks.json, and that path is not a directory in this repository. A lane owns its subtree and this phase writes into it, so there is nothing to generate into: scaffold a project there with /appweaver foundation (a pack or a spec for {{fe_profile}}, or a spec you give it), create one with the stack's own tooling, or re-run /appweaver select-stack and point the lane at the directory that really holds its source. Nothing is generated for this lane; any other declared lane still runs."
608
609
  - id: warn_fe_project
609
610
  condition: "{{fe_declared}} == true"
610
611
  action: verify_context
611
612
  require_true: fe_project_ok
612
613
  on_false: continue
613
- on_false_message: "FRONTEND LANE SKIPPED — no frontend project found under the {{fe_lane_id}} lane's source path `{{fe_source_path}}`. detect-project searched that subtree and then the whole repository, and answered at scope `{{fe_project_scope}}`; `lane` is the only scope this lane accepts. Scaffold a project there — /appweaver foundation <FoundationName> <AppName> where a bundle ships for {{fe_profile}}, or the stack's own tooling — and re-run implement. A manifest found elsewhere in the repository does NOT count: that one belongs to another lane, and generating this lane's code against it is how a frontend that was never built reports green."
614
+ on_false_message: "FRONTEND LANE SKIPPED — no frontend project found under the {{fe_lane_id}} lane root folder `{{fe_source_path}}`. detect-project searched that subtree and then the whole repository, and answered at scope `{{fe_project_scope}}`; `lane` is the only scope this lane accepts. Scaffold a project there — /appweaver foundation, from a pack or a spec for {{fe_profile}} or a spec you give it, or the stack's own tooling — and re-run implement. A manifest found elsewhere in the repository does NOT count: that one belongs to another lane, and generating this lane's code against it is how a frontend that was never built reports green."
614
615
 
615
- # 6. RUNNABLE = declared AND its source path is on disk AND its plan is there AND its
616
+ # 6. RUNNABLE = declared AND its lane root folder is on disk AND its plan is there AND its
616
617
  # project is there, as one ordered assignment plus a knockdown per condition, since
617
618
  # the engine has no compound conditions. An undeclared lane stays false either way —
618
619
  # its `declared` value is what the raise assigns.
@@ -676,7 +677,7 @@ workflow:
676
677
  action: verify_context
677
678
  require_true: generate_any
678
679
  on_false: stop
679
- on_false_message: "Nothing to implement — no declared lane is both ready and confirmed. Either every declared lane was skipped for a reason printed above (its source path, its plan or its project is missing), or each one that was ready was declined at the prompt. Backend lane declared {{be_declared}}, ready {{be_runnable}}; frontend lane declared {{fe_declared}}, ready {{fe_runnable}}. Fix the reasons named above, or re-run and confirm a lane."
680
+ on_false_message: "Nothing to implement — no declared lane is both ready and confirmed. Either every declared lane was skipped for a reason printed above (its lane root folder, its plan or its project is missing), or each one that was ready was declined at the prompt. Backend lane declared {{be_declared}}, ready {{be_runnable}}; frontend lane declared {{fe_declared}}, ready {{fe_runnable}}. Fix the reasons named above, or re-run and confirm a lane."
680
681
 
681
682
  # 8. EACH GENERATING LANE'S authoring MODE — the run's mode where the lane is going, and
682
683
  # `skip` where it is not, which silences both of that lane's branches without a
@@ -1165,7 +1166,7 @@ workflow:
1165
1166
  # recorded). Without the union a backend run would erase the frontend lane's source_files
1166
1167
  # and vice-versa, and either lane may have run first. ⌛ The trade-off is that a file this
1167
1168
  # lane DELETED stays listed until something prunes it; a lane-scoped replace needs
1168
- # concept-upsert to learn about lane roots, which is a script change and not built.
1169
+ # concept-upsert to learn about lane root folders, which is a script change and not built.
1169
1170
  - id: xref_concept_backend
1170
1171
  condition: "{{be_go}} == true"
1171
1172
  action: execute_script
@@ -1554,7 +1555,7 @@ workflow:
1554
1555
  action: verify_context
1555
1556
  require_true: lanes_complete
1556
1557
  on_false: stop
1557
- on_false_message: "PARTIAL GENERATION — implement did not realise every plan element, even after one completion pass. Backend lane: {{be_gaps_text}}. Frontend lane: {{fe_gaps_text}}. Everything written so far is kept and recorded in the OKF concept. An element reported `blocked` names what stops it — a plan that is wrong is fixed with /appweaver plan (then analyze-plan or analyze-plan-delta). An element with no code under the lane's source path is still to be written, or was written under a name that is not the plan's: re-run /appweaver implement to finish, which extends existing files rather than regenerating them."
1558
+ on_false_message: "PARTIAL GENERATION — implement did not realise every plan element, even after one completion pass. Backend lane: {{be_gaps_text}}. Frontend lane: {{fe_gaps_text}}. Everything written so far is kept and recorded in the OKF concept. An element reported `blocked` names what stops it — a plan that is wrong is fixed with /appweaver plan (then analyze-plan or analyze-plan-delta). An element with no code under the lane root folder is still to be written, or was written under a name that is not the plan's: re-run /appweaver implement to finish, which extends existing files rather than regenerating them."
1558
1559
 
1559
1560
  # 11. CROSS-SLICE EDGES — a Cross-References row written into every SIBLING aggregate
1560
1561
  # this one uses, read off the master backend plan (§1 References-by-id + its External
@@ -1691,5 +1692,5 @@ outputs:
1691
1692
  plan_gate_at: "{{gate_at}}"
1692
1693
  plan_gate_verdict: "{{gate_verdict}}"
1693
1694
  plan_gate_routed_to_specify: "{{gate_routed_csv}}" # open spec/model gaps this code does not cover
1694
- note: "Lanes come from .appweaver/stacks.json — backend declared {{be_declared}} (ready {{be_runnable}}, implemented {{be_go}}), frontend declared {{fe_declared}} (ready {{fe_runnable}}, implemented {{fe_go}}). A declared lane that was skipped printed its reason above and did not stop the other one; an undeclared lane produces nothing and that is not a failure. Each generating lane read its PLAN for what to build and {{domain_model}} for what the domain is — plus {{delta_model}} on the delta path, since the master model does not carry the change until finalize-delta merges it. Every one of those documents was READ and none was written: this phase generates code and nothing else. Each lane's outcome is backend={{be_outcome}}, frontend={{fe_outcome}} — `already-implemented` means the lane wrote no files because every plan element was already realised in its source path, which is the correct result of re-running implement on a finished feature and not a failure. On the bootstrap path the plans were checked against analyze-plan's receipt before anything generated (tracked={{gate_tracked}}, fresh={{gate_fresh}}, gated {{gate_at}}) — tracked=false means this feature has never passed analyze-plan since the gate began recording what it proved, which is an unknown rather than a stale plan and blocks nothing; run /appweaver analyze-plan once to start the record."
1695
+ note: "Lanes come from .appweaver/stacks.json — backend declared {{be_declared}} (ready {{be_runnable}}, implemented {{be_go}}), frontend declared {{fe_declared}} (ready {{fe_runnable}}, implemented {{fe_go}}). A declared lane that was skipped printed its reason above and did not stop the other one; an undeclared lane produces nothing and that is not a failure. Each generating lane read its PLAN for what to build and {{domain_model}} for what the domain is — plus {{delta_model}} on the delta path, since the master model does not carry the change until finalize-delta merges it. Every one of those documents was READ and none was written: this phase generates code and nothing else. Each lane's outcome is backend={{be_outcome}}, frontend={{fe_outcome}} — `already-implemented` means the lane wrote no files because every plan element was already realised in its lane root folder, which is the correct result of re-running implement on a finished feature and not a failure. On the bootstrap path the plans were checked against analyze-plan's receipt before anything generated (tracked={{gate_tracked}}, fresh={{gate_fresh}}, gated {{gate_at}}) — tracked=false means this feature has never passed analyze-plan since the gate began recording what it proved, which is an unknown rather than a stale plan and blocks nothing; run /appweaver analyze-plan once to start the record."
1695
1696
  next: "This run was mode `{{mode}}`, change `{{active_change}}` (empty on the bootstrap path). BOOTSTRAP → /appweaver build → analyze-slice → run. DELTA → /appweaver build → analyze-slice-delta {{active_change}} → finalize-delta → analyze-slice → close-delta, with the change still OPEN throughout — compile first, then analyze-slice-delta verifies that every element the delta plans marked ADDED or MODIFIED is actually in the code with a paired test (the gate that catches a lane you declined at the prompt above), then finalize-delta merges it into spec.md + the context's domain-model.md while leaving it open, analyze-slice verifies the slice against those merged masters while a red result is still recoverable, and close-delta LAST archives the change and bumps the version."
@@ -22,7 +22,7 @@
22
22
  # for either reads as "the document exists" to every gate downstream.
23
23
  #
24
24
  # 3. GOVERNANCE SCAFFOLD — the PROJECT-level governing tier: the split constitution
25
- # (technical + domain), the guardrails/projects/brf-<domain>/domain/ rule-file set
25
+ # (technical + domain), the guardrails/brf-<domain>/domain/ rule-file set
26
26
  # (+ domain-rule-bindings), the domain charter that set is headed by, and the
27
27
  # activated domain. The FIRST context to onboard AUTHORS it from the whole-repo
28
28
  # scan. Every LATER context AMENDS it from its own code — ADDITIVELY: a rule file
@@ -71,8 +71,8 @@
71
71
  #
72
72
  # CODE-DERIVED RULE SETS + MAPS (both tiers): onboard authors, from the code ALONE
73
73
  # (never a greenfield rule file), BOTH the DOMAIN rule-file set
74
- # (guardrails/projects/brf-<domain>/domain/*.domain.md +
75
- # domain-rule-bindings.md) AND the TECHNICAL rule-file set (guardrails/projects/brf-<domain>/service/*.md
74
+ # (guardrails/brf-<domain>/domain/*.domain.md +
75
+ # domain-rule-bindings.md) AND the TECHNICAL rule-file set (guardrails/brf-<domain>/service/*.md
76
76
  # + tech-rule-bindings.md), then WIRES each per-workflow. This is what makes the WHOLE
77
77
  # forward pipeline AND adopt govern against THIS codebase's rules — resolve-domain /
78
78
  # resolve-tech read the activated brf-<domain>'s maps, so no workflow ever falls back to a
@@ -92,7 +92,7 @@
92
92
  # .appweaver/memory/constitution.ui.md — the lane's UX-* base, authored from the UI
93
93
  # source (never from a greenfield UI template's content), then linted like the other
94
94
  # halves and composed in. Parallel to the technical base, so its numbering is its own.
95
- # guardrails/projects/brf-<domain>/frontend/*.md — the code-derived lane rule set, the detail
95
+ # guardrails/brf-<domain>/frontend/*.md — the code-derived lane rule set, the detail
96
96
  # layer under those UX-* principles, wired into tech-rule-bindings.md under the lane's
97
97
  # three headings: `## /aw-spec-ui-constitution` (what a later /appweaver constitution
98
98
  # re-ratifies the UI half from), `## /aw-spec-plan-ui` and `## /aw-spec-implement-ui`
@@ -112,7 +112,7 @@
112
112
  # generated, which subtrees are scanned, and what technology the derived rules name.
113
113
  # select-stack detects all three from the repo's own files and proposes them, so answering
114
114
  # it on an existing codebase is mostly confirmation — but it is a person's confirmation,
115
- # which is exactly what detection on a legacy repo needs. A declared source path that is
115
+ # which is exactly what detection on a legacy repo needs. A declared lane root folder that is
116
116
  # not a directory stops this run with the fix named rather than producing a scaffold
117
117
  # reverse-engineered from nothing.
118
118
  #
@@ -122,7 +122,7 @@
122
122
  # for the service lane gets no technical half and no service rules. The deterministic
123
123
  # scan is still what reads the code, now pointed AT the declared subtree: it decides what
124
124
  # the governance SAYS, and the declaration decides what there is to govern. A declared
125
- # lane whose source path holds nothing recognisable is reported, because the governance
125
+ # lane whose lane root folder holds nothing recognisable is reported, because the governance
126
126
  # derived from it will be thin.
127
127
  #
128
128
  # ONE ORACLE, UNCHANGED. Nothing about where the CONTENT comes from has moved. Every
@@ -138,7 +138,7 @@
138
138
  # — select-stack — and this workflow only reads.
139
139
  #
140
140
  # Never modifies source — every write lands in the OKF bundle, the context's specs/
141
- # directories, guardrails/projects/ (domain/ + service/ + frontend/ rule sets + both
141
+ # directories, guardrails/brf-<domain>/ (domain/ + service/ + frontend/ rule sets + both
142
142
  # maps), or the .appweaver/templates/overrides/ design templates.
143
143
  #
144
144
  # Launch: /appweaver onboard [<BoundedContext>] [; concerns: a, b, c]
@@ -149,7 +149,7 @@
149
149
  # =============================================================================
150
150
 
151
151
  name: aw-spec-onboard
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.
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/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
153
  version: 2.3.0
154
154
  agent_agnostic: true
155
155
  dialect: aw-spec.orchestrator/v1
@@ -242,7 +242,7 @@ workflow:
242
242
  # right technology).
243
243
  #
244
244
  # The on-disk check is ON here, unlike in constitution: this run is about to READ
245
- # those directories. A declared path that is not there stops the run with the fix
245
+ # those directories. A declared lane root folder that is not there stops the run with the fix
246
246
  # named, rather than producing a governance scaffold reverse-engineered from
247
247
  # nothing.
248
248
  - id: lane_model
@@ -272,7 +272,7 @@ workflow:
272
272
  onboard reverse-engineers this repository's governance out of its source, so it
273
273
  has to be told which subtrees hold which lane before it starts scanning. Run
274
274
  /appweaver select-stack first — it detects what this repo already is, proposes
275
- the stack and the source path for each lane, and lets you correct both.
275
+ the stack and the lane root folder for each lane, and lets you correct both.
276
276
 
277
277
  - id: lane_kinds_gate
278
278
  action: verify_context
@@ -507,7 +507,7 @@ workflow:
507
507
  # component library, a front end whose API lives in another repository. The
508
508
  # technical half, the service rule set and the service design templates are all the
509
509
  # SERVICE lane's, so none of them is authored, and saying so is better than leaving
510
- # someone to notice that guardrails/projects/<p>/service/ is empty.
510
+ # someone to notice that guardrails/<p>/service/ is empty.
511
511
  - id: svc_lane_warning
512
512
  action: verify_context
513
513
  require_true: svc_lane
@@ -532,13 +532,13 @@ workflow:
532
532
  condition: "{{fe_declared}}"
533
533
  vars:
534
534
  ui_lane: "true"
535
- ui_evidence: "lane '{{fe_lane_id}}' ({{fe_profile}}) is declared at the source path {{fe_root}}; the scan found UI source there — {{frontend_roots}}"
536
- ui_declaration_note: "lane '{{fe_lane_id}}' ({{fe_profile}}) at {{fe_root}} — the declared source path this run reverse-engineered the UI governance out of"
535
+ ui_evidence: "lane '{{fe_lane_id}}' ({{fe_profile}}) is declared at the lane root folder {{fe_root}}; the scan found UI source there — {{frontend_roots}}"
536
+ ui_declaration_note: "lane '{{fe_lane_id}}' ({{fe_profile}}) at {{fe_root}} — the declared lane root folder this run reverse-engineered the UI governance out of"
537
537
 
538
- # A declared UI lane whose source path holds nothing a scan recognises as UI. The
538
+ # A declared UI lane whose lane root folder holds nothing a scan recognises as UI. The
539
539
  # path exists — lane-verify already refused the run otherwise — so this is not a
540
540
  # broken declaration, it is an empty one: a lane scaffolded but not yet built, or a
541
- # source path one directory too high. Announce and continue rather than stop: the
541
+ # lane root folder one directory too high. Announce and continue rather than stop: the
542
542
  # declaration is a person's statement and is left exactly as it stands, but the UI
543
543
  # governance below will be thin, and it is better to say why now than to let someone
544
544
  # discover a UX base derived from an empty directory.
@@ -551,7 +551,7 @@ workflow:
551
551
  Frontend lane '{{fe_lane_id}}' is declared at {{fe_root}}, but the scan found no
552
552
  component, view or build-config files under that path ({{frontend_file_count}}
553
553
  file(s) there in total). The UI governance authored below is reverse-engineered
554
- from that subtree, so it will be thin or empty. Check that the source path points
554
+ from that subtree, so it will be thin or empty. Check that the lane root folder points
555
555
  at the directory holding the UI — /appweaver select-stack can move it — or
556
556
  retire the lane there with (none) if this repo has no UI yet.
557
557
 
@@ -673,7 +673,7 @@ workflow:
673
673
  repo must not get one). It is the UI counterpart of the platform note and the
674
674
  evidence the frontend lane's constitution is scaffolded from. Read the candidate
675
675
  roots in `frontend_signals` and then READ REPRESENTATIVE UI SOURCE from their
676
- component/route/store file lists, and record AS-BUILT: the lane root(s) and whether
676
+ component/route/store file lists, and record AS-BUILT: the lane root folder(s) and whether
677
677
  the UI is separable or rendered inside the service tree; what it is built with (name
678
678
  it from the code — the `framework_markers` are markers, not conclusions); how
679
679
  components are organized and named; routing/navigation; where client state and
@@ -877,7 +877,7 @@ workflow:
877
877
  - { name: project_name, from: "$.project_name" }
878
878
  - { name: overview, from: "$.overview" }
879
879
 
880
- # Slugify + `brf-` prefix the domain name and create guardrails/projects/brf-<domain>/.
880
+ # Slugify + `brf-` prefix the domain name and create guardrails/brf-<domain>/.
881
881
  # Name: explicit arg → the ACTIVE brf- project → PROJECT name from the OKF overview →
882
882
  # repo basename. It reports which tiers already hold rule files, and lists them.
883
883
  # The governance project is named from the PROJECT — `gov_name` is empty, so
@@ -974,8 +974,8 @@ workflow:
974
974
  permission_mode: acceptEdits
975
975
  task: |
976
976
  Scaffold the PROJECT-level DOMAIN RULE SET for **{{project_name}}** (domain
977
- {{domain_slug}}) into guardrails/projects/{{domain_slug}}/domain/ (the dir exists),
978
- plus the domain map guardrails/projects/{{domain_slug}}/domain-rule-bindings.md at the
977
+ {{domain_slug}}) into guardrails/{{domain_slug}}/domain/ (the dir exists),
978
+ plus the domain map guardrails/{{domain_slug}}/domain-rule-bindings.md at the
979
979
  project root. A project keeps its three rule classes in domain/ · service/ · frontend/
980
980
  and both maps at its root; adopt reconciles this set in place, so a file written
981
981
  anywhere else is unreachable.
@@ -1039,8 +1039,8 @@ workflow:
1039
1039
  - `## /aw-spec-plan` — `_None — plan loads no domain file. Domain reaches plan through the spec and the context's domain-model.md._`
1040
1040
  - `## /aw-spec-implement` — `_None — implement loads no domain file. Domain reaches implement through the lane plans and the context's domain-model.md._`
1041
1041
  - `## /aw-spec-gate` — the conformance-checklist set (the *.domain.md files).
1042
- Each bullet is a workspace-relative path `- guardrails/projects/{{domain_slug}}/domain/<file>`.
1043
- Write ONLY inside guardrails/projects/{{domain_slug}}/ (domain/ + the map). Report the
1042
+ Each bullet is a workspace-relative path `- guardrails/{{domain_slug}}/domain/<file>`.
1043
+ Write ONLY inside guardrails/{{domain_slug}}/ (domain/ + the map). Report the
1044
1044
  files written.
1045
1045
  outputs:
1046
1046
  - { name: pack_files, from: "$.files" }
@@ -1050,7 +1050,7 @@ workflow:
1050
1050
  action: verify_context
1051
1051
  require_non_empty: pack_files
1052
1052
  on_empty: stop
1053
- on_empty_message: "No domain rule files were written to guardrails/projects/{{domain_slug}}/domain/. Ensure the feature map carries a modellable domain (a feature map + ubiquitous language) and re-run."
1053
+ on_empty_message: "No domain rule files were written to guardrails/{{domain_slug}}/domain/. Ensure the feature map carries a modellable domain (a feature map + ubiquitous language) and re-run."
1054
1054
  - id: require_domain_rule_bindings
1055
1055
  condition: "{{author_repo}} == true"
1056
1056
  action: verify_context
@@ -1426,7 +1426,7 @@ workflow:
1426
1426
 
1427
1427
  EVIDENCE = THE UI CODE ITSELF (deep read). Authority, in order:
1428
1428
  1. THE ACTUAL UI SOURCE (ground truth). Use {{inventory_ui_json}} (in context):
1429
- `frontend_signals` lists the candidate lane roots with their kind
1429
+ `frontend_signals` lists the candidate lane root folders with their kind
1430
1430
  (spa / server-rendered / desktop), their framework markers, and their
1431
1431
  component / route / store / style file lists. READ ENOUGH OF THOSE FILES to
1432
1432
  state each principle from what the UI ACTUALLY does. Do NOT assert an
@@ -1764,14 +1764,14 @@ workflow:
1764
1764
  # under a constitution.technical.md principle (thin ratified line ↑ / enforceable rule ↓).
1765
1765
  # Evidence = the CODE (deep read via inventory_json's file lists) + the validated technical
1766
1766
  # constitution + the shallow platform note (corroboration only). Writes:
1767
- # 1. guardrails/projects/<domain>/service/<concern>.md — evidenced-only code-derived tech rule
1767
+ # 1. guardrails/<domain>/service/<concern>.md — evidenced-only code-derived tech rule
1768
1768
  # files (the ANALOG of a greenfield project's architecture · security · governance set, but reverse-
1769
1769
  # engineered from THIS code, never a greenfield file), INCLUDING the one file that
1770
1770
  # feeds /specify: service/domain-modelling.md, the as-built modelling METHODOLOGY (the
1771
1771
  # analog of the greenfield corpus's technology/<stack>/domain-driven-design.md). Without it brownfield
1772
1772
  # specify has a model but no HOW-to-model standard, and models a NEW feature in a
1773
1773
  # different idiom than the code it joins, and
1774
- # 2. guardrails/projects/<domain>/tech-rule-bindings.md — the TECHNICAL map (resolve-tech +
1774
+ # 2. guardrails/<domain>/tech-rule-bindings.md — the TECHNICAL map (resolve-tech +
1775
1775
  # tech-select read it by that exact name), wiring the generated files per-workflow.
1776
1776
  # Because onboard already ACTIVATED brf-<domain>, the forward pipeline's + adopt's tech_select
1777
1777
  # steps now resolve to THESE files — never another project's rules, ever. The files live
@@ -1796,8 +1796,8 @@ workflow:
1796
1796
  task: |
1797
1797
  Scaffold the PROJECT-level TECHNICAL RULE SET for **{{project_name}}** (domain
1798
1798
  {{domain_slug}}) — the CODE-DERIVED replacement for the greenfield technical rule set —
1799
- into guardrails/projects/{{domain_slug}}/service/ (create it), plus the technical map
1800
- guardrails/projects/{{domain_slug}}/tech-rule-bindings.md. This is the TECHNICAL twin of the
1799
+ into guardrails/{{domain_slug}}/service/ (create it), plus the technical map
1800
+ guardrails/{{domain_slug}}/tech-rule-bindings.md. This is the TECHNICAL twin of the
1801
1801
  already-generated domain set: it feeds the HOW phases (plan/implement/build/…) plus
1802
1802
  ONE modelling-methodology file for /specify (see domain-modelling below) — and nothing
1803
1803
  else ever reaches /specify from this tier.
@@ -1815,9 +1815,9 @@ workflow:
1815
1815
  numeral on the rules it details. Never contradict it; never restate it wholesale.
1816
1816
  3. The OKF platform.md (in context, if present) — SECONDARY, shallow corroboration only.
1817
1817
  NEVER reference, read, copy, or list a rule file belonging to another project
1818
- (guardrails/projects/<other>/**) — those are the
1818
+ (any other project folder under guardrails/, e.g. guardrails/project-specific/**) — those are the
1819
1819
  greenfield fixture, NOT this project's rules. Every path you write lives under
1820
- guardrails/projects/{{domain_slug}}/service/.
1820
+ guardrails/{{domain_slug}}/service/.
1821
1821
 
1822
1822
  CONCERNS HINT: {{concerns_line}} Treat any listed concern as a SEARCH HINT — look for it
1823
1823
  in the code — but DECIDE presence from evidence: write a tech rule file for a concern ONLY
@@ -1868,8 +1868,8 @@ workflow:
1868
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.
1869
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).
1870
1870
  Each bullet is a
1871
- workspace-relative path `- guardrails/projects/{{domain_slug}}/service/<file>`. Close with the
1872
- quick-reference table. Write ONLY inside guardrails/projects/{{domain_slug}}/ (service/ + the map);
1871
+ workspace-relative path `- guardrails/{{domain_slug}}/service/<file>`. Close with the
1872
+ quick-reference table. Write ONLY inside guardrails/{{domain_slug}}/ (service/ + the map);
1873
1873
  modify no source. Report the files written + the concerns you found present (with the code
1874
1874
  paths that evidence them).
1875
1875
  outputs:
@@ -1880,7 +1880,7 @@ workflow:
1880
1880
  condition: "{{author_svc}} == true"
1881
1881
  require_non_empty: tech_pack_files
1882
1882
  on_empty: stop
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."
1883
+ on_empty_message: "No technical rule files were written to guardrails/{{domain_slug}}/service/. Ensure the scan substrate (inventory_json) + the validated technical constitution carry an as-built technology base and re-run."
1884
1884
  - id: require_tech_rule_bindings
1885
1885
  condition: "{{author_svc}} == true"
1886
1886
  action: verify_context
@@ -1908,7 +1908,7 @@ workflow:
1908
1908
  require_non_empty: specify_rules
1909
1909
  on_empty: continue
1910
1910
  on_empty_message: >
1911
- guardrails/projects/{{domain_slug}}/tech-rule-bindings.md maps nothing under
1911
+ guardrails/{{domain_slug}}/tech-rule-bindings.md maps nothing under
1912
1912
  `## /aw-spec-specify`, so brownfield specify will model new features with no
1913
1913
  as-built modelling methodology to follow. That is correct only where the code has no
1914
1914
  discernible domain model (a pure script/ETL repo). Otherwise add
@@ -1947,15 +1947,15 @@ workflow:
1947
1947
  task: |
1948
1948
  Scaffold the PROJECT-level FRONTEND RULE-FILE PACK for **{{project_name}}** (domain
1949
1949
  {{domain_slug}}) — the CODE-DERIVED lane rules — into
1950
- guardrails/projects/{{domain_slug}}/frontend/ (create it), and WIRE it into the existing
1951
- guardrails/projects/{{domain_slug}}/tech-rule-bindings.md. This is the FRONTEND LANE's
1950
+ guardrails/{{domain_slug}}/frontend/ (create it), and WIRE it into the existing
1951
+ guardrails/{{domain_slug}}/tech-rule-bindings.md. This is the FRONTEND LANE's
1952
1952
  twin of the service/ set you have already generated: it is the detail layer under
1953
- constitution.ui.md's UX-* principles, and it governs only code under the lane's root.
1953
+ constitution.ui.md's UX-* principles, and it governs only code under the lane root folder.
1954
1954
 
1955
1955
  EVIDENCE = THE UI CODE ITSELF (deep read) + THE VALIDATED UI CONSTITUTION. Authority,
1956
1956
  in order:
1957
1957
  1. THE ACTUAL UI SOURCE (ground truth). Use {{inventory_ui_json}} (in context):
1958
- `frontend_signals` gives the lane roots, their kind, their framework markers and
1958
+ `frontend_signals` gives the lane root folders, their kind, their framework markers and
1959
1959
  their component / route / store / style file lists. Read enough of those files to
1960
1960
  state each rule from what the UI ACTUALLY does. Do NOT assert a convention you
1961
1961
  have not seen in the code.
@@ -1964,10 +1964,10 @@ workflow:
1964
1964
  it details. Never contradict it; never restate it wholesale.
1965
1965
  3. The OKF architecture/frontend.md (in context, if present) — SECONDARY, shallow.
1966
1966
  NEVER reference, read, copy, or list a rule file belonging to another project
1967
- (guardrails/projects/<other>/**) — those are the greenfield fixture, NOT this project's
1967
+ (any other project folder under guardrails/, e.g. guardrails/project-specific/**) — those are the greenfield fixture, NOT this project's
1968
1968
  rules. Never carry over a convention, an accessibility target, a folder taxonomy or a
1969
1969
  quality gate from a greenfield UI rule file or from how frontends are usually built.
1970
- Every path you write lives under guardrails/projects/{{domain_slug}}/frontend/.
1970
+ Every path you write lives under guardrails/{{domain_slug}}/frontend/.
1971
1971
 
1972
1972
  EVIDENCED-ONLY (lean). Follow the SHAPE of frontend-rule-file.skeleton.md (in context):
1973
1973
  frontmatter (origin: reverse-engineered, generated_by: {{generated_by}}, concern),
@@ -1986,13 +1986,13 @@ workflow:
1986
1986
  divergence with its coordinates. Do not upgrade a partial into a greenfield ideal, and
1987
1987
  do not create a debt/backlog sink — modernization is a separate later phase.
1988
1988
 
1989
- WIRE THE MAP — guardrails/projects/{{domain_slug}}/tech-rule-bindings.md. Where the
1989
+ WIRE THE MAP — guardrails/{{domain_slug}}/tech-rule-bindings.md. Where the
1990
1990
  service rule set was generated it exists and carries the technical headings: EDIT IT IN
1991
1991
  PLACE and PRESERVE every one of them byte-for-byte. Where this project has no service
1992
1992
  lane it does not exist yet: CREATE it with the skeleton's title and framing and only the
1993
1993
  headings below. Add the lane's THREE headings after the last technical heading and
1994
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:
1995
+ `- guardrails/{{domain_slug}}/frontend/<file>` naming a file you just generated:
1996
1996
  1. `## /aw-spec-ui-constitution` — the lane's RATIFIABLE standards,
1997
1997
  `frontend/ui-constitution.md` first. It is what a later /appweaver constitution
1998
1998
  re-ratifies the UI half from, and the authoritative signal that the project has a
@@ -2010,7 +2010,7 @@ workflow:
2010
2010
  file, no service/ file and no example under any of the three. Give each heading its row
2011
2011
  in the quick-reference table, in the same format as the existing rows.
2012
2012
 
2013
- Write ONLY inside guardrails/projects/{{domain_slug}}/ (frontend/ + the map edit); modify
2013
+ Write ONLY inside guardrails/{{domain_slug}}/ (frontend/ + the map edit); modify
2014
2014
  no source. Report the files written, the concerns you found present with the code paths
2015
2015
  that evidence them, and the concerns you deliberately omitted.
2016
2016
  outputs:
@@ -2022,7 +2022,7 @@ workflow:
2022
2022
  require_non_empty: ui_pack_files
2023
2023
  required_files: ["{{pack_dir}}/frontend/ui-constitution.md", "{{pack_dir}}/tech-rule-bindings.md"]
2024
2024
  on_empty: stop
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."
2025
+ on_empty_message: "A frontend lane was detected ({{ui_evidence}}) but no lane rule files were written to guardrails/{{domain_slug}}/frontend/. Check that the scan substrate's frontend_signals carry readable UI source, then re-run."
2026
2026
 
2027
2027
  # Did the lane's heading land in the map? The files above are only half the wiring:
2028
2028
  # `## /aw-spec-ui-constitution` is what a later /appweaver constitution re-ratifies
@@ -2044,8 +2044,8 @@ workflow:
2044
2044
  require_non_empty: ui_map_rules
2045
2045
  on_empty: continue
2046
2046
  on_empty_message: >
2047
- The lane rule files were written to guardrails/projects/{{domain_slug}}/frontend/,
2048
- but guardrails/projects/{{domain_slug}}/tech-rule-bindings.md maps nothing under
2047
+ The lane rule files were written to guardrails/{{domain_slug}}/frontend/,
2048
+ but guardrails/{{domain_slug}}/tech-rule-bindings.md maps nothing under
2049
2049
  `## /aw-spec-ui-constitution`. Without that heading a later /appweaver
2050
2050
  constitution finds no lane rules to re-ratify the UI half from, and reads this
2051
2051
  project as backend-only. Add the heading after the last technical one, bulleting
@@ -2069,7 +2069,7 @@ workflow:
2069
2069
  require_non_empty: ui_plan_rules
2070
2070
  on_empty: continue
2071
2071
  on_empty_message: >
2072
- guardrails/projects/{{domain_slug}}/tech-rule-bindings.md maps nothing under
2072
+ guardrails/{{domain_slug}}/tech-rule-bindings.md maps nothing under
2073
2073
  `## /aw-spec-plan-ui`, so the frontend lane of /appweaver plan will author
2074
2074
  frontend-plan.md with no project rule file. Add the heading, bulleting the
2075
2075
  frontend/ files whose rules shape a feature's screens, state and interactions.
@@ -2088,7 +2088,7 @@ workflow:
2088
2088
  require_non_empty: ui_impl_rules
2089
2089
  on_empty: continue
2090
2090
  on_empty_message: >
2091
- guardrails/projects/{{domain_slug}}/tech-rule-bindings.md maps nothing under
2091
+ guardrails/{{domain_slug}}/tech-rule-bindings.md maps nothing under
2092
2092
  `## /aw-spec-implement-ui`, so the frontend lane of /appweaver implement will
2093
2093
  generate UI code with no project rule file. Add the heading, bulleting the
2094
2094
  frontend/ files whose rules govern component, state, styling and test conventions.
@@ -2161,7 +2161,7 @@ workflow:
2161
2161
  #
2162
2162
  # WHERE A FRONTEND LANE EXISTS the lane gets its OWN pair (ui-design-template +
2163
2163
  # ui-delta-design-template, below), so this pair covers the SERVICE lane only and excludes
2164
- # the lane's roots from the structure it derives. One lane's template never describes the
2164
+ # the lane root folders from the structure it derives. One lane's template never describes the
2165
2165
  # other's code. The templates are authored when their lane's tier is first authored — by
2166
2166
  # the first context, or by the run that first sees a lane declared later — and are never
2167
2167
  # amended: every plan already written follows their shape.
@@ -2215,7 +2215,7 @@ workflow:
2215
2215
  into §1.1 or §2 from memory. DESIGN-FORMAT.md (in context, § Brownfield variant) states
2216
2216
  which anchors are pinned and why.
2217
2217
 
2218
- SERVICE LANE ONLY. Frontend lane roots this repo has: {{frontend_roots}} (empty = none).
2218
+ SERVICE LANE ONLY. Frontend lane root folders this repo has: {{frontend_roots}} (empty = none).
2219
2219
  Where that is non-empty, EXCLUDE those roots when deriving the structure — the lane has
2220
2220
  its own design template pair, generated next, and one lane's template must never describe
2221
2221
  the other's code. A UI tier that is NOT a separable lane (rendered inside the service
@@ -2458,7 +2458,7 @@ workflow:
2458
2458
 
2459
2459
  GROUND EVERYTHING IN THE LANE'S OWN CODE. Evidence authority, in order:
2460
2460
  1. THE ACTUAL UI SOURCE (ground truth). Use {{inventory_ui_json}} (in context):
2461
- `frontend_signals` gives the lane roots, their kind (spa / server-rendered /
2461
+ `frontend_signals` gives the lane root folders, their kind (spa / server-rendered /
2462
2462
  desktop), their framework markers and their component / route / store / style
2463
2463
  file lists. READ ENOUGH OF THOSE FILES to state each structural claim from what
2464
2464
  the UI ACTUALLY does. Do NOT assert a convention you have not seen.
@@ -2467,7 +2467,7 @@ workflow:
2467
2467
  serves; cite them by their real numerals.
2468
2468
  3. The generated frontend/ui-constitution.md and the OKF architecture/frontend.md
2469
2469
  (in context, if present) — the lane's own rule detail and a shallow corroboration.
2470
- STAY INSIDE THE LANE. Derive structure ONLY from code under the lane's roots. The
2470
+ STAY INSIDE THE LANE. Derive structure ONLY from code under the lane root folders. The
2471
2471
  service lane has its own template, generated just above; this one never describes
2472
2472
  server-side structure.
2473
2473
 
@@ -2655,4 +2655,4 @@ outputs:
2655
2655
  amended_domain_files: "{{amended_domain_files}}"
2656
2656
  amended_service_files: "{{amended_service_files}}"
2657
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)."
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/{{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 lane root folders it named (scanned_service_root / scanned_ui_root); scanned_backend_files / scanned_ui_files report each. ui_source_evidence_found false means the declared lane root folder of the UI lane held nothing a scan recognises as UI, so its governance is thin — move the lane root folder 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)."