aw-spec-cli 0.1.5 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/.agents/agent.json +1 -1
- package/assets/.agents/skills/{aw-spec-orch → appweaver}/SKILL.md +10 -10
- package/assets/.agents/skills/{aw-spec-orch-demo → appweaver-demo}/SKILL.md +9 -9
- package/assets/.claude/agent.json +1 -1
- package/assets/.claude/skills/{aw-spec-orch → appweaver}/SKILL.md +10 -10
- package/assets/.claude/skills/{aw-spec-orch-demo → appweaver-demo}/SKILL.md +9 -9
- package/assets/.kilocode/agent.json +1 -1
- package/assets/.kilocode/workflows/{aw-spec-orch-demo.md → appweaver-demo.md} +9 -9
- package/assets/.kilocode/workflows/{aw-spec-orch.md → appweaver.md} +10 -10
- package/assets/docs/pharma-constitution.my-ref.md +86 -0
- package/dist/utils/paths.js +1 -1
- package/dist/utils/paths.js.map +1 -1
- package/package.json +1 -1
- package/assets/.aw-spec/DESIGN-FORMAT.md +0 -151
- package/assets/.aw-spec/ORCH-DIALECT.md +0 -156
- package/assets/.aw-spec/RULE-PARTITION.md +0 -126
- package/assets/.aw-spec/domain.json +0 -3
- package/assets/.aw-spec/extensions/.registry +0 -19
- package/assets/.aw-spec/extensions/agent-context/README.md +0 -57
- package/assets/.aw-spec/extensions/agent-context/agent-context-config.yml +0 -4
- package/assets/.aw-spec/extensions/agent-context/commands/aw-spec.agent-context.update.md +0 -26
- package/assets/.aw-spec/extensions/agent-context/extension.yml +0 -37
- package/assets/.aw-spec/extensions/agent-context/scripts/bash/update-agent-context.sh +0 -201
- package/assets/.aw-spec/extensions/agent-context/scripts/powershell/update-agent-context.ps1 +0 -237
- package/assets/.aw-spec/extensions.yml +0 -16
- package/assets/.aw-spec/feature.json +0 -3
- package/assets/.aw-spec/init-options.json +0 -9
- package/assets/.aw-spec/integration.json +0 -15
- package/assets/.aw-spec/integrations/aw-spec.manifest.json +0 -9
- package/assets/.aw-spec/interpreter/run-skill.py +0 -1158
- package/assets/.aw-spec/memory/constitution.md +0 -50
- package/assets/.aw-spec/orchestrator/AGENT-PROFILE.md +0 -94
- package/assets/.aw-spec/orchestrator/README.md +0 -300
- package/assets/.aw-spec/orchestrator/adapters/claude_agent_sdk.py +0 -74
- package/assets/.aw-spec/orchestrator/adapters/google_antigravity.py +0 -74
- package/assets/.aw-spec/orchestrator/modules/delta-design.orch.yaml +0 -105
- package/assets/.aw-spec/orchestrator/modules/delta-spec.orch.yaml +0 -79
- package/assets/.aw-spec/orchestrator/modules/domain-select.orch.yaml +0 -81
- package/assets/.aw-spec/orchestrator/modules/tech-select.orch.yaml +0 -75
- package/assets/.aw-spec/orchestrator/orchestrator.py +0 -1721
- package/assets/.aw-spec/orchestrator/rev-templates/ai-rules.reference.md +0 -40
- package/assets/.aw-spec/orchestrator/rev-templates/comandrulemap.skeleton.md +0 -59
- package/assets/.aw-spec/orchestrator/rev-templates/commandtechrulemap.skeleton.md +0 -97
- package/assets/.aw-spec/orchestrator/rev-templates/domain-constitution.skeleton.md +0 -61
- package/assets/.aw-spec/orchestrator/rev-templates/domain-requirements.skeleton.md +0 -48
- package/assets/.aw-spec/orchestrator/rev-templates/domain-rule-file.skeleton.md +0 -39
- package/assets/.aw-spec/orchestrator/rev-templates/technical-constitution.skeleton.md +0 -106
- package/assets/.aw-spec/orchestrator/rev-templates/technical-rule-file.skeleton.md +0 -54
- package/assets/.aw-spec/orchestrator/workflows/_smoke.orch.yaml +0 -160
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-add-component.orch.yaml +0 -244
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-adopt.orch.yaml +0 -775
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-analyze-delta-design.orch.yaml +0 -248
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-analyze-design.orch.yaml +0 -261
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-analyze-slice.orch.yaml +0 -425
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-build.orch.yaml +0 -188
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-characterize.orch.yaml +0 -474
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-close-delta.orch.yaml +0 -181
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-constitution.orch.yaml +0 -284
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-demo.orch.yaml +0 -103
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-dependency-tree.orch.yaml +0 -69
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-deploy.orch.yaml +0 -85
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-design.orch.yaml +0 -382
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-finalize-delta.orch.yaml +0 -382
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-foundation.orch.yaml +0 -246
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-implement-delta.orch.yaml +0 -231
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-implement.orch.yaml +0 -258
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-inventory.orch.yaml +0 -236
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-onboard.orch.yaml +0 -949
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-parity.orch.yaml +0 -293
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-run.orch.yaml +0 -177
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-select-domain.orch.yaml +0 -79
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-select-feature.orch.yaml +0 -128
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-specify.orch.yaml +0 -412
- package/assets/.aw-spec/scripts/bash/aw-inventory.sh +0 -14
- package/assets/.aw-spec/scripts/bash/aw-parity.sh +0 -13
- package/assets/.aw-spec/scripts/bash/aw-rev-constitution.sh +0 -13
- package/assets/.aw-spec/scripts/bash/aw-spec-actions.sh +0 -1899
- package/assets/.aw-spec/scripts/bash/aw-xref.sh +0 -15
- package/assets/.aw-spec/scripts/bash/common.sh +0 -533
- package/assets/.aw-spec/scripts/powershell/aw-inventory.ps1 +0 -14
- package/assets/.aw-spec/scripts/powershell/aw-parity.ps1 +0 -13
- package/assets/.aw-spec/scripts/powershell/aw-rev-constitution.ps1 +0 -13
- package/assets/.aw-spec/scripts/powershell/aw-spec-actions.ps1 +0 -1563
- package/assets/.aw-spec/scripts/powershell/aw-xref.ps1 +0 -15
- package/assets/.aw-spec/scripts/python/aw-inventory.py +0 -683
- package/assets/.aw-spec/scripts/python/aw-parity.py +0 -380
- package/assets/.aw-spec/scripts/python/aw-rev-constitution.py +0 -312
- package/assets/.aw-spec/scripts/python/aw-xref.py +0 -1330
- package/assets/.aw-spec/scripts/python/validate_okf.py +0 -349
- package/assets/.aw-spec/templates/constitution-domain-template.md +0 -75
- package/assets/.aw-spec/templates/constitution-technical-template.md +0 -70
- package/assets/.aw-spec/templates/delta-design-template.md +0 -69
- package/assets/.aw-spec/templates/delta-spec-template.md +0 -60
- package/assets/.aw-spec/templates/design-template.md +0 -383
- package/assets/.aw-spec/templates/okf-concept-template.md +0 -103
- package/assets/.aw-spec/templates/parity-manifest-template.json +0 -49
- package/assets/.aw-spec/templates/source-map-template.md +0 -85
- package/assets/.aw-spec/templates/spec-template.md +0 -252
- package/assets/docs/ModularMonolith/ModularMonolith.Reference.pack.txt +0 -25248
- package/assets/docs/ModularMonolith/ModularMonolith.pack.txt +0 -5726
- package/assets/docs/ModularMonolith/pack-foundation.ps1 +0 -145
- package/assets/docs/ModularMonolith/pack-foundation.sh +0 -196
- package/assets/docs/ModularMonolith/pack-reference-foundation.ps1 +0 -157
- package/assets/docs/ModularMonolith/pack-reference-foundation.sh +0 -209
- package/assets/docs/ModularMonolith/unpack-foundation.ps1 +0 -126
- package/assets/docs/ModularMonolith/unpack-foundation.sh +0 -217
- package/assets/docs/ModularMonolith/unpack-reference-foundation.ps1 +0 -129
- package/assets/docs/ModularMonolith/unpack-reference-foundation.sh +0 -218
- package/assets/docs/README.md +0 -106
- package/assets/docs/VerticalSlice/PACKAGING.md +0 -185
- package/assets/docs/VerticalSlice/VerticalSlice.Reference.pack.txt +0 -19318
- package/assets/docs/VerticalSlice/VerticalSlice.pack.txt +0 -2833
- package/assets/docs/VerticalSlice/pack-foundation.ps1 +0 -145
- package/assets/docs/VerticalSlice/pack-foundation.sh +0 -196
- package/assets/docs/VerticalSlice/pack-reference-foundation.ps1 +0 -157
- package/assets/docs/VerticalSlice/pack-reference-foundation.sh +0 -209
- package/assets/docs/VerticalSlice/unpack-foundation.ps1 +0 -126
- package/assets/docs/VerticalSlice/unpack-foundation.sh +0 -217
- package/assets/docs/VerticalSlice/unpack-reference-foundation.ps1 +0 -129
- package/assets/docs/VerticalSlice/unpack-reference-foundation.sh +0 -218
- package/assets/docs/architecture/clean-architecture.md +0 -71
- package/assets/docs/architecture/cqrs.md +0 -141
- package/assets/docs/architecture/eventing.md +0 -83
- package/assets/docs/architecture/folder-structure.md +0 -61
- package/assets/docs/architecture/modular-monolith.md +0 -47
- package/assets/docs/architecture/persistence.md +0 -269
- package/assets/docs/architecture/testing.md +0 -55
- package/assets/docs/architecture/vertical-slices.md +0 -201
- package/assets/docs/components/Email/README.md +0 -119
- package/assets/docs/components/Email/ReferenceEndpoints/SendEmailEndpoint.cs +0 -84
- package/assets/docs/components/Email/integration.md +0 -300
- package/assets/docs/components/Jobs/README.md +0 -113
- package/assets/docs/components/Jobs/integration.md +0 -259
- package/assets/docs/components/QrGenerator/README.md +0 -85
- package/assets/docs/components/QrGenerator/ReferenceEndpoints/GenerateQrEndpoint.cs +0 -57
- package/assets/docs/components/QrGenerator/integration.md +0 -230
- package/assets/docs/components/README.md +0 -74
- package/assets/docs/domain/domain-driven-design.md +0 -212
- package/assets/docs/domainspecs/healthcare/ai-rules.domain.md +0 -34
- package/assets/docs/domainspecs/healthcare/api-versioning.domain.md +0 -17
- package/assets/docs/domainspecs/healthcare/auditing.domain.md +0 -97
- package/assets/docs/domainspecs/healthcare/authorization.domain.md +0 -26
- package/assets/docs/domainspecs/healthcare/clinical-terms.md +0 -20
- package/assets/docs/domainspecs/healthcare/coding-standards.domain.md +0 -26
- package/assets/docs/domainspecs/healthcare/comandrulemap.md +0 -100
- package/assets/docs/domainspecs/healthcare/commandtechrulemap.md +0 -119
- package/assets/docs/domainspecs/healthcare/consent.md +0 -19
- package/assets/docs/domainspecs/healthcare/cqrs.domain.md +0 -12
- package/assets/docs/domainspecs/healthcare/data-classification.domain.md +0 -28
- package/assets/docs/domainspecs/healthcare/dependency-policy.domain.md +0 -11
- package/assets/docs/domainspecs/healthcare/dicom.md +0 -15
- package/assets/docs/domainspecs/healthcare/domain-driven-design.domain.md +0 -28
- package/assets/docs/domainspecs/healthcare/domain-requirements.md +0 -55
- package/assets/docs/domainspecs/healthcare/eventing.domain.md +0 -18
- package/assets/docs/domainspecs/healthcare/fhir.md +0 -36
- package/assets/docs/domainspecs/healthcare/folder-structure.domain.md +0 -23
- package/assets/docs/domainspecs/healthcare/hipaa.md +0 -34
- package/assets/docs/domainspecs/healthcare/hl7.md +0 -15
- package/assets/docs/domainspecs/healthcare/integration-terms.md +0 -21
- package/assets/docs/domainspecs/healthcare/persistence.domain.md +0 -20
- package/assets/docs/domainspecs/healthcare/terminology.md +0 -30
- package/assets/docs/domainspecs/healthcare/testing.domain.md +0 -15
- package/assets/docs/domainspecs/healthcare/vertical-slices.domain.md +0 -18
- package/assets/docs/domainspecs/healthcare/zero-trust.domain.md +0 -12
- package/assets/docs/domainspecs/pharma/ai-rules.domain.md +0 -32
- package/assets/docs/domainspecs/pharma/api-versioning.domain.md +0 -20
- package/assets/docs/domainspecs/pharma/atc.md +0 -22
- package/assets/docs/domainspecs/pharma/auditing.domain.md +0 -90
- package/assets/docs/domainspecs/pharma/authorization.domain.md +0 -25
- package/assets/docs/domainspecs/pharma/coding-standards.domain.md +0 -28
- package/assets/docs/domainspecs/pharma/comandrulemap.md +0 -108
- package/assets/docs/domainspecs/pharma/commandtechrulemap.md +0 -119
- package/assets/docs/domainspecs/pharma/cqrs.domain.md +0 -16
- package/assets/docs/domainspecs/pharma/data-classification.domain.md +0 -24
- package/assets/docs/domainspecs/pharma/data-provenance.md +0 -21
- package/assets/docs/domainspecs/pharma/dependency-policy.domain.md +0 -11
- package/assets/docs/domainspecs/pharma/domain-driven-design.domain.md +0 -36
- package/assets/docs/domainspecs/pharma/domain-requirements.md +0 -99
- package/assets/docs/domainspecs/pharma/eventing.domain.md +0 -18
- package/assets/docs/domainspecs/pharma/fhir.md +0 -31
- package/assets/docs/domainspecs/pharma/folder-structure.domain.md +0 -24
- package/assets/docs/domainspecs/pharma/hl7.md +0 -17
- package/assets/docs/domainspecs/pharma/idmp.md +0 -26
- package/assets/docs/domainspecs/pharma/integration-terms.md +0 -21
- package/assets/docs/domainspecs/pharma/ndc.md +0 -28
- package/assets/docs/domainspecs/pharma/persistence.domain.md +0 -23
- package/assets/docs/domainspecs/pharma/pharma-terms.md +0 -27
- package/assets/docs/domainspecs/pharma/product-lifecycle.domain.md +0 -30
- package/assets/docs/domainspecs/pharma/regulatory-compliance.md +0 -19
- package/assets/docs/domainspecs/pharma/terminology.md +0 -32
- package/assets/docs/domainspecs/pharma/testing.domain.md +0 -19
- package/assets/docs/domainspecs/pharma/vertical-slices.domain.md +0 -17
- package/assets/docs/domainspecs/pharma/zero-trust.domain.md +0 -12
- package/assets/docs/glossary/ai-rules.md +0 -59
- package/assets/docs/governance/api-versioning.md +0 -99
- package/assets/docs/governance/coding-standards.md +0 -87
- package/assets/docs/governance/dependency-policy.md +0 -40
- package/assets/docs/interop/ihe-conformance.md +0 -31
- package/assets/docs/requirement-spec.txt +0 -27
- package/assets/docs/security/auditing.md +0 -160
- package/assets/docs/security/authorization-matrix.md +0 -14
- package/assets/docs/security/authorization.md +0 -87
- package/assets/docs/security/data-classification.md +0 -38
- package/assets/docs/security/zero-trust.md +0 -76
- package/assets/docs/technology-constitution.md +0 -172
|
@@ -1,474 +0,0 @@
|
|
|
1
|
-
# =============================================================================
|
|
2
|
-
# aw-spec-characterize (orchestrator) — B2 of the Brownfield Pipeline
|
|
3
|
-
#
|
|
4
|
-
# The REGRESSION FENCE. After a slice is adopted (spec.md + design.md +
|
|
5
|
-
# source-map.md), pin what the legacy code CURRENTLY DOES as golden-master /
|
|
6
|
-
# characterization tests — observed behaviour asserted AS-IS, bugs and quirks
|
|
7
|
-
# included. These are NOT correctness claims; they are the missing behaviour
|
|
8
|
-
# ORACLE that lets the slice be changed under a net.
|
|
9
|
-
#
|
|
10
|
-
# inventory → adopt → CHARACTERIZE → [ forward pipeline / parity → cutover ] ← you are here
|
|
11
|
-
#
|
|
12
|
-
# Characterize is to brownfield what analyze-slice is to greenfield: greenfield verifies
|
|
13
|
-
# against ACs it authored; brownfield verifies against behaviour it OBSERVED. The
|
|
14
|
-
# key inversion vs. analyze-slice: here the CODE is the oracle — if a characterization
|
|
15
|
-
# test disagrees with the running code, the TEST is wrong (fix the assertion to
|
|
16
|
-
# the observed output), never the production code. When a golden-master later
|
|
17
|
-
# MUST change, that is a deliberate, reviewed decision recorded as a MODIFIED spec
|
|
18
|
-
# item via the CR delta loop — never a silent drift.
|
|
19
|
-
#
|
|
20
|
-
# Characterize GENERATES tests only; it does NOT modify production code and does
|
|
21
|
-
# NOT change spec.md / design.md.
|
|
22
|
-
#
|
|
23
|
-
# EXISTING TESTS. A legacy repo usually already has some. They are not a fence — they
|
|
24
|
-
# assert INTENDED behaviour, which is exactly what brownfield cannot assume. So before
|
|
25
|
-
# authoring, characterize scans for overlap and asks the operator how to resolve it
|
|
26
|
-
# (keep both / keep existing / override), defaulting to the additive choice. Overlap only
|
|
27
|
-
# counts when the behaviour AND the seam match and the existing test agrees with the code;
|
|
28
|
-
# an existing test that DISAGREES is a drift finding routed to a CR, never deduped.
|
|
29
|
-
#
|
|
30
|
-
# DRIFT REPORT. Those disagreements are the most valuable thing a brownfield adoption
|
|
31
|
-
# surfaces — intent (what a past author asserted) vs. as-built (what the code does) — so
|
|
32
|
-
# they are not left in a run log: characterize writes them to `drifted-tests.md` beside the
|
|
33
|
-
# slice's spec, one triaged finding per existing test, as the CR queue. It is rewritten on
|
|
34
|
-
# every run (never appended), so it always reflects the CURRENT scan and can never go stale.
|
|
35
|
-
#
|
|
36
|
-
# Launch: /aw-spec-orch characterize [strategy] [focus/guidance]
|
|
37
|
-
# Prereq: /aw-spec-orch adopt <Aggregate> (spec.md + design.md + source-map.md),
|
|
38
|
-
# and a scaffolded project (/aw-spec-orch foundation) to host + run tests.
|
|
39
|
-
# =============================================================================
|
|
40
|
-
|
|
41
|
-
name: aw-spec-characterize
|
|
42
|
-
description: Generate golden-master / characterization tests that pin the adopted slice's CURRENT observed behaviour as-is (quirks included), reconciling them against the legacy project's existing tests under an operator-chosen dedup policy, reporting intent-vs-as-built drift to drifted-tests.md, then run them green against the legacy code — the brownfield regression fence. The code is the oracle (fix the test, never the code); does not modify production code or the spec/design.
|
|
43
|
-
version: 1.2.0
|
|
44
|
-
agent_agnostic: true
|
|
45
|
-
dialect: aw-spec.orchestrator/v1
|
|
46
|
-
|
|
47
|
-
inputs:
|
|
48
|
-
user_input:
|
|
49
|
-
description: Optional focus / guidance (an area to prioritize, extra input cases to cover).
|
|
50
|
-
required: false
|
|
51
|
-
bind: USER_INPUT
|
|
52
|
-
|
|
53
|
-
scripts:
|
|
54
|
-
actions:
|
|
55
|
-
sh: .aw-spec/scripts/bash/aw-spec-actions.sh
|
|
56
|
-
ps1: .aw-spec/scripts/powershell/aw-spec-actions.ps1
|
|
57
|
-
|
|
58
|
-
# Sticky standards seed = the UNIVERSAL always-on rule only (ai-rules). The FRAMEWORK /
|
|
59
|
-
# test-generation set (same as implement/analyze-slice — HOW to write + place tests) is no
|
|
60
|
-
# longer hardcoded here — it is now CONFIGURATION, loaded per-command from
|
|
61
|
-
# docs/domainspecs/<domain>/commandtechrulemap.md under "## /aw-spec-characterize" by the
|
|
62
|
-
# tech-select module (see the tech_select step below). No domain files: the behaviour to
|
|
63
|
-
# fence comes from the CODE + the adopted spec/design/source-map (constitution.technical.md
|
|
64
|
-
# is referred to directly as context), not from domain rules — the tech map lists only
|
|
65
|
-
# technical files. (missing files skipped at assembly time)
|
|
66
|
-
standards:
|
|
67
|
-
- { path: docs/glossary/ai-rules.md, optional: true }
|
|
68
|
-
|
|
69
|
-
vars:
|
|
70
|
-
test_ok: "false"
|
|
71
|
-
# Dedup-pass defaults, so the outputs stay readable when the scan finds nothing
|
|
72
|
-
# (a repo with no pre-existing tests skips the question entirely).
|
|
73
|
-
dup_count: "0"
|
|
74
|
-
duplicates: ""
|
|
75
|
-
drift_count: "0"
|
|
76
|
-
drift: ""
|
|
77
|
-
dedup_policy: "Keep both (add the golden-master alongside the existing test)"
|
|
78
|
-
|
|
79
|
-
workflow:
|
|
80
|
-
|
|
81
|
-
# 0. TECHNICAL rule files → sticky standards (configuration, not hardcoded). tech-select
|
|
82
|
-
# reads docs/domainspecs/<domain>/commandtechrulemap.md under "## /aw-spec-characterize"
|
|
83
|
-
# and loads that test-generation set into the sticky standards the agent_generate steps
|
|
84
|
-
# ALWAYS prepend. No domain rule file is loaded here — the tech map lists only technical
|
|
85
|
-
# files. No blocking gate: an unconfigured project soft-continues (the golden-master is
|
|
86
|
-
# still fenced from the CODE + adopted spec/design/source-map + constitution.technical.md).
|
|
87
|
-
- id: tech_select
|
|
88
|
-
action: include
|
|
89
|
-
module: .aw-spec/orchestrator/modules/tech-select.orch.yaml
|
|
90
|
-
with: { command: aw-spec-characterize }
|
|
91
|
-
|
|
92
|
-
# 1. Resolve the current feature + its adopted artifacts.
|
|
93
|
-
- id: feature_paths
|
|
94
|
-
action: execute_script
|
|
95
|
-
on_error: continue # never crash raw on 'no feature set' — the gate below explains it
|
|
96
|
-
script: { ref: actions }
|
|
97
|
-
subcommand: feature-paths
|
|
98
|
-
outputs:
|
|
99
|
-
- { name: feature_dir, from: "$.feature_dir" }
|
|
100
|
-
- { name: spec_file, from: "$.spec_file" }
|
|
101
|
-
- { name: design_file, from: "$.design_file" }
|
|
102
|
-
- { name: spec_exists, from: "$.spec_exists" }
|
|
103
|
-
- { name: design_exists, from: "$.design_exists" }
|
|
104
|
-
|
|
105
|
-
- id: require_feature
|
|
106
|
-
action: verify_context
|
|
107
|
-
require_non_empty: feature_dir
|
|
108
|
-
on_empty: stop
|
|
109
|
-
on_empty_message: "No active feature. Run /aw-spec-orch select-feature first (pick or create the aggregate, e.g. Order), then re-run characterize."
|
|
110
|
-
|
|
111
|
-
- id: verify_spec
|
|
112
|
-
action: verify_context
|
|
113
|
-
require_true: spec_exists
|
|
114
|
-
on_false: stop
|
|
115
|
-
on_false_message: "No spec.md for the current feature. Adopt the slice first: /aw-spec-orch adopt <Aggregate>."
|
|
116
|
-
|
|
117
|
-
- id: verify_design
|
|
118
|
-
action: verify_context
|
|
119
|
-
require_true: design_exists
|
|
120
|
-
on_false: stop
|
|
121
|
-
on_false_message: "No design.md for the current feature. Run /aw-spec-orch adopt <Aggregate> (or /aw-spec-orch design) first."
|
|
122
|
-
|
|
123
|
-
# 1b. Require the ADOPT source-map sidecar — characterize fences an ADOPTED
|
|
124
|
-
# legacy slice (its as-built quirks + owned source files live here).
|
|
125
|
-
- id: set_source_map
|
|
126
|
-
action: set
|
|
127
|
-
vars:
|
|
128
|
-
source_map: "{{feature_dir}}/source-map.md"
|
|
129
|
-
# The drift report lives BESIDE the slice's spec (like source-map.md) — it is a
|
|
130
|
-
# per-slice adoption artifact, not a run log, and is rewritten on every run.
|
|
131
|
-
drift_report: "{{feature_dir}}/drifted-tests.md"
|
|
132
|
-
# required_files raises a fixed Stop that NAMES the missing file (it does not
|
|
133
|
-
# take a custom message) — "required file not in context: specs/<Agg>/source-map.md"
|
|
134
|
-
# → run /aw-spec-orch adopt first (it writes source-map.md with files + quirks).
|
|
135
|
-
- id: require_source_map
|
|
136
|
-
action: verify_context
|
|
137
|
-
required_files: ["{{source_map}}"]
|
|
138
|
-
|
|
139
|
-
# 1c. Require the FOUNDATION — a compiling project — to host + run the tests.
|
|
140
|
-
- id: detect_foundation
|
|
141
|
-
action: execute_script
|
|
142
|
-
script: { ref: actions }
|
|
143
|
-
subcommand: detect-project
|
|
144
|
-
outputs:
|
|
145
|
-
- { name: foundation_present, from: "$.scaffolded" }
|
|
146
|
-
|
|
147
|
-
- id: foundation_gate
|
|
148
|
-
action: verify_context
|
|
149
|
-
require_true: foundation_present
|
|
150
|
-
on_false: stop
|
|
151
|
-
on_false_message: "No scaffolded project found — run /aw-spec-orch foundation <FoundationName> <AppName> first. characterize writes tests INTO the project's test tree and RUNS them; there is nowhere to place/run them without it."
|
|
152
|
-
|
|
153
|
-
# 2. Pre-execution hooks.
|
|
154
|
-
- id: resolve_pre_hooks
|
|
155
|
-
action: execute_script
|
|
156
|
-
script: { ref: actions }
|
|
157
|
-
subcommand: resolve-hooks
|
|
158
|
-
args: ["--phase", "before_characterize"]
|
|
159
|
-
outputs:
|
|
160
|
-
- { name: before_hooks, from: "$.hooks" }
|
|
161
|
-
- id: dispatch_pre_hooks
|
|
162
|
-
action: dispatch_hooks
|
|
163
|
-
hooks_from_variable: before_hooks
|
|
164
|
-
|
|
165
|
-
# ═══════ 3. DEDUP PASS — reconcile against the legacy project's EXISTING tests ═══════
|
|
166
|
-
# A brownfield repo usually ALREADY has unit tests. They are not a fence: they assert
|
|
167
|
-
# INTENDED behaviour (and may be stale, skipped, or aspirational), whereas a golden-master
|
|
168
|
-
# asserts OBSERVED behaviour as-is. So they neither substitute for the fence nor are they
|
|
169
|
-
# disposable — the operator decides. Scan first (read-only), then ask ONLY if the scan
|
|
170
|
-
# found real overlap, so a repo with no tests is never interrupted.
|
|
171
|
-
#
|
|
172
|
-
# Two rules keep this honest, and both live in the scan schema rather than the question:
|
|
173
|
-
# • SAME BEHAVIOUR + DIFFERENT SEAM is NOT a duplicate. An existing test that mocks the
|
|
174
|
-
# repository and asserts a domain method is COMPLEMENTARY to a golden-master asserting
|
|
175
|
-
# the endpoint response; deduping them would punch a hole in the fence, which is
|
|
176
|
-
# deliberately pinned at the outermost seam so it survives an internal refactor.
|
|
177
|
-
# • DISAGREEMENT IS NOT DUPLICATION. An existing test asserting behaviour the code does
|
|
178
|
-
# NOT exhibit is a DRIFT FINDING (intent vs. as-built) — the most valuable thing a
|
|
179
|
-
# brownfield adoption surfaces. It is reported, never resolved by the dedup policy:
|
|
180
|
-
# overriding it would delete the bug report, and keeping it leaves a red test the
|
|
181
|
-
# capture loop cannot reach (that loop only sees char_files). Route it to a CR.
|
|
182
|
-
- id: ctx_dup_scan
|
|
183
|
-
action: build_context
|
|
184
|
-
context:
|
|
185
|
-
- { path: "{{source_map}}" }
|
|
186
|
-
- { path: "{{spec_file}}" }
|
|
187
|
-
- { path: "{{design_file}}" }
|
|
188
|
-
- id: scan_existing_tests
|
|
189
|
-
action: agent_query
|
|
190
|
-
include_standards: false
|
|
191
|
-
schema:
|
|
192
|
-
duplicates: [ { behaviour: "<observable behaviour>", spec_id: "<US-/FR-/BR- id>", existing_test: "<file:test-name>", seam: "<endpoint|handler|domain|persistence>", source_file: "<production file it covers>" } ]
|
|
193
|
-
drift: [ { existing_test: "<file:test-name>", asserts: "<what the test expects>", code_actually: "<what the code does>", source_file: "<production file it covers>", spec_id: "<US-/FR-/BR- id, or ->", test_state: "<failing|ignored|inconclusive>" } ]
|
|
194
|
-
dup_count: 0
|
|
195
|
-
drift_count: 0
|
|
196
|
-
mock: { duplicates: [], drift: [], dup_count: 0, drift_count: 0 }
|
|
197
|
-
task: |
|
|
198
|
-
Before any characterization tests are written, survey the project's EXISTING
|
|
199
|
-
tests for this slice and report where they would OVERLAP the golden-masters
|
|
200
|
-
about to be generated. Read the slice's production files (listed in
|
|
201
|
-
source-map.md, in context) and locate the existing test project(s) covering
|
|
202
|
-
them (glob the test tree; match by class/namespace/file under test).
|
|
203
|
-
Report, for each observable behaviour of this slice:
|
|
204
|
-
- `duplicates` — an existing test that pins the SAME behaviour at the SAME (or
|
|
205
|
-
equivalent) seam AND currently AGREES with what the code does. ONLY these are
|
|
206
|
-
duplicates. A test at a DIFFERENT seam (e.g. a mocked domain-level unit test vs.
|
|
207
|
-
an endpoint/persisted-state assertion) is COMPLEMENTARY, not a duplicate — do NOT
|
|
208
|
-
list it. A skipped/ignored test is NOT a duplicate (it pins nothing) — do not list it.
|
|
209
|
-
- `drift` — an existing test whose EXPECTATION differs from what the code actually
|
|
210
|
-
does right now (including tests that are currently failing, or that assert an
|
|
211
|
-
intended-but-absent behaviour). These are NOT duplicates: they are intent-vs-as-built
|
|
212
|
-
findings. List them separately; they are reported, never deduped. For each, set
|
|
213
|
-
`test_state`: `failing` (it runs and is red today — it will also redden the
|
|
214
|
-
characterize suite run), `ignored` (skipped/commented-out/[Ignore]d, so it is
|
|
215
|
-
DORMANT intent and blocks nothing), or `inconclusive` (you cannot tell from
|
|
216
|
-
reading alone — say so rather than guessing). Quote the assertion in `asserts`
|
|
217
|
-
and the observed behaviour in `code_actually` precisely enough that a reviewer
|
|
218
|
-
can act without re-reading both files.
|
|
219
|
-
Set dup_count / drift_count to the list lengths. If the project has no existing
|
|
220
|
-
tests for this slice, return empty lists and zero counts. Do not modify any file.
|
|
221
|
-
outputs:
|
|
222
|
-
- { name: duplicates, from: "$.duplicates" }
|
|
223
|
-
- { name: dup_count, from: "$.dup_count" }
|
|
224
|
-
- { name: drift, from: "$.drift" }
|
|
225
|
-
- { name: drift_count, from: "$.drift_count" }
|
|
226
|
-
|
|
227
|
-
# ── DRIFT REPORT ── the scan's second list is the valuable one, so it becomes a durable
|
|
228
|
-
# per-slice artifact rather than a line in a run log. Written BEFORE the dedup question so
|
|
229
|
-
# the operator can open it while answering, and UNCONDITIONALLY — a report that is only
|
|
230
|
-
# written when drift exists would leave a stale file from an earlier run standing after the
|
|
231
|
-
# drift was resolved, which is worse than no file. A zero-drift run rewrites it to say so.
|
|
232
|
-
- id: ctx_drift_report
|
|
233
|
-
action: build_context
|
|
234
|
-
vars:
|
|
235
|
-
drift: "{{drift}}"
|
|
236
|
-
drift_count: "{{drift_count}}"
|
|
237
|
-
context:
|
|
238
|
-
- { path: "{{source_map}}" } # source files + as-built quirks
|
|
239
|
-
- { path: "{{spec_file}}" } # for the US-/FR-/BR- ids to cite
|
|
240
|
-
- id: write_drift_report
|
|
241
|
-
action: agent_author
|
|
242
|
-
include_standards: false # a report, not generated code
|
|
243
|
-
output_target: { type: file, path: "{{drift_report}}" }
|
|
244
|
-
task: |
|
|
245
|
-
Author the INTENT-VS-AS-BUILT DRIFT REPORT for this slice: the pre-existing tests
|
|
246
|
-
whose expectations disagree with what the legacy code actually does. This is the
|
|
247
|
-
CR queue for the adoption — each finding is a decision someone must make, NOT a
|
|
248
|
-
thing characterize may fix. {{drift_count}} finding(s) from the scan:
|
|
249
|
-
{{drift}}
|
|
250
|
-
Write markdown, in this order:
|
|
251
|
-
- `# Drifted Tests — <slice>` and a one-line statement of what this file is:
|
|
252
|
-
pre-existing tests that assert behaviour the code does not exhibit, found while
|
|
253
|
-
building the regression fence. Note that characterize did NOT change them.
|
|
254
|
-
- A SUMMARY line: total findings, split by test_state (failing / ignored /
|
|
255
|
-
inconclusive). Say plainly that `failing` findings are red in the suite TODAY
|
|
256
|
-
(they will also show in the characterize test run and are not the golden-masters'
|
|
257
|
-
fault), while `ignored` ones are dormant intent that blocks nothing.
|
|
258
|
-
- One `##` section per finding, titled with the test. Under it state, each on its
|
|
259
|
-
own labelled line: the production file it covers, the spec id it maps to (or `—`),
|
|
260
|
-
its state, what the TEST asserts, what the CODE ACTUALLY does, and a RESOLUTION
|
|
261
|
-
line offering the reviewer the real choice — either the code is wrong (a defect:
|
|
262
|
-
open a CR to change the code, and the golden-master pinning today's behaviour
|
|
263
|
-
must then change with it as a reviewed MODIFIED spec item) or the TEST is wrong /
|
|
264
|
-
obsolete (delete or correct it in a CR). Recommend one and say why; do not
|
|
265
|
-
pretend to certainty you do not have — for `inconclusive`, say what must be run
|
|
266
|
-
or read to decide.
|
|
267
|
-
- A closing `## How to use this file` noting it is REGENERATED on every
|
|
268
|
-
`/aw-spec-orch characterize` run (do not edit it in place — resolve findings via
|
|
269
|
-
CRs and re-run), and that the golden-masters deliberately pin the code's CURRENT
|
|
270
|
-
behaviour, drift included.
|
|
271
|
-
If there are no findings, still write the file: the heading, and a short statement
|
|
272
|
-
that the scan found no pre-existing test disagreeing with the as-built code —
|
|
273
|
-
keep it to a few lines, invent nothing, and add no empty sections.
|
|
274
|
-
Do NOT propose edits to production code or to any test in this file.
|
|
275
|
-
outputs:
|
|
276
|
-
- { name: drift_report_file, from: "$.files" }
|
|
277
|
-
|
|
278
|
-
# The question fires ONLY when the scan found true duplicates, and it shows them, so the
|
|
279
|
-
# policy is chosen against evidence rather than blind. Option order is load-bearing:
|
|
280
|
-
# act_ask takes options[0] under --non-interactive, so the ADDITIVE, non-destructive
|
|
281
|
-
# choice MUST be first — a headless/CI run must never silently delete a hand-written test.
|
|
282
|
-
# Pin it deterministically in CI with: --answer dedup_policy="<exact option text>".
|
|
283
|
-
- id: ask_dedup
|
|
284
|
-
condition: "{{dup_count}} != 0"
|
|
285
|
-
action: ask
|
|
286
|
-
answer_key: dedup_policy
|
|
287
|
-
prompt: |
|
|
288
|
-
EXISTING TESTS OVERLAP THIS SLICE'S GOLDEN-MASTERS.
|
|
289
|
-
{{dup_count}} existing test(s) already pin the same behaviour at the same seam
|
|
290
|
-
AND agree with the current code:
|
|
291
|
-
{{duplicates}}
|
|
292
|
-
How should characterize handle them?
|
|
293
|
-
- Keep both = additive and safest. The golden-master is written anyway. The
|
|
294
|
-
existing test keeps its INTENT claim; the golden-master adds the
|
|
295
|
-
as-is claim at the outer seam. Costs some redundancy.
|
|
296
|
-
- Keep existing = skip the golden-master; the existing test IS the fence for that
|
|
297
|
-
behaviour. Leanest suite, but the fence then depends on a test
|
|
298
|
-
written against intent, and char_files will not list that
|
|
299
|
-
behaviour — coverage moves off the recorded fence.
|
|
300
|
-
- Override = replace the duplicated existing test with the golden-master.
|
|
301
|
-
DESTRUCTIVE: a hand-written test can encode knowledge (why a
|
|
302
|
-
boundary is what it is) that is not recoverable from the code.
|
|
303
|
-
Only the named duplicates are touched; recover via git.
|
|
304
|
-
options:
|
|
305
|
-
- "Keep both (add the golden-master alongside the existing test)"
|
|
306
|
-
- "Keep existing (skip the golden-master; the existing test is the fence)"
|
|
307
|
-
- "Override (replace the existing test with the golden-master)"
|
|
308
|
-
answer_var: dedup_policy
|
|
309
|
-
|
|
310
|
-
# 4. GENERATE the characterization / golden-master tests from the OBSERVED
|
|
311
|
-
# behaviour of the legacy code. The adopted artifacts frame the surface;
|
|
312
|
-
# the CODE is the source of truth (the agent reads it).
|
|
313
|
-
- id: ctx_characterize
|
|
314
|
-
action: build_context
|
|
315
|
-
context:
|
|
316
|
-
- { path: "{{source_map}}" } # owned source files + seam + AS-BUILT QUIRKS
|
|
317
|
-
- { path: "{{spec_file}}" } # the observable surface (US / FR / endpoints)
|
|
318
|
-
- { path: "{{design_file}}" } # structure (handlers, events, ports)
|
|
319
|
-
- { path: .aw-spec/memory/constitution.technical.md, optional: true } # stack + test framework
|
|
320
|
-
- id: generate
|
|
321
|
-
action: agent_generate
|
|
322
|
-
tools: "Read,Write,Edit"
|
|
323
|
-
permission_mode: acceptEdits
|
|
324
|
-
task: |
|
|
325
|
-
Generate CHARACTERIZATION / golden-master tests for this adopted slice that
|
|
326
|
-
pin what the legacy code CURRENTLY DOES — the regression fence. READ the
|
|
327
|
-
slice's PRODUCTION code (the files listed in source-map.md, in context) and
|
|
328
|
-
OBSERVE its actual behaviour; the spec.md + design.md (in context) frame the
|
|
329
|
-
observable surface. Guidance: {{USER_INPUT}}
|
|
330
|
-
Rules:
|
|
331
|
-
- ASSERT OBSERVED BEHAVIOUR, AS-IS. Capture what the code returns/emits/persists
|
|
332
|
-
for representative inputs RIGHT NOW — bugs and quirks INCLUDED. Do NOT assert
|
|
333
|
-
ideal/intended behaviour, and do NOT "correct" anything. Every "as-built quirk"
|
|
334
|
-
recorded in source-map.md MUST get a test that pins that quirk explicitly (name
|
|
335
|
-
it so a reader knows it is a captured quirk, not a desired outcome).
|
|
336
|
-
- These are a REGRESSION FENCE, not correctness claims. Mark each test as a
|
|
337
|
-
characterization/golden-master (class/file name + a header comment stating
|
|
338
|
-
"captures CURRENT behaviour as-is; a change here is a reviewed CR decision").
|
|
339
|
-
Cite the source file and the spec id (US-/FR-/BR-) it pins, and the quirk id
|
|
340
|
-
where relevant.
|
|
341
|
-
- COVERAGE: one test per observable behaviour — each command / query / endpoint
|
|
342
|
-
/ handler path, each domain invariant, each emitted event and resulting state.
|
|
343
|
-
Choose representative inputs: the happy path, boundaries, and the quirk cases.
|
|
344
|
-
Prefer the OUTERMOST observable seam (endpoint / handler response, emitted
|
|
345
|
-
event, persisted state) over private internals, so the fence survives an
|
|
346
|
-
internal refactor.
|
|
347
|
-
- BIND THE STACK + test framework from the constitution + the project's EXISTING
|
|
348
|
-
test project conventions; place files in the test tree per folder-structure and
|
|
349
|
-
match the surrounding test style. Reuse existing fixtures/builders.
|
|
350
|
-
- Do NOT modify any PRODUCTION code — tests only. Do NOT edit spec.md / design.md.
|
|
351
|
-
If a behaviour is genuinely non-deterministic (time, random, external I/O),
|
|
352
|
-
pin it via the seam the code already exposes (clock/port) or assert the stable
|
|
353
|
-
shape; note it in the test rather than asserting a flaky value.
|
|
354
|
-
- DEDUP — the operator chose: {{dedup_policy}}
|
|
355
|
-
It applies ONLY to these already-identified duplicates (same behaviour, same seam,
|
|
356
|
-
agreeing with the code). Every OTHER behaviour still gets its golden-master, and no
|
|
357
|
-
test outside this list may be edited or deleted for any reason:
|
|
358
|
-
{{duplicates}}
|
|
359
|
-
• "Keep both" → write the golden-master anyway; leave the existing test
|
|
360
|
-
untouched. In the golden-master's header comment, name the
|
|
361
|
-
existing test it doubles, so a reader knows the redundancy is
|
|
362
|
-
deliberate (as-is claim vs. the existing intent claim).
|
|
363
|
-
• "Keep existing" → do NOT write a golden-master for that behaviour. Instead add a
|
|
364
|
-
header comment IN THIS SLICE'S golden-master file recording the
|
|
365
|
-
delegation ("FR-x fenced by <file:test-name> — no golden-master
|
|
366
|
-
by operator decision"), so the fence stays auditable even though
|
|
367
|
-
char_files will not list that behaviour.
|
|
368
|
-
• "Override" → write the golden-master, then remove ONLY the specific duplicated
|
|
369
|
-
test METHOD/case named above — never a whole file wholesale, never
|
|
370
|
-
a neighbouring test. State in the golden-master's header which
|
|
371
|
-
test it supersedes and why.
|
|
372
|
-
- DRIFT — do NOT act on these. {{drift_count}} existing test(s) disagree with what the
|
|
373
|
-
code actually does; they are intent-vs-as-built findings, not duplicates. Leave them
|
|
374
|
-
exactly as they are (do not fix, delete, or "align" them) and pin the code's ACTUAL
|
|
375
|
-
behaviour in your golden-master as usual. They are already reported in
|
|
376
|
-
{{drift_report}}; resolving them is a reviewed CR decision:
|
|
377
|
-
{{drift}}
|
|
378
|
-
outputs:
|
|
379
|
-
- { name: char_files, from: "$.files" }
|
|
380
|
-
|
|
381
|
-
- id: verify_generated
|
|
382
|
-
action: verify_context
|
|
383
|
-
require_non_empty: char_files
|
|
384
|
-
on_empty: stop
|
|
385
|
-
on_empty_message: "No characterization tests were generated. Ensure source-map.md lists the slice's source files (from /aw-spec-orch adopt) and re-run."
|
|
386
|
-
|
|
387
|
-
# 5. GREEN-RUN the fence: the golden-masters MUST pass against the CURRENT code
|
|
388
|
-
# (a capture that fails the live code is a wrong capture). The CODE is the
|
|
389
|
-
# ORACLE — on failure, fix the TEST to match observed behaviour, NEVER the
|
|
390
|
-
# production code. Bounded (3×).
|
|
391
|
-
- id: capture_loop
|
|
392
|
-
action: loop
|
|
393
|
-
while: "{{test_ok}} != true"
|
|
394
|
-
max_iterations: 3
|
|
395
|
-
steps:
|
|
396
|
-
- id: run_tests
|
|
397
|
-
action: execute_script
|
|
398
|
-
on_error: continue
|
|
399
|
-
script: { ref: actions }
|
|
400
|
-
subcommand: test-run
|
|
401
|
-
args: ["--feature-dir", "{{feature_dir}}"]
|
|
402
|
-
outputs:
|
|
403
|
-
- { name: test_ok, from: "$.ok" }
|
|
404
|
-
- { name: test_tool, from: "$.tool" }
|
|
405
|
-
- { name: test_log, from: "$.log_tail" }
|
|
406
|
-
- id: green_break
|
|
407
|
-
action: break
|
|
408
|
-
condition: "{{test_ok}} == true"
|
|
409
|
-
- id: ctx_fix
|
|
410
|
-
action: build_context
|
|
411
|
-
vars:
|
|
412
|
-
test_log: "{{test_log}}"
|
|
413
|
-
context:
|
|
414
|
-
- { path: "{{source_map}}" }
|
|
415
|
-
context_from: char_files # the generated golden-master tests
|
|
416
|
-
- id: fix
|
|
417
|
-
action: agent_generate
|
|
418
|
-
tools: "Read,Write,Edit,Bash"
|
|
419
|
-
permission_mode: acceptEdits
|
|
420
|
-
task: |
|
|
421
|
-
A characterization test failed. In characterize the legacy CODE is the
|
|
422
|
-
ORACLE — its current behaviour is correct BY DEFINITION here. So make the
|
|
423
|
-
fence green by fixing the TESTS (in context), NOT the production code:
|
|
424
|
-
- If an assertion's EXPECTED value differs from what the code actually
|
|
425
|
-
returns/emits/persists, correct the expected value to the OBSERVED output
|
|
426
|
-
(read the code / run it to confirm) — that is the whole point of a
|
|
427
|
-
golden-master.
|
|
428
|
-
- If a generated test has a COMPILE or setup error, fix the test code.
|
|
429
|
-
- If a test encodes an INTENDED-but-absent behaviour (the code does not do
|
|
430
|
-
it), DELETE that test — desired behaviour belongs in a CR/spec MODIFIED
|
|
431
|
-
item, not a golden-master of current behaviour.
|
|
432
|
-
NEVER modify production code to make a characterization test pass — that
|
|
433
|
-
would alter the very behaviour you are fencing.
|
|
434
|
-
SCOPE: fix ONLY the golden-master files in context. The suite also contains the
|
|
435
|
-
legacy project's PRE-EXISTING tests; a failure in one of those is NOT yours to
|
|
436
|
-
fix — it is an intent-vs-as-built finding for a CR, and the ones already known
|
|
437
|
-
are listed in {{drift_report}}. Do not edit, delete, or skip a pre-existing test
|
|
438
|
-
to make the run green. Test log:
|
|
439
|
-
{{test_log}}
|
|
440
|
-
outputs:
|
|
441
|
-
- { name: fixed_files, from: "$.files" }
|
|
442
|
-
|
|
443
|
-
- id: characterize_gate
|
|
444
|
-
action: verify_context
|
|
445
|
-
require_true: test_ok
|
|
446
|
-
on_false: stop
|
|
447
|
-
on_false_message: "The characterization fence is not green after 3 attempts (last log: {{test_log}}). Either the captured behaviour still mismatches the code (fix the TEST assertions to the observed output) or the project does not build. The code is the oracle — never change production code to pass a golden-master."
|
|
448
|
-
|
|
449
|
-
# 6. Post-execution hooks.
|
|
450
|
-
- id: resolve_post_hooks
|
|
451
|
-
action: execute_script
|
|
452
|
-
script: { ref: actions }
|
|
453
|
-
subcommand: resolve-hooks
|
|
454
|
-
args: ["--phase", "after_characterize"]
|
|
455
|
-
outputs:
|
|
456
|
-
- { name: after_hooks, from: "$.hooks" }
|
|
457
|
-
- id: dispatch_post_hooks
|
|
458
|
-
action: dispatch_hooks
|
|
459
|
-
hooks_from_variable: after_hooks
|
|
460
|
-
|
|
461
|
-
outputs:
|
|
462
|
-
feature_dir: "{{feature_dir}}"
|
|
463
|
-
spec_file: "{{spec_file}}"
|
|
464
|
-
source_map: "{{source_map}}"
|
|
465
|
-
characterization_tests: "{{char_files}}"
|
|
466
|
-
test_tool: "{{test_tool}}"
|
|
467
|
-
# Dedup audit trail: what overlapped, how it was resolved, and what drifted. `drift` is
|
|
468
|
-
# the CR queue — existing tests whose intent disagrees with the as-built code.
|
|
469
|
-
existing_test_duplicates: "{{dup_count}}"
|
|
470
|
-
dedup_policy: "{{dedup_policy}}"
|
|
471
|
-
intent_drift_count: "{{drift_count}}"
|
|
472
|
-
intent_drift: "{{drift}}"
|
|
473
|
-
drift_report: "{{drift_report}}"
|
|
474
|
-
next: "Regression fence is GREEN against the legacy code. The slice can now be changed under a net: refine/re-implement via the forward loop + CR delta (a golden-master that MUST change = a MODIFIED spec item, reviewed — never a silent drift). If intent_drift_count is non-zero, READ {{drift_report}} and open a CR per finding — those pre-existing tests assert behaviour the code does not have, and each one is either a defect in the code or an obsolete test. Next brownfield gate: /aw-spec-orch parity (legacy vs. new, per slice) before cutover."
|
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
# =============================================================================
|
|
2
|
-
# aw-spec-close-delta (orchestrator) — ARCHIVE the change + bump the version
|
|
3
|
-
#
|
|
4
|
-
# The last of the five CR stages, and the counterpart of finalize-delta:
|
|
5
|
-
# finalize-delta MERGES the delta into the master docs (the change stays OPEN)
|
|
6
|
-
# close-delta ARCHIVES the change + bumps the version (the change is CLOSED)
|
|
7
|
-
#
|
|
8
|
-
# specify → design → analyze-delta-design → implement-delta → build
|
|
9
|
-
# → finalize-delta → analyze-slice → close-delta ← you are here
|
|
10
|
-
#
|
|
11
|
-
# WHY THE SPLIT. finalize-delta used to do both. Merging first lets analyze-slice run
|
|
12
|
-
# against a master spec.md/design.md that ALREADY carries the change — so its fix loops
|
|
13
|
-
# repair code against the true, current requirements with no delta-awareness needed. But
|
|
14
|
-
# if the close travelled with the merge, a red analyze-slice would land on a change that
|
|
15
|
-
# was already archived and version-bumped: the only remedy would be a NEW change to
|
|
16
|
-
# repair the one just shipped. Deferring the close to here keeps the change OPEN across
|
|
17
|
-
# analyze-slice, so a red gate is still "fix and re-run", and the version is stamped only
|
|
18
|
-
# once the slice is green, domain-conformant and has not broken a referrer.
|
|
19
|
-
#
|
|
20
|
-
# This stage AUTHORS nothing and generates NO code — no model is invoked. It moves
|
|
21
|
-
# changes/<id>/ into changes/archive/, bumps the minor version, clears active_change,
|
|
22
|
-
# and STAMPS that version into the `**Version**:` header of spec.md + design.md — the
|
|
23
|
-
# single irreversible act of the CR loop, deliberately isolated in a stage of its own.
|
|
24
|
-
#
|
|
25
|
-
# THE VERSION SPINE LIVES HERE, AND ONLY HERE. The number has three carriers — spec.md's
|
|
26
|
-
# header, design.md's header, active_version.json — and all three move in this one step
|
|
27
|
-
# by one deterministic mechanism. Before, design.md's header was bumped by the MODEL at
|
|
28
|
-
# finalize-delta (a stage early, and guessing the target since the number was never
|
|
29
|
-
# passed into the merge prompt) while spec.md's header was bumped by nobody at all,
|
|
30
|
-
# leaving the "living truth" document permanently at v1.0. finalize-delta now writes the
|
|
31
|
-
# Change History rows using version-read's `next_version` — the same bump() authority
|
|
32
|
-
# this stage applies — and touches neither header.
|
|
33
|
-
#
|
|
34
|
-
# NOTE: nothing MECHANICALLY proves analyze-slice ran green before this point — the
|
|
35
|
-
# stage boundary is operator-driven, as everywhere else in this pipeline. What IS
|
|
36
|
-
# enforced is the reverse: while a change is open, `specify` refuses to open another on
|
|
37
|
-
# the same feature (_active_version's open-guard), so a forgotten close-delta blocks the
|
|
38
|
-
# next change rather than passing silently.
|
|
39
|
-
#
|
|
40
|
-
# Launch: /aw-spec-orch close-delta [strategy]
|
|
41
|
-
# Prereq: an OPEN change whose delta was merged by finalize-delta and whose slice
|
|
42
|
-
# passed /aw-spec-orch analyze-slice.
|
|
43
|
-
# =============================================================================
|
|
44
|
-
|
|
45
|
-
name: aw-spec-close-delta
|
|
46
|
-
description: Close the open change — archive changes/<id>/ into changes/archive/, bump the minor version, clear active_change, and stamp that version into spec.md's and design.md's headers, then anchor the close in the OKF freshness log. The final CR stage, run after finalize-delta merged the delta and analyze-slice verified the slice. The sole owner of the version spine; invokes no model and generates no code.
|
|
47
|
-
version: 1.1.0
|
|
48
|
-
agent_agnostic: true
|
|
49
|
-
dialect: aw-spec.orchestrator/v1
|
|
50
|
-
|
|
51
|
-
scripts:
|
|
52
|
-
actions:
|
|
53
|
-
sh: .aw-spec/scripts/bash/aw-spec-actions.sh
|
|
54
|
-
ps1: .aw-spec/scripts/powershell/aw-spec-actions.ps1
|
|
55
|
-
xref:
|
|
56
|
-
sh: .aw-spec/scripts/bash/aw-xref.sh
|
|
57
|
-
ps1: .aw-spec/scripts/powershell/aw-xref.ps1
|
|
58
|
-
|
|
59
|
-
# No standards seed and no domain/tech rule selection: this stage authors nothing, so it
|
|
60
|
-
# has no prompt to govern. It is pure bookkeeping over active_version.json + changes/ +
|
|
61
|
-
# the two version headers.
|
|
62
|
-
standards: []
|
|
63
|
-
|
|
64
|
-
vars:
|
|
65
|
-
active_change: ""
|
|
66
|
-
has_change: "false"
|
|
67
|
-
version: ""
|
|
68
|
-
stamped_docs: "" # which master headers version-stamp actually rewrote
|
|
69
|
-
stamped_count: "0"
|
|
70
|
-
|
|
71
|
-
workflow:
|
|
72
|
-
|
|
73
|
-
# 1. Resolve the active feature.
|
|
74
|
-
- id: feature_paths
|
|
75
|
-
action: execute_script
|
|
76
|
-
on_error: continue # never crash raw on 'no feature set' — the gate below explains it
|
|
77
|
-
script: { ref: actions }
|
|
78
|
-
subcommand: feature-paths
|
|
79
|
-
outputs:
|
|
80
|
-
- { name: feature_dir, from: "$.feature_dir" }
|
|
81
|
-
- { name: spec_file, from: "$.spec_file" }
|
|
82
|
-
|
|
83
|
-
- id: require_feature
|
|
84
|
-
action: verify_context
|
|
85
|
-
require_non_empty: feature_dir
|
|
86
|
-
on_empty: stop
|
|
87
|
-
on_empty_message: "No active feature. Run /aw-spec-orch select-feature first (pick or create the aggregate, e.g. Order), then re-run close-delta."
|
|
88
|
-
|
|
89
|
-
# 2. There must be a change to close. On the BOOTSTRAP path (implement → build →
|
|
90
|
-
# analyze-slice) there is none and this stage does not apply at all.
|
|
91
|
-
- id: read_change
|
|
92
|
-
action: execute_script
|
|
93
|
-
script: { ref: actions }
|
|
94
|
-
subcommand: version-read
|
|
95
|
-
args: ["--feature-dir", "{{feature_dir}}"]
|
|
96
|
-
outputs:
|
|
97
|
-
- { name: active_change, from: "$.active_change" }
|
|
98
|
-
- { name: has_change, from: "$.has_change" }
|
|
99
|
-
- { name: version, from: "$.version" }
|
|
100
|
-
|
|
101
|
-
- id: require_change
|
|
102
|
-
action: verify_context
|
|
103
|
-
require_true: has_change
|
|
104
|
-
on_false: stop
|
|
105
|
-
on_false_message: "No open change on this feature — nothing to close. A change is opened by /aw-spec-orch specify (or design) and merged by /aw-spec-orch finalize-delta before it can be closed here. If you have not merged yet, run /aw-spec-orch finalize-delta → analyze-slice first."
|
|
106
|
-
|
|
107
|
-
# 3. Pre-execution hooks.
|
|
108
|
-
- id: resolve_pre_hooks
|
|
109
|
-
action: execute_script
|
|
110
|
-
script: { ref: actions }
|
|
111
|
-
subcommand: resolve-hooks
|
|
112
|
-
args: ["--phase", "before_close_cr"]
|
|
113
|
-
outputs:
|
|
114
|
-
- { name: before_hooks, from: "$.hooks" }
|
|
115
|
-
- id: dispatch_pre_hooks
|
|
116
|
-
action: dispatch_hooks
|
|
117
|
-
hooks_from_variable: before_hooks
|
|
118
|
-
|
|
119
|
-
# 4. THE CLOSE. Moves changes/{{active_change}}/ to changes/archive/, bumps the minor
|
|
120
|
-
# version in active_version.json and clears active_change. Idempotent on the
|
|
121
|
-
# directory (an already-moved change leaves archived_dir empty) but NOT on the
|
|
122
|
-
# version — the bump fires whenever a change was open, which the gate above
|
|
123
|
-
# guarantees. This is the irreversible step of the CR loop.
|
|
124
|
-
- id: archive
|
|
125
|
-
action: execute_script
|
|
126
|
-
script: { ref: actions }
|
|
127
|
-
subcommand: cr-archive
|
|
128
|
-
args: ["--feature-dir", "{{feature_dir}}", "--cr-id", "{{active_change}}"]
|
|
129
|
-
outputs:
|
|
130
|
-
- { name: version, from: "$.version" }
|
|
131
|
-
- { name: previous_version, from: "$.previous" }
|
|
132
|
-
- { name: archived_dir, from: "$.archived_dir" }
|
|
133
|
-
|
|
134
|
-
# 4b. STAMP the number just computed into the two master headers, so spec.md,
|
|
135
|
-
# design.md and active_version.json all carry it from the same instant by the
|
|
136
|
-
# same mechanism. Previously design.md's header was bumped by the MODEL back at
|
|
137
|
-
# finalize-delta (guessing the target — the number was never passed to it) and
|
|
138
|
-
# spec.md's header was bumped by nobody, so it sat at v1.0 for the life of the
|
|
139
|
-
# feature. Deterministic and idempotent; only the header value moves.
|
|
140
|
-
- id: stamp_version
|
|
141
|
-
action: execute_script
|
|
142
|
-
script: { ref: actions }
|
|
143
|
-
subcommand: version-stamp
|
|
144
|
-
args: ["--feature-dir", "{{feature_dir}}", "--version", "{{version}}"]
|
|
145
|
-
outputs:
|
|
146
|
-
- { name: stamped_docs, from: "$.stamped" }
|
|
147
|
-
- { name: stamped_count, from: "$.count" }
|
|
148
|
-
|
|
149
|
-
# 5. Anchor the CLOSE in the OKF bundle's freshness journal (log.md, OKF §7).
|
|
150
|
-
# finalize-delta logs the MERGE; this logs the SHIP — the version bump is the event
|
|
151
|
-
# a reader of the journal is looking for. Best-effort + git-aware: a no-op when there
|
|
152
|
-
# is no bundle or no commit, so it never writes a non-conformant block.
|
|
153
|
-
- id: xref_log
|
|
154
|
-
action: execute_script
|
|
155
|
-
on_error: continue
|
|
156
|
-
script: { ref: xref }
|
|
157
|
-
subcommand: log
|
|
158
|
-
args: ["--note", "CR {{active_change}} closed — archived, version {{previous_version}} -> {{version}}"]
|
|
159
|
-
outputs:
|
|
160
|
-
- { name: xref_log, from: "$.log" }
|
|
161
|
-
|
|
162
|
-
# 6. Post-execution hooks.
|
|
163
|
-
- id: resolve_post_hooks
|
|
164
|
-
action: execute_script
|
|
165
|
-
script: { ref: actions }
|
|
166
|
-
subcommand: resolve-hooks
|
|
167
|
-
args: ["--phase", "after_close_cr"]
|
|
168
|
-
outputs:
|
|
169
|
-
- { name: after_hooks, from: "$.hooks" }
|
|
170
|
-
- id: dispatch_post_hooks
|
|
171
|
-
action: dispatch_hooks
|
|
172
|
-
hooks_from_variable: after_hooks
|
|
173
|
-
|
|
174
|
-
outputs:
|
|
175
|
-
feature_dir: "{{feature_dir}}"
|
|
176
|
-
cr_id: "{{active_change}}"
|
|
177
|
-
version: "{{version}}"
|
|
178
|
-
previous_version: "{{previous_version}}"
|
|
179
|
-
archived_dir: "{{archived_dir}}"
|
|
180
|
-
stamped_docs: "{{stamped_docs}}"
|
|
181
|
-
next: "Change {{active_change}} CLOSED — archived to {{archived_dir}}, version {{previous_version}} -> {{version}}, stamped into {{stamped_count}} master header(s) ({{stamped_docs}}). spec.md, design.md and active_version.json now all read {{version}}; the masters describe the shipped state and the feature is free to take a new change. Next: /aw-spec-orch run → deploy, or start the next change with /aw-spec-orch specify."
|