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.
- package/assets/.agents/skills/appweaver/SKILL.md +7 -47
- package/assets/.appweaver/ORCH-DIALECT.md +13 -9
- package/assets/.appweaver/RULE-PARTITION.md +3 -3
- package/assets/.appweaver/STACK-PROFILES.md +188 -101
- package/assets/.appweaver/domain.json +1 -1
- package/assets/.appweaver/orchestrator/AGENT-PROFILE.md +38 -10
- package/assets/.appweaver/orchestrator/LAUNCHER.md +88 -0
- package/assets/.appweaver/orchestrator/README.md +120 -53
- package/assets/.appweaver/orchestrator/adapters/claude_agent_sdk.py +1 -1
- package/assets/.appweaver/orchestrator/modules/domain-select.orch.yaml +6 -4
- package/assets/.appweaver/orchestrator/modules/foundation-lane.orch.yaml +237 -0
- package/assets/.appweaver/orchestrator/modules/foundation-pack.orch.yaml +349 -0
- package/assets/.appweaver/orchestrator/modules/foundation-spec.orch.yaml +381 -0
- package/assets/.appweaver/orchestrator/modules/lane-gate.orch.yaml +4 -4
- package/assets/.appweaver/orchestrator/modules/tech-select.orch.yaml +3 -3
- package/assets/.appweaver/orchestrator/orchestrator.py +162 -63
- package/assets/.appweaver/orchestrator/rev-templates/domain-constitution.skeleton.md +2 -2
- package/assets/.appweaver/orchestrator/rev-templates/domain-requirements.skeleton.md +2 -2
- package/assets/.appweaver/orchestrator/rev-templates/domain-rule-bindings.skeleton.md +5 -5
- package/assets/.appweaver/orchestrator/rev-templates/frontend-rule-file.skeleton.md +1 -1
- package/assets/.appweaver/orchestrator/rev-templates/tech-rule-bindings.skeleton.md +14 -14
- package/assets/.appweaver/orchestrator/rev-templates/technical-constitution.skeleton.md +2 -2
- package/assets/.appweaver/orchestrator/rev-templates/technical-rule-file.skeleton.md +1 -1
- package/assets/.appweaver/orchestrator/rev-templates/ui-constitution.skeleton.md +3 -3
- package/assets/.appweaver/orchestrator/workflows/_smoke.orch.yaml +41 -3
- package/assets/.appweaver/orchestrator/workflows/aw-spec-add-component.orch.yaml +1 -1
- package/assets/.appweaver/orchestrator/workflows/aw-spec-adopt.orch.yaml +13 -13
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-slice-delta.orch.yaml +3 -3
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-slice.orch.yaml +3 -3
- package/assets/.appweaver/orchestrator/workflows/aw-spec-build.orch.yaml +4 -4
- package/assets/.appweaver/orchestrator/workflows/aw-spec-characterize.orch.yaml +2 -2
- package/assets/.appweaver/orchestrator/workflows/aw-spec-constitution.orch.yaml +61 -12
- package/assets/.appweaver/orchestrator/workflows/aw-spec-foundation.orch.yaml +172 -293
- package/assets/.appweaver/orchestrator/workflows/aw-spec-implement.orch.yaml +29 -28
- package/assets/.appweaver/orchestrator/workflows/aw-spec-onboard.orch.yaml +53 -53
- package/assets/.appweaver/orchestrator/workflows/aw-spec-parity.orch.yaml +2 -2
- package/assets/.appweaver/orchestrator/workflows/aw-spec-plan.orch.yaml +3 -3
- package/assets/.appweaver/orchestrator/workflows/aw-spec-run.orch.yaml +4 -4
- package/assets/.appweaver/orchestrator/workflows/aw-spec-select-bounded-context.orch.yaml +26 -2
- package/assets/.appweaver/orchestrator/workflows/aw-spec-select-domain.orch.yaml +21 -15
- package/assets/.appweaver/orchestrator/workflows/aw-spec-select-stack.orch.yaml +14 -14
- package/assets/.appweaver/orchestrator/workflows/aw-spec-specify.orch.yaml +2 -2
- package/assets/.appweaver/orchestrator/workflows/aw-spec-ui-model.orch.yaml +3 -3
- package/assets/.appweaver/orchestrator/workflows/aw-spec-ui-prototype.orch.yaml +6 -6
- package/assets/.appweaver/scripts/bash/aw-spec-actions.sh +284 -128
- package/assets/.appweaver/scripts/powershell/aw-spec-actions.ps1 +224 -70
- package/assets/.appweaver/scripts/python/aw-foundation.py +809 -20
- package/assets/.appweaver/scripts/python/aw-inventory.py +28 -21
- package/assets/.appweaver/scripts/python/aw-plan-coverage.py +2 -2
- package/assets/.appweaver/scripts/python/aw-rev-constitution.py +6 -6
- package/assets/.appweaver/scripts/python/aw-stack.py +195 -89
- package/assets/.appweaver/stack-profiles/angular.json +2 -1
- package/assets/.appweaver/stack-profiles/blazor-wasm.json +2 -1
- package/assets/.appweaver/stack-profiles/dotnet-webapi.json +16 -3
- package/assets/.appweaver/stack-profiles/go-chi.json +6 -1
- package/assets/.appweaver/stack-profiles/java-spring.json +12 -5
- package/assets/.appweaver/stack-profiles/nextjs.json +2 -1
- package/assets/.appweaver/stack-profiles/node-express.json +8 -2
- package/assets/.appweaver/stack-profiles/python-fastapi.json +9 -2
- package/assets/.appweaver/stack-profiles/react-vite.json +2 -1
- package/assets/.appweaver/stack-profiles/sveltekit.json +2 -1
- package/assets/.appweaver/stack-profiles/vue-vite.json +2 -1
- package/assets/.appweaver/stacks.json +37 -1
- package/assets/.appweaver/templates/constitution-ui-template.md +2 -2
- package/assets/.claude/skills/appweaver/SKILL.md +7 -46
- package/assets/foundations/dotnet/ModularMonolith/ModularMonolith.Reference.rules.json +31 -0
- package/assets/foundations/dotnet/VerticalSlice/VerticalSlice.Reference.rules.json +16 -0
- package/assets/foundations/foundation.spec.template.txt +73 -0
- package/assets/foundations/java/Hexagonal/Hexagonal.pack.txt +1 -1
- package/assets/foundations/java/Hexagonal/unpack-foundation.sh +4 -5
- package/assets/foundations/node/NextAppRouter/NextAppRouter.spec.txt +68 -0
- package/assets/guardrails/README.md +31 -17
- package/assets/guardrails/{projects/dotnet-default-project → project-specific}/domain-rule-bindings.md +5 -5
- package/assets/guardrails/{projects/dotnet-default-project → project-specific}/tech-rule-bindings.md +151 -114
- package/assets/guardrails/technology/dotnet-webapi/PACKAGING.md +58 -4
- package/assets/guardrails/technology/dotnet-webapi/coding-standards.md +1 -1
- package/assets/guardrails/technology/dotnet-webapi/dependency-policy.md +1 -1
- package/assets/guardrails/technology/dotnet-webapi/folder-structure.md +1 -1
- package/assets/guardrails/technology/dotnet-webapi/framework-api-map.md +1 -1
- package/assets/guardrails/technology/dotnet-webapi/testing.md +1 -1
- package/assets/guardrails/technology/nextjs/api-client.md +1 -1
- package/assets/guardrails/technology/nextjs/component-architecture.md +1 -1
- package/assets/guardrails/technology/nextjs/component-conventions.md +2 -2
- package/assets/guardrails/technology/nextjs/design-system.md +1 -1
- package/assets/guardrails/technology/nextjs/frontend-testing.md +1 -1
- package/assets/guardrails/technology/nextjs/routing-navigation.md +1 -1
- package/assets/guardrails/technology/nextjs/ui-constitution.md +3 -3
- package/package.json +1 -1
- package/assets/.agents/skills/appweaver-demo/SKILL.md +0 -59
- package/assets/.appweaver/orchestrator/.smoke-out/smoke.md +0 -6
- package/assets/.appweaver/orchestrator/workflows/aw-spec-demo.orch.yaml +0 -100
- package/assets/.claude/skills/appweaver-demo/SKILL.md +0 -59
- package/assets/.kilocode/agent.json +0 -28
- package/assets/.kilocode/workflows/appweaver-demo.md +0 -59
- package/assets/.kilocode/workflows/appweaver.md +0 -55
- /package/assets/guardrails/{projects/dotnet-default-project → project-specific}/domain/domain-requirements.md +0 -0
- /package/assets/guardrails/{projects/dotnet-default-project → project-specific}/frontend/ui-requirements.md +0 -0
- /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
|
|
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
|
|
91
|
-
# test path lane-verify resolves
|
|
92
|
-
#
|
|
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
|
|
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
|
|
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
|
-
#
|
|
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
|
|
121
|
-
# so with no project there is nowhere to place the files. /appweaver foundation
|
|
122
|
-
#
|
|
123
|
-
#
|
|
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
|
|
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
|
|
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
|
|
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
|
-
#
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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/
|
|
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/
|
|
75
|
-
# domain-rule-bindings.md) AND the TECHNICAL rule-file set (guardrails/
|
|
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/
|
|
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
|
|
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
|
|
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/
|
|
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/
|
|
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
|
|
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
|
|
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
|
|
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
|
|
536
|
-
ui_declaration_note: "lane '{{fe_lane_id}}' ({{fe_profile}}) at {{fe_root}} — the declared
|
|
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
|
|
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
|
-
#
|
|
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
|
|
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/
|
|
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/
|
|
978
|
-
plus the domain map guardrails/
|
|
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/
|
|
1043
|
-
Write ONLY inside guardrails/
|
|
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/
|
|
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
|
|
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
|
|
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
|
|
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/
|
|
1800
|
-
guardrails/
|
|
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/
|
|
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/
|
|
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/
|
|
1872
|
-
quick-reference table. Write ONLY inside guardrails/
|
|
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/
|
|
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/
|
|
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/
|
|
1951
|
-
guardrails/
|
|
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
|
|
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
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
2048
|
-
but guardrails/
|
|
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/
|
|
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/
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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/
|
|
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)."
|