aw-spec-cli 0.1.33 → 0.1.34
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/README.md +76 -81
- package/assets/.appweaver/DESIGN-FORMAT.md +57 -25
- package/assets/.appweaver/STACK-PROFILES.md +95 -60
- package/assets/.appweaver/orchestrator/LAUNCHER.md +1 -1
- package/assets/.appweaver/orchestrator/modules/delta-plan.orch.yaml +173 -32
- package/assets/.appweaver/orchestrator/modules/domain-select.orch.yaml +29 -1
- package/assets/.appweaver/orchestrator/modules/foundation-pack.orch.yaml +7 -4
- package/assets/.appweaver/orchestrator/modules/foundation-spec.orch.yaml +49 -60
- package/assets/.appweaver/orchestrator/modules/tech-select.orch.yaml +58 -0
- package/assets/.appweaver/orchestrator/orchestrator.py +26 -8
- package/assets/.appweaver/orchestrator/rev-templates/delta-design-template.skeleton.md +20 -20
- package/assets/.appweaver/orchestrator/rev-templates/design-template.skeleton.md +22 -48
- package/assets/.appweaver/orchestrator/rev-templates/ui-delta-design-template.skeleton.md +9 -7
- package/assets/.appweaver/orchestrator/rev-templates/ui-design-template.skeleton.md +5 -5
- package/assets/.appweaver/orchestrator/workflows/aw-spec-adopt.orch.yaml +239 -40
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-plan-delta.orch.yaml +254 -43
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-plan.orch.yaml +248 -68
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-slice-delta.orch.yaml +251 -20
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-slice.orch.yaml +316 -10
- package/assets/.appweaver/orchestrator/workflows/aw-spec-build.orch.yaml +6 -47
- package/assets/.appweaver/orchestrator/workflows/aw-spec-close-delta.orch.yaml +62 -16
- package/assets/.appweaver/orchestrator/workflows/aw-spec-finalize-delta.orch.yaml +132 -9
- package/assets/.appweaver/orchestrator/workflows/aw-spec-fix-test-coverage.orch.yaml +965 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-implement.orch.yaml +222 -169
- package/assets/.appweaver/orchestrator/workflows/aw-spec-onboard.orch.yaml +21 -22
- package/assets/.appweaver/orchestrator/workflows/aw-spec-plan.orch.yaml +453 -120
- package/assets/.appweaver/orchestrator/workflows/aw-spec-select-lane.orch.yaml +2 -2
- package/assets/.appweaver/orchestrator/workflows/aw-spec-select-stack.orch.yaml +83 -6
- package/assets/.appweaver/orchestrator/workflows/aw-spec-specify.orch.yaml +45 -2
- package/assets/.appweaver/scripts/bash/aw-spec-actions.sh +324 -74
- package/assets/.appweaver/scripts/powershell/aw-spec-actions.ps1 +275 -44
- package/assets/.appweaver/scripts/python/aw-foundation.py +16 -13
- package/assets/.appweaver/scripts/python/aw-gaps.py +11 -3
- package/assets/.appweaver/scripts/python/aw-model-guard.py +295 -0
- package/assets/.appweaver/scripts/python/aw-plan-coverage.py +412 -3
- package/assets/.appweaver/scripts/python/aw-plangate.py +23 -16
- package/assets/.appweaver/scripts/python/aw-stack.py +1794 -265
- package/assets/.appweaver/stack-profiles/dotnet-webapi.json +0 -2
- package/assets/.appweaver/stack-profiles/java-spring.json +0 -2
- package/assets/.appweaver/templates/api-plan-template.md +107 -0
- package/assets/.appweaver/templates/delta-api-plan-template.md +87 -0
- package/assets/.appweaver/templates/delta-design-template.md +25 -23
- package/assets/.appweaver/templates/delta-spec-template.md +3 -3
- package/assets/.appweaver/templates/design-template.md +20 -42
- package/assets/.appweaver/templates/domain-model-template.md +3 -0
- package/assets/.appweaver/templates/ui-delta-design-template.md +11 -8
- package/assets/.appweaver/templates/ui-design-template.md +4 -4
- package/assets/foundations/foundation.spec.template.txt +25 -18
- package/assets/guardrails/README.md +61 -25
- package/assets/guardrails/methodology/ux/accessibility-standards.md +38 -0
- package/assets/guardrails/methodology/ux/content-design.md +34 -0
- package/assets/guardrails/methodology/ux/interaction-states.md +45 -0
- package/assets/guardrails/methodology/ux/journey-mapping.md +41 -0
- package/assets/guardrails/project-specific/domain/domain-requirements.md +25 -38
- package/assets/guardrails/project-specific/domain-rule-bindings.md +33 -69
- package/assets/guardrails/project-specific/frontend/ui-requirements.md +2 -2
- package/assets/guardrails/project-specific/service/technical-requirements.md +2 -2
- package/assets/guardrails/project-specific/tech-rule-bindings.md +16 -13
- package/assets/guardrails/sample-healthcare/domain/domain-requirements.md +58 -0
- package/assets/guardrails/sample-healthcare/domain-rule-bindings.md +138 -0
- package/assets/guardrails/sample-healthcare/frontend/ui-requirements.md +43 -0
- package/assets/guardrails/sample-healthcare/service/technical-requirements.md +40 -0
- package/assets/guardrails/sample-healthcare/tech-rule-bindings.md +303 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +216 -7
- package/dist/commands/init.js.map +1 -1
- package/dist/utils/config.js +1 -1
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/foundation.d.ts +36 -0
- package/dist/utils/foundation.d.ts.map +1 -0
- package/dist/utils/foundation.js +109 -0
- package/dist/utils/foundation.js.map +1 -0
- package/dist/utils/paths.js +1 -1
- package/dist/utils/paths.js.map +1 -1
- package/package.json +1 -1
|
@@ -13,12 +13,14 @@
|
|
|
13
13
|
# is ACTIVATED so the stages after this one act on the same delta.
|
|
14
14
|
#
|
|
15
15
|
# THE FIVE CHECKS:
|
|
16
|
-
# 1. delta-spec.md → delta-backend-plan.md
|
|
16
|
+
# 1. delta-spec.md → delta-backend-plan.md + delta-api-plan.md — every ADDED/MODIFIED
|
|
17
|
+
# spec item realised, and every endpoint the change's API adds or changes realised by
|
|
18
|
+
# an element of its delta backend plan
|
|
17
19
|
# 2. delta-spec.md → delta-frontend-plan.md — every experience item realised
|
|
18
|
-
# 3.
|
|
19
|
-
# delta binds to must appear in the
|
|
20
|
-
#
|
|
21
|
-
#
|
|
20
|
+
# 3. the change's API ↔ delta-frontend-plan.md — CONTRACT BINDING across the change: what
|
|
21
|
+
# the frontend delta binds to must appear in the change's API (its delta-api-plan.md)
|
|
22
|
+
# or in the feature's (api-plan.md). A call neither publishes passes both one-sided
|
|
23
|
+
# checks and fails at integration.
|
|
22
24
|
# 4. THE EFFECTIVE MODEL — domain-model.md + this change's model delta + the model
|
|
23
25
|
# deltas of every LOWER-WAVE change (its predecessors). Every structural item the
|
|
24
26
|
# model delta adds has a realisation row; nothing structural is invented in a plan.
|
|
@@ -41,8 +43,16 @@
|
|
|
41
43
|
# repaired or stopped on. Its delta plan not existing yet is a note, not a refusal — check 3
|
|
42
44
|
# waits until both halves are on disk.
|
|
43
45
|
#
|
|
46
|
+
# THE SERVICE HALF IS TWO DOCUMENTS. The endpoints a change adds, changes and removes, and
|
|
47
|
+
# the requests it answers, are in its delta-api-plan.md — the one finalize-delta merges into
|
|
48
|
+
# api-plan.md, block by block — and its delta-backend-plan.md realises them. Both are in
|
|
49
|
+
# context with the feature's API plan, and a repair rewrites the one the gap is in, the
|
|
50
|
+
# delta API plan first. A change planned before delta API plans existed keeps its API in
|
|
51
|
+
# its delta backend plan's contract table and API section, which every check then reads and
|
|
52
|
+
# an API repair rewrites.
|
|
53
|
+
#
|
|
44
54
|
# A SERVICE CHANGE THAT BREAKS A FRONTEND BINDING IS A WARNING (contract-impact). An
|
|
45
|
-
# operation the
|
|
55
|
+
# operation the change's API changes or removes that the master frontend plan binds to,
|
|
46
56
|
# and that the change's frontend delta plan does not name, is reported by script before the
|
|
47
57
|
# check — whatever lanes the change names. The frontend half may follow from its own
|
|
48
58
|
# developer or in a follow-up change, so it never stops the gate.
|
|
@@ -72,8 +82,8 @@
|
|
|
72
82
|
# =============================================================================
|
|
73
83
|
|
|
74
84
|
name: aw-spec-analyze-plan-delta
|
|
75
|
-
description: The delta-spec↔delta-plan conformance gate for ONE open change — confirm its delta-backend-plan.md and delta-frontend-plan.md realise delta-spec.md,
|
|
76
|
-
version: 2.
|
|
85
|
+
description: The delta-spec↔delta-plan conformance gate for ONE open change — confirm its delta-api-plan.md, delta-backend-plan.md and delta-frontend-plan.md realise delta-spec.md, that the frontend delta binds to the API the change and the feature publish, realise this change's domain model delta, and only MODIFY elements the masters really define. Checked against the EFFECTIVE model (domain-model.md plus this change's model delta plus every lower-wave predecessor's, whose delta-specs are in context too) and told, deterministically, which other open changes touch the same aggregates. Gates only the lanes the change names that you work on — the other developer's delta plan is read for the contract check, its gaps are reported for them, and its absence is a note. Warns, by script, when the service delta changes or removes an operation the frontend binds to and the frontend half does not follow. Asks which open change it is gating when more than one names your lane; a CR id as the argument selects without a prompt. Does not modify the masters or close the change.
|
|
86
|
+
version: 2.5.0
|
|
77
87
|
agent_agnostic: true
|
|
78
88
|
dialect: aw-spec.orchestrator/v1
|
|
79
89
|
|
|
@@ -158,6 +168,28 @@ vars:
|
|
|
158
168
|
backend_repair: "false"
|
|
159
169
|
frontend_repair: "false"
|
|
160
170
|
delta_backend_plan: ""
|
|
171
|
+
# THE API — the change's delta-api-plan.md and the feature's api-plan.md, each in context
|
|
172
|
+
# with the backend lane's documents when it exists. A change planned before delta API
|
|
173
|
+
# plans has none: its delta backend plan carries its API, and an API repair goes there.
|
|
174
|
+
delta_api_plan: ""
|
|
175
|
+
delta_api_plan_exists: "false"
|
|
176
|
+
api_plan: ""
|
|
177
|
+
api_plan_exists: "false"
|
|
178
|
+
impact_go: "false" # a delta backend or delta API plan is on disk ⇒ contract-impact runs
|
|
179
|
+
api_delta_go: "false"
|
|
180
|
+
api_master_go: "false"
|
|
181
|
+
be_api_delta_ctx: ""
|
|
182
|
+
api_master_ctx: ""
|
|
183
|
+
api_repair: "false" # the analyze pass found a gap in an endpoint of the change's API
|
|
184
|
+
api_repair_go: "false" # …and this pass rewrites delta-api-plan.md for it
|
|
185
|
+
api_in_backend: "false" # …or, with no delta API plan, rewrites the delta backend plan
|
|
186
|
+
# What the delta backend plan's repair is told about the change's API — set below.
|
|
187
|
+
be_delta_api_rule: ""
|
|
188
|
+
change_draft_path: ""
|
|
189
|
+
change_draft_plan: "" # the document the change's draft was drawn from
|
|
190
|
+
change_draft_unread: "0"
|
|
191
|
+
change_draft_unread_text: "none"
|
|
192
|
+
change_draft_clean: "true"
|
|
161
193
|
delta_frontend_plan: ""
|
|
162
194
|
# The plan paths AS CONTEXT — bound only for a lane this run actually gates. feature-paths
|
|
163
195
|
# and cr-paths resolve every path whatever the declaration says, so putting them straight
|
|
@@ -205,6 +237,8 @@ workflow:
|
|
|
205
237
|
- { name: frontend_plan, from: "$.frontend_plan" }
|
|
206
238
|
- { name: backend_plan_exists, from: "$.backend_plan_exists" }
|
|
207
239
|
- { name: frontend_plan_exists, from: "$.frontend_plan_exists" }
|
|
240
|
+
- { name: api_plan, from: "$.api_plan" }
|
|
241
|
+
- { name: api_plan_exists, from: "$.api_plan_exists" }
|
|
208
242
|
|
|
209
243
|
# THIS FEATURE'S LANES. lane_resolve above read the REPO's declaration; one feature may
|
|
210
244
|
# own no part of a lane's surface — adopt records `lanes: [backend]` in
|
|
@@ -329,6 +363,8 @@ workflow:
|
|
|
329
363
|
- { name: delta_frontend_plan, from: "$.delta_frontend_plan" }
|
|
330
364
|
- { name: delta_backend_plan_exists, from: "$.delta_backend_plan_exists" }
|
|
331
365
|
- { name: delta_frontend_plan_exists, from: "$.delta_frontend_plan_exists" }
|
|
366
|
+
- { name: delta_api_plan, from: "$.delta_api_plan" }
|
|
367
|
+
- { name: delta_api_plan_exists, from: "$.delta_api_plan_exists" }
|
|
332
368
|
- { name: wave, from: "$.wave" }
|
|
333
369
|
- { name: predecessor_docs, from: "$.predecessor_docs" }
|
|
334
370
|
- { name: predecessor_count, from: "$.predecessor_count" }
|
|
@@ -464,9 +500,20 @@ workflow:
|
|
|
464
500
|
on_false: continue
|
|
465
501
|
on_false_message: "NOTE — change {{cr_id}} also names the {{awaited_txt}} lane, whose developer has not written its delta plan yet. This run gates your half only; the contract between the two halves (check 3) is checked once both delta plans are on disk."
|
|
466
502
|
|
|
467
|
-
# D4b. What the
|
|
468
|
-
-
|
|
503
|
+
# D4b. What the change's API changes or removes that the frontend binds to, by script.
|
|
504
|
+
# contract-impact reads the delta API plan beside --delta-backend, and the delta
|
|
505
|
+
# backend plan's own contract table for a change planned before delta API plans;
|
|
506
|
+
# it runs when either document is on disk.
|
|
507
|
+
- id: impact_go_be
|
|
469
508
|
condition: "{{delta_backend_plan_exists}} == true"
|
|
509
|
+
action: set
|
|
510
|
+
vars: { impact_go: "true" }
|
|
511
|
+
- id: impact_go_api
|
|
512
|
+
condition: "{{delta_api_plan_exists}} == true"
|
|
513
|
+
action: set
|
|
514
|
+
vars: { impact_go: "true" }
|
|
515
|
+
- id: contract_impact
|
|
516
|
+
condition: "{{impact_go}} == true"
|
|
470
517
|
action: execute_script
|
|
471
518
|
on_error: continue
|
|
472
519
|
script: { ref: actions }
|
|
@@ -542,18 +589,74 @@ workflow:
|
|
|
542
589
|
condition: "{{fe_seen}} == true"
|
|
543
590
|
action: set
|
|
544
591
|
vars: { fe_master_ctx: "{{frontend_plan}}" }
|
|
592
|
+
# The API documents ride with the backend lane's: the change's delta API plan with its
|
|
593
|
+
# delta backend plan, the feature's API plan with the master backend plan — each only when
|
|
594
|
+
# it exists.
|
|
595
|
+
- id: api_delta_arm
|
|
596
|
+
condition: "{{be_seen}} == true"
|
|
597
|
+
action: set
|
|
598
|
+
vars: { api_delta_go: "{{delta_api_plan_exists}}" }
|
|
599
|
+
- id: api_delta_ctx_path
|
|
600
|
+
condition: "{{api_delta_go}} == true"
|
|
601
|
+
action: set
|
|
602
|
+
vars: { be_api_delta_ctx: "{{delta_api_plan}}" }
|
|
603
|
+
- id: api_master_arm
|
|
604
|
+
condition: "{{be_master_ctx}} != "
|
|
605
|
+
action: set
|
|
606
|
+
vars: { api_master_go: "{{api_plan_exists}}" }
|
|
607
|
+
- id: api_master_ctx_path
|
|
608
|
+
condition: "{{api_master_go}} == true"
|
|
609
|
+
action: set
|
|
610
|
+
vars: { api_master_ctx: "{{api_plan}}" }
|
|
611
|
+
|
|
612
|
+
# What the delta backend plan's repair is told about the change's API: the delta API
|
|
613
|
+
# plan, or — for a change planned before those — its own contract table and API section.
|
|
614
|
+
- id: be_delta_api_rule_api
|
|
615
|
+
action: set
|
|
616
|
+
vars:
|
|
617
|
+
be_delta_api_rule: "THE CHANGE'S API IS IN delta-api-plan.md (in context), repaired before this document whenever a gap was in one of its endpoints. Do NOT publish or restate endpoints here: REALISE each endpoint it adds or changes as the use-case its **Maps to** names, ADDED or MODIFIED here, with request and response DTOs matching its shapes. A gap in an endpoint itself — its row, its block, its operation id, a request's answer — is the delta API plan's, not this document's."
|
|
618
|
+
- id: be_delta_api_rule_in_plan
|
|
619
|
+
condition: "{{delta_api_plan_exists}} == false"
|
|
620
|
+
action: set
|
|
621
|
+
vars:
|
|
622
|
+
be_delta_api_rule: "THIS CHANGE'S API IS IN THIS DOCUMENT — it was planned before delta API plans existed. CONTRACT gaps whose lane is `backend`: publish the missing surface in '## Contract deltas for the frontend lane' — one row per endpoint added, changed or removed, with its operation id — and write each added or changed endpoint in full under '## API — added and changed endpoints', every shape `{ field: type }`. Those are the only parts of this document the experience delta may bind to."
|
|
545
623
|
|
|
546
624
|
# 4b. Load the domain GATE overlays (the domain-rule-bindings `/aw-spec-gate` checklist)
|
|
547
625
|
# as the conformance checklist — VALIDATION input only, NEVER authoring. analyze sees
|
|
548
626
|
# them (include_standards: true); the repair steps do NOT (the delta conforms to the
|
|
549
|
-
# delta SPEC, not to the overlays). Empty/no-op for a non-domain project
|
|
627
|
+
# delta SPEC, not to the overlays). Empty/no-op for a non-domain project — a map whose
|
|
628
|
+
# heading holds a `_None_` line. A map with no such heading, or one naming a file that
|
|
629
|
+
# is not on disk, warns and carries on.
|
|
550
630
|
- id: resolve_gate_overlays
|
|
551
631
|
action: execute_script
|
|
552
632
|
script: { ref: actions }
|
|
553
633
|
subcommand: resolve-domain
|
|
554
634
|
args: ["--command", "aw-spec-gate"]
|
|
555
635
|
outputs:
|
|
556
|
-
- { name: gate_overlays,
|
|
636
|
+
- { name: gate_overlays, from: "$.candidates" }
|
|
637
|
+
- { name: gate_domain, from: "$.domain" }
|
|
638
|
+
- { name: gate_map_exists, from: "$.rulemap_exists" }
|
|
639
|
+
- { name: gate_heading_found, from: "$.heading_found" }
|
|
640
|
+
- { name: gate_missing, from: "$.missing" }
|
|
641
|
+
- id: gate_flags
|
|
642
|
+
action: set
|
|
643
|
+
vars: { gate_all_on_disk: "true" }
|
|
644
|
+
- id: gate_flag_missing
|
|
645
|
+
condition: "{{gate_missing}} != []"
|
|
646
|
+
action: set
|
|
647
|
+
vars: { gate_all_on_disk: "false" }
|
|
648
|
+
- id: warn_gate_heading
|
|
649
|
+
condition: "{{gate_map_exists}} == true"
|
|
650
|
+
action: verify_context
|
|
651
|
+
require_true: gate_heading_found
|
|
652
|
+
on_false: continue
|
|
653
|
+
on_false_message: "WARNING — guardrails/{{gate_domain}}/domain-rule-bindings.md has no `## /aw-spec-gate` heading, so the change's plans are checked against no domain checklist. If that is not intended, add the heading and its overlay files — it must read exactly `## /aw-spec-gate`; a project with no checklist keeps the heading with a `_None_` line."
|
|
654
|
+
- id: warn_gate_missing
|
|
655
|
+
condition: "{{gate_map_exists}} == true"
|
|
656
|
+
action: verify_context
|
|
657
|
+
require_true: gate_all_on_disk
|
|
658
|
+
on_false: continue
|
|
659
|
+
on_false_message: "WARNING — guardrails/{{gate_domain}}/domain-rule-bindings.md maps these checklist files under `## /aw-spec-gate`, but they are not on disk, so the change's plans were not checked against them: {{gate_missing}}. Correct the paths, or add the files."
|
|
557
660
|
- id: load_gate_overlays
|
|
558
661
|
action: load_standards
|
|
559
662
|
files_from_variable: gate_overlays
|
|
@@ -583,9 +686,11 @@ workflow:
|
|
|
583
686
|
context:
|
|
584
687
|
- { path: "{{delta_spec}}" } # THE ANCHOR for this change
|
|
585
688
|
- { path: "{{delta_model}}", optional: true } # its model half — unfilled on a plan-only change
|
|
689
|
+
- { path: "{{be_api_delta_ctx}}", optional: true } # the change's API — merged into api-plan.md at finalize-delta
|
|
586
690
|
- { path: "{{be_delta_ctx}}", optional: true }
|
|
587
691
|
- { path: "{{fe_delta_ctx}}", optional: true }
|
|
588
692
|
- { path: "{{spec_file}}" } # the master spec (READ ONLY)
|
|
693
|
+
- { path: "{{api_master_ctx}}", optional: true } # the feature's API (READ ONLY) — what a changed or removed endpoint must name
|
|
589
694
|
- { path: "{{be_master_ctx}}", optional: true } # the master plans (READ ONLY) — the base
|
|
590
695
|
- { path: "{{fe_master_ctx}}", optional: true } # every MODIFIED element must name
|
|
591
696
|
- { path: "{{domain_model}}", optional: true } # the canonical model (READ ONLY)
|
|
@@ -613,8 +718,8 @@ workflow:
|
|
|
613
718
|
- id: analyze
|
|
614
719
|
action: agent_query
|
|
615
720
|
include_standards: true # the gate overlays (checklist) are in the standards
|
|
616
|
-
schema: { ok: true, backend_repair: false, frontend_repair: false, gaps: [ { severity: "high", check: "<spec-backend|spec-frontend|contract|model|master|wave|overlay>", lane: "<backend|frontend>", spec_ref: "<delta FR/BR/CN/DC/IC/UX/US or overlay or —>", where: "<delta-plan section>", gap: "<how it drifts>" } ] }
|
|
617
|
-
mock: { ok: true, backend_repair: false, frontend_repair: false, gaps: [] }
|
|
721
|
+
schema: { ok: true, backend_repair: false, api_repair: false, frontend_repair: false, gaps: [ { severity: "high", check: "<spec-backend|spec-frontend|contract|model|master|wave|overlay>", lane: "<backend|frontend>", spec_ref: "<delta FR/BR/CN/DC/IC/UX/US or overlay or —>", where: "<delta-plan section>", gap: "<how it drifts>" } ] }
|
|
722
|
+
mock: { ok: true, backend_repair: false, api_repair: false, frontend_repair: false, gaps: [] }
|
|
618
723
|
task: |
|
|
619
724
|
delta-spec.md is the ANCHOR for change {{cr_id}} (wave {{wave}}). Gate this
|
|
620
725
|
change's DELTA PLANS against it, against the masters they change, and against the
|
|
@@ -628,7 +733,16 @@ workflow:
|
|
|
628
733
|
nothing else. Every gap still carries the `lane` whose document must change to
|
|
629
734
|
close it, even when that lane is not gated here.
|
|
630
735
|
|
|
631
|
-
|
|
736
|
+
THE CHANGE'S API is its delta-api-plan.md when it is in context — the endpoints
|
|
737
|
+
the change adds, changes and removes (its Contract deltas table and the whole
|
|
738
|
+
blocks under it) and the requests it answers; finalize-delta merges it into the
|
|
739
|
+
feature's api-plan.md by script, block by block. With no delta-api-plan.md in
|
|
740
|
+
context the change was planned before those existed, and its delta backend plan's
|
|
741
|
+
contract table and API section are its API. THE FEATURE'S API is api-plan.md when
|
|
742
|
+
it is in context, else the master backend plan's API section.
|
|
743
|
+
|
|
744
|
+
CHECK 1 — delta-spec.md → delta-backend-plan.md and the change's API (when the
|
|
745
|
+
delta backend plan is in context):
|
|
632
746
|
(a) every ADDED / MODIFIED delta-spec item — FR / BR / CN- / DC- / IC- / user
|
|
633
747
|
story — has a home in the delta plan (an ADDED or MODIFIED element that serves
|
|
634
748
|
it). A delta-spec item with no delta-plan element is a HIGH gap. EXCEPT the
|
|
@@ -640,7 +754,14 @@ workflow:
|
|
|
640
754
|
(d) PLAN-ONLY CHANGE — if the delta-spec is an unfilled stub, the spec is
|
|
641
755
|
deliberately unchanged and this change moves only HOW existing ids are realised.
|
|
642
756
|
Then every changed element must still trace to an EXISTING spec id in the master
|
|
643
|
-
spec (in context). An element tracing to nothing at all is still a HIGH gap
|
|
757
|
+
spec (in context). An element tracing to nothing at all is still a HIGH gap;
|
|
758
|
+
(e) with a delta-api-plan.md: every endpoint it adds or changes names under
|
|
759
|
+
**Maps to** a use-case the delta backend plan ADDS or MODIFIES, or one the master
|
|
760
|
+
backend plan defines — an endpoint nothing realises is a HIGH gap on lane
|
|
761
|
+
`backend` — and the delta backend plan restates none of it. Every `added` or
|
|
762
|
+
`changed` row has its block, written WHOLE (the merge puts it in place of the
|
|
763
|
+
API plan's block as it stands, so a block that carries only the difference loses
|
|
764
|
+
the rest), every shape as `{ field: type }`; a `removed` row has no block.
|
|
644
765
|
|
|
645
766
|
CHECK 2 — delta-spec.md → delta-frontend-plan.md (when it is in context):
|
|
646
767
|
(a) every UX- item in the delta-spec has a home HERE — the service lane excludes
|
|
@@ -656,8 +777,7 @@ workflow:
|
|
|
656
777
|
CHECK 3 — CONTRACT BINDING across the change (ONLY when {{both_lanes}} is true;
|
|
657
778
|
skip entirely otherwise):
|
|
658
779
|
(a) EVERY call, endpoint or payload the experience delta binds to is EITHER in
|
|
659
|
-
the
|
|
660
|
-
the MASTER backend plan's published surface. One that is in neither is a HIGH
|
|
780
|
+
the change's API OR already in the feature's API. One that is in neither is a HIGH
|
|
661
781
|
`contract` gap — lane `backend` when the delta-spec requires the capability, lane
|
|
662
782
|
`frontend` when the experience invented it;
|
|
663
783
|
(b) FIELD SHAPES agree in both directions — a field the experience reads that the
|
|
@@ -666,14 +786,15 @@ workflow:
|
|
|
666
786
|
(c) anything the experience delta raised under "Contract deltas needed" is
|
|
667
787
|
UNRESOLVED by definition: report it so it is closed here rather than at
|
|
668
788
|
integration;
|
|
669
|
-
(d) a contract the
|
|
789
|
+
(d) a contract the change's API REMOVES or narrows that the master frontend plan
|
|
670
790
|
still uses is a HIGH gap — the experience delta has to carry the matching change;
|
|
671
791
|
(e) OPERATION IDS MATCH. Every binding row the experience delta adds or changes
|
|
672
|
-
leads with an operation id, and that id is the one the
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
792
|
+
leads with an operation id, and that id is the one the change's API or the
|
|
793
|
+
feature's API gives the endpoint, spelled exactly. A binding with no id, or with
|
|
794
|
+
an id neither names, is a HIGH `contract` gap on lane `frontend`; a Contract
|
|
795
|
+
deltas row with no operation id is one on lane `backend`. Implement finds each
|
|
796
|
+
endpoint by this id in the API document drafted from the API plans, this change's
|
|
797
|
+
included.
|
|
677
798
|
|
|
678
799
|
CHECK 4 — THE EFFECTIVE MODEL. It is domain-model.md PLUS this change's model
|
|
679
800
|
delta PLUS the model deltas of every LOWER-WAVE change in context (its
|
|
@@ -701,9 +822,14 @@ workflow:
|
|
|
701
822
|
cannot MODIFY what the master does not define (that would be an ADD). A dangling
|
|
702
823
|
MODIFIED reference is a HIGH `master` gap;
|
|
703
824
|
(b) every MODIFIED / REMOVED spec id names one the master spec really defines;
|
|
704
|
-
(c) nothing in a delta plan edits the master: the delta plans are the whole
|
|
705
|
-
for this change, and no stage merges them back — a master plan is
|
|
706
|
-
the spec and the
|
|
825
|
+
(c) nothing in a delta plan edits the master: the delta lane plans are the whole
|
|
826
|
+
plan for this change, and no stage merges them back — a master plan is
|
|
827
|
+
re-derived from the spec, the model and the API that finalize-delta merges;
|
|
828
|
+
(d) every `changed` or `removed` endpoint of the change's API names an endpoint
|
|
829
|
+
the feature's API really has, by its operation id — the merge finds it by that id
|
|
830
|
+
— and an `added` one takes an id the feature's API does not already use. A
|
|
831
|
+
`changed` endpoint the feature does not have is a HIGH `master` gap on lane
|
|
832
|
+
`backend`: it is an `added` one.
|
|
707
833
|
|
|
708
834
|
CHECK 6 — WAVE DISCIPLINE. This change is wave {{wave}}. Other open changes
|
|
709
835
|
touching the same aggregates, computed from the pending model deltas:
|
|
@@ -730,14 +856,18 @@ workflow:
|
|
|
730
856
|
a delta plan).
|
|
731
857
|
|
|
732
858
|
Tag every gap with its `check` and the `lane` whose document must change to close
|
|
733
|
-
it. Set
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
859
|
+
it. Set api_repair true if any gap is in an endpoint of the change's API — a
|
|
860
|
+
Contract deltas row, a block, an operation id, a request's answer — and
|
|
861
|
+
backend_repair true if any needs the delta backend plan itself rewritten; both
|
|
862
|
+
when both are. Set frontend_repair likewise. (If a delta plan is still the empty
|
|
863
|
+
template, treat the WHOLE delta spec as gaps against it.) Set ok=true ONLY when
|
|
864
|
+
every applicable check passes and no touched checklist constraint is unaccounted
|
|
865
|
+
for.
|
|
737
866
|
outputs:
|
|
738
867
|
- { name: analyze_ok, from: "$.ok" }
|
|
739
868
|
- { name: analyze_gaps, from: "$.gaps" }
|
|
740
869
|
- { name: backend_repair, from: "$.backend_repair" }
|
|
870
|
+
- { name: api_repair, from: "$.api_repair" }
|
|
741
871
|
- { name: frontend_repair, from: "$.frontend_repair" }
|
|
742
872
|
- id: conform_break
|
|
743
873
|
action: break
|
|
@@ -821,6 +951,27 @@ workflow:
|
|
|
821
951
|
condition: "{{backend_repair}} == true"
|
|
822
952
|
action: set
|
|
823
953
|
vars: { be_repair: "{{be_present}}" }
|
|
954
|
+
# The change's API by the same assignments. With no delta API plan the change's API
|
|
955
|
+
# is in its delta backend plan, so an API gap raises that repair instead.
|
|
956
|
+
- id: api_repair_clear
|
|
957
|
+
action: set
|
|
958
|
+
vars: { api_repair_go: "false", api_in_backend: "false" }
|
|
959
|
+
- id: api_repair_flag
|
|
960
|
+
condition: "{{api_repair}} == true"
|
|
961
|
+
action: set
|
|
962
|
+
vars: { api_repair_go: "{{be_present}}" }
|
|
963
|
+
- id: api_repair_in_backend
|
|
964
|
+
condition: "{{delta_api_plan_exists}} == false"
|
|
965
|
+
action: set
|
|
966
|
+
vars: { api_in_backend: "{{api_repair_go}}" }
|
|
967
|
+
- id: api_repair_no_plan
|
|
968
|
+
condition: "{{delta_api_plan_exists}} == false"
|
|
969
|
+
action: set
|
|
970
|
+
vars: { api_repair_go: "false" }
|
|
971
|
+
- id: be_repair_for_api
|
|
972
|
+
condition: "{{api_in_backend}} == true"
|
|
973
|
+
action: set
|
|
974
|
+
vars: { be_repair: "true" }
|
|
824
975
|
- id: fe_repair_clear
|
|
825
976
|
action: set
|
|
826
977
|
vars: { fe_repair: "false" }
|
|
@@ -829,6 +980,36 @@ workflow:
|
|
|
829
980
|
action: set
|
|
830
981
|
vars: { fe_repair: "{{fe_present}}" }
|
|
831
982
|
|
|
983
|
+
# The change's API first, so the delta backend repair below reads it as repaired.
|
|
984
|
+
- id: repair_api
|
|
985
|
+
condition: "{{api_repair_go}} == true"
|
|
986
|
+
action: agent_author
|
|
987
|
+
include_standards: false # rewrite-in-place: the delta spec anchors — NOT the overlays
|
|
988
|
+
output_target: { type: file, path: "{{delta_api_plan}}" }
|
|
989
|
+
task: |
|
|
990
|
+
delta-spec.md is the ANCHOR — update the DELTA API PLAN for {{cr_id}} (in context)
|
|
991
|
+
to REALISE it, closing the gaps whose lane is `backend` that are in one of its
|
|
992
|
+
endpoints (the delta spec WINS every time):
|
|
993
|
+
{{analyze_gaps}}
|
|
994
|
+
- "## Contract deltas for the frontend lane": one row per endpoint the change
|
|
995
|
+
adds, changes or removes, with its operation id. A changed or removed endpoint
|
|
996
|
+
names one the feature's API (in context) really has, by its id; one it does not
|
|
997
|
+
have is `added`. A new endpoint takes an id unique across the service.
|
|
998
|
+
- "## Endpoints added or changed": each `added` or `changed` endpoint as a WHOLE
|
|
999
|
+
block — the `### `VERB /route`` heading, then **Operation id**, **Auth**,
|
|
1000
|
+
**Request**, **Success**, the **Errors** table and **Maps to**, every shape as
|
|
1001
|
+
`{ field: type }`. finalize-delta puts this block in place of the API plan's, so
|
|
1002
|
+
it carries the unchanged fields too. A removed endpoint has no block.
|
|
1003
|
+
- "## Requests from the frontend lane": only the requests this change's delta spec
|
|
1004
|
+
gives a basis for; `None` when it answers none.
|
|
1005
|
+
- REMOVE any endpoint with no delta-spec basis (on a PLAN-ONLY change, no existing
|
|
1006
|
+
spec id); **Maps to** names the use-case the delta backend plan realises it with.
|
|
1007
|
+
- Preserve every already-conformant row and block VERBATIM. Do NOT change the
|
|
1008
|
+
delta spec, the feature's API plan, either delta lane plan, the masters or the
|
|
1009
|
+
domain model. Do NOT edit the Wave / Base version / Delta spec / Delta backend
|
|
1010
|
+
plan headers — scripts stamp those.
|
|
1011
|
+
Return the COMPLETE updated delta API plan content only.
|
|
1012
|
+
|
|
832
1013
|
- id: repair_backend
|
|
833
1014
|
condition: "{{be_repair}} == true"
|
|
834
1015
|
action: agent_author
|
|
@@ -852,9 +1033,7 @@ workflow:
|
|
|
852
1033
|
EDIT domain-model.md or the model delta: they are spec-tier. A gap that can
|
|
853
1034
|
only be closed by ADDING to the model stays open with a DA-n saying it routes
|
|
854
1035
|
to /appweaver specify.
|
|
855
|
-
-
|
|
856
|
-
"## Contract deltas for the frontend lane" as field shapes. That table is the
|
|
857
|
-
only part of this document the experience delta may bind to.
|
|
1036
|
+
- {{be_delta_api_rule}}
|
|
858
1037
|
- WAVE gaps: name a lower-wave change you build on under "## Depends on", and
|
|
859
1038
|
name a same-wave overlap under "Other open deltas" — you may NOT assume a
|
|
860
1039
|
same-wave change's structure or contract, because nothing orders it against
|
|
@@ -867,8 +1046,9 @@ workflow:
|
|
|
867
1046
|
the delta spec".
|
|
868
1047
|
- Keep the technology-agnostic form (signatures + pre/post/invariant, field
|
|
869
1048
|
shapes — NO code). Preserve every already-conformant section VERBATIM. Do NOT
|
|
870
|
-
change the delta spec, the masters or the domain model. Do
|
|
871
|
-
Base version / Delta spec / Model delta
|
|
1049
|
+
change the delta spec, the delta API plan, the masters or the domain model. Do
|
|
1050
|
+
NOT edit the Wave / Base version / Delta spec / Model delta / API delta headers
|
|
1051
|
+
— scripts stamp those.
|
|
872
1052
|
Return the COMPLETE updated delta plan content only.
|
|
873
1053
|
|
|
874
1054
|
- id: repair_frontend
|
|
@@ -888,10 +1068,11 @@ workflow:
|
|
|
888
1068
|
from the master frontend plan (in context); if the master does not define it,
|
|
889
1069
|
make it an ADDED element instead. A shared component is MODIFIED in place,
|
|
890
1070
|
never copied into the change.
|
|
891
|
-
- CONTRACT gaps whose lane is `frontend`: bind ONLY to the
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
introduce NO server-side behaviour or persistence
|
|
1071
|
+
- CONTRACT gaps whose lane is `frontend`: bind ONLY to the change's API (its
|
|
1072
|
+
delta API plan — or, for a change planned before those, its delta backend plan's
|
|
1073
|
+
contract table) and to the feature's API. CITE them; do not restate, re-derive
|
|
1074
|
+
or contradict them, and introduce NO server-side behaviour or persistence
|
|
1075
|
+
assumption. A capability the
|
|
895
1076
|
experience needs that neither offers stays under "Contract deltas needed" — it
|
|
896
1077
|
is the service lane's to publish, never a client-side workaround.
|
|
897
1078
|
- WAVE gaps: name a lower-wave change you build on under "## Depends on", and a
|
|
@@ -905,10 +1086,38 @@ workflow:
|
|
|
905
1086
|
requirement here.
|
|
906
1087
|
- Stay TECHNOLOGY-AGNOSTIC: no framework, router, state library, component
|
|
907
1088
|
library or styling approach. Preserve every already-conformant section
|
|
908
|
-
VERBATIM. Do NOT edit the Wave / Base version / Delta spec /
|
|
909
|
-
|
|
1089
|
+
VERBATIM. Do NOT edit the Wave / Base version / Delta spec / API delta headers
|
|
1090
|
+
— scripts stamp those.
|
|
910
1091
|
Return the COMPLETE updated delta plan content only.
|
|
911
1092
|
|
|
1093
|
+
# THE CHANGE'S API DRAFT, redrawn from the change's API as this run leaves it — its delta
|
|
1094
|
+
# API plan, or the delta backend plan of a change planned before those; a repair may have
|
|
1095
|
+
# added, changed or removed an endpoint. The frontend lane binds to it while the change is
|
|
1096
|
+
# open, and analyze-slice-delta checks the built service against it. Advisory: it never
|
|
1097
|
+
# fails the gate.
|
|
1098
|
+
- id: contract_draft_change
|
|
1099
|
+
condition: "{{be_present}} == true"
|
|
1100
|
+
action: execute_script
|
|
1101
|
+
on_error: continue
|
|
1102
|
+
script: { ref: actions }
|
|
1103
|
+
subcommand: contract-draft
|
|
1104
|
+
args: ["--feature-dir", "{{feature_dir}}", "--cr", "{{cr_id}}"]
|
|
1105
|
+
outputs:
|
|
1106
|
+
- { name: change_draft_path, from: "$.path" }
|
|
1107
|
+
- { name: change_draft_plan, from: "$.plan" }
|
|
1108
|
+
- { name: change_draft_unread, from: "$.unread_count" }
|
|
1109
|
+
- { name: change_draft_unread_text, from: "$.unread_text" }
|
|
1110
|
+
- id: change_draft_unread_flag
|
|
1111
|
+
condition: "{{change_draft_unread}} != 0"
|
|
1112
|
+
action: set
|
|
1113
|
+
vars: { change_draft_clean: "false" }
|
|
1114
|
+
- id: warn_change_draft_unread
|
|
1115
|
+
condition: "{{be_present}} == true"
|
|
1116
|
+
action: verify_context
|
|
1117
|
+
require_true: change_draft_clean
|
|
1118
|
+
on_false: continue
|
|
1119
|
+
on_false_message: "API DRAFT — {{change_draft_unread}} endpoint shape(s) in {{change_draft_plan}} are not written as `{ field: type }`, so the frontend's client gets that data untyped: {{change_draft_unread_text}}. Write each endpoint the change adds or changes as a whole block under its endpoints section, the way the API plan does."
|
|
1120
|
+
|
|
912
1121
|
# THE STOP. Two independent raises: nothing drifts, or what drifts is only the other
|
|
913
1122
|
# developer's to close — reported for them below.
|
|
914
1123
|
- id: gate_ok_conformant
|
|
@@ -948,6 +1157,7 @@ outputs:
|
|
|
948
1157
|
cr_id: "{{cr_id}}"
|
|
949
1158
|
cr_dir: "{{cr_dir}}"
|
|
950
1159
|
wave: "{{wave}}"
|
|
1160
|
+
delta_api_plan: "{{be_api_delta_ctx}}" # the change's API, gated with its delta backend plan; empty for a change planned before delta API plans
|
|
951
1161
|
delta_backend_plan: "{{delta_backend_plan}}" # empty when that lane has no delta plan
|
|
952
1162
|
delta_frontend_plan: "{{delta_frontend_plan}}"
|
|
953
1163
|
conformant: "{{analyze_ok}}" # every check passed, the other developer's half included; false on a run that finishes means only other_lane_gaps are left
|
|
@@ -957,6 +1167,7 @@ outputs:
|
|
|
957
1167
|
gated_backend: "{{be_present}}" # checked and repaired by this run
|
|
958
1168
|
gated_frontend: "{{fe_present}}"
|
|
959
1169
|
other_lane_gaps: "{{other_csv}}" # gaps only the other developer's delta plan can close
|
|
960
|
-
contract_impact: "{{impact_csv}}" # operations the
|
|
1170
|
+
contract_impact: "{{impact_csv}}" # operations the change's API changes or removes that the frontend still binds to
|
|
1171
|
+
change_api_draft: "{{change_draft_path}}" # changes/<CR-id>/api-draft.json, redrawn from {{change_draft_plan}}
|
|
961
1172
|
note: "Gated change {{cr_id}} (wave {{wave}}) against its delta spec, the masters it changes, and the EFFECTIVE model — domain-model.md plus this change's model delta plus the {{predecessor_count}} predecessor change(s) from LOWER waves (each one's model delta and its delta-spec). Same-wave changes are visible but never assumed: {{sibling_count}} open at the same or a higher wave, overlapping this one on — {{overlap_report}}. The masters and the model were READ, never written."
|
|
962
1173
|
next: "/appweaver implement {{cr_id}} → build → analyze-slice-delta → finalize-delta → analyze-slice → close-delta (implement is one command for both lanes and both paths — passing the id above skips its 'which change' prompt; the delta plans realise the delta spec; the change stays OPEN through finalize-delta's merge and analyze-slice's verification, and only close-delta archives it and bumps the version)"
|