aw-spec-cli 0.1.14 → 0.1.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/assets/.appweaver/STACK-PROFILES.md +1 -1
  2. package/assets/.appweaver/orchestrator/modules/spec-state-gate.orch.yaml +87 -0
  3. package/assets/.appweaver/orchestrator/orchestrator.py +5 -0
  4. package/assets/.appweaver/orchestrator/rev-templates/domain-rule-bindings.skeleton.md +10 -3
  5. package/assets/.appweaver/orchestrator/rev-templates/tech-rule-bindings.skeleton.md +38 -11
  6. package/assets/.appweaver/orchestrator/workflows/aw-spec-adopt.orch.yaml +2 -1
  7. package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-design.orch.yaml +672 -124
  8. package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-slice.orch.yaml +700 -72
  9. package/assets/.appweaver/orchestrator/workflows/aw-spec-implement-ui.orch.yaml +531 -135
  10. package/assets/.appweaver/orchestrator/workflows/aw-spec-implement.orch.yaml +573 -145
  11. package/assets/.appweaver/orchestrator/workflows/aw-spec-onboard.orch.yaml +78 -14
  12. package/assets/.appweaver/orchestrator/workflows/aw-spec-plan-ui.orch.yaml +600 -0
  13. package/assets/.appweaver/orchestrator/workflows/aw-spec-plan.orch.yaml +721 -0
  14. package/assets/.appweaver/orchestrator/workflows/aw-spec-select-feature.orch.yaml +3 -3
  15. package/assets/.appweaver/orchestrator/workflows/aw-spec-specify.orch.yaml +119 -32
  16. package/assets/.appweaver/orchestrator/workflows/aw-spec-story-plan.orch.yaml +1147 -0
  17. package/assets/.appweaver/orchestrator/workflows/aw-spec-sync-stories.orch.yaml +1121 -0
  18. package/assets/.appweaver/scripts/bash/aw-spec-actions.sh +2564 -38
  19. package/assets/.appweaver/scripts/bash/aw-xref.sh +2 -1
  20. package/assets/.appweaver/scripts/powershell/aw-spec-actions.ps1 +2458 -22
  21. package/assets/.appweaver/scripts/powershell/aw-xref.ps1 +2 -1
  22. package/assets/.appweaver/scripts/python/aw-payload-parity.py +158 -0
  23. package/assets/.appweaver/scripts/python/aw-xref.py +431 -48
  24. package/assets/.appweaver/templates/design-template.md +88 -54
  25. package/assets/.appweaver/templates/spec-template.md +12 -10
  26. package/assets/.appweaver/templates/story-template.md +83 -12
  27. package/assets/.appweaver/templates/ui-design-template.md +71 -39
  28. package/assets/guardrails/projects/dotnet-default-project/domain-rule-bindings.md +19 -7
  29. package/assets/guardrails/projects/dotnet-default-project/tech-rule-bindings.md +35 -26
  30. package/package.json +1 -1
  31. package/assets/.appweaver/orchestrator/workflows/aw-spec-design-ui.orch.yaml +0 -386
  32. package/assets/.appweaver/orchestrator/workflows/aw-spec-design.orch.yaml +0 -382
@@ -443,7 +443,7 @@ they are content the kit cannot invent:
443
443
  | `{{backend_ecosystem}}` / `{{frontend_ecosystem}}` | that lane's `ecosystem` |
444
444
 
445
445
  ```md
446
- ## /aw-spec-design
446
+ ## /aw-spec-plan
447
447
  - guardrails/technology/{{stack}}/persistence.md
448
448
  - guardrails/technology/{{frontend_stack}}/ui-constitution.md
449
449
  ```
@@ -0,0 +1,87 @@
1
+ # =============================================================================
2
+ # spec-state-gate (orchestrator) — the ledger tripwire, gated on STATE
3
+ #
4
+ # Included by every phase that READS spec.md as an oracle and does not stamp it.
5
+ # It answers one question before that phase starts doing work:
6
+ #
7
+ # is spec.md's version an honest name for spec.md's contents?
8
+ #
9
+ # WHY THE `ok` BOOLEAN IS NOT ENOUGH. spec-check's decisive branch asks only "is
10
+ # there a version ROW above the version the kit last recorded", and never opens the
11
+ # body. Two of its states are therefore ok:true with a body nobody has re-baselined:
12
+ #
13
+ # ledgered_edit a row exists above the recorded version — the edit was RECORDED,
14
+ # but the kit has not re-hashed, so every LATER edit lands inside
15
+ # the same window and passes the same test. Verified: a requirement
16
+ # DELETED with no row naming it passes.
17
+ # header_behind the same, with the document's header not yet caught up.
18
+ #
19
+ # Both are legitimate transient states and both have the same remedy — spec-stamp,
20
+ # which re-baselines the hash and closes the window. That remedy is already named in
21
+ # these phases' own refusal messages and in SPEC-EDIT-PROTOCOL.md.
22
+ #
23
+ # WHY NOT FLIP `ok` INSTEAD. Because specify is the stamper. It MUST keep accepting
24
+ # both states — it is the command that resolves them — so making spec-check refuse
25
+ # them would wedge the one workflow that can fix them. The distinction belongs at the
26
+ # consumer, which is what this module is.
27
+ #
28
+ # WHAT IT DOES NOT DO. It never stamps, never edits and never repairs. Every state
29
+ # spec-check already refuses (unrowed_edit, unledgered_edit, rollback, no_ledger,
30
+ # delta_open) still stops on `ok`, with spec-check's own message.
31
+ #
32
+ # Inputs (via include `with`):
33
+ # command — the phase being gated, quoted back in the failure message
34
+ #
35
+ # Produces: spec_ok / spec_state (the raw answers) and spec_current (true when the
36
+ # state is one this phase may read from), for a caller that wants to say more.
37
+ # =============================================================================
38
+
39
+ name: spec-state-gate
40
+ dialect: aw-spec.orchestrator/v1
41
+
42
+ scripts:
43
+ actions:
44
+ sh: .appweaver/scripts/bash/aw-spec-actions.sh
45
+ ps1: .appweaver/scripts/powershell/aw-spec-actions.ps1
46
+
47
+ workflow:
48
+
49
+ - id: spec_guard_read
50
+ action: execute_script
51
+ script: { ref: actions }
52
+ subcommand: spec-check
53
+ args: ["--feature-dir", "{{feature_dir}}"]
54
+ outputs:
55
+ - { name: spec_ok, from: "$.ok" }
56
+ - { name: spec_state, from: "$.state" }
57
+
58
+ # The states spec-check itself refuses. Kept first and kept separate: its own error
59
+ # text says which one and why, and this module has nothing to add to it.
60
+ - id: spec_guard
61
+ action: verify_context
62
+ require_true: spec_ok
63
+ on_false: stop
64
+ on_false_message: "{{command}} cannot run: spec.md has moved outside the ledger (state: {{spec_state}}), so its version no longer names its contents and nothing read from it can be trusted. Record what changed in a Change History row naming the ids, then re-run spec-stamp to re-baseline — or, when the edit touched no requirement at all, spec-stamp alone (see .appweaver/SPEC-EDIT-PROTOCOL.md)."
65
+
66
+ # The two states that pass `ok` and still leave the body un-baselined. Ordered sets
67
+ # rather than a compound condition — the evaluator takes single comparisons only, so
68
+ # the refusal is the default and each acceptable state lifts it.
69
+ - id: spec_state_default
70
+ action: set
71
+ vars: { spec_current: "false" }
72
+ - id: spec_state_clean
73
+ condition: "{{spec_state}} == clean"
74
+ action: set
75
+ vars: { spec_current: "true" }
76
+ # A pre-ledger spec the kit has never stamped. Legitimate: nothing has been recorded
77
+ # against it, so there is no window between a row and a baseline to fall into.
78
+ - id: spec_state_unstamped
79
+ condition: "{{spec_state}} == unstamped"
80
+ action: set
81
+ vars: { spec_current: "true" }
82
+
83
+ - id: spec_state_gate
84
+ action: verify_context
85
+ require_true: spec_current
86
+ on_false: stop
87
+ on_false_message: "{{command}} cannot run: spec.md is in state '{{spec_state}}' — the edit is recorded in a Change History row, but the kit has not re-baselined the document, so its recorded hash still describes the text before the edit. Until it does, every FURTHER edit passes the same tripwire unnoticed, including a requirement deleted with no row naming it. Run /appweaver specify (which stamps), or re-run spec-stamp to re-baseline directly, then re-run {{command}}."
@@ -1345,6 +1345,11 @@ class Orchestrator:
1345
1345
  raise Stop(f"loop '{loop_id}': 'over' is not a list: {step.get('over')}")
1346
1346
  for idx, item in enumerate(items):
1347
1347
  if max_it is not None and idx >= max_it:
1348
+ # Says so, the way the while branch does. A foreach that stops early
1349
+ # drops the tail of its list, and a run that drops work in silence
1350
+ # reports the same success as one that did all of it.
1351
+ self.emit(f"[loop] {loop_id} hit max_iterations={max_it} — "
1352
+ f"{len(items) - max_it} item(s) not run")
1348
1353
  break
1349
1354
  self.vars[as_name] = item
1350
1355
  self.vars[as_name + "_index"] = idx
@@ -35,8 +35,15 @@ partition; preserve it exactly.
35
35
  into the spec's CN-/DC-/IC- (design/implement never see these files). -->
36
36
  - guardrails/projects/[project]/domain/[each generated domain rule file].md
37
37
 
38
- ## /aw-spec-design
39
- _None — design loads no domain file. Domain reaches design only through the spec (BR-/CN-/DC-/IC-)._
38
+ ## /aw-spec-plan
39
+ _None — the service lane's design loads no domain file. Domain reaches it only through the spec
40
+ (BR-/CN-/DC-/IC-)._
41
+
42
+ ## /aw-spec-plan-ui
43
+ _None — the frontend lane's design loads no domain file either: domain reaches frontend-plan.md
44
+ as spec ids (UX-/CN-/DC-/IC-). Written out rather than left absent, because an absent heading and
45
+ an empty one behave identically and only one of them is a decision. Keep this heading even in a
46
+ backend-only repo — it costs nothing and records the partition._
40
47
 
41
48
  ## /aw-spec-implement
42
49
  _None — implement loads no domain file. Domain reaches implement only through design.md._
@@ -54,6 +61,6 @@ _None — implement loads no domain file. Domain reaches implement only through
54
61
  |---|---|---|
55
62
  | /aw-spec-constitution | [n] | domain principles |
56
63
  | /aw-spec-specify | [n] | author into spec (lift → CN-/DC-/IC-) |
57
- | /aw-spec-design | 0 | none — spec is the only domain input |
64
+ | /aw-spec-plan | 0 | none — spec is the only domain input |
58
65
  | /aw-spec-implement | 0 | none — design is the only domain input |
59
66
  | /aw-spec-gate | [n] | conformance checklist (validate, don't author) |
@@ -43,7 +43,7 @@ refers to it directly, as-is.
43
43
  wired via domain-rule-bindings). No technology rule may appear under this heading. -->
44
44
  - guardrails/projects/[project]/service/domain-modelling.md
45
45
 
46
- ## /aw-spec-design
46
+ ## /aw-spec-plan
47
47
  <!-- The as-built architecture / cross-cutting technical rules the design author mediates the spec
48
48
  against. NO domain file here — domain reaches design only as spec ids. -->
49
49
  - guardrails/projects/[project]/service/[as-built-architecture].md
@@ -62,7 +62,7 @@ refers to it directly, as-is.
62
62
  - guardrails/projects/[project]/service/[as-built-architecture].md
63
63
 
64
64
  ## /aw-spec-analyze-slice
65
- <!-- The design↔code conformance gate's TECHNICAL checklist (validate, don't author). -->
65
+ <!-- The spec↔code conformance gate's TECHNICAL checklist (validate, don't author). -->
66
66
  - guardrails/projects/[project]/service/[testing/convention rule to validate against].md
67
67
 
68
68
  ## /aw-spec-adopt
@@ -86,13 +86,34 @@ refers to it directly, as-is.
86
86
  a runtime/hosting concern file. NOT data-migration (migration is the deferred later phase). -->
87
87
  - guardrails/projects/[project]/service/[runtime/hosting rule].md
88
88
 
89
- <!-- ## /aw-spec-ui-constitution — the FRONTEND LANE's heading. It is NOT written by the step
90
- that authors this map; onboard's frontend rule-set step APPENDS it here, after the technical
91
- headings and before the quick-reference table, but only where the scan found a UI in the
92
- code. It maps the generated frontend/ lane rules (frontend/ui-constitution.md first), and
93
- it is also the authoritative signal that this project HAS a frontend lane — a later
94
- /appweaver constitution reads it to decide whether to author constitution.ui.md at all.
95
- A backend-only repo simply never gets the heading.
89
+ <!-- THE FRONTEND LANE'S THREE HEADINGS. None of them is written by the step that authors
90
+ this map; onboard's frontend rule-set step APPENDS all three here, after the technical
91
+ headings and before the quick-reference table, and ONLY where the scan found a UI in the
92
+ code. A backend-only repo never gets any of them, which is correct and not an omission.
93
+
94
+ ## /aw-spec-ui-constitution — the ratifiable lane standards, frontend/ui-constitution.md
95
+ first. It is also the authoritative signal that this project HAS a frontend lane: a
96
+ later /appweaver constitution reads it to decide whether to author constitution.ui.md
97
+ at all.
98
+ ## /aw-spec-plan-ui — the DESIGN set /appweaver plan-ui works from when it authors
99
+ or conforms frontend-plan.md: composition, routing, client state, interaction states,
100
+ forms, accessibility, i18n, performance — whichever of those the generated set holds.
101
+ ## /aw-spec-implement-ui — the CODE-GENERATION set /appweaver implement-ui builds
102
+ against: conventions, the client/service pairing, styling, forms, accessibility, i18n,
103
+ performance, testing — again, whichever exist.
104
+
105
+ THE TWO PHASE SETS OVERLAP ON PURPOSE. A concern like forms, accessibility, i18n or
106
+ performance carries a DESIGN half and an IMPLEMENT half of one rule — the design decides
107
+ the states, affordances and targets; implement realises them. A rule mapped under only
108
+ one heading loses the pairing, and the half that goes unread is the half that goes
109
+ unbuilt. Map such a file under BOTH.
110
+
111
+ WHY ALL THREE AND NOT JUST THE FIRST. `## /aw-spec-ui-constitution` alone wires the lane
112
+ for re-ratification and NOTHING else: with no `## /aw-spec-plan-ui`, plan-ui loads zero
113
+ mapped frontend rules and designs the experience from constitution.ui.md alone, while the
114
+ files it needed sit on disk unreferenced — and because an absent heading soft-continues,
115
+ nobody is told. Both phases ship (/appweaver plan-ui, /appweaver implement-ui), so both
116
+ headings are claims the kit CAN honour.
96
117
 
97
118
  Do NOT add /aw-spec-characterize or /aw-spec-parity in the DEV flow — characterize is
98
119
  opt-on-touch and parity is deferred to the migration phase. Add any other heading later
@@ -106,11 +127,17 @@ refers to it directly, as-is.
106
127
  | Command | Technical rule files | Role |
107
128
  |---|---|---|
108
129
  | /aw-spec-specify | 1 | the as-built modelling methodology the domain model is expressed in — no technology |
109
- | /aw-spec-design | [n] | as-built architecture the design author mediates the spec against |
130
+ | /aw-spec-plan | [n] | as-built architecture the design author mediates the spec against |
110
131
  | /aw-spec-implement | [n] | code-generation set the generator builds against (from design.md) |
111
132
  | /aw-spec-implement-delta | [n] | same code-generation set, scoped to the open change's delta-design |
112
133
  | /aw-spec-build | [n] | layering + convention rules the compile-fixer respects |
113
- | /aw-spec-analyze-slice | [n] | conformance rules the design↔code gate validates against |
134
+ | /aw-spec-analyze-slice | [n] | conformance rules the spec↔code gate validates against |
114
135
  | /aw-spec-adopt | [n] | technical reference set for the reversed design (brownfield) |
115
136
  | /aw-spec-constitution | [n] | the standards the technical constitution half is re-ratified from |
116
137
  | /aw-spec-run | [n] | runtime/execution conventions the app-run step honors (only if evidenced) |
138
+
139
+ <!-- The frontend lane's rows are appended by the same step that appends its headings, and
140
+ only where the lane exists:
141
+ | /aw-spec-ui-constitution | [n] | the ratifiable lane standards the UI constitution half is re-ratified from |
142
+ | /aw-spec-plan-ui | [n] | the as-built experience rules plan-ui authors frontend-plan.md against |
143
+ | /aw-spec-implement-ui | [n] | the as-built code-generation set implement-ui builds the UI against | -->
@@ -637,7 +637,8 @@ workflow:
637
637
  spec.md (a resolved [NEEDS CLARIFICATION] / Assumption) or log a deviation.
638
638
  Review items: {{review_items}}
639
639
  - "## How to proceed": resolve blocking gaps first; then the slice is a normal
640
- feature — run /appweaver analyze-design (spec↔design gate) if desired, then
640
+ feature — run /appweaver plan (which renames this design.md to backend-plan.md and
641
+ conforms it) and then /appweaver analyze-design (the spec↔plan gate), then
641
642
  drive every change through the CR delta loop. If a change edits untested legacy
642
643
  behaviour with blast radius, characterize just that surface first (optional
643
644
  on-touch fence) — it is not a required phase.