aw-spec-cli 0.1.26 → 0.1.28
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 +11 -12
- package/assets/.appweaver/STACK-PROFILES.md +260 -108
- package/assets/.appweaver/domain.json +1 -1
- package/assets/.appweaver/interpreter/run-skill.py +28 -7
- 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/delta-plan.orch.yaml +17 -7
- 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 +392 -0
- package/assets/.appweaver/orchestrator/modules/foundation-spec.orch.yaml +548 -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/delta-design-template.skeleton.md +5 -4
- package/assets/.appweaver/orchestrator/rev-templates/design-template.skeleton.md +3 -1
- 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 +21 -13
- package/assets/.appweaver/orchestrator/rev-templates/frontend-rule-file.skeleton.md +1 -1
- package/assets/.appweaver/orchestrator/rev-templates/tech-rule-bindings.skeleton.md +28 -31
- 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/rev-templates/ui-delta-design-template.skeleton.md +4 -1
- package/assets/.appweaver/orchestrator/rev-templates/ui-design-template.skeleton.md +6 -4
- 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 +17 -16
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-plan-delta.orch.yaml +7 -1
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-plan.orch.yaml +7 -1
- 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-deploy.orch.yaml +1 -1
- package/assets/.appweaver/orchestrator/workflows/aw-spec-foundation.orch.yaml +172 -293
- package/assets/.appweaver/orchestrator/workflows/aw-spec-implement.orch.yaml +253 -44
- package/assets/.appweaver/orchestrator/workflows/aw-spec-onboard.orch.yaml +72 -71
- package/assets/.appweaver/orchestrator/workflows/aw-spec-parity.orch.yaml +2 -2
- package/assets/.appweaver/orchestrator/workflows/aw-spec-plan.orch.yaml +38 -14
- 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 +3 -3
- 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 +371 -131
- package/assets/.appweaver/scripts/powershell/aw-spec-actions.ps1 +293 -76
- package/assets/.appweaver/scripts/python/aw-foundation.py +885 -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 +676 -99
- 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 +18 -3
- package/assets/.appweaver/stack-profiles/go-chi.json +6 -1
- package/assets/.appweaver/stack-profiles/java-spring.json +14 -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 +40 -1
- package/assets/.appweaver/templates/constitution-ui-template.md +2 -2
- package/assets/.appweaver/templates/delta-design-template.md +7 -5
- package/assets/.appweaver/templates/design-template.md +3 -0
- package/assets/.appweaver/templates/ui-delta-design-template.md +1 -1
- package/assets/.appweaver/templates/ui-design-template.md +6 -4
- package/assets/.claude/skills/appweaver/SKILL.md +7 -46
- package/assets/foundations/dotnet/ModularMonolith/ModularMonolith.Reference.rules.json +31 -0
- package/assets/foundations/dotnet/ModularMonolith/ModularMonolith.lane.json +6 -0
- package/assets/foundations/dotnet/VerticalSlice/VerticalSlice.Reference.rules.json +16 -0
- package/assets/foundations/dotnet/VerticalSlice/VerticalSlice.lane.json +6 -0
- package/assets/foundations/foundation.spec.template.txt +98 -0
- package/assets/foundations/java/Hexagonal/Hexagonal.lane.json +6 -0
- package/assets/foundations/java/Hexagonal/Hexagonal.pack.txt +8 -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 +25 -13
- package/assets/guardrails/project-specific/tech-rule-bindings.md +296 -0
- package/assets/guardrails/technology/dotnet-webapi/PACKAGING.md +58 -4
- package/assets/guardrails/technology/dotnet-webapi/api-versioning.md +1 -1
- package/assets/guardrails/technology/dotnet-webapi/auditing.md +1 -1
- package/assets/guardrails/technology/dotnet-webapi/authorization.md +1 -1
- package/assets/guardrails/technology/dotnet-webapi/clean-architecture.md +1 -1
- package/assets/guardrails/technology/dotnet-webapi/coding-standards.md +1 -1
- package/assets/guardrails/technology/dotnet-webapi/cqrs.md +1 -1
- package/assets/guardrails/technology/dotnet-webapi/data-classification.md +1 -1
- package/assets/guardrails/technology/dotnet-webapi/dependency-policy.md +1 -1
- package/assets/guardrails/technology/dotnet-webapi/eventing.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/modular-monolith.md +1 -1
- package/assets/guardrails/technology/dotnet-webapi/persistence.md +1 -1
- package/assets/guardrails/technology/dotnet-webapi/testing.md +1 -1
- package/assets/guardrails/technology/dotnet-webapi/vertical-slices.md +1 -1
- package/assets/guardrails/technology/dotnet-webapi/zero-trust.md +1 -1
- package/assets/guardrails/technology/nextjs/accessibility-implementation.md +1 -1
- package/assets/guardrails/technology/nextjs/api-client.md +1 -1
- package/assets/guardrails/technology/nextjs/api-integration.dotnet-webapi.md +1 -1
- package/assets/guardrails/technology/nextjs/api-integration.java-spring.md +1 -1
- package/assets/guardrails/technology/nextjs/auth-session.md +1 -1
- package/assets/guardrails/technology/nextjs/client-security.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/error-handling.md +1 -1
- package/assets/guardrails/technology/nextjs/forms-and-validation.md +1 -1
- package/assets/guardrails/technology/nextjs/frontend-testing.md +1 -1
- package/assets/guardrails/technology/nextjs/i18n.md +1 -1
- package/assets/guardrails/technology/nextjs/observability.md +1 -1
- package/assets/guardrails/technology/nextjs/performance-budgets.md +1 -1
- package/assets/guardrails/technology/nextjs/routing-navigation.md +1 -1
- package/assets/guardrails/technology/nextjs/state-management.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/tech-rule-bindings.md +0 -271
- /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
|
@@ -17,11 +17,14 @@
|
|
|
17
17
|
# against no declared stack invents its own.
|
|
18
18
|
#
|
|
19
19
|
# ONE COMMAND, TWO LANES, TWO RULE SETS. The lanes take their rules from different
|
|
20
|
-
# headings of tech-rule-bindings (`## /aw-spec-plan` for the service,
|
|
21
|
-
# for the frontend), and
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
#
|
|
20
|
+
# headings of tech-rule-bindings (`## /aw-spec-plan-backend` for the service,
|
|
21
|
+
# `## /aw-spec-plan-frontend` for the frontend), and each set is loaded only when its lane
|
|
22
|
+
# is declared. The two are never loaded together: the service set loads at step 1, before
|
|
23
|
+
# the backend sections, and the frontend set REPLACES it at the lane swap before the
|
|
24
|
+
# frontend sections — tech_select_ui_master on the master path, the delta-plan module's
|
|
25
|
+
# own swap on the change path. Each plan is therefore authored with only its own lane's
|
|
26
|
+
# rule set in its envelope. Where the two plans meet is stated in the frontend plan's
|
|
27
|
+
# §5 Contract Binding, which binds to the service's published surface only.
|
|
25
28
|
#
|
|
26
29
|
# RENAMED FROM `design`. design.md → backend-plan.md, design.ui.md → frontend-plan.md,
|
|
27
30
|
# and the former separate `design-ui` command is FOLDED IN here. The scaffold MIGRATES a
|
|
@@ -105,7 +108,7 @@ scripts:
|
|
|
105
108
|
|
|
106
109
|
# Sticky standards seed = the UNIVERSAL always-on rule only (ai-rules). The TECHNICAL/
|
|
107
110
|
# architecture rule files are CONFIGURATION, loaded per-command from
|
|
108
|
-
# guardrails
|
|
111
|
+
# guardrails/<project>/tech-rule-bindings.md by the tech-select module (see the
|
|
109
112
|
# tech_select steps below), exactly as the DOMAIN rule files are loaded by domain-select.
|
|
110
113
|
# Per the rule-partition this phase loads NO domain rule file — the domain reaches the
|
|
111
114
|
# plan as spec ids (BR-/CN-/DC-/IC-) and as the context's domain model. The technology
|
|
@@ -179,7 +182,7 @@ vars:
|
|
|
179
182
|
workflow:
|
|
180
183
|
|
|
181
184
|
# 0. WHICH LANES EXIST. lane-resolve reads the declaration only — it does NOT check the
|
|
182
|
-
#
|
|
185
|
+
# lane root folder on disk, unlike the lane-gate module, because a plan is authored BEFORE
|
|
183
186
|
# the code exists. That is the point of planning.
|
|
184
187
|
- id: lane_resolve
|
|
185
188
|
action: execute_script
|
|
@@ -201,18 +204,18 @@ workflow:
|
|
|
201
204
|
action: verify_context
|
|
202
205
|
require_true: lanes_declared
|
|
203
206
|
on_false: stop
|
|
204
|
-
on_false_message: "No lane is declared in .appweaver/stacks.json, so there is nothing to plan. Run /appweaver select-stack and declare the backend stack, the frontend stack, or both — plus each one's
|
|
207
|
+
on_false_message: "No lane is declared in .appweaver/stacks.json, so there is nothing to plan. Run /appweaver select-stack and declare the backend stack, the frontend stack, or both — plus each one's lane root folder — then re-run plan. The declaration is what tells this phase which documents to write; a plan written against no declared stack invents its own."
|
|
205
208
|
|
|
206
209
|
# 1. TECHNICAL rule files → sticky standards (configuration, not hardcoded).
|
|
207
|
-
# The service lane's set is loaded under `## /aw-spec-plan`; the frontend lane's
|
|
208
|
-
# `## /aw-spec-plan-
|
|
210
|
+
# The service lane's set is loaded under `## /aw-spec-plan-backend`; the frontend lane's
|
|
211
|
+
# under `## /aw-spec-plan-frontend`, and ONLY when that lane is declared — so a backend-only
|
|
209
212
|
# project's standards are exactly what they were before the two commands merged.
|
|
210
213
|
# No blocking gate: an unconfigured project soft-continues (the constitutions still
|
|
211
214
|
# carry each lane's ratified base).
|
|
212
215
|
#
|
|
213
216
|
# ONLY THE BACKEND'S RULES LOAD HERE. The frontend's used to load alongside them,
|
|
214
217
|
# before either lane authored anything, and sticky standards only accumulate — so the
|
|
215
|
-
# service plan was authored with `## /aw-spec-plan-
|
|
218
|
+
# service plan was authored with `## /aw-spec-plan-frontend` in its envelope and the
|
|
216
219
|
# experience plan with the service set. Each prompt names its lane, but it said so
|
|
217
220
|
# inside an envelope that contradicted it. The UI set now loads at the frontend
|
|
218
221
|
# boundary instead, with `replace`, in both places a frontend document is authored:
|
|
@@ -222,7 +225,7 @@ workflow:
|
|
|
222
225
|
condition: "{{be_declared}} == true"
|
|
223
226
|
action: include
|
|
224
227
|
module: .appweaver/orchestrator/modules/tech-select.orch.yaml
|
|
225
|
-
with: { command: aw-spec-plan }
|
|
228
|
+
with: { command: aw-spec-plan-backend }
|
|
226
229
|
|
|
227
230
|
# 2. Resolve the current feature and require its spec.
|
|
228
231
|
- id: feature_paths
|
|
@@ -617,6 +620,10 @@ workflow:
|
|
|
617
620
|
as field shapes. That section is the ONLY part of this document the frontend plan
|
|
618
621
|
may read; keep it complete and self-contained, because a contract the UI needs and
|
|
619
622
|
this document never states becomes a client-side workaround.
|
|
623
|
+
- NAME EVERY ENDPOINT. Each §3 endpoint carries an **Operation id** — its name in the
|
|
624
|
+
service's published API document (e.g. `CreatePatient`), unique across the
|
|
625
|
+
service and never reused. The frontend plan cites it, and implement gives the
|
|
626
|
+
endpoint exactly this id, so the two lanes meet on it.
|
|
620
627
|
- CONSTITUTION-MANDATED CROSS-CUTTING (from the loaded technical constitution, NOT
|
|
621
628
|
the spec): a NON-NEGOTIABLE technical principle you must apply that has NO
|
|
622
629
|
per-feature spec id. APPLY it (it is non-negotiable), and because it is not
|
|
@@ -704,6 +711,10 @@ workflow:
|
|
|
704
711
|
- PUBLISH THE SURFACE THE FRONTEND LANE BINDS TO: the section carrying this feature's
|
|
705
712
|
endpoints states each contract as field shapes, completely, because it is the only
|
|
706
713
|
part of this document the frontend plan may read.
|
|
714
|
+
- NAME EVERY ENDPOINT with its route, verb and operation id — its name in the
|
|
715
|
+
service's published API document, unique across the service. Where the code
|
|
716
|
+
already gives the endpoint one, record THAT id exactly as the code spells it; the
|
|
717
|
+
frontend plan cites it and implement finds the endpoint by it.
|
|
707
718
|
- CONSTITUTION-MANDATED CROSS-CUTTING (from the loaded technical constitution, NOT
|
|
708
719
|
the spec): a NON-NEGOTIABLE technical principle with no per-feature spec id —
|
|
709
720
|
APPLY it, and LOG it as a §5 DA-n whose basis cites the mandating principle
|
|
@@ -773,6 +784,9 @@ workflow:
|
|
|
773
784
|
workarounds are DECISIONS THIS TEAM MADE, not derivations from the spec — keep
|
|
774
785
|
every one, with its id and its basis, unless the thing it decided about is gone.
|
|
775
786
|
Never renumber a surviving entry: its id is cited elsewhere.
|
|
787
|
+
- OPERATION IDS ARE STABLE. Every endpoint keeps the operation id it already has —
|
|
788
|
+
the frontend plan and the built code both use it. A new endpoint gets one, unique
|
|
789
|
+
across the service; an endpoint without one gets one now.
|
|
776
790
|
- THE CODE THAT EXISTS IS THE WHAT-IS AUTHORITY. {{source_count}} source file(s)
|
|
777
791
|
realise this feature: {{source_files}}. READ them, and where the plan and the code
|
|
778
792
|
disagree about STRUCTURE, the code is what is actually there — conform to it and
|
|
@@ -788,7 +802,7 @@ workflow:
|
|
|
788
802
|
# ══════════════ THE LANE SWAP — the frontend's rules replace the backend's ═══
|
|
789
803
|
# Both tech-select includes used to run up at step 4, before either lane authored
|
|
790
804
|
# anything, and sticky standards only accumulate — so on a full-stack run the backend
|
|
791
|
-
# plan was authored with `## /aw-spec-plan-
|
|
805
|
+
# plan was authored with `## /aw-spec-plan-frontend` in its envelope and the frontend plan with
|
|
792
806
|
# the service set. Each prompt names its lane, but it did so inside an envelope that
|
|
793
807
|
# contradicted it, and the envelope is the half the model cannot argue with.
|
|
794
808
|
#
|
|
@@ -800,7 +814,7 @@ workflow:
|
|
|
800
814
|
condition: "{{fe_mode}} != skip"
|
|
801
815
|
action: include
|
|
802
816
|
module: .appweaver/orchestrator/modules/tech-select.orch.yaml
|
|
803
|
-
with: { command: aw-spec-plan-
|
|
817
|
+
with: { command: aw-spec-plan-frontend, replace: "true" }
|
|
804
818
|
|
|
805
819
|
# ═══════════ FRONTEND LANE — bootstrap, greenfield experience template ═══════
|
|
806
820
|
# The experience twin of the service plan, and the MEDIATOR between spec.md and the
|
|
@@ -867,6 +881,10 @@ workflow:
|
|
|
867
881
|
DELTA raised back to the service lane under "Contract deltas needed" — never a
|
|
868
882
|
workaround in the client. Where no service plan is in context, bind from the
|
|
869
883
|
spec's IC- surface and record that as a §8 DA-n.
|
|
884
|
+
- EVERY §5 ROW CITES ITS OPERATION ID, copied exactly from the endpoint's
|
|
885
|
+
**Operation id** in the backend plan's §3 — implement looks the endpoint up by it
|
|
886
|
+
in the service's exported API document. Where no service plan names one, write
|
|
887
|
+
`—` and record it in the same §8 DA-n.
|
|
870
888
|
- CONSTITUTION-MANDATED CROSS-CUTTING (from the loaded UI constitution, NOT the
|
|
871
889
|
spec): a NON-NEGOTIABLE UX principle you must apply that has no per-feature spec
|
|
872
890
|
id. APPLY it, and because it is not spec-derived, LOG it as a §8 DA-n whose
|
|
@@ -952,6 +970,9 @@ workflow:
|
|
|
952
970
|
states. Cite them; do not restate, re-derive or contradict them, and introduce no
|
|
953
971
|
server-side behaviour. What the experience needs and the surface lacks is a
|
|
954
972
|
contract delta raised back to the service lane, never a client workaround.
|
|
973
|
+
- EVERY BINDING ROW CITES ITS OPERATION ID, copied exactly from the backend plan —
|
|
974
|
+
implement looks the endpoint up by it in the service's exported API document.
|
|
975
|
+
Where no service plan names one, write `—` and record it as a DA-n.
|
|
955
976
|
- CONSTITUTION-MANDATED CROSS-CUTTING with no per-feature spec id: apply it, and
|
|
956
977
|
log it as a DA-n citing the mandating principle ("per constitution.ui.md
|
|
957
978
|
UX-<n>"). Do not fabricate a spec id for it and do not leave it uncited.
|
|
@@ -1010,6 +1031,9 @@ workflow:
|
|
|
1010
1031
|
— the spec's IC- ids and, where the backend plan is in context, the API contracts
|
|
1011
1032
|
it states. What the experience needs and the surface lacks is a contract delta
|
|
1012
1033
|
raised back to the service lane, never a client workaround.
|
|
1034
|
+
- EVERY BINDING ROW CITES ITS OPERATION ID, copied exactly from the backend plan; a
|
|
1035
|
+
row that has none yet gets it now, and a row whose id the backend plan no longer
|
|
1036
|
+
has is re-bound. Where no service plan names one, write `—` with a DA-n.
|
|
1013
1037
|
- TECHNOLOGY-AGNOSTIC: no framework, router, state library, component library or
|
|
1014
1038
|
styling approach — responsibilities, field shapes, events and states only.
|
|
1015
1039
|
- ADD ONE Change History row for this re-derivation, describing what MOVED and why.
|
|
@@ -32,7 +32,7 @@ scripts:
|
|
|
32
32
|
# operating rules, which is where "never run a migration against a shared environment"
|
|
33
33
|
# lives. The technical rule file
|
|
34
34
|
# the migration step works against (persistence) is now CONFIGURATION, loaded per-command from
|
|
35
|
-
# guardrails
|
|
35
|
+
# guardrails/<project>/tech-rule-bindings.md under "## /aw-spec-run" by the tech-select
|
|
36
36
|
# module (see the tech_select step below). No domain files; run does not reference
|
|
37
37
|
# constitution.technical.md. (missing files skipped at assembly time)
|
|
38
38
|
standards:
|
|
@@ -44,7 +44,7 @@ vars:
|
|
|
44
44
|
workflow:
|
|
45
45
|
|
|
46
46
|
# 0. TECHNICAL rule files → sticky standards (configuration, not hardcoded). tech-select
|
|
47
|
-
# reads guardrails
|
|
47
|
+
# reads guardrails/<project>/tech-rule-bindings.md under "## /aw-spec-run" and loads
|
|
48
48
|
# that set (persistence) into the sticky standards the agent_generate migration step ALWAYS
|
|
49
49
|
# prepends. No domain rule file here. No blocking gate: an unconfigured project soft-continues.
|
|
50
50
|
- id: tech_select
|
|
@@ -66,8 +66,8 @@ workflow:
|
|
|
66
66
|
on_empty: stop
|
|
67
67
|
on_empty_message: "No active feature. Run /appweaver select-feature first (pick or create the feature, e.g. Order or PatientRegistration), then re-run run."
|
|
68
68
|
|
|
69
|
-
# Require the SERVICE LANE and its
|
|
70
|
-
# lane by definition, and run-migrate searches that lane
|
|
69
|
+
# Require the SERVICE LANE and its lane root folder. Migrations belong to the backend
|
|
70
|
+
# lane by definition, and run-migrate searches that lane root folder for the project
|
|
71
71
|
# instead of assuming `src/` — which is what lets a repo whose service code sits
|
|
72
72
|
# in `Legacy/App/` or `backend/` find its own migrations.
|
|
73
73
|
- id: lane_gate
|
|
@@ -24,6 +24,9 @@
|
|
|
24
24
|
# list-contexts → user_select (existing | "+ create new") → [ask name] → set-context
|
|
25
25
|
#
|
|
26
26
|
# Persists .appweaver/context.json {"context":"<Name>","context_directory":"specs/<Name>"}.
|
|
27
|
+
# When the chosen context does not contain the active feature, set-context also clears
|
|
28
|
+
# .appweaver/feature.json, so specify and every later stage stop until select-feature
|
|
29
|
+
# picks a feature inside the new context.
|
|
27
30
|
#
|
|
28
31
|
# Launch:
|
|
29
32
|
# /appweaver select-bounded-context # interactive: list + add-new
|
|
@@ -32,7 +35,7 @@
|
|
|
32
35
|
|
|
33
36
|
name: aw-spec-select-bounded-context
|
|
34
37
|
description: Pick an existing bounded context or create a new one, and store it in .appweaver/context.json so select-feature nests its features inside it and every spec in the context shares one domain-model.md. Zero LLM — scripts + one selection only.
|
|
35
|
-
version: 1.
|
|
38
|
+
version: 1.1.0
|
|
36
39
|
agent_agnostic: true
|
|
37
40
|
dialect: aw-spec.orchestrator/v1
|
|
38
41
|
|
|
@@ -51,6 +54,8 @@ vars:
|
|
|
51
54
|
new_sentinel: "+ Create a new bounded context" # source of truth is list-contexts $.sentinel; overwritten below
|
|
52
55
|
typed_name: ""
|
|
53
56
|
target_name: ""
|
|
57
|
+
feature_cleared: "false"
|
|
58
|
+
cleared_feature: ""
|
|
54
59
|
|
|
55
60
|
workflow:
|
|
56
61
|
|
|
@@ -120,6 +125,23 @@ workflow:
|
|
|
120
125
|
- { name: existed, from: "$.existed" }
|
|
121
126
|
- { name: created, from: "$.created" }
|
|
122
127
|
- { name: domain_model_exists, from: "$.domain_model_exists" }
|
|
128
|
+
- { name: feature_cleared, from: "$.feature_cleared" }
|
|
129
|
+
- { name: cleared_feature, from: "$.cleared_feature" }
|
|
130
|
+
|
|
131
|
+
# 6. Say when the active feature was cleared: every feature-scoped stage stops until
|
|
132
|
+
# select-feature runs. The never-satisfiable `equals` is the engine's announce-only
|
|
133
|
+
# idiom: the step is entered only when a feature was cleared, and the comparison
|
|
134
|
+
# always misses, so the message is emitted and the run continues.
|
|
135
|
+
- id: feature_cleared_notice
|
|
136
|
+
action: verify_context
|
|
137
|
+
condition: "{{feature_cleared}} == true"
|
|
138
|
+
require_value: feature_cleared
|
|
139
|
+
equals: "never"
|
|
140
|
+
on_mismatch: continue
|
|
141
|
+
on_mismatch_message: >
|
|
142
|
+
The previously active feature {{cleared_feature}} is not in {{context}}, so it is
|
|
143
|
+
no longer active. Run /appweaver select-feature to pick or create a feature in
|
|
144
|
+
{{context_dir}}/ before specify or any later stage.
|
|
123
145
|
|
|
124
146
|
outputs:
|
|
125
147
|
context: "{{context}}"
|
|
@@ -128,5 +150,7 @@ outputs:
|
|
|
128
150
|
domain_model_exists: "{{domain_model_exists}}"
|
|
129
151
|
created: "{{created}}"
|
|
130
152
|
legacy_features: "{{legacy_features}}"
|
|
131
|
-
|
|
153
|
+
feature_cleared: "{{feature_cleared}}"
|
|
154
|
+
cleared_feature: "{{cleared_feature}}"
|
|
155
|
+
note: "Active bounded context set in .appweaver/context.json. select-feature now creates and lists features inside {{context_dir}}/, and every spec there shares {{domain_model}} as its domain model. When the previously active feature is not in this context, .appweaver/feature.json is cleared (feature_cleared true, cleared_feature names it) and specify and every later stage stop until select-feature runs. Features already sitting flat under specs/ are listed as legacy_features — they are not moved; re-run select-feature after selecting a context to place new work inside it."
|
|
132
156
|
next: "/appweaver select-feature (creates {{context_dir}}/<Feature>/, then specify)"
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
# =============================================================================
|
|
2
|
-
# aw-spec-select-domain (orchestrator) — select the active PROJECT under guardrails/
|
|
2
|
+
# aw-spec-select-domain (orchestrator) — select the active PROJECT folder under guardrails/
|
|
3
3
|
#
|
|
4
4
|
# The command name and .appweaver/domain.json are historical: what is selected is a
|
|
5
5
|
# project folder, and a project is bound to rules by its two maps, not by an industry.
|
|
6
6
|
#
|
|
7
|
+
# OPTIONAL: no sequence runs it. domain.json ships naming guardrails/project-specific/ and
|
|
8
|
+
# onboard points it at the guardrails/brf-<domain>/ it creates; this command switches to
|
|
9
|
+
# any other project folder that already exists (e.g. a copy of project-specific). It never
|
|
10
|
+
# creates one — a name with no folder is not offered, and the user picks from the list.
|
|
11
|
+
#
|
|
7
12
|
# Pure orchestration/governance, NO generation: scripts + one gate + one HITL select.
|
|
8
13
|
# Exercises the D1 interaction channel: under ANY strategy the `user_select`
|
|
9
14
|
# step suspends via --checkpoint (kind 'select') so the LAUNCHING agent asks
|
|
@@ -17,14 +22,14 @@
|
|
|
17
22
|
# =============================================================================
|
|
18
23
|
|
|
19
24
|
name: aw-spec-select-domain
|
|
20
|
-
description:
|
|
21
|
-
version: 1.
|
|
25
|
+
description: Switch the active project — a folder under guardrails/ that holds the rule maps — by storing its name in .appweaver/domain.json, binding both of that project's rule maps (domain-rule-bindings.md and tech-rule-bindings.md) so every AW-Spec command loads that project's domain AND technical rule files. Optional; domain.json names guardrails/project-specific/ by default.
|
|
26
|
+
version: 1.1.0
|
|
22
27
|
agent_agnostic: true
|
|
23
28
|
dialect: aw-spec.orchestrator/v1
|
|
24
29
|
|
|
25
30
|
inputs:
|
|
26
31
|
user_input:
|
|
27
|
-
description: Optional project folder name under guardrails/
|
|
32
|
+
description: Optional project folder name under guardrails/ to set directly (e.g. project-specific). The folder must already exist and hold a rule map; any other name shows the list of projects instead. An industry name is not a valid value — an industry is a corpus a project's map points at, never a selection.
|
|
28
33
|
required: false
|
|
29
34
|
bind: USER_INPUT
|
|
30
35
|
|
|
@@ -35,7 +40,7 @@ scripts:
|
|
|
35
40
|
|
|
36
41
|
workflow:
|
|
37
42
|
|
|
38
|
-
# 1. Discover candidate projects =
|
|
43
|
+
# 1. Discover candidate projects = top-level folders of guardrails/ carrying a rule map.
|
|
39
44
|
- id: list_domains
|
|
40
45
|
action: execute_script
|
|
41
46
|
script: { ref: actions }
|
|
@@ -43,21 +48,22 @@ workflow:
|
|
|
43
48
|
outputs:
|
|
44
49
|
- { name: domains, from: "$.domains" }
|
|
45
50
|
|
|
46
|
-
# 2. Stop early if there are no
|
|
51
|
+
# 2. Stop early if there are no projects to choose from.
|
|
47
52
|
- id: guard_no_domains
|
|
48
53
|
action: verify_context
|
|
49
54
|
require_non_empty: domains
|
|
50
55
|
on_empty_message: >
|
|
51
|
-
No
|
|
52
|
-
guardrails
|
|
53
|
-
|
|
56
|
+
No project folders found under guardrails/. Copy guardrails/project-specific/ to
|
|
57
|
+
guardrails/<name>/, change the guardrails/project-specific/ paths inside its two maps
|
|
58
|
+
to guardrails/<name>/, repoint the maps at the technology and domain corpora this
|
|
59
|
+
project uses, then re-run.
|
|
54
60
|
on_empty: stop
|
|
55
61
|
|
|
56
|
-
# 3. Choose the
|
|
62
|
+
# 3. Choose the project. If USER_INPUT names a listed project it is used directly;
|
|
57
63
|
# otherwise the launcher relays the choice to the user. One option => confirm.
|
|
58
64
|
- id: select_domain
|
|
59
65
|
action: user_select
|
|
60
|
-
prompt: "Select the active
|
|
66
|
+
prompt: "Select the active project:"
|
|
61
67
|
options_from_variable: domains
|
|
62
68
|
preselect_from: USER_INPUT # direct-argument fast path
|
|
63
69
|
single_option_confirm: true
|
|
@@ -79,7 +85,7 @@ outputs:
|
|
|
79
85
|
domain: "{{domain}}"
|
|
80
86
|
domain_rule_bindings: "{{map_path}}"
|
|
81
87
|
domain_rule_bindings_exists: "{{map_exists}}"
|
|
82
|
-
note: "Active project '{{domain}}' persisted to .appweaver/domain.json. It selects TWO rule maps under guardrails/
|
|
83
|
-
# constitution
|
|
84
|
-
#
|
|
85
|
-
next: "
|
|
88
|
+
note: "Active project '{{domain}}' persisted to .appweaver/domain.json. It selects TWO rule maps under guardrails/{{domain}}/ — domain-rule-bindings.md (DOMAIN rules; read by constitution + specify only, because the spec is the pivot) and tech-rule-bindings.md (TECHNICAL rules; read by the HOW phases incl. foundation's spec builds, plan, implement, build and run). The rule FILES themselves live in shared corpora — guardrails/technology/<stack>/ and guardrails/domain/<industry>/ — and the maps are what bind this project to them, so two projects can share a corpus and differ only in their maps and their own three requirements files. domain_rule_bindings_exists reports the domain half only. A map that is absent, or a command with no heading in one, loads nothing for that class and SOFT-CONTINUES — an absent heading is a valid state, never a failure."
|
|
89
|
+
# constitution reads the domain rule map this workflow just bound; the halves it
|
|
90
|
+
# already wrote stay as they are until it runs again.
|
|
91
|
+
next: "Switching the project changes which rule files later commands load; it does not rewrite anything already written. Re-run /appweaver constitution so constitution.domain.md, constitution.technical.md and constitution.ui.md are authored from the new project's rules — specify declares constitution.domain.md as REQUIRED context, and plan and implement read constitution.technical.md (plus constitution.ui.md on a frontend lane). Specs and plans already written keep the rules they were written under. GREENFIELD with no project scaffolded yet: /appweaver foundation first — a lane built from a spec follows the technical rules this run just bound (`## /aw-spec-foundation-backend` / `## /aw-spec-foundation-frontend`) — then /appweaver constitution → specify. To add another project, copy guardrails/project-specific/ to guardrails/<name>/, change the guardrails/project-specific/ paths inside its two maps to guardrails/<name>/, and run /appweaver select-domain <name>. Re-run /appweaver select-domain any time to switch back; it rebinds both maps at once."
|
|
@@ -14,12 +14,12 @@
|
|
|
14
14
|
# evidence sits in, and both are only ever proposals — an operator selects from the
|
|
15
15
|
# list or types a path the kit has never seen.
|
|
16
16
|
#
|
|
17
|
-
# stack-list --suggest backend → select stack → stack-list --profile → ask
|
|
18
|
-
# stack-list --suggest frontend → select stack → stack-list --profile → ask
|
|
17
|
+
# stack-list --suggest backend → select stack → stack-list --profile → ask lane root folder → lane-declare
|
|
18
|
+
# stack-list --suggest frontend → select stack → stack-list --profile → ask lane root folder → lane-declare
|
|
19
19
|
#
|
|
20
20
|
# THE SOURCE-PATH OPTIONS ARE BUILT AFTER THE STACK IS CHOSEN. Most profiles of a kind
|
|
21
|
-
# share a default root (
|
|
22
|
-
# choice cannot say which stack an option belongs to. The second stack-list call answers
|
|
21
|
+
# share a default root (every backend stack defaults to backend/, every frontend stack to
|
|
22
|
+
# frontend/), so a list built before the choice cannot say which stack an option belongs to. The second stack-list call answers
|
|
23
23
|
# for the chosen stack alone.
|
|
24
24
|
#
|
|
25
25
|
# (none) IS A REAL ANSWER FOR EITHER LANE, and it is how a project says "I do not
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
# lane a person already declared. Every other workflow calls `lane-resolve` to read
|
|
35
35
|
# and `lane-verify` to gate, and neither can write.
|
|
36
36
|
#
|
|
37
|
-
# WHY THE
|
|
37
|
+
# WHY THE LANE ROOT FOLDER IS ASKED AND NOT INHERITED. A lane root folder is the subtree its lane
|
|
38
38
|
# OWNS: the only place implement's lane for it may write, the directory its build and
|
|
39
39
|
# run commands act on, and in brownfield the code onboard reads. A profile's default
|
|
40
40
|
# root describes how a NEW project of that stack is usually laid out, which is a
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
# =============================================================================
|
|
61
61
|
|
|
62
62
|
name: aw-spec-select-stack
|
|
63
|
-
description: Declare the project's lanes — each lane's STACK and its
|
|
63
|
+
description: Declare the project's lanes — each lane's STACK and its LANE ROOT FOLDER — and persist them to .appweaver/stacks.json, the single channel every later workflow resolves and gates on. The first command of both the greenfield and the brownfield sequence, and the sole writer of the lane model.
|
|
64
64
|
version: 2.3.0
|
|
65
65
|
agent_agnostic: true
|
|
66
66
|
dialect: aw-spec.orchestrator/v1
|
|
@@ -139,7 +139,7 @@ workflow:
|
|
|
139
139
|
# 5. WHERE the service lane's source lives. Offered best-first for the CHOSEN stack —
|
|
140
140
|
# where its evidence sits, then its own default, then where another stack's
|
|
141
141
|
# evidence sits — and free text is accepted, because a repo that matches no
|
|
142
|
-
# profile still has a
|
|
142
|
+
# profile still has a lane root folder. The label after the path says why it is
|
|
143
143
|
# offered and is stripped on the way in.
|
|
144
144
|
- id: list_api_roots
|
|
145
145
|
action: execute_script
|
|
@@ -153,7 +153,7 @@ workflow:
|
|
|
153
153
|
- id: ask_api_source_path
|
|
154
154
|
action: ask
|
|
155
155
|
condition: "{{api_selected}}"
|
|
156
|
-
prompt: "Service
|
|
156
|
+
prompt: "Service LANE ROOT FOLDER — the subtree this lane owns, where implement writes its code, and the directory build/test/run act on. Its tests go to the stack's test path — inside it for a new project (backend/tests/ for .NET), beside it in a classic layout (tests/ next to src/) — shown in the summary. Pick one or type your own:"
|
|
157
157
|
options_from_variable: api_root_options
|
|
158
158
|
answer_var: api_source_path
|
|
159
159
|
|
|
@@ -224,7 +224,7 @@ workflow:
|
|
|
224
224
|
- id: ask_ui_source_path
|
|
225
225
|
action: ask
|
|
226
226
|
condition: "{{ui_selected}}"
|
|
227
|
-
prompt: "UI
|
|
227
|
+
prompt: "UI LANE ROOT FOLDER — the subtree this lane owns, the only place implement's frontend lane may write. It must not overlap the service lane's. Pick one or type your own:"
|
|
228
228
|
options_from_variable: ui_root_options
|
|
229
229
|
answer_var: ui_source_path
|
|
230
230
|
|
|
@@ -243,7 +243,7 @@ workflow:
|
|
|
243
243
|
|
|
244
244
|
# ═══════════════ CHECK + REPORT ═════════════════════════════════════════════
|
|
245
245
|
|
|
246
|
-
# 10. Is what was just written sound? --allow-missing-root because a
|
|
246
|
+
# 10. Is what was just written sound? --allow-missing-root because a lane root folder
|
|
247
247
|
# declared here legitimately does not exist yet; what this catches is a lane
|
|
248
248
|
# declared with NO path at all, which no later phase could act on. The on-disk
|
|
249
249
|
# check belongs to the phases that read the subtree, and runs there.
|
|
@@ -279,7 +279,7 @@ workflow:
|
|
|
279
279
|
- id: api_summary_lane
|
|
280
280
|
action: set
|
|
281
281
|
condition: "{{api_declared}}"
|
|
282
|
-
vars: { api_summary: "{{api_lane_id}} ({{api_profile}}) at {{api_root}}, tests at {{api_test_path}} —
|
|
282
|
+
vars: { api_summary: "{{api_lane_id}} ({{api_profile}}) at {{api_root}}, tests at {{api_test_path}} — lane root folder exists: {{api_root_exists}}" }
|
|
283
283
|
|
|
284
284
|
- id: ui_summary_none
|
|
285
285
|
action: set
|
|
@@ -287,7 +287,7 @@ workflow:
|
|
|
287
287
|
- id: ui_summary_lane
|
|
288
288
|
action: set
|
|
289
289
|
condition: "{{ui_declared}}"
|
|
290
|
-
vars: { ui_summary: "{{ui_lane_id}} ({{ui_profile}}) at {{ui_root}}, tests at {{ui_test_path}} —
|
|
290
|
+
vars: { ui_summary: "{{ui_lane_id}} ({{ui_profile}}) at {{ui_root}}, tests at {{ui_test_path}} — lane root folder exists: {{ui_root_exists}}" }
|
|
291
291
|
|
|
292
292
|
# 12. Read the finished declaration back through the reader every later workflow
|
|
293
293
|
# uses, so what this run reports is what they will resolve.
|
|
@@ -316,5 +316,5 @@ outputs:
|
|
|
316
316
|
api_detected: "{{api_detected}}"
|
|
317
317
|
ui_detected: "{{ui_detected}}"
|
|
318
318
|
prototype: "{{prototype}}"
|
|
319
|
-
note: "Lanes persisted to .appweaver/stacks.json. Each lane carries a STACK and a
|
|
320
|
-
next: "GREENFIELD: /appweaver foundation —
|
|
319
|
+
note: "Lanes persisted to .appweaver/stacks.json. Each lane carries a STACK and a LANE ROOT FOLDER, and both are load-bearing. The LANE ROOT FOLDER is ownership: implement's service lane writes its code only under the service lane's and its frontend lane only under the UI lane's, build/test/run act on it, and onboard reverse-engineers out of it. Each lane also owns a TEST PATH, taken from its stack profile — tests/ beside a .NET src/, the lane root folder itself for a stack that keeps its tests inside — and implement writes the lane's tests there. Overlapping paths of either kind are refused here rather than discovered later as two generators writing one file. The build/test/run commands are project-supplied strings the engine shells out to, which is how it stays stdlib-only and stack-ignorant. api_detected / ui_detected report what this repo's own files pointed at, whether or not it was chosen, as '<stack> at <path>' — or 'nothing detected' on a greenfield repo with nothing to detect. A lane root folder that does not exist yet is NORMAL here and reported rather than refused: greenfield declares src/ before implement creates it. The on-disk check runs in the phases that read the subtree — implement, build, run and onboard all call lane-verify and STOP with the fix named. Declining a lane with (none) is a real declaration and removes any lane of that kind a previous run left behind; it is also what stops that lane's constitution half and rule files being authored. `prototype` is not a lane — it has a root and a run command so an operator can open it, and nothing else. Re-run this workflow any time to re-stack a lane, move a lane root folder, or drop a lane with (none); it is the only workflow that may write this file."
|
|
320
|
+
next: "GREENFIELD: /appweaver foundation → constitution → specify. The project rules live in guardrails/project-specific/, which .appweaver/domain.json names by default — fill in its rule files and its two maps; /appweaver select-domain switches to another project folder under guardrails/ when you keep more than one. On a project with no specs yet, constitution creates the default bounded context MainContext and its feature CoreFeature and makes both active; to use your own names, run /appweaver select-bounded-context <Name> and then /appweaver select-feature <Name> before specify. Once any bounded context exists, select-feature refuses to run until one is selected. foundation scaffolds every lane declared here in one run, backend then frontend — from a verified pack, from a spec the agent builds the project from, or skipped for a lane whose code already exists — and a spec build follows the technical rules the active project maps under `## /aw-spec-foundation-backend` and `## /aw-spec-foundation-frontend`. BROWNFIELD: /appweaver inventory — it scans the lane root folders declared here and proposes the bounded contexts and features as specs/proposed-inventory.md; edit that map, run /appweaver inventory apply, then /appweaver onboard <Context> once per bounded context, which reverse-engineers the governance out of the same lane root folders and activates it: onboard creates guardrails/brf-<domain>/ from the code and names it in .appweaver/domain.json. Run this workflow FIRST in either sequence: foundation scaffolds into the lane root folders declared here, constitution reads the declaration to decide which halves to author, and inventory and onboard read it to decide what to scan."
|
|
@@ -93,7 +93,7 @@ scripts:
|
|
|
93
93
|
# Sticky standards seed = the UNIVERSAL always-on rule only (ai-rules). Specify's ONE
|
|
94
94
|
# technical input — the MODELLING METHODOLOGY (DDD tactical patterns) — is no longer
|
|
95
95
|
# hardcoded here: it is now CONFIGURATION, loaded per-command from
|
|
96
|
-
# guardrails
|
|
96
|
+
# guardrails/<project>/tech-rule-bindings.md by the tech-select module (see the
|
|
97
97
|
# tech_select step below), exactly as the DOMAIN rule files are loaded by domain-select.
|
|
98
98
|
# Per the rule-partition that heading may carry a modelling methodology ONLY — never an
|
|
99
99
|
# architecture / persistence / codegen file; those belong to design + implement, and
|
|
@@ -193,7 +193,7 @@ workflow:
|
|
|
193
193
|
- { name: next_wave, from: "$.next_wave" }
|
|
194
194
|
|
|
195
195
|
# 2. TECHNICAL rule files → sticky standards (configuration, not hardcoded).
|
|
196
|
-
# tech-select reads guardrails
|
|
196
|
+
# tech-select reads guardrails/<project>/tech-rule-bindings.md under
|
|
197
197
|
# "## /aw-spec-specify" and loads that set. Per the rule-partition that heading is
|
|
198
198
|
# the MODELLING-METHODOLOGY slot only (DDD tactical patterns) — it must never list an
|
|
199
199
|
# architecture / persistence / codegen file, which would break specify's domain purity.
|
|
@@ -643,7 +643,7 @@ workflow:
|
|
|
643
643
|
action: verify_context
|
|
644
644
|
require_true: nn_compliant
|
|
645
645
|
on_false: stop
|
|
646
|
-
on_false_message: "The answer to
|
|
646
|
+
on_false_message: "The answer to '{{c.question}}' departs from NON-NEGOTIABLE principle {{nn_principle}}: {{nn_why}}. That principle is ratified in .appweaver/memory/ and this answer has no approver — it was settled in this run, not by a domain owner, and the constitution's Governance section holds that a deviation with no named approver is a defect rather than a decision. Re-run specify and answer in a way the principle allows; if the project genuinely intends to depart from it, amend the constitution through its own amendment process FIRST (which names the approver the departure needs) and re-run. Nothing was written to {{quality_target}} for this clarification."
|
|
647
647
|
|
|
648
648
|
- id: resolve_clar
|
|
649
649
|
action: agent_author
|
|
@@ -115,9 +115,9 @@ workflow:
|
|
|
115
115
|
context:
|
|
116
116
|
- "{{feature_dir}}/ui/workflow-model.md"
|
|
117
117
|
- "{{spec_file}}"
|
|
118
|
-
- { path: "guardrails/
|
|
119
|
-
- { path: "guardrails/
|
|
120
|
-
- { path: "guardrails/
|
|
118
|
+
- { path: "guardrails/{{domain}}/frontend/design.md", optional: true }
|
|
119
|
+
- { path: "guardrails/{{domain}}/frontend/DESIGN.md", optional: true }
|
|
120
|
+
- { path: "guardrails/{{domain}}/frontend/ui-requirements.md", optional: true }
|
|
121
121
|
- { path: ".appweaver/templates/ui-model-template.md", optional: true }
|
|
122
122
|
- { path: ".appweaver/memory/constitution.ui.md", optional: true }
|
|
123
123
|
|
|
@@ -141,9 +141,9 @@ workflow:
|
|
|
141
141
|
- { path: "{{domain_model}}", optional: true }
|
|
142
142
|
- { path: "{{feature_dir}}/ui/workflow-model.md", optional: true }
|
|
143
143
|
- { path: "{{feature_dir}}/ui/ui-model.md", optional: true }
|
|
144
|
-
- { path: "guardrails/
|
|
145
|
-
- { path: "guardrails/
|
|
146
|
-
- { path: "guardrails/
|
|
144
|
+
- { path: "guardrails/{{domain}}/frontend/design.md", optional: true }
|
|
145
|
+
- { path: "guardrails/{{domain}}/frontend/DESIGN.md", optional: true }
|
|
146
|
+
- { path: "guardrails/{{domain}}/frontend/ui-requirements.md", optional: true }
|
|
147
147
|
- { path: ".appweaver/memory/constitution.domain.md", optional: true }
|
|
148
148
|
- { path: ".appweaver/memory/constitution.ui.md", optional: true }
|
|
149
149
|
- { path: "{{feature_dir}}/changes/{{active_change}}/delta-spec.md", optional: true }
|
|
@@ -254,7 +254,7 @@ workflow:
|
|
|
254
254
|
The feature specification is taken directly from the bounded context directory and feature path defined in `.appweaver/feature.json`:
|
|
255
255
|
`{{spec_file}}` (Bounded Context: `{{context_name}}`, Feature: `{{feature_name}}`).
|
|
256
256
|
Read this specification strictly from `{{spec_file}}`, along with the bounded context's canonical domain model (`{{domain_model}}`),
|
|
257
|
-
the project Design System if present (`guardrails/
|
|
257
|
+
the project Design System if present (`guardrails/{{domain}}/frontend/design.md` or `DESIGN.md`, or `{{feature_dir}}/ui/design.md`),
|
|
258
258
|
and when available, the Workflow Model (`{{feature_dir}}/ui/workflow-model.md`) and UI Model (`{{feature_dir}}/ui/ui-model.md`), plus `{{prototype_root}}/lib/screens-registry.ts` / `screens.json`.
|
|
259
259
|
If `workflow-model.md` and `ui-model.md` are not provided, derive all UI surfaces, workflows, and interaction states directly from `{{spec_file}}`.
|
|
260
260
|
|
|
@@ -342,7 +342,7 @@ workflow:
|
|
|
342
342
|
Tailwind/CSS config from the shell is intact. If it's missing or broken, fix it
|
|
343
343
|
as part of this run and note that in your final summary; don't build a styled-looking
|
|
344
344
|
screen on top of a broken/absent styling pipeline.
|
|
345
|
-
- If a project visual design system is present in context (`guardrails/
|
|
345
|
+
- If a project visual design system is present in context (`guardrails/{{domain}}/frontend/design.md` or `DESIGN.md`),
|
|
346
346
|
apply its visual design tokens (colors, accent, surface, border, typography, card elevation, and status states)
|
|
347
347
|
consistently across all cards, badges, buttons, forms, and headers on this screen.
|
|
348
348
|
- Use the shell's existing design tokens and Tailwind utility classes (or whatever
|
|
@@ -386,7 +386,7 @@ workflow:
|
|
|
386
386
|
- Generate or update `{{feature_dir}}/ui/ui-spec.md` alongside the prototype code.
|
|
387
387
|
- Format as a markdown document with a brief title and capture intro, followed by a SINGLE fenced `json` code block adhering strictly to the JSON schema defined in `skill/references/output-ui-spec.md`:
|
|
388
388
|
- `screen`: user-facing screen name and route
|
|
389
|
-
- `captureNotes`: viewport width, CSS px, DPR, and design system token origin (`guardrails/
|
|
389
|
+
- `captureNotes`: viewport width, CSS px, DPR, and design system token origin (`guardrails/{{domain}}/frontend/DESIGN.md` or `design.md`)
|
|
390
390
|
- `regions`: ordered list of UI regions (nav-bar, header, step-card, content, dialogs, drawers) with `layout` (`position`, `wrap`, `direction`) and `elements` array
|
|
391
391
|
- `elements`: each element detailing `id`, `kind` (`text`, `button`, `badge`, `avatar`, `card`, `input`, etc.), verbatim `content`, `style` (`shape`, `colorToken`, `typographyToken`, `spacingPx`), `state` (`default`, `active`, `hover`), and `fields`
|
|
392
392
|
- `navigation`: ordered nav items, activeItem, activeStyle
|