@dzhechkov/skills-feature-adr 1.3.57 β 1.3.59
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 +32 -0
- package/package.json +1 -1
- package/templates/.claude/rules/feature-adr-conventions.md +28 -0
- package/templates/.claude/skills/code-critic/SKILL.md +27 -0
- package/templates/.claude/skills/code-impl/SKILL.md +17 -0
- package/templates/.claude/skills/feature-adr/SKILL.md +14 -0
- package/templates/.claude/skills/feature-adr/modules/03.5-ideation-swarm.md +22 -1
- package/templates/.claude/skills/feature-adr/modules/06-implementation-plan.md +5 -0
- package/templates/.claude/skills/feature-adr/modules/07-code.md +18 -0
- package/templates/.claude/skills/feature-adr/modules/08-qe.md +24 -0
- package/templates/.claude/workflows/feature-adr.js +23 -5
package/README.md
CHANGED
|
@@ -471,6 +471,38 @@ Step 3 and Step 8 share an ADR best-practices contract distilled from the
|
|
|
471
471
|
The pipeline **dog-foods** this: a harness test runs the gate against feature-adr's own generated ADR, so a
|
|
472
472
|
Step-3βStep-8 drift fails CI rather than shipping.
|
|
473
473
|
|
|
474
|
+
### Amendments are mini-ADRs + the π¦ Gates line (v1.3.58)
|
|
475
|
+
|
|
476
|
+
Three additions derived from a real post-release incident analysis (a pipeline shipped slices whose defects
|
|
477
|
+
only a *full* post-push review caught), organized by one principle β the **cost-of-detection ladder**: every
|
|
478
|
+
check lives on the cheapest layer that reliably holds it (deterministic test > always-loaded file > pipeline
|
|
479
|
+
gate > reviewer judgment > memory). A miss usually means a check lived one layer too weak.
|
|
480
|
+
|
|
481
|
+
- **Amendment Confirmation discipline.** Corrections folded into a run (a Step-3.5 CONDITIONAL condition, a
|
|
482
|
+
challenge-panel confirmed finding, a user checkpoint steer) were historically the least-tested part of the
|
|
483
|
+
pipeline β prose deltas with no proving test. Now every amendment is a **mini-ADR** in a `## Amendments`
|
|
484
|
+
section with a fixed, lintable shape:
|
|
485
|
+
```
|
|
486
|
+
AM-N (qcsd|challenge-panel|user-steer): <change>. Confirmation: <property> β test `test_name` (fails if reverted).
|
|
487
|
+
```
|
|
488
|
+
Step 8 verifies each named test **exists** and is **non-vacuous** β amendment tests join the ADR property
|
|
489
|
+
test in the same `dz discrimination-check` run (a test that stays green at pre-feature base proves
|
|
490
|
+
nothing). A *safeguard* amendment needs a test proving it actually **fires** on a real input, not just
|
|
491
|
+
that its code path exists. No `## Amendments` section β the gate skips silently (zero cost).
|
|
492
|
+
- **The `π¦ Gates:` line.** Every checkpoint banner (and the workflow's return objects) carries a gate map
|
|
493
|
+
**derived from machine state** β artifact existence, JSON verdicts, test results β never from what the
|
|
494
|
+
orchestrator remembers. `β` passed Β· `β` failed Β· `not-run` pending Β· `β` N/A. The line doesn't make a
|
|
495
|
+
gate run; it makes NOT running one loud.
|
|
496
|
+
- **I/O-on-pure-path rule.** A change that adds I/O (DB/network/file) to a previously-pure path β above all
|
|
497
|
+
startup/lifespan/health β must carry a **negative resource-down test** (broken resource β the declared
|
|
498
|
+
degradation contract: fail-open for advisory, fail-fast for load-bearing), and Step 8 hunts the
|
|
499
|
+
**fixture-swap smell**: replacing a broken fixture with a healthy one silently deletes the negative
|
|
500
|
+
control that proved the path was I/O-free. The bundled role-default skills gained the matching entries
|
|
501
|
+
(`code-impl` P25, `code-critic` AP14).
|
|
502
|
+
|
|
503
|
+
Both forms carry all of it: the interactive skill (step modules + banner template) and the deterministic
|
|
504
|
+
workflow (stage prompts + derived `gates` in its returns) β same shapes, same vocabulary.
|
|
505
|
+
|
|
474
506
|
### The `Model` / `Fable?` columns β read this before swapping models
|
|
475
507
|
|
|
476
508
|
The `Model` column is the **default recommendation, fully overridable** β the routing rule is
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dzhechkov/skills-feature-adr",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.59",
|
|
4
4
|
"description": "Adaptive Feature Development skill pack for Claude Code β 11-step pipeline with Complexity Router (S/M/L/XL), ADR-driven architecture, 15 agentic-qe skills, multi-agent fleet QE. Supports --full-qe, --full-qe-extended, --with-learning, and --knowledge-extractor modes.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"skills-feature-adr": "./bin/cli.js"
|
|
@@ -83,3 +83,31 @@ After completion:
|
|
|
83
83
|
- Code changes live in the actual codebase (not just in `features/`)
|
|
84
84
|
- `features/<slug>/` contains the design artifacts (ADRs, diagrams, reports)
|
|
85
85
|
- These artifacts serve as documentation for the feature
|
|
86
|
+
## The cost-of-detection ladder (place every check on its cheapest reliable layer)
|
|
87
|
+
|
|
88
|
+
For every quality check the pipeline performs, put it on the **strongest layer that can express it**
|
|
89
|
+
(strong = cheap to run, deterministic, silent-proof). A miss almost always means a check lived one layer
|
|
90
|
+
too weak for its nature:
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
STRONGEST (cheap, catches 100%, no model needed)
|
|
94
|
+
1. CI / deterministic test wc -l cap, sha256 pin, grep-guard, dz guard rule
|
|
95
|
+
2. always-loaded role file architecture/*.md, project-critic β read EVERY run
|
|
96
|
+
3. pipeline step gate Step-8 QE, claim-check, discrimination-check, amendment gate
|
|
97
|
+
4. skill judgment "the reviewer will notice" β runs if invoked well
|
|
98
|
+
5. agent memory / vibes "I should remember toβ¦" β runs if recalled
|
|
99
|
+
WEAKEST (probabilistic, model-dependent, silent when it lapses)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Design rule when adding ANY new check:
|
|
103
|
+
- Deterministic (size, presence, absence, format) β a **repo test / dz guard rule** (layer 1).
|
|
104
|
+
- Structural-but-contextual (a named property must have a proving test) β a **step gate** with a
|
|
105
|
+
machine-checkable output (layer 3) β e.g. the ADR Confirmation link, the amendment gate,
|
|
106
|
+
`dz discrimination-check`.
|
|
107
|
+
- Semantic/adversarial (honesty, product-fit, exploitability) β a **review plane run by an independent
|
|
108
|
+
model** (layer 3, model-backed) β e.g. cross-model QE, challenge-panel. Never leave it to layer-4.
|
|
109
|
+
|
|
110
|
+
Anti-pattern: "the critic/QE agent will catch it" for anything a 5-line test could catch. Every such push
|
|
111
|
+
from layer 1 up to layer 4 turns a deterministic guarantee into a probabilistic one β a future silent miss.
|
|
112
|
+
(Origin: fa-improvements 2026-07-18 β a 700-line cap enforced by reviewer judgment caught one file and
|
|
113
|
+
missed its sibling in the same merge request; `wc -l` catches both, always.)
|
|
@@ -723,6 +723,33 @@ rollback semantics are lost; recovery becomes case-by-case repair.
|
|
|
723
723
|
operation, not inside its parts. If parts must commit separately,
|
|
724
724
|
name why and ensure each is independently retryable."
|
|
725
725
|
|
|
726
|
+
### AP14. I/O added to a previously-pure path without a negative resource-down test (HIGH)
|
|
727
|
+
|
|
728
|
+
**Principle:** a change that introduces I/O (DB, network, file) into a
|
|
729
|
+
previously I/O-free path β especially startup/lifespan/health β must
|
|
730
|
+
carry a negative resource-down test proving the declared degradation
|
|
731
|
+
contract (fail-open for advisory, explicit fail-fast for load-bearing),
|
|
732
|
+
not only a happy-path test.
|
|
733
|
+
|
|
734
|
+
**Detection cue:** the code diff adds a DB/network/file call to a
|
|
735
|
+
module that previously imported no I/O; the TEST diff replaces a
|
|
736
|
+
broken/unbound fixture with a healthy one (fixture-swap β the old
|
|
737
|
+
fixture was likely a negative control) with no compensating
|
|
738
|
+
resource-down test; a new I/O call in a startup path has no
|
|
739
|
+
try/except and no test with a dead resource handle.
|
|
740
|
+
|
|
741
|
+
**FP exception:** the path already performed I/O (the change only adds
|
|
742
|
+
another call of the same kind); the new call is wrapped and a negative
|
|
743
|
+
test exists elsewhere covering the same contract (name it).
|
|
744
|
+
|
|
745
|
+
**Why bad:** a resource outage takes down the whole path β including
|
|
746
|
+
health checks β for the sake of the new feature; healthy test fixtures
|
|
747
|
+
hide exactly this case, so it surfaces first in production.
|
|
748
|
+
|
|
749
|
+
**Suggestion direction:** "Keep both tests: healthy fixture (new
|
|
750
|
+
behavior) + broken fixture (degradation contract). State the contract:
|
|
751
|
+
fail-open or fail-fast β and prove it with a dead resource handle."
|
|
752
|
+
|
|
726
753
|
---
|
|
727
754
|
|
|
728
755
|
## Section E. Type / contract issues
|
|
@@ -583,6 +583,23 @@ boundary (validator + retry, normalizer) β not a fourth, sterner
|
|
|
583
583
|
prompt. Models also send `null` where the schema says `"none"` β
|
|
584
584
|
tolerate real model behavior at the parsing boundary.
|
|
585
585
|
|
|
586
|
+
### P25. I/O added to a previously-pure path needs a negative resource-down test
|
|
587
|
+
|
|
588
|
+
If your change introduces I/O (DB, network, file) into a path that was
|
|
589
|
+
previously I/O-free β above all a startup, lifespan, or health path β
|
|
590
|
+
the happy-path test is not enough. Also write the NEGATIVE test: a
|
|
591
|
+
broken/unbound resource handle β the path degrades per its declared
|
|
592
|
+
contract (fail-open for an advisory feature, explicit fail-fast for a
|
|
593
|
+
load-bearing one). Otherwise an outage of that resource takes down the
|
|
594
|
+
whole path β including health checks β for the sake of an advisory
|
|
595
|
+
feature, and healthy fixtures will hide it until production.
|
|
596
|
+
|
|
597
|
+
Corollary β the fixture-swap smell: if making new code pass required
|
|
598
|
+
replacing a "broken" test fixture with a healthy one, stop. The old
|
|
599
|
+
fixture was probably a negative control proving the path was I/O-free.
|
|
600
|
+
Keep BOTH tests (healthy = new behavior, broken = degradation
|
|
601
|
+
contract); never silently delete the case that proved the old property.
|
|
602
|
+
|
|
586
603
|
---
|
|
587
604
|
|
|
588
605
|
## Section 7. Decision discipline
|
|
@@ -589,6 +589,7 @@ npx @dzhechkov/skills-feature-adr init --with-learning --knowledge-extractor
|
|
|
589
589
|
<promise>[PROMISE_TAG]</promise>
|
|
590
590
|
Tier: {COMPLEXITY_TIER} | Active Steps: {ACTIVE_STEPS}
|
|
591
591
|
π Learning: {recalled} patterns recalled for this feature, {stored} new stored this run
|
|
592
|
+
π¦ Gates: challenge-panel β Β· claim-check β Β· discrimination not-run Β· amendments β Β· fleet β
|
|
592
593
|
|
|
593
594
|
[2-3 line summary]
|
|
594
595
|
Artifacts: [list] β
|
|
@@ -598,3 +599,16 @@ Artifacts: [list] β
|
|
|
598
599
|
β’ "[feedback]" β adjust
|
|
599
600
|
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
600
601
|
```
|
|
602
|
+
|
|
603
|
+
### The π¦ Gates line (mandatory, DERIVED β never asserted from memory)
|
|
604
|
+
|
|
605
|
+
Every checkpoint banner carries a `π¦ Gates:` line listing each gate relevant to the run so far. Symbols:
|
|
606
|
+
`β` ran and passed Β· `β` ran and failed Β· `not-run` pending Β· `β` N/A for this tier/slice (say why once).
|
|
607
|
+
Each value is **derived from machine-checkable state** β an artifact's existence, a command's JSON verdict, a
|
|
608
|
+
test result β never from what the orchestrator remembers doing. The line does not make a gate run; it makes
|
|
609
|
+
NOT running one loud: a skipped gate shows as `not-run` by construction instead of being silently forgotten
|
|
610
|
+
(cost-of-detection ladder: the banner is the one surface emitted at EVERY step boundary, so strapping the
|
|
611
|
+
checklist to it is the cheapest way to harden orchestrator judgment). Gate sources: challenge-panel β its
|
|
612
|
+
verdict exists; claim-check β its JSON counts (`high-findings` vs `clean`); discrimination β the
|
|
613
|
+
`dz discrimination-check` aggregate; amendments β every `AM-N` row carries its `β test` and it was checked;
|
|
614
|
+
fleet β the 09 artifact (L/XL only, else `β`).
|
|
@@ -119,7 +119,8 @@ After all agents complete, apply decision logic:
|
|
|
119
119
|
| Critical Risks | > 2 | 1-2 | 0 |
|
|
120
120
|
|
|
121
121
|
- **NO-GO**: BLOCK. Requirements/ADR need rework. Return to Step 1 or Step 3.
|
|
122
|
-
- **CONDITIONAL**: Proceed with warnings.
|
|
122
|
+
- **CONDITIONAL**: Proceed with warnings. Each condition becomes an **amendment row** in a `## Amendments`
|
|
123
|
+
section (see below) β not loose advisory prose.
|
|
123
124
|
- **GO**: Full confidence. Proceed to Step 6.
|
|
124
125
|
|
|
125
126
|
### 5. Synthesis Report
|
|
@@ -132,6 +133,26 @@ Generate consolidated `03.5_ideation_report.md` with:
|
|
|
132
133
|
5. Test ideas (categorized: unit / integration / E2E)
|
|
133
134
|
6. Conditional agent findings (if any)
|
|
134
135
|
7. Recommendations prioritized by risk Γ impact
|
|
136
|
+
8. `## Amendments` β on a CONDITIONAL verdict, every condition as a fixed-shape row (see below)
|
|
137
|
+
|
|
138
|
+
### Amendment Confirmation discipline (every amendment is a mini-ADR)
|
|
139
|
+
|
|
140
|
+
Amendments are where the sharpest design corrections land β and, historically, the least-tested part of a
|
|
141
|
+
run: they arrive as prose AFTER the ADR's Confirmation discipline already ran, so a coder can implement one
|
|
142
|
+
with no test proving it works. Therefore every amendment carries a one-line **Confirmation**, in a fixed,
|
|
143
|
+
machine-checkable shape:
|
|
144
|
+
|
|
145
|
+
```
|
|
146
|
+
AM-N (source): <change>. Confirmation: <property> β test `test_name` (fails if reverted).
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
- `source` names where it came from (qcsd | challenge-panel | user-steer).
|
|
150
|
+
- The named test must FAIL if the amendment were reverted/broken (non-vacuous β Step 8 verifies via
|
|
151
|
+
`dz discrimination-check`).
|
|
152
|
+
- For a **safeguard** amendment (a warning/guard/fallback): the test must prove the safeguard actually
|
|
153
|
+
**TRIGGERS on a real input** β not merely that its code path exists. A structurally-dead safeguard passes
|
|
154
|
+
an existence test and never fires in production.
|
|
155
|
+
- A cheap lint holds the shape: every `AM-N` line must contain a `β test ` token naming a test that exists.
|
|
135
156
|
|
|
136
157
|
## Output
|
|
137
158
|
|
|
@@ -149,6 +149,11 @@ Create `features/<slug>/06_implementation_plan.md` with:
|
|
|
149
149
|
- Parallel groups
|
|
150
150
|
- Checkpoint schedule
|
|
151
151
|
- Risk assessment (L/XL)
|
|
152
|
+
- `## Amendments` β every correction folded into this plan (a Step-3.5 CONDITIONAL condition, a
|
|
153
|
+
challenge-panel confirmed finding, a user checkpoint steer) as a fixed-shape row:
|
|
154
|
+
`AM-N (source): <change>. Confirmation: <property> β test `test_name` (fails if reverted).`
|
|
155
|
+
A safeguard amendment's named test must prove it TRIGGERS on a real input, not merely that its code
|
|
156
|
+
path exists. Step 8 verifies every named test exists and is non-vacuous (`dz discrimination-check`).
|
|
152
157
|
|
|
153
158
|
Set `{IMPL_PLAN}` variable.
|
|
154
159
|
|
|
@@ -31,6 +31,24 @@ Before writing any code:
|
|
|
31
31
|
- [ ] Identify import patterns and module structure
|
|
32
32
|
- [ ] Identify error handling patterns
|
|
33
33
|
- [ ] Identify test patterns
|
|
34
|
+
- [ ] Plan carries `## Amendments`? β implement every AM-N row AND its named Confirmation test (a
|
|
35
|
+
safeguard amendment needs a test proving it FIRES on a real input)
|
|
36
|
+
- [ ] Does the diff add I/O (DB/network/file) to a previously-pure path β especially
|
|
37
|
+
startup/lifespan/health? β name the NEGATIVE resource-down test, or justify N/A
|
|
38
|
+
|
|
39
|
+
### The I/O-on-pure-path rule (and the fixture-swap smell)
|
|
40
|
+
|
|
41
|
+
If a change introduces I/O into a path that was previously I/O-free β above all a startup, lifespan, or
|
|
42
|
+
health path β the happy-path test is NOT enough. Also write a **negative resource-down test**: a
|
|
43
|
+
broken/unbound resource handle (dead DB, missing table, exhausted pool) β the path degrades per its
|
|
44
|
+
declared contract β **fail-open** for an advisory feature, **explicit fail-fast** for a load-bearing one.
|
|
45
|
+
Without it, an outage of the resource takes down the whole path (including health checks) for the sake of
|
|
46
|
+
an advisory feature β and healthy test fixtures will hide it.
|
|
47
|
+
|
|
48
|
+
**Fixture-swap smell:** if making the new code pass required replacing a "broken" test fixture with a
|
|
49
|
+
healthy one β stop. The old fixture was probably a negative control proving the path was I/O-free. Keep
|
|
50
|
+
BOTH tests: the healthy one (new behavior) and the broken one (degradation contract). Never silently
|
|
51
|
+
delete the case that proved the old property.
|
|
34
52
|
|
|
35
53
|
### 2. Execute Tasks per Plan
|
|
36
54
|
|
|
@@ -158,6 +158,30 @@ Reject explainer-masquerading-as-ADR: if the document describes a problem space
|
|
|
158
158
|
|
|
159
159
|
The Confirmation-to-test link is load-bearing. If absent, grade no better than C and record a blocker gap; for architecture dependency/layering/interface rules, recommend an ArchUnit or ArchUnitTS fitness function.
|
|
160
160
|
|
|
161
|
+
### 3b. Amendment Gate (P2 β amendments inherit the Confirmation discipline)
|
|
162
|
+
|
|
163
|
+
Read the `## Amendments` sections of `03.5_ideation_report.md` and `06_implementation_plan.md` (skip
|
|
164
|
+
silently if absent). For EVERY `AM-N` row verify:
|
|
165
|
+
1. the row contains a `β test ` token naming a real test (the fixed shape);
|
|
166
|
+
2. the named test **exists** in the suite;
|
|
167
|
+
3. it is **non-vacuous** β include the amendment test files in the SAME
|
|
168
|
+
`dz discrimination-check --test <f1,f2,...> --base HEAD --json` run as the ADR property test. An
|
|
169
|
+
amendment test that stays green at pre-feature base proves nothing about its amendment;
|
|
170
|
+
4. a **safeguard** amendment's test proves the safeguard FIRES on a real input (a structurally-dead
|
|
171
|
+
safeguard passes an existence test and never fires in production).
|
|
172
|
+
|
|
173
|
+
A missing, unnamed, or vacuous amendment test is a HIGH gap. This closes the distance between "we caught
|
|
174
|
+
the design flaw" (challenge-panel/QCSD) and "we proved the fix works".
|
|
175
|
+
|
|
176
|
+
### 3c. I/O-on-pure-path + fixture-swap hunt (P5)
|
|
177
|
+
|
|
178
|
+
In the TEST diff, hunt for replacements of broken/unbound fixtures with healthy ones β the old fixture was
|
|
179
|
+
probably a **negative control** proving a path was I/O-free; each such swap requires a compensating
|
|
180
|
+
negative resource-down test. In the CODE diff, hunt for new I/O (DB/network/file) on previously-pure
|
|
181
|
+
paths β especially startup/lifespan/health: require a negative resource-down test (broken resource β the
|
|
182
|
+
path degrades per its declared contract: fail-open for advisory, explicit fail-fast for load-bearing).
|
|
183
|
+
Missing β HIGH gap.
|
|
184
|
+
|
|
161
185
|
### 4. Multi-Agent Review Panel (L/XL)
|
|
162
186
|
|
|
163
187
|
For L/XL features, spawn 3 parallel review agents using brutal-honesty modes:
|
|
@@ -560,6 +560,14 @@ const ADR_FITNESS_CHECKLIST = 'ADR fitness checklist for Step 8: read every ' +
|
|
|
560
560
|
// an auto-abort (dz's rule: a false gate kills trust). Byte-inlined guidance; the safe worktree/run lives in `dz
|
|
561
561
|
// discrimination-check` (harness-core/src/discrimination-gate.ts).
|
|
562
562
|
const DISCRIMINATION_GATE = 'Β§42 TEST-DISCRIMINATION GATE (run right after asserting the property has a test): the ADR Confirmation names `Required automated check: <test file>` for the load-bearing property. Prove that test DISCRIMINATES, not just that it is green β via Bash run EXACTLY `dz discrimination-check --test <that test file> --base HEAD --json` (the Step-7 feature diff is UNCOMMITTED, so HEAD is the pre-feature base). It runs the property test in an isolated git worktree at HEAD (no feature diff) and reports {aggregate, finding}. Parse it: `NON_DISCRIMINATING` = the test PASSES even without the fix (a false green that would stay green if the property regressed) β record a HIGH gap "property test does not discriminate: <file>" but do NOT drop the grade to a blocker on that alone (advisory β the owner decides). `DISCRIMINATES` (red by assertion) and `DISCRIMINATES_VIA_ERROR` (could not load at base β inferred, note it) both PASS. `CANNOT_ISOLATE` folds into the existing "property untested" finding. Record the verdict in the 08_qe_report.md ADR Fitness section. If `dz discrimination-check` is unavailable, note it and continue β never block on the tool.'
|
|
563
|
+
// P2 (amendment-confirmation-discipline, fa-improvements 2026-07-18): amendments are where the SHARPEST design
|
|
564
|
+
// corrections land (challenge-panel/QCSD) and were the least-tested β prose deltas with no proving test. Every
|
|
565
|
+
// amendment is a mini-ADR: it carries a one-line Confirmation naming the test that falsifies it. Machine-checkable
|
|
566
|
+
// shape (a linter can assert the `β test ` token); Step-8 verifies existence + non-vacuity via the SAME
|
|
567
|
+
// dz discrimination-check that guards the ADR property (cost-of-detection ladder: judgment β step gate).
|
|
568
|
+
const AMENDMENT_RULE = 'AMENDMENT CONFIRMATION DISCIPLINE (every amendment is a mini-ADR): whenever a correction/amendment is folded in (a QCSD CONDITIONAL condition, a challenge-panel confirmed finding, or a user checkpoint steer), record it in a `## Amendments` section as a fixed-shape row: `AM-N (source): <change>. Confirmation: <property> β test `test_name` (fails if reverted).` β naming the test that would FAIL if the amendment were reverted/broken. For a SAFEGUARD amendment (a warning/guard/fallback), the named test must prove the safeguard actually TRIGGERS on a real input β not merely that its code path exists (a structurally-dead safeguard passes an existence test and never fires in production).'
|
|
569
|
+
const AMENDMENT_GATE = 'AMENDMENT GATE (P2): read the `## Amendments` sections of ' + FDIR + '/03.5_ideation_report.md and ' + FDIR + '/06_implementation_plan.md (skip silently if absent). EVERY `AM-N` row must contain a `β test ` token naming a real test. Verify: (a) the named test EXISTS in the suite; (b) it is NON-VACUOUS β include the amendment test files in the SAME `dz discrimination-check --test <f1,f2,...> --base HEAD --json` run as the ADR property test (an amendment test that stays green at pre-feature base proves nothing); (c) a safeguard amendment\'s test proves the safeguard FIRES on a real input. A missing, unnamed, or vacuous amendment test is a HIGH gap. ' +
|
|
570
|
+
'IO-ON-PURE-PATH + FIXTURE-SWAP HUNT (P5): in the test diff, hunt for replacements of broken/unbound fixtures with healthy ones β the old fixture was probably a NEGATIVE CONTROL proving a path was I/O-free; each such swap requires a compensating negative resource-down test. If the code diff adds I/O (DB/network/file) to a previously-pure path β especially startup/lifespan/health β require a negative resource-down test (broken/unbound resource β the path degrades per its declared contract: fail-open for advisory, explicit fail-fast for load-bearing). Missing β HIGH gap.'
|
|
563
571
|
|
|
564
572
|
// Step 0: Router + MANDATORY self-learning recall
|
|
565
573
|
phase('Router')
|
|
@@ -656,7 +664,7 @@ modelsUsed.ddd = modelLabel(archOpts)
|
|
|
656
664
|
designThunks.push(() => designStage('Step 1 (Requirements)' + (isLplus ? ' + Step 2 (Research)' : '') + ' of /feature-adr for "' + DESC + '" (tier ' + tier + ', slug ' + SLUG + '). Code: ' + CODE_HINT + '. APPLY these Step-0 recalled LEARNED PATTERNS (fold the applicable ones into requirements/constraints - the loop paying off): ' + LEARNED + '. Write ' + FDIR + '/01_requirements.md (functional + non-functional requirements, acceptance criteria, constraints, and an "Applied learned patterns" note).' + reqExtra + ' Return wrote[] + a 1-line summary.' + PS_GUIDANCE('design'), reqOpts, FDIR + '/01_requirements.md', 'requirements'))
|
|
657
665
|
if (isMplus) {
|
|
658
666
|
designThunks.push(() => designStage('Step 3 (ADR + shift-left testability) of /feature-adr for "' + DESC + '" (' + SLUG + '). READ the actual code (' + CODE_HINT + ') to ground it. ' + ADR_TEMPLATE_GUIDE + ' Write ' + FDIR + '/03_adr/001-' + SLUG + '.md as a MADR-structured ADR that PASSES the Step-8 ADR fitness checklist (do NOT emit the legacy shape). Emit ALL of these sections, in order: a decision-shaped # Title (present-tense imperative verb β the auto-filename tracks the feature slug, so the IMPERATIVE signal lives in the title); ## Status (proposed/accepted/rejected/deprecated/superseded + a reversibility/revisit clause); ## Context (neutral, problem-first, BEFORE the Decision); ## Decision Drivers (ranked/weighted D1, D2, β¦); ## Considered Options (frame the CHOSEN approach as one option ALONGSIDE the rejected ones, each with symmetric Pros:/Cons:); ## Decision (concrete/testable β exact names, versions, paths, commands); ## Rationale (map each point to a driver Dn + why the losers lost); ## Consequences (Positive + Negative/Accepted Downsides + Follow-up ADRs + After-action Review with owner + date); a REQUIRED ## Confirmation stanza with Method:, Monitoring:, Success metric:, Owner:, Load-bearing property:, and Required automated check: `<test file>` NAMING the load-bearing property that MUST have a Step-8 test (the recurring lesson: the key safety property is often the untested one); and a ## Links traceability block (requirements, driving use case, related ADRs). Add a one-line provenance note (model-generated, edited for clarity) and, for a long ADR, a top-of-file table of contents. Do NOT use an "Alternatives considered" or "Testability/shift-left" heading in place of Considered Options / Confirmation. When creating ADDITIONAL ADRs, name them 03_adr/NNN-{decision-slug}.md with a lowercase-kebab, present-tense imperative, dateless, ticketless slug. Return wrote[] + summary.', adrOpts, FDIR + '/03_adr/001-' + SLUG + '.md', 'adr'))
|
|
659
|
-
designThunks.push(() => designStage('Step 3.5 (QCSD ideation swarm - HTSM quality criteria + SFDIPOT risk) of /feature-adr for "' + DESC + '" (' + SLUG + '). Assess quality criteria + product-factors risk. Write ' + FDIR + '/03.5_ideation_report.md with a GO/CONDITIONAL/NO-GO verdict + top quality risks for QE. Return wrote[] + summary.', qcsdOpts, FDIR + '/03.5_ideation_report.md', 'qcsd'))
|
|
667
|
+
designThunks.push(() => designStage('Step 3.5 (QCSD ideation swarm - HTSM quality criteria + SFDIPOT risk) of /feature-adr for "' + DESC + '" (' + SLUG + '). Assess quality criteria + product-factors risk. Write ' + FDIR + '/03.5_ideation_report.md with a GO/CONDITIONAL/NO-GO verdict + top quality risks for QE. On a CONDITIONAL verdict, write each condition as an amendment row in a `## Amendments` section. ' + AMENDMENT_RULE + ' Return wrote[] + summary.', qcsdOpts, FDIR + '/03.5_ideation_report.md', 'qcsd'))
|
|
660
668
|
const archExtra = isLplus ? ' Also ' + FDIR + '/04_domain_model.md (DDD).' : ''
|
|
661
669
|
designThunks.push(() => designStage((isLplus ? 'Step 4 (DDD) + ' : '') + 'Step 5 (Architecture) of /feature-adr for "' + DESC + '" (' + SLUG + '). READ the code. Write ' + FDIR + '/05_architecture.md (components, data flow, integration points, the emit/merge/wiring shape).' + archExtra + ' Return wrote[] + summary.', archOpts, FDIR + '/05_architecture.md', 'architecture'))
|
|
662
670
|
}
|
|
@@ -668,7 +676,7 @@ const design = await parallel(designThunks)
|
|
|
668
676
|
// unavailable/errors β the pipeline never blocks on Codex.
|
|
669
677
|
phase('Plan')
|
|
670
678
|
await usageProbe('Plan')
|
|
671
|
-
const planPrompt = 'Step 6 (SPARC-GOAP implementation plan) of /feature-adr for "' + DESC + '" (' + SLUG + ', tier ' + tier + '). Given the requirements + ADR + architecture in ' + FDIR + ', decompose into milestones + concrete tasks with success metrics. Write ' + FDIR + '/06_implementation_plan.md. Return wrote[] + summary.' + ABSOLUTE_PATH_NOTE
|
|
679
|
+
const planPrompt = 'Step 6 (SPARC-GOAP implementation plan) of /feature-adr for "' + DESC + '" (' + SLUG + ', tier ' + tier + '). Given the requirements + ADR + architecture in ' + FDIR + ', decompose into milestones + concrete tasks with success metrics. Write ' + FDIR + '/06_implementation_plan.md. If any corrections from Step 3.5 (a CONDITIONAL verdict) or other sources are folded into this plan, carry them in a `## Amendments` section. ' + AMENDMENT_RULE + ' Return wrote[] + summary.' + ABSOLUTE_PATH_NOTE
|
|
672
680
|
// Resolve the plan model. args.models.plan wins; else the planner:'codex' knob (via routingRequested +
|
|
673
681
|
// DEFAULT_MODELS/coder-fold) or the DEFAULT_MODELS.plan ('sonnet') under routing; else {} (BC).
|
|
674
682
|
const planModel = resolveStageModel('plan')
|
|
@@ -779,13 +787,16 @@ if (stopHere) {
|
|
|
779
787
|
let challengeVerdict = null
|
|
780
788
|
try { challengeVerdict = plan ? await runChallengePanel('features/' + SLUG + '/06_implementation_plan.md', plan.planner) : null }
|
|
781
789
|
catch (e) { log('Challenge panel errored (advisory, ignored): ' + (e && e.message ? e.message : String(e))) }
|
|
782
|
-
|
|
790
|
+
// P4 (checkpoint-gate-line): a DERIVED gates map β each entry comes from machine state (artifact/verdict
|
|
791
|
+
// presence), never from prose, so a skipped gate shows as 'not-run' instead of being silently forgotten.
|
|
792
|
+
const planGates = { plan: (plan ? 'produced' : 'missing'), challengePanel: (challengeVerdict ? 'ran' : 'not-run'), code: 'not-run', qe: 'not-run' }
|
|
793
|
+
return { tier: tier, phase: 'checkpoint-after-plan', artifactsDir: FDIR, planner: (plan ? plan.planner : null), plan: (plan ? plan.summary : null), modelsUsed: plannedModels, challengeVerdict: challengeVerdict, gates: planGates, usageEvents: usageEvents, usageThreshold: USAGE_THRESHOLD, polymorphism: POLY.hasManifest ? POLY.report : null, note: 'L/XL checkpoint - review the ADR + plan (+ the planned code/qe/fleet models) + the challenge panel verdict (advisory) + the gates line, then re-invoke with args.stopAfter="none" to implement + QE. Present the gates map as a `π¦ Gates:` line in the checkpoint banner.' }
|
|
783
794
|
}
|
|
784
795
|
|
|
785
796
|
// Step 7: Code (optional Codex fallback on Claude-limit exhaustion)
|
|
786
797
|
phase('Code')
|
|
787
798
|
await usageProbe('Code')
|
|
788
|
-
const codePrompt = 'Step 7 (Code) of /feature-adr for "' + DESC + '" (' + SLUG + '). Implement the feature per the plan + ADR + architecture in ' + FDIR + '. Write the ACTUAL production code + its tests (mirror the closest existing implementation named in research/architecture). Follow repo conventions; build must pass. Write a change manifest ' + FDIR + '/07_code_changes/change_manifest.md listing every file touched. Return wrote[] (incl. real source files) + summary.' + ABSOLUTE_PATH_NOTE + PS_GUIDANCE('code')
|
|
799
|
+
const codePrompt = 'Step 7 (Code) of /feature-adr for "' + DESC + '" (' + SLUG + '). Implement the feature per the plan + ADR + architecture in ' + FDIR + '. Write the ACTUAL production code + its tests (mirror the closest existing implementation named in research/architecture). If the plan carries a `## Amendments` section, implement every AM-N row AND its named Confirmation test (for a safeguard amendment: a test proving it FIRES on a real input). IO-ON-PURE-PATH RULE: if your diff adds I/O (DB/network/file) to a previously-pure path β especially a startup/lifespan/health path β also write a NEGATIVE resource-down test (broken/unbound resource handle β the path degrades per its declared contract: fail-open for an advisory feature, explicit fail-fast for a load-bearing one) alongside the happy-path test; never fix a failing test by swapping a broken fixture for a healthy one without keeping BOTH cases. Follow repo conventions; build must pass. Write a change manifest ' + FDIR + '/07_code_changes/change_manifest.md listing every file touched. Return wrote[] (incl. real source files) + summary.' + ABSOLUTE_PATH_NOTE + PS_GUIDANCE('code')
|
|
789
800
|
// Resolve the coder model. args.models.code wins (a direct 'codex' spec = codex-first); else the legacy
|
|
790
801
|
// CODER knob drives it (with its codex-fallback null-guard). resolveStageModel('code') folds both via the
|
|
791
802
|
// code:null sentinel β resolveCoderSpec(). A Claude resolution merges {model} onto the Claude branch;
|
|
@@ -827,7 +838,7 @@ if (needsCodeLandedBarrier(coderUsed)) {
|
|
|
827
838
|
// Step 8: QE (brutal-honesty, agentic-qe) + MANDATORY teach
|
|
828
839
|
phase('QE')
|
|
829
840
|
await usageProbe('QE')
|
|
830
|
-
const qePrompt = 'Step 8 (QE - brutal-honesty review, agentic-qe) of /feature-adr for "' + DESC + '" (' + SLUG + '). Adversarially review the SHIPPED code (read it): correctness, edge cases, error handling, and the LOAD-BEARING property the ADR named (ASSERT it has a test - the recurring lesson). Run this ADR gate before final grading: ' + ADR_FITNESS_CHECKLIST + ' ' + DISCRIMINATION_GATE + ' Grade A/B/C/D honestly. Assess code-test adequacy + doc-test presence. List CONFIRMED gaps with severity. Write ' + FDIR + '/08_qe_report.md with an ADR Fitness Checklist section showing PASS/FAIL per ADR and evidence for the Confirmation-linked test. MANDATORY SELF-LEARNING STORE (close the loop, never skip): compare every candidate lesson against the Step-0 recalled LEARNED patterns above. Teach ONLY lessons NOT covered by Step-0 recall. On overlap, run `dz teach --reinforce "<recalled pattern id or exact text>" --project ' + BRAIN + '` instead of minting a near-duplicate; if --reinforce is unavailable, skip the duplicate teach and report `reinforced existing pattern <id>` in the QE report. Store every genuinely new lesson in the CANONICAL BRAIN store at `' + BRAIN + '` so it is NOT lost to a target repo you may have cd`d into. Via Bash run EXACTLY `' + DZ_TEACH('<a durable reusable lesson from this feature - a rule/pattern/pitfall, NOT a checkpoint echo>', '<0.7-0.95>', '<area>') + '` for each genuine NEW lesson (1-3 max, high-signal) β the `cd ' + BRAIN + ' &&` prefix + `--project ' + BRAIN + '` pin guarantee the lesson lands in the brain regardless of your CWD. Then run `' + DZ + ' statusline --fa-record --slug ' + SLUG + ' --step "Step 8 QE" --recalled 3 --stored <count taught> --reinforced <count reinforced> --mode ' + MODE + ' --project ' + REPO + '` (run it verbatim via Bash, do not skip). Do NOT teach trivia or invent gaps. AUTHORING-TIME CLAIM-CHECK (Deliverable of claim-check-authoring-time): after writing ' + FDIR + '/08_qe_report.md, run EXACTLY `dz claim-check ' + FDIR + '/08_qe_report.md --json --fail-on none` via Bash, parse the {ok, findings, scanned} JSON, and report claimCheck: {findings: N, high: N, medium: N} (counts by severity) in your return object. TAG EVERY QUANTITATIVE CLAIM you write in the report using the convention the checker recognizes as honest β write "1131 tests pass (MEASURED β `npx vitest run`)", never a bare "1131 tests pass" β and where you QUOTE a forbidden phrase as an example (e.g. the retracted "100% passing" framing), backtick the literal so it reads as code, not an assertion, so your own compliant report scans clean. Return {grade, gaps, codeTestsAdequate, docTestsPresent, claimCheck}.' + ABSOLUTE_PATH_NOTE + landedNote + PS_GUIDANCE('qe')
|
|
841
|
+
const qePrompt = 'Step 8 (QE - brutal-honesty review, agentic-qe) of /feature-adr for "' + DESC + '" (' + SLUG + '). Adversarially review the SHIPPED code (read it): correctness, edge cases, error handling, and the LOAD-BEARING property the ADR named (ASSERT it has a test - the recurring lesson). Run this ADR gate before final grading: ' + ADR_FITNESS_CHECKLIST + ' ' + DISCRIMINATION_GATE + ' ' + AMENDMENT_GATE + ' Grade A/B/C/D honestly. Assess code-test adequacy + doc-test presence. List CONFIRMED gaps with severity. Write ' + FDIR + '/08_qe_report.md with an ADR Fitness Checklist section showing PASS/FAIL per ADR and evidence for the Confirmation-linked test. MANDATORY SELF-LEARNING STORE (close the loop, never skip): compare every candidate lesson against the Step-0 recalled LEARNED patterns above. Teach ONLY lessons NOT covered by Step-0 recall. On overlap, run `dz teach --reinforce "<recalled pattern id or exact text>" --project ' + BRAIN + '` instead of minting a near-duplicate; if --reinforce is unavailable, skip the duplicate teach and report `reinforced existing pattern <id>` in the QE report. Store every genuinely new lesson in the CANONICAL BRAIN store at `' + BRAIN + '` so it is NOT lost to a target repo you may have cd`d into. Via Bash run EXACTLY `' + DZ_TEACH('<a durable reusable lesson from this feature - a rule/pattern/pitfall, NOT a checkpoint echo>', '<0.7-0.95>', '<area>') + '` for each genuine NEW lesson (1-3 max, high-signal) β the `cd ' + BRAIN + ' &&` prefix + `--project ' + BRAIN + '` pin guarantee the lesson lands in the brain regardless of your CWD. Then run `' + DZ + ' statusline --fa-record --slug ' + SLUG + ' --step "Step 8 QE" --recalled 3 --stored <count taught> --reinforced <count reinforced> --mode ' + MODE + ' --project ' + REPO + '` (run it verbatim via Bash, do not skip). Do NOT teach trivia or invent gaps. AUTHORING-TIME CLAIM-CHECK (Deliverable of claim-check-authoring-time): after writing ' + FDIR + '/08_qe_report.md, run EXACTLY `dz claim-check ' + FDIR + '/08_qe_report.md --json --fail-on none` via Bash, parse the {ok, findings, scanned} JSON, and report claimCheck: {findings: N, high: N, medium: N} (counts by severity) in your return object. TAG EVERY QUANTITATIVE CLAIM you write in the report using the convention the checker recognizes as honest β write "1131 tests pass (MEASURED β `npx vitest run`)", never a bare "1131 tests pass" β and where you QUOTE a forbidden phrase as an example (e.g. the retracted "100% passing" framing), backtick the literal so it reads as code, not an assertion, so your own compliant report scans clean. Return {grade, gaps, codeTestsAdequate, docTestsPresent, claimCheck}.' + ABSOLUTE_PATH_NOTE + landedNote + PS_GUIDANCE('qe')
|
|
831
842
|
// CROSS-MODEL QE (load-bearing): resolveStageModel('qe') derives the OTHER family than the resolved
|
|
832
843
|
// coder when args.models.qe is unset (coder-codex β opus; coder-Claude β codex, or opus if codex absent).
|
|
833
844
|
// An explicit args.models.qe wins. A Claude qe spec is merged onto the qe-code-reviewer base (role
|
|
@@ -974,5 +985,12 @@ return {
|
|
|
974
985
|
polymorphism: POLY.hasManifest ? POLY.report : null,
|
|
975
986
|
claimGate: claimGate,
|
|
976
987
|
autoCost: Object.keys(AUTOCOST).length ? AUTOCOST : null,
|
|
988
|
+
// P4 (checkpoint-gate-line): DERIVED gate map for the final banner β from actual run state, never prose.
|
|
989
|
+
gates: {
|
|
990
|
+
code: (code ? 'produced' : 'missing'),
|
|
991
|
+
qe: (qe ? (qe.grade || 'ran') : 'not-run'),
|
|
992
|
+
claimCheck: (qe && qe.claimCheck ? (qe.claimCheck.high > 0 ? 'high-findings' : 'clean') : 'not-run'),
|
|
993
|
+
fleet: (isLplus ? (fleet ? 'ran' : 'not-run') : 'n/a'),
|
|
994
|
+
},
|
|
977
995
|
promiseTags: tags,
|
|
978
996
|
}
|