aw-spec-cli 0.1.13 → 0.1.15
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/.appweaver/STACK-PROFILES.md +1 -1
- package/assets/.appweaver/orchestrator/orchestrator.py +5 -0
- package/assets/.appweaver/orchestrator/rev-templates/domain-rule-bindings.skeleton.md +10 -3
- package/assets/.appweaver/orchestrator/rev-templates/tech-rule-bindings.skeleton.md +38 -11
- package/assets/.appweaver/orchestrator/workflows/aw-spec-adopt.orch.yaml +2 -1
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-design.orch.yaml +607 -123
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-slice.orch.yaml +625 -66
- package/assets/.appweaver/orchestrator/workflows/aw-spec-implement-ui.orch.yaml +407 -134
- package/assets/.appweaver/orchestrator/workflows/aw-spec-implement.orch.yaml +452 -143
- package/assets/.appweaver/orchestrator/workflows/aw-spec-onboard.orch.yaml +78 -14
- package/assets/.appweaver/orchestrator/workflows/aw-spec-plan-ui.orch.yaml +597 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-plan.orch.yaml +688 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-select-feature.orch.yaml +3 -3
- package/assets/.appweaver/orchestrator/workflows/aw-spec-specify.orch.yaml +23 -23
- package/assets/.appweaver/orchestrator/workflows/aw-spec-story-plan.orch.yaml +945 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-sync-stories.orch.yaml +1040 -0
- package/assets/.appweaver/scripts/bash/aw-spec-actions.sh +2069 -28
- package/assets/.appweaver/scripts/bash/aw-xref.sh +2 -1
- package/assets/.appweaver/scripts/powershell/aw-spec-actions.ps1 +1973 -13
- package/assets/.appweaver/scripts/powershell/aw-xref.ps1 +2 -1
- package/assets/.appweaver/scripts/python/aw-xref.py +246 -20
- package/assets/.appweaver/templates/design-template.md +88 -54
- package/assets/.appweaver/templates/spec-template.md +12 -10
- package/assets/.appweaver/templates/story-template.md +48 -8
- package/assets/.appweaver/templates/ui-design-template.md +71 -39
- package/assets/guardrails/projects/dotnet-default-project/domain-rule-bindings.md +19 -7
- package/assets/guardrails/projects/dotnet-default-project/tech-rule-bindings.md +35 -26
- package/package.json +1 -1
- package/assets/.appweaver/orchestrator/workflows/aw-spec-design-ui.orch.yaml +0 -386
- package/assets/.appweaver/orchestrator/workflows/aw-spec-design.orch.yaml +0 -382
|
@@ -0,0 +1,597 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# aw-spec-plan-ui (orchestrator) — the spec-anchored Plan phase (frontend lane)
|
|
3
|
+
#
|
|
4
|
+
# Authors and MAINTAINS the frontend lane's single high-level plan —
|
|
5
|
+
# specs/<Aggregate>/frontend-plan.md — the experience twin of backend-plan.md and
|
|
6
|
+
# the MEDIATOR between the spec and the components implement-ui generates (formerly
|
|
7
|
+
# design.ui.md; the scaffold migrates a legacy design.ui.md by renaming it). Its
|
|
8
|
+
# sections are the experience, not the four clean-architecture layers. See
|
|
9
|
+
# .appweaver/DESIGN-FORMAT.md ("Frontend lane variant") +
|
|
10
|
+
# .appweaver/templates/ui-design-template.md.
|
|
11
|
+
#
|
|
12
|
+
# WHY A SEPARATE COMMAND, NOT A UI BRANCH INSIDE `plan`. The two lanes are governed
|
|
13
|
+
# by different rule sets (tech-rule-bindings gives each lane its own set for zero
|
|
14
|
+
# mechanism change); a UI branch inside plan would put the lane's structure under
|
|
15
|
+
# the service lane's rules and hand one phase the whole rule surface of both lanes.
|
|
16
|
+
#
|
|
17
|
+
# THREE MODES, resolved deterministically (self-detecting on the doc's existence):
|
|
18
|
+
# • bootstrap_gf (default) — no frontend-plan.md yet: author the master from the
|
|
19
|
+
# whole spec, shipped experience template (§0–§9).
|
|
20
|
+
# • bootstrap_bf — same, but onboard installed the code-derived ui-design-template
|
|
21
|
+
# override: author with the lane's AS-BUILT composition axes instead.
|
|
22
|
+
# • update — frontend-plan.md exists: conform it to what the spec's Change History
|
|
23
|
+
# ledger says moved SINCE THIS PLAN WAS LAST DERIVED, and nothing else. This
|
|
24
|
+
# replaces the former bootstrap-only refusal that routed to ⌛ delta-design-ui.
|
|
25
|
+
#
|
|
26
|
+
# TRACKING is identical to plan's: plan-check computes the state (fresh | untracked |
|
|
27
|
+
# clean | behind | edited | edited_behind) and the moved ids; plan-stamp is the only
|
|
28
|
+
# writer of the **Version** header, the doc's own Change History row and the body
|
|
29
|
+
# hash in .aw-plan-track.frontend-plan.json — its OWN track file, so a backend plan
|
|
30
|
+
# stamped at the same moment never contends with it. Hand edits are refused unless accept_manual:true
|
|
31
|
+
# folds them in. The model writes NO version anywhere.
|
|
32
|
+
#
|
|
33
|
+
# WHERE IT SITS. specify/sync-spec move the spec; the developer then runs plan (the
|
|
34
|
+
# service lane) and plan-ui, which conform each lane's design to what moved. FE story
|
|
35
|
+
# designs READ this document for the ids they carry and NEVER write back — nothing
|
|
36
|
+
# merges into it, so it keeps exactly one writer. It is the FEATURE-LEVEL
|
|
37
|
+
# ARCHITECTURAL CONFIRMATION for the experience, with the concrete component-level
|
|
38
|
+
# work left to the per-story passes.
|
|
39
|
+
#
|
|
40
|
+
# IT READS THE CODE. concept-paths resolves the feature's OKF concept to the files
|
|
41
|
+
# realising its UI today and the authoring steps declare `tools: Read`, so a plan over
|
|
42
|
+
# an existing frontend ADJUSTS to the composition, naming and state handling actually
|
|
43
|
+
# there. The code is the what-exists authority; the spec stays the only authority on
|
|
44
|
+
# required behaviour. source_count 0 = greenfield, and the phase never blocks on it.
|
|
45
|
+
#
|
|
46
|
+
# IT CONSUMES THE INTERFACE LOG — it never writes one. specs/<Aggregate>/interfaces.md
|
|
47
|
+
# is the service lane's published surface, published by /appweaver plan and APPEND-ONLY:
|
|
48
|
+
# §5 Contract Binding binds to the LATEST entry per interface (a `supersedes:` entry
|
|
49
|
+
# replaces the one it names), cited BY IF- id, never restated. A `proposed` entry is
|
|
50
|
+
# the designed contract and is bindable. What the experience needs and the surface
|
|
51
|
+
# lacks is a CONTRACT DELTA raised back to the service lane, never a client workaround.
|
|
52
|
+
#
|
|
53
|
+
# Launch: /appweaver plan-ui [guidance] (accept_manual:true folds hand edits in)
|
|
54
|
+
# Prereq: /appweaver specify; /appweaver plan (so interfaces.md exists to bind
|
|
55
|
+
# against); a frontend lane declared via /appweaver select-stack
|
|
56
|
+
# =============================================================================
|
|
57
|
+
|
|
58
|
+
name: aw-spec-plan-ui
|
|
59
|
+
description: "Author or update the frontend lane's high-level plan — specs/<Feature>/frontend-plan.md — from the spec: the experience twin of backend-plan.md, mediating between spec.md and the components implement-ui generates. Self-detects: no plan yet ⇒ bootstrap the master (shipped experience template, or the code-derived structure when onboard installed the ui-design-template override); plan exists ⇒ UPDATE — conform exactly the sections serving the ids the spec's Change History moved since this plan's derivation stamp, preserving the Assumptions/Workarounds/Change History ledgers. Realises the spec's UX- Experience Standards, which backend-plan.md excludes by contract; the service lane enters only at §5 Contract Binding, CONSUMING specs/<Feature>/interfaces.md — the append-only interface log /appweaver plan publishes, latest entry per id — cited by IF- id and never written to by this lane. Tracking is script-owned (plan-check / plan-stamp); hand edits are refused unless accept_manual folds them in. Technology-agnostic: the stack binds at implement-ui."
|
|
60
|
+
version: 2.1.0
|
|
61
|
+
agent_agnostic: true
|
|
62
|
+
dialect: aw-spec.orchestrator/v1
|
|
63
|
+
|
|
64
|
+
inputs:
|
|
65
|
+
user_input:
|
|
66
|
+
description: Optional plan guidance (flow preferences, screen decomposition hints, constraints).
|
|
67
|
+
required: false
|
|
68
|
+
bind: USER_INPUT
|
|
69
|
+
accept_manual:
|
|
70
|
+
description: "true ⇒ a hand-edited plan (tracking state edited/edited_behind) is folded in instead of refused: the update keeps the manual edits' intent, reconciles them with the spec, and the stamp re-baselines."
|
|
71
|
+
required: false
|
|
72
|
+
bind: ACCEPT_MANUAL
|
|
73
|
+
|
|
74
|
+
scripts:
|
|
75
|
+
actions:
|
|
76
|
+
sh: .appweaver/scripts/bash/aw-spec-actions.sh
|
|
77
|
+
ps1: .appweaver/scripts/powershell/aw-spec-actions.ps1
|
|
78
|
+
xref:
|
|
79
|
+
sh: .appweaver/scripts/bash/aw-xref.sh
|
|
80
|
+
ps1: .appweaver/scripts/powershell/aw-xref.ps1
|
|
81
|
+
|
|
82
|
+
# Sticky standards seed = the UNIVERSAL always-on rule only (ai-rules). The lane's
|
|
83
|
+
# FRONTEND rule files are CONFIGURATION, loaded per-command from
|
|
84
|
+
# guardrails/projects/<project>/tech-rule-bindings.md under `## /aw-spec-plan-ui` by the
|
|
85
|
+
# tech-select module. Per the rule-partition this phase loads NO domain rule file —
|
|
86
|
+
# the domain reaches it as spec ids, exactly as it reaches design.md. The lane's
|
|
87
|
+
# ratified base arrives via constitution.ui.md (referred to directly, as-is — NOT
|
|
88
|
+
# mapped). (missing files skipped at assembly time)
|
|
89
|
+
standards:
|
|
90
|
+
- { path: .appweaver/ai-rules.md } # kit-resident: the universal operating rules, every flow
|
|
91
|
+
|
|
92
|
+
vars:
|
|
93
|
+
source_csv: "" # concept-paths — the files realising this feature's UI today
|
|
94
|
+
source_count: "0" # 0 ⇒ greenfield: no frontend code for this feature yet
|
|
95
|
+
okf_concept: "" # the feature's OKF concept doc
|
|
96
|
+
ui_plan_mode: "bootstrap_gf" # resolved below → bootstrap_gf | bootstrap_bf | update
|
|
97
|
+
ui_plan_created: "false" # scaffold.created — true ⇒ the doc was absent ⇒ bootstrap
|
|
98
|
+
ui_plan_migrated: "false" # scaffold renamed a legacy design.ui.md into frontend-plan.md this run
|
|
99
|
+
track_state: "" # plan-check → fresh | untracked | clean | behind | edited | edited_behind
|
|
100
|
+
derived_version: ""
|
|
101
|
+
current_version: ""
|
|
102
|
+
changed_csv: ""
|
|
103
|
+
changed_summary: ""
|
|
104
|
+
manual_ok: "true" # false ⇒ hand edits present and accept_manual not given
|
|
105
|
+
plan_stale: "true" # false ⇒ update mode with nothing to do (clean) — friendly stop
|
|
106
|
+
stamp_ok: "false"
|
|
107
|
+
stamp_error: ""
|
|
108
|
+
|
|
109
|
+
workflow:
|
|
110
|
+
|
|
111
|
+
# 0. FRONTEND rule files → sticky standards (configuration, not hardcoded).
|
|
112
|
+
# No blocking gate: a project that has not mapped the heading soft-continues,
|
|
113
|
+
# because constitution.ui.md still carries the lane's ratified base.
|
|
114
|
+
- id: tech_select
|
|
115
|
+
action: include
|
|
116
|
+
module: .appweaver/orchestrator/modules/tech-select.orch.yaml
|
|
117
|
+
with: { command: aw-spec-plan-ui }
|
|
118
|
+
|
|
119
|
+
# 1. The lane must EXIST. This phase writes a document, not code, so it asks the
|
|
120
|
+
# declaration whether there is a frontend lane at all — not the lane-gate module,
|
|
121
|
+
# whose on-disk check would refuse a greenfield project that has declared `web/`
|
|
122
|
+
# but not scaffolded it yet. A UI design is authored before the UI exists; that is
|
|
123
|
+
# the point of designing.
|
|
124
|
+
- id: lane_resolve
|
|
125
|
+
action: execute_script
|
|
126
|
+
on_error: continue # never crash raw on an undeclared lane — the gate below explains it
|
|
127
|
+
script: { ref: actions }
|
|
128
|
+
subcommand: lane-resolve
|
|
129
|
+
outputs:
|
|
130
|
+
- { name: fe_declared, from: "$.frontend_declared" }
|
|
131
|
+
- { name: lane_id, from: "$.frontend_lane_id" }
|
|
132
|
+
- { name: lane_title, from: "$.frontend_title" }
|
|
133
|
+
- { name: lane_language, from: "$.frontend_language" }
|
|
134
|
+
- { name: lane_ecosystem, from: "$.frontend_ecosystem" }
|
|
135
|
+
- { name: lane_root, from: "$.frontend_source_path" }
|
|
136
|
+
|
|
137
|
+
- id: require_lane
|
|
138
|
+
action: verify_context
|
|
139
|
+
require_true: fe_declared
|
|
140
|
+
on_false: stop
|
|
141
|
+
on_false_message: "No frontend lane is declared in .appweaver/stacks.json, so there is no experience to plan. Run /appweaver select-stack and declare the UI stack plus its source path, then re-run plan-ui. A project that genuinely has no UI plans the service lane alone with /appweaver plan."
|
|
142
|
+
|
|
143
|
+
# 2. Resolve the current feature and require its spec — this phase's only domain input.
|
|
144
|
+
- id: feature_paths
|
|
145
|
+
action: execute_script
|
|
146
|
+
on_error: continue # never crash raw on 'no feature set' — the gate below explains it
|
|
147
|
+
script: { ref: actions }
|
|
148
|
+
subcommand: feature-paths
|
|
149
|
+
outputs:
|
|
150
|
+
- { name: feature_dir, from: "$.feature_dir" }
|
|
151
|
+
- { name: spec_file, from: "$.spec_file" }
|
|
152
|
+
- { name: spec_exists, from: "$.spec_exists" }
|
|
153
|
+
- { name: service_design, from: "$.design_file" } # legacy name — a repo not yet migrated
|
|
154
|
+
- { name: service_plan, from: "$.backend_plan_file" } # the service lane's plan (post-rename)
|
|
155
|
+
|
|
156
|
+
- id: require_feature
|
|
157
|
+
action: verify_context
|
|
158
|
+
require_non_empty: feature_dir
|
|
159
|
+
on_empty: stop
|
|
160
|
+
on_empty_message: "No active feature. Run /appweaver select-feature first (pick or create the aggregate, e.g. Order), then re-run plan-ui."
|
|
161
|
+
|
|
162
|
+
- id: verify_spec
|
|
163
|
+
action: verify_context
|
|
164
|
+
require_true: spec_exists
|
|
165
|
+
on_false: stop
|
|
166
|
+
on_false_message: "No spec.md for the current feature. Run /appweaver specify first — the spec is this phase's only domain input, and its Experience Standards (UX-) are what frontend-plan.md realises."
|
|
167
|
+
|
|
168
|
+
# 1b. The spec's own ledger tripwire — a plan derived from an unledgered spec
|
|
169
|
+
# stamps a baseline the ledger cannot name (same fence as plan's).
|
|
170
|
+
- id: spec_guard_read
|
|
171
|
+
action: execute_script
|
|
172
|
+
script: { ref: actions }
|
|
173
|
+
subcommand: spec-check
|
|
174
|
+
args: ["--feature-dir", "{{feature_dir}}"]
|
|
175
|
+
outputs:
|
|
176
|
+
- { name: spec_ok, from: "$.ok" }
|
|
177
|
+
- { name: spec_state, from: "$.state" }
|
|
178
|
+
- id: spec_guard
|
|
179
|
+
action: verify_context
|
|
180
|
+
require_true: spec_ok
|
|
181
|
+
on_false: stop
|
|
182
|
+
on_false_message: "spec.md has moved outside the ledger (state: {{spec_state}}). Record what changed in a Change History row (or fold it back through /appweaver sync-spec), re-run spec-stamp to re-baseline, then re-run plan-ui."
|
|
183
|
+
|
|
184
|
+
# 2. Scaffold frontend-plan.md (idempotent). --lane frontend resolves the pair
|
|
185
|
+
# ui-design-template → frontend-plan.md, and MIGRATES a legacy design.ui.md by
|
|
186
|
+
# renaming it (created=false, migrated=true) — one document, never two.
|
|
187
|
+
- id: ui_plan_scaffold
|
|
188
|
+
action: execute_script
|
|
189
|
+
script: { ref: actions }
|
|
190
|
+
subcommand: design-scaffold
|
|
191
|
+
args: ["--feature-dir", "{{feature_dir}}", "--lane", "frontend"]
|
|
192
|
+
outputs:
|
|
193
|
+
- { name: ui_plan_doc, from: "$.design_doc" }
|
|
194
|
+
- { name: ui_override, from: "$.override_active" } # true ⇒ onboard installed the code-derived template
|
|
195
|
+
- { name: ui_plan_created, from: "$.created" }
|
|
196
|
+
- { name: ui_plan_migrated, from: "$.migrated" }
|
|
197
|
+
|
|
198
|
+
# 4a. Resolve the authoring MODE. Ordered override rather than a branch — the engine
|
|
199
|
+
# has no compound conditions: state the greenfield default, let the code-derived
|
|
200
|
+
# override replace it.
|
|
201
|
+
- id: mode_brownfield
|
|
202
|
+
condition: "{{ui_override}} == true"
|
|
203
|
+
action: set
|
|
204
|
+
vars: { ui_plan_mode: "bootstrap_bf" }
|
|
205
|
+
- id: mode_update
|
|
206
|
+
condition: "{{ui_plan_created}} == false"
|
|
207
|
+
action: set
|
|
208
|
+
vars: { ui_plan_mode: "update" }
|
|
209
|
+
|
|
210
|
+
# 3. Tracking: what moved since this plan was derived, and whether the doc was
|
|
211
|
+
# hand-edited since its stamp. Same machinery and fences as plan's.
|
|
212
|
+
- id: plan_track
|
|
213
|
+
action: execute_script
|
|
214
|
+
script: { ref: actions }
|
|
215
|
+
subcommand: plan-check
|
|
216
|
+
args: ["--feature-dir", "{{feature_dir}}", "--doc", "{{ui_plan_doc}}"]
|
|
217
|
+
outputs:
|
|
218
|
+
- { name: track_state, from: "$.state" }
|
|
219
|
+
- { name: derived_version, from: "$.derived_version" }
|
|
220
|
+
- { name: current_version, from: "$.current_version" }
|
|
221
|
+
- { name: changed_csv, from: "$.changed_csv" }
|
|
222
|
+
- { name: changed_summary, from: "$.changed_summary" }
|
|
223
|
+
- id: manual_flag_edited
|
|
224
|
+
condition: "{{track_state}} == edited"
|
|
225
|
+
action: set
|
|
226
|
+
vars: { manual_ok: "false" }
|
|
227
|
+
- id: manual_flag_edited_behind
|
|
228
|
+
condition: "{{track_state}} == edited_behind"
|
|
229
|
+
action: set
|
|
230
|
+
vars: { manual_ok: "false" }
|
|
231
|
+
- id: manual_accept
|
|
232
|
+
condition: "{{ACCEPT_MANUAL}} == true"
|
|
233
|
+
action: set
|
|
234
|
+
vars: { manual_ok: "true" }
|
|
235
|
+
- id: manual_fence
|
|
236
|
+
action: verify_context
|
|
237
|
+
require_true: manual_ok
|
|
238
|
+
on_false: stop
|
|
239
|
+
on_false_message: "frontend-plan.md was hand-edited since its last stamp (tracking state: {{track_state}}). Re-run plan-ui with accept_manual:true to fold the edits in (kept, reconciled with the spec, recorded in the ledgers, re-baselined) — or restore the document to its stamped state."
|
|
240
|
+
- id: clean_flag
|
|
241
|
+
condition: "{{track_state}} == clean"
|
|
242
|
+
action: set
|
|
243
|
+
vars: { plan_stale: "false" }
|
|
244
|
+
- id: clean_stop
|
|
245
|
+
action: verify_context
|
|
246
|
+
require_true: plan_stale
|
|
247
|
+
on_false: stop
|
|
248
|
+
on_false_message: "frontend-plan.md is in step with spec {{current_version}} — nothing to update."
|
|
249
|
+
|
|
250
|
+
# 5. Pre-execution hooks.
|
|
251
|
+
# THE CODE. The UI plan is an architectural confirmation too, so it must know what
|
|
252
|
+
# this feature's experience already looks like on disk: concept-paths resolves the
|
|
253
|
+
# feature's OKF concept to the files realising it, and the authoring steps declare
|
|
254
|
+
# `tools: Read`. A PATH LIST, not inlined content (E60). on_error: continue — a
|
|
255
|
+
# greenfield feature has no concept doc and must never be blocked by one;
|
|
256
|
+
# source_count 0 is the greenfield signal the tasks read.
|
|
257
|
+
- id: concept_paths
|
|
258
|
+
action: execute_script
|
|
259
|
+
on_error: continue
|
|
260
|
+
script: { ref: xref }
|
|
261
|
+
subcommand: concept-paths
|
|
262
|
+
args: ["--feature-dir", "{{feature_dir}}"]
|
|
263
|
+
outputs:
|
|
264
|
+
- { name: source_csv, from: "$.csv" }
|
|
265
|
+
- { name: source_count, from: "$.count" }
|
|
266
|
+
- { name: okf_concept, from: "$.concept" }
|
|
267
|
+
|
|
268
|
+
- id: resolve_pre_hooks
|
|
269
|
+
action: execute_script
|
|
270
|
+
script: { ref: actions }
|
|
271
|
+
subcommand: resolve-hooks
|
|
272
|
+
args: ["--phase", "before_design_ui"]
|
|
273
|
+
outputs:
|
|
274
|
+
- { name: before_hooks, from: "$.hooks" }
|
|
275
|
+
- id: dispatch_pre_hooks
|
|
276
|
+
action: dispatch_hooks
|
|
277
|
+
hooks_from_variable: before_hooks
|
|
278
|
+
|
|
279
|
+
# ═══════════ GREENFIELD — the shipped experience template (§0–§9) ═══════════
|
|
280
|
+
# build_context REPLACES the per-request envelope; the sticky frontend standards
|
|
281
|
+
# stay prepended. The ENGINE writes ui_design_doc.
|
|
282
|
+
- id: ctx_ui_plan
|
|
283
|
+
condition: "{{ui_plan_mode}} == bootstrap_gf"
|
|
284
|
+
action: build_context
|
|
285
|
+
context:
|
|
286
|
+
- { path: "{{ui_plan_doc}}" } # the copied template = section structure
|
|
287
|
+
- { path: "{{spec_file}}" } # the source of truth (UX/US/FR/CN/DC/IC/SC)
|
|
288
|
+
- { path: .appweaver/DESIGN-FORMAT.md } # the design-doc contract + its frontend lane variant
|
|
289
|
+
- { path: .appweaver/memory/constitution.ui.md, optional: true } # the lane's ratified UX-* base — optional: a lane may be declared before it is ratified
|
|
290
|
+
- { path: "{{feature_dir}}/interfaces.md", optional: true } # THE CONTRACT — the service lane's published surface, latest entry per id wins
|
|
291
|
+
- { path: "{{okf_concept}}", optional: true } # the feature's OKF concept: use-case log + source map
|
|
292
|
+
- { path: "{{service_plan}}", optional: true } # §5 ONLY — the service's structure; its API section only CITES the log
|
|
293
|
+
- { path: "{{service_design}}", optional: true } # the same surface under its legacy name (unmigrated repo)
|
|
294
|
+
- id: gen_ui_plan
|
|
295
|
+
condition: "{{ui_plan_mode}} == bootstrap_gf"
|
|
296
|
+
action: agent_author
|
|
297
|
+
tools: Read # the current frontend code arrives as {{source_csv}} paths, not inlined
|
|
298
|
+
output_target: { type: file, path: "{{ui_plan_doc}}" }
|
|
299
|
+
task: |
|
|
300
|
+
Author the MASTER UI plan (the target frontend-plan.md in context) for this
|
|
301
|
+
feature's EXPERIENCE by filling out the template from the feature spec + the
|
|
302
|
+
loaded frontend standards. This is the frontend lane's MEDIATOR between the spec
|
|
303
|
+
and the components `implement-ui` will generate. Guidance: {{USER_INPUT}}
|
|
304
|
+
Rules:
|
|
305
|
+
- THE SPEC IS THE ONLY DOMAIN INPUT. You have the spec + frontend standards, and
|
|
306
|
+
NO domain rule files. The domain arrives as spec ids only — realise them, and
|
|
307
|
+
invent no domain rule the spec omits (an unavoidable new concept → §8 DA-n).
|
|
308
|
+
- THE CODE IS THE WHAT-EXISTS AUTHORITY, and it is a DIFFERENT authority from the
|
|
309
|
+
spec. {{source_count}} file(s) realise this feature's experience today; read the
|
|
310
|
+
ones that bear on what you are deciding and ADJUST this plan to the composition,
|
|
311
|
+
naming and state handling that are actually there rather than to an idealised
|
|
312
|
+
shape. An empty list is greenfield — design from a clean slate and say so. The
|
|
313
|
+
code NEVER overrides the spec on required behaviour and introduces no rule the
|
|
314
|
+
spec omits: code contradicting the spec is recorded as a DA-n and designed to
|
|
315
|
+
the SPEC. A deliberate divergence from the as-built is a WA-n with its trigger.
|
|
316
|
+
{{source_csv}}
|
|
317
|
+
- Keep the template's section order and headings: §0 Design Overview, §1
|
|
318
|
+
Navigation & Screen Structure, §2 Client State, §3 Component Structure, §4
|
|
319
|
+
Interaction & Flow, §5 Contract Binding, §6 Cross-Cutting, §7 Traceability,
|
|
320
|
+
§8 Assumptions, §9 Workarounds, Change History.
|
|
321
|
+
- REALISE THE SPEC'S EXPERIENCE CONTENT:
|
|
322
|
+
• Experience Standards (UX-) are THIS document's to realise — backend-plan.md
|
|
323
|
+
excludes them by contract, so a UX- with no home here is a DROPPED
|
|
324
|
+
requirement, not a tidy omission. Every UX- gets a §7 row.
|
|
325
|
+
• Experience Scope (actors · channels · device/browser/AT floors) bounds §1
|
|
326
|
+
and §6 — design for the floors the spec names and no more.
|
|
327
|
+
• Each FR- with a user-facing surface gets a screen home in §1 and a flow in
|
|
328
|
+
§4. Such an FR- with no screen is a coverage failure. (Stories live in
|
|
329
|
+
stories/ and never appear in this document — it traces to requirements.)
|
|
330
|
+
• Interaction-state requirements are ordinary FR- ids (the EARS
|
|
331
|
+
unwanted-behaviour form). Each one gets a §4 row.
|
|
332
|
+
- REALISE THE LIFTED CONSTRAINTS, each citing its spec id:
|
|
333
|
+
• CN- → §6 Authorization surface and the §1 access conditions (what is hidden
|
|
334
|
+
vs disabled vs enforced server-side — the client never becomes the authority).
|
|
335
|
+
• DC- → §2 "what must NOT be held" and the §6 data-exposure row: what may not
|
|
336
|
+
reach the client, its logs, its storage or its URLs.
|
|
337
|
+
• IC-/SC- → §5 binding rows and the §6 performance row respectively.
|
|
338
|
+
- §4 INTERACTION & FLOW AND §6 CROSS-CUTTING ARE NEVER OMITTED, however thin the
|
|
339
|
+
feature. Loading, empty, error, permission-denied and in-flight states, plus
|
|
340
|
+
validation timing, focus placement and keyboard reachability, are where most UI
|
|
341
|
+
defects live. A state the UI can reach that the spec does not describe is a SPEC
|
|
342
|
+
gap: log it as a §8 DA-n and say it routes to `specify`; never invent the
|
|
343
|
+
requirement here.
|
|
344
|
+
- §5 IS THE LANE BOUNDARY, AND `interfaces.md` IS THE CONTRACT. The service
|
|
345
|
+
lane's published surface lives in that append-only log, which /appweaver plan
|
|
346
|
+
writes: bind against the LATEST entry per interface — an entry naming an
|
|
347
|
+
earlier id in `supersedes:` replaces it — plus the spec's IC- ids. CITE those
|
|
348
|
+
entries BY IF- id; do NOT restate, re-derive or contradict them, and introduce
|
|
349
|
+
NO server-side behaviour, persistence assumption or handler detail. An entry at
|
|
350
|
+
`status: proposed` is the designed contract and IS bindable; note the status
|
|
351
|
+
where it matters. NEVER WRITE TO THE LOG — this lane consumes it. Anything the
|
|
352
|
+
experience needs that the surface does not offer is a CONTRACT DELTA raised
|
|
353
|
+
back to the service lane under "Contract deltas needed" — never a workaround in
|
|
354
|
+
the client. Where the log is absent (the service lane has not planned this
|
|
355
|
+
feature yet), bind from the spec's IC- surface and record that as a §8 DA-n
|
|
356
|
+
saying so.
|
|
357
|
+
- CONSTITUTION-MANDATED CROSS-CUTTING (from the loaded UI constitution, NOT the
|
|
358
|
+
spec): a NON-NEGOTIABLE UX principle you must apply that has no per-feature spec
|
|
359
|
+
id. APPLY it, and because it is not spec-derived, LOG it as a §8 DA-n whose
|
|
360
|
+
basis cites the mandating principle ("per constitution.ui.md UX-<n>"); set the
|
|
361
|
+
corresponding §6 row's "Serves" to that DA-n. Do NOT fabricate a spec UX- for
|
|
362
|
+
it, and do NOT leave it uncited.
|
|
363
|
+
- TECHNOLOGY-AGNOSTIC: name no framework, router, state library, component library
|
|
364
|
+
or styling approach. Describe a component by its RESPONSIBILITY, its INPUTS as
|
|
365
|
+
field shapes, the EVENTS it raises and the STATES it can be in; describe routing
|
|
366
|
+
as a conceptual shape. The framework binds at `implement-ui`. Do NOT include
|
|
367
|
+
file placement, naming conventions or test mechanics — those are the UI
|
|
368
|
+
constitution's and `implement-ui`'s, identical for every feature.
|
|
369
|
+
- The header's Lane field is `{{lane_id}}`. That identifier is the ONLY thing you
|
|
370
|
+
are told about the lane: its framework and language are deliberately withheld,
|
|
371
|
+
because a design that knows them starts naming them.
|
|
372
|
+
- STAY IN THE LANE'S SCOPE. This feature's screens only. The app shell, global
|
|
373
|
+
layout and the design system belong to no single feature: cite them under
|
|
374
|
+
"Screens this feature does NOT own" / "Reused from the design system", and do
|
|
375
|
+
not claim or redesign them here.
|
|
376
|
+
- §7 TRACEABILITY IS THE SPINE — fill it completely, both ways: a row for EVERY
|
|
377
|
+
UX-, every FR- with a user-facing surface, and every CN-/DC-/IC-/SC- with an
|
|
378
|
+
experience obligation, so no
|
|
379
|
+
lifted constraint is silently dropped; and no UI element without a spec reason.
|
|
380
|
+
- Fill the two ledgers: §8 Assumptions (DA-n, to clarify later) and §9 Workarounds
|
|
381
|
+
(WA-n, to clear later). Empty → "None (as of v1.0)".
|
|
382
|
+
- Complete the template's INITIAL Change History row, and write NO other version
|
|
383
|
+
anywhere — the stamp step owns the **Version** header. No component code anywhere.
|
|
384
|
+
|
|
385
|
+
# ═══ BROWNFIELD — code-derived template, NEW feature in an EXISTING app ════
|
|
386
|
+
# Same contract as above (technology-agnostic, spec is the only domain input, full §7
|
|
387
|
+
# and both ledgers), with ONE difference: the STRUCTURE follows the code-derived
|
|
388
|
+
# template's own composition axes and the lane's as-built conventions, so a new
|
|
389
|
+
# feature slots into the app already there instead of introducing a second convention.
|
|
390
|
+
# Runs only when onboard generated the ui-design-template override.
|
|
391
|
+
- id: ctx_ui_plan_brownfield
|
|
392
|
+
condition: "{{ui_plan_mode}} == bootstrap_bf"
|
|
393
|
+
action: build_context
|
|
394
|
+
context:
|
|
395
|
+
- { path: "{{ui_plan_doc}}" } # the scaffolded CODE-DERIVED template = as-built section structure
|
|
396
|
+
- { path: "{{spec_file}}" } # the source of truth (UX/US/FR/CN/DC/IC/SC)
|
|
397
|
+
- { path: .appweaver/DESIGN-FORMAT.md } # the design-doc contract + its frontend lane variant
|
|
398
|
+
- { path: .appweaver/memory/constitution.ui.md, optional: true } # the lane's UX-* base, reversed by onboard from this same UI
|
|
399
|
+
- { path: knowledge/architecture/frontend.md, optional: true } # the as-built UI architecture + the SHARED surface no slice owns
|
|
400
|
+
- { path: "{{feature_dir}}/interfaces.md", optional: true } # THE CONTRACT — the service lane's published surface, latest entry per id wins
|
|
401
|
+
- { path: "{{okf_concept}}", optional: true } # the feature's OKF concept: use-case log + source map
|
|
402
|
+
- { path: "{{service_plan}}", optional: true } # §5 ONLY — the service's structure; its API section only CITES the log
|
|
403
|
+
- { path: "{{service_design}}", optional: true } # the same surface under its legacy name (unmigrated repo)
|
|
404
|
+
- id: gen_ui_plan_brownfield
|
|
405
|
+
condition: "{{ui_plan_mode}} == bootstrap_bf"
|
|
406
|
+
action: agent_author
|
|
407
|
+
tools: Read # the current frontend code arrives as {{source_csv}} paths, not inlined
|
|
408
|
+
output_target: { type: file, path: "{{ui_plan_doc}}" }
|
|
409
|
+
task: |
|
|
410
|
+
Author the MASTER UI plan (the target frontend-plan.md in context — it is this
|
|
411
|
+
project's CODE-DERIVED UI design template) for this NEW feature being added to an
|
|
412
|
+
EXISTING frontend, by filling the template from the feature spec + the loaded
|
|
413
|
+
frontend standards. It is the MEDIATOR between the spec and the components
|
|
414
|
+
`implement-ui` will generate. Guidance: {{USER_INPUT}}
|
|
415
|
+
Rules:
|
|
416
|
+
- THE SPEC IS THE ONLY DOMAIN INPUT. You have the spec + frontend standards + the
|
|
417
|
+
lane's as-built architecture reference, and NO domain rule files. The domain
|
|
418
|
+
arrives as spec ids only; an unavoidable new concept is an Assumption (DA-n).
|
|
419
|
+
- THE CODE IS THE WHAT-EXISTS AUTHORITY, and it is a DIFFERENT authority from the
|
|
420
|
+
spec. {{source_count}} file(s) realise this feature's experience today; read the
|
|
421
|
+
ones that bear on what you are deciding and ADJUST this plan to the composition,
|
|
422
|
+
naming and state handling that are actually there rather than to an idealised
|
|
423
|
+
shape. An empty list is greenfield — design from a clean slate and say so. The
|
|
424
|
+
code NEVER overrides the spec on required behaviour and introduces no rule the
|
|
425
|
+
spec omits: code contradicting the spec is recorded as a DA-n and designed to
|
|
426
|
+
the SPEC. A deliberate divergence from the as-built is a WA-n with its trigger.
|
|
427
|
+
{{source_csv}}
|
|
428
|
+
- STRUCTURE FOLLOWS THE TEMPLATE AND THE LANE AS-BUILT, not a fixed screen
|
|
429
|
+
taxonomy. Keep the template's own section order and headings, and create one
|
|
430
|
+
component subsection per composition axis THIS feature actually needs, titled
|
|
431
|
+
with the lane's OWN name for it. ALIGN this feature to the app already there —
|
|
432
|
+
read the as-built architecture reference in context and MATCH its screen
|
|
433
|
+
organisation, its state and data-fetching placement and its styling approach, so
|
|
434
|
+
the feature slots in rather than introducing a second convention.
|
|
435
|
+
- KEEP THE NEUTRAL ANCHORS the template pins: the navigation/screen inventory, the
|
|
436
|
+
client-state table, the interaction-and-flow section, the cross-cutting table
|
|
437
|
+
and the traceability spine exist in every UI design, whatever the axes are
|
|
438
|
+
called. INTERACTION & FLOW and CROSS-CUTTING are NEVER omitted, however thin the
|
|
439
|
+
feature — loading, empty, error, permission-denied and in-flight states, focus
|
|
440
|
+
placement and keyboard reachability are where most UI defects live.
|
|
441
|
+
- REALISE THE SPEC'S EXPERIENCE CONTENT: every Experience Standard (UX-) gets a
|
|
442
|
+
traceability row (backend-plan.md excludes them by contract, so this is their only
|
|
443
|
+
home), every User Story a screen and a flow, every interaction-state FR- a flow
|
|
444
|
+
row. Realise the lifted constraints citing their ids — CN- as the authorization
|
|
445
|
+
surface and access conditions, DC- as what may not reach the client or its logs,
|
|
446
|
+
storage and URLs, IC- as binding rows, SC- as the performance decision.
|
|
447
|
+
- THE LANE BOUNDARY, AND `interfaces.md` IS THE CONTRACT: bind against the
|
|
448
|
+
LATEST entry per interface in that append-only log (a `supersedes:` entry
|
|
449
|
+
replaces the one it names), plus the spec's IC- ids. Cite them BY IF- id; do
|
|
450
|
+
not restate, re-derive or contradict them, introduce no server-side behaviour,
|
|
451
|
+
and NEVER write to the log — this lane consumes it. What the experience needs
|
|
452
|
+
and the surface lacks is a contract delta raised back to the service lane,
|
|
453
|
+
never a client workaround. Where the log is absent, bind from the spec's IC-
|
|
454
|
+
surface and record a DA-n saying so.
|
|
455
|
+
- CONSTITUTION-MANDATED CROSS-CUTTING with no per-feature spec id: apply it, and
|
|
456
|
+
log it as a DA-n citing the mandating principle ("per constitution.ui.md
|
|
457
|
+
UX-<n>"). Do not fabricate a spec id for it and do not leave it uncited.
|
|
458
|
+
- TECHNOLOGY-AGNOSTIC: name no framework, router, state library, component library
|
|
459
|
+
or styling approach — responsibilities, field shapes, events and states only.
|
|
460
|
+
Naming the lane's as-built CONVENTION is not naming a framework; naming the
|
|
461
|
+
library that implements it is. The framework binds at `implement-ui`.
|
|
462
|
+
- The header's Lane field is `{{lane_id}}`. That identifier is the ONLY thing you
|
|
463
|
+
are told about the lane: its framework and language are deliberately withheld,
|
|
464
|
+
because a design that knows them starts naming them.
|
|
465
|
+
- THE SHARED SURFACE (app shell, global layout, design system) belongs to no
|
|
466
|
+
feature. Cite it; do not copy it in and do not claim it here.
|
|
467
|
+
- Fill the traceability spine completely, both ways, and both ledgers —
|
|
468
|
+
Assumptions (DA-n) and Workarounds (WA-n), "None (as of v1.0)" when empty.
|
|
469
|
+
- Complete the template's INITIAL Change History row, and write NO other version
|
|
470
|
+
anywhere — the stamp step owns the **Version** header. No component code anywhere.
|
|
471
|
+
|
|
472
|
+
# ══════════════════ UPDATE — conform the existing plan to the moved spec ═════
|
|
473
|
+
# The work list is COMPUTED, never guessed: the ledger rows above this plan's
|
|
474
|
+
# derivation stamp name exactly the ids to conform. Everything else stays
|
|
475
|
+
# byte-identical.
|
|
476
|
+
- id: ctx_ui_plan_update
|
|
477
|
+
condition: "{{ui_plan_mode}} == update"
|
|
478
|
+
action: build_context
|
|
479
|
+
context:
|
|
480
|
+
- { path: "{{ui_plan_doc}}" } # the CURRENT plan — the document being conformed
|
|
481
|
+
- { path: "{{spec_file}}" } # the source of truth at {{current_version}}
|
|
482
|
+
- { path: .appweaver/DESIGN-FORMAT.md } # the design-doc contract + its frontend lane variant
|
|
483
|
+
- { path: .appweaver/memory/constitution.ui.md, optional: true } # the lane's ratified UX-* base
|
|
484
|
+
- { path: knowledge/architecture/frontend.md, optional: true } # brownfield repos: the as-built UI architecture
|
|
485
|
+
- { path: "{{feature_dir}}/interfaces.md", optional: true } # THE CONTRACT — the service lane's published surface, latest entry per id wins
|
|
486
|
+
- { path: "{{okf_concept}}", optional: true } # the feature's OKF concept: use-case log + source map
|
|
487
|
+
- { path: "{{service_plan}}", optional: true } # §5 ONLY — the service's structure; its API section only CITES the log
|
|
488
|
+
- { path: "{{service_design}}", optional: true } # the same surface under its legacy name (unmigrated repo)
|
|
489
|
+
- id: gen_ui_plan_update
|
|
490
|
+
condition: "{{ui_plan_mode}} == update"
|
|
491
|
+
action: agent_author
|
|
492
|
+
tools: Read # the current frontend code arrives as {{source_csv}} paths, not inlined
|
|
493
|
+
output_target: { type: file, path: "{{ui_plan_doc}}" }
|
|
494
|
+
task: |
|
|
495
|
+
UPDATE the master UI plan (the target frontend-plan.md in context) so it
|
|
496
|
+
conforms to the CURRENT spec. Tracking state: {{track_state}}. The spec moved
|
|
497
|
+
from {{derived_version}} (this plan's derivation) to {{current_version}}; the
|
|
498
|
+
ledger rows above the derivation name what moved:
|
|
499
|
+
ids: {{changed_csv}}
|
|
500
|
+
changes: {{changed_summary}}
|
|
501
|
+
Guidance: {{USER_INPUT}}
|
|
502
|
+
Rules:
|
|
503
|
+
- SCOPE IS THE COMPUTED WORK LIST. Rework ONLY the screens, flows, state rows,
|
|
504
|
+
binding rows, cross-cutting rows and traceability rows that realise the ids
|
|
505
|
+
above. Every other line stays BYTE-IDENTICAL; an unrelated "improvement" is
|
|
506
|
+
drift. EXCEPTION — tracking state `untracked`: this document has no baseline
|
|
507
|
+
(a migrated legacy design.ui.md), so reconcile the WHOLE plan to the spec
|
|
508
|
+
once; the stamp then baselines it.
|
|
509
|
+
- accept_manual: {{ACCEPT_MANUAL}}. When true, the document carries hand edits
|
|
510
|
+
that were deliberately accepted: KEEP their intent, reconcile them with the
|
|
511
|
+
spec, and record each kept deviation honestly — a new concept as an
|
|
512
|
+
Assumptions DA-n, a deliberate shortcut as a Workarounds WA-n. Never silently
|
|
513
|
+
revert a hand edit.
|
|
514
|
+
- AN ID THE SPEC NO LONGER DEFINES LOSES ITS REALISATION; an id whose wording
|
|
515
|
+
moved is re-realised from the spec's CURRENT text — the spec is the wording.
|
|
516
|
+
A UX- is THIS document's to realise: a moved UX- with no home here after the
|
|
517
|
+
update is a DROPPED requirement.
|
|
518
|
+
- THE CODE IS THE WHAT-EXISTS AUTHORITY, and it is a DIFFERENT authority from the
|
|
519
|
+
spec. {{source_count}} file(s) realise this feature's experience today; re-read the
|
|
520
|
+
ones the moved ids touch (code state is read FRESH every run, never assumed) and ADJUST this plan to the composition,
|
|
521
|
+
naming and state handling that are actually there rather than to an idealised
|
|
522
|
+
shape. An empty list is greenfield — design from a clean slate and say so. The
|
|
523
|
+
code NEVER overrides the spec on required behaviour and introduces no rule the
|
|
524
|
+
spec omits: code contradicting the spec is recorded as a DA-n and designed to
|
|
525
|
+
the SPEC. A deliberate divergence from the as-built is a WA-n with its trigger.
|
|
526
|
+
{{source_csv}}
|
|
527
|
+
- THE SPEC IS THE ONLY DOMAIN INPUT, and §5 stays the lane boundary: bind
|
|
528
|
+
against `interfaces.md` — the LATEST entry per interface, cited by IF- id —
|
|
529
|
+
introduce no server-side behaviour, and never write to the log. A moved id
|
|
530
|
+
whose interface changed appears there as a SUPERSEDING entry: rebind §5 to it.
|
|
531
|
+
What the experience needs and the surface lacks is a contract delta raised
|
|
532
|
+
back to the service lane.
|
|
533
|
+
- PRESERVE THE LEDGERS: Assumptions, Workarounds and Change History keep every
|
|
534
|
+
existing entry and their numbering — append, never rewrite. Write NO version
|
|
535
|
+
numbers anywhere and ADD NO Change History row: the stamp step appends the
|
|
536
|
+
row and moves the **Version** header.
|
|
537
|
+
- TRACEABILITY STAYS COMPLETE both ways after the update; TECHNOLOGY-AGNOSTIC,
|
|
538
|
+
no component code, same contract as at bootstrap.
|
|
539
|
+
|
|
540
|
+
# 5. STAMP — the only writer of the plan's version identity; refuses (no baseline)
|
|
541
|
+
# if the write dropped the Change History section.
|
|
542
|
+
- id: stamp_bootstrap
|
|
543
|
+
condition: "{{ui_plan_mode}} != update"
|
|
544
|
+
action: execute_script
|
|
545
|
+
script: { ref: actions }
|
|
546
|
+
subcommand: plan-stamp
|
|
547
|
+
args: ["--feature-dir", "{{feature_dir}}", "--doc", "{{ui_plan_doc}}", "--no-row"]
|
|
548
|
+
outputs:
|
|
549
|
+
- { name: stamp_ok, from: "$.ok" }
|
|
550
|
+
- { name: stamp_error, from: "$.error" }
|
|
551
|
+
- { name: current_version, from: "$.version" }
|
|
552
|
+
- id: stamp_update
|
|
553
|
+
condition: "{{ui_plan_mode}} == update"
|
|
554
|
+
action: execute_script
|
|
555
|
+
script: { ref: actions }
|
|
556
|
+
subcommand: plan-stamp
|
|
557
|
+
args: ["--feature-dir", "{{feature_dir}}", "--doc", "{{ui_plan_doc}}", "--ids", "{{changed_csv}}", "--note", "Conformed to spec {{current_version}}"]
|
|
558
|
+
outputs:
|
|
559
|
+
- { name: stamp_ok, from: "$.ok" }
|
|
560
|
+
- { name: stamp_error, from: "$.error" }
|
|
561
|
+
- id: stamp_fence
|
|
562
|
+
action: verify_context
|
|
563
|
+
require_true: stamp_ok
|
|
564
|
+
on_false: stop
|
|
565
|
+
on_false_message: "plan-stamp refused: {{stamp_error}} — frontend-plan.md has been written but NOT baselined. Restore the missing ledger section, then re-run plan-ui (or plan-stamp) to record the baseline."
|
|
566
|
+
|
|
567
|
+
# ═══════════ HANDOFF — authoring only; the gate is a SEPARATE stage ════════
|
|
568
|
+
# → /appweaver analyze-design gates this write. It is ONE command over BOTH
|
|
569
|
+
# lanes, not a per-lane pair: the coverage question spans them (a UX- has its
|
|
570
|
+
# only home here, a BR- only in backend-plan.md, an FR- with a surface needs
|
|
571
|
+
# both), so no per-lane gate could answer it. It reads §7 Traceability as the
|
|
572
|
+
# two-way spine and refuses to certify a plan the spec has moved past.
|
|
573
|
+
# → /appweaver implement-ui generates the components from this document alone.
|
|
574
|
+
|
|
575
|
+
# 6. Post-execution hooks.
|
|
576
|
+
- id: resolve_post_hooks
|
|
577
|
+
action: execute_script
|
|
578
|
+
script: { ref: actions }
|
|
579
|
+
subcommand: resolve-hooks
|
|
580
|
+
args: ["--phase", "after_design_ui"]
|
|
581
|
+
outputs:
|
|
582
|
+
- { name: after_hooks, from: "$.hooks" }
|
|
583
|
+
- id: dispatch_post_hooks
|
|
584
|
+
action: dispatch_hooks
|
|
585
|
+
hooks_from_variable: after_hooks
|
|
586
|
+
|
|
587
|
+
outputs:
|
|
588
|
+
feature_dir: "{{feature_dir}}"
|
|
589
|
+
ui_plan_doc: "{{ui_plan_doc}}"
|
|
590
|
+
ui_plan_mode: "{{ui_plan_mode}}"
|
|
591
|
+
source_files_read: "{{source_count}}"
|
|
592
|
+
migrated_legacy_design: "{{ui_plan_migrated}}"
|
|
593
|
+
lane_id: "{{lane_id}}"
|
|
594
|
+
lane_root: "{{lane_root}}"
|
|
595
|
+
derived_from_spec: "{{current_version}}"
|
|
596
|
+
conformed_ids: "{{changed_csv}}"
|
|
597
|
+
next: "frontend-plan.md written for the {{lane_id}} lane at {{ui_plan_doc}} (mode: {{ui_plan_mode}}). Gate this write: /appweaver analyze-design — one command over BOTH lanes, which is what proves no UX- fell between them; it reads §7 Traceability as the two-way spine. CHECK §5 CONTRACT BINDING: it binds to interfaces.md, which /appweaver plan publishes — if that log was absent this run, §5 was bound from the spec's IC- ids alone and a DA-n says so, which means running plan first and re-running this command is what turns an assumption into the real contract. Contract deltas needed goes back to the service lane, never into the client. source_files_read {{source_count}} is how many existing UI files this plan was written against; 0 means greenfield. Then /appweaver implement-ui. NOTE while the pipeline is mid-rename: migrated_legacy_design=true means design.ui.md is now frontend-plan.md, and stages not yet rebuilt for the rename (implement-ui, the delta chain) still look for design.ui.md — rebuild or point them at frontend-plan.md before relying on them."
|