@dzhechkov/skills-feature-adr 1.3.66 → 1.3.67
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/.dz-manifest.json +12 -12
- package/README.md +35 -0
- package/package.json +1 -1
- package/sbom.json +11 -11
- package/templates/.claude/skills/feature-adr/SKILL.md +9 -0
- package/templates/.claude/skills/feature-adr/modules/01-requirements.md +26 -0
- package/templates/.claude/skills/feature-adr/modules/02-research.md +26 -0
- package/templates/.claude/skills/feature-adr/modules/03-adr.md +26 -0
- package/templates/.claude/skills/feature-adr/modules/03.5-ideation-swarm.md +25 -0
- package/templates/.claude/skills/feature-adr/modules/04-ddd.md +25 -0
- package/templates/.claude/skills/feature-adr/modules/05-architecture.md +26 -0
- package/templates/.claude/skills/feature-adr/modules/06-implementation-plan.md +26 -0
- package/templates/.claude/workflows/feature-adr.js +19 -5
package/.dz-manifest.json
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
},
|
|
14
14
|
{
|
|
15
15
|
"path": "README.md",
|
|
16
|
-
"sha256": "
|
|
16
|
+
"sha256": "1d123dcb15ac44b9adfe8266cb72d2dc69d5086f54003540795296c36e06e1b2"
|
|
17
17
|
},
|
|
18
18
|
{
|
|
19
19
|
"path": "bin/cli.js",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
},
|
|
26
26
|
{
|
|
27
27
|
"path": "package.json",
|
|
28
|
-
"sha256": "
|
|
28
|
+
"sha256": "31de034ec7534b585ee99a2dac0105bc4e43dca0c5b419076e66c43e797509d3"
|
|
29
29
|
},
|
|
30
30
|
{
|
|
31
31
|
"path": "scripts/sync-templates.js",
|
|
@@ -121,7 +121,7 @@
|
|
|
121
121
|
},
|
|
122
122
|
{
|
|
123
123
|
"path": "templates/.claude/skills/feature-adr/SKILL.md",
|
|
124
|
-
"sha256": "
|
|
124
|
+
"sha256": "bdedfed69d985eb6969f158a72d92f63c6b1b993008c3661f7ffc2c6a7ccfbae"
|
|
125
125
|
},
|
|
126
126
|
{
|
|
127
127
|
"path": "templates/.claude/skills/feature-adr/examples/sample-feature-output.md",
|
|
@@ -133,31 +133,31 @@
|
|
|
133
133
|
},
|
|
134
134
|
{
|
|
135
135
|
"path": "templates/.claude/skills/feature-adr/modules/01-requirements.md",
|
|
136
|
-
"sha256": "
|
|
136
|
+
"sha256": "e6ea3a224b555d5b7410cf2ddf02a3fb8d009fa01109463353e2b993c318270c"
|
|
137
137
|
},
|
|
138
138
|
{
|
|
139
139
|
"path": "templates/.claude/skills/feature-adr/modules/02-research.md",
|
|
140
|
-
"sha256": "
|
|
140
|
+
"sha256": "e2506e42251c74485188473acc4586f841afbec3ae7c5eaa8a3d8f73f6e14cc5"
|
|
141
141
|
},
|
|
142
142
|
{
|
|
143
143
|
"path": "templates/.claude/skills/feature-adr/modules/03-adr.md",
|
|
144
|
-
"sha256": "
|
|
144
|
+
"sha256": "ea03eee136c89267888b8034baa1a1cb0057314a2e745df71654a9ebee5d46b6"
|
|
145
145
|
},
|
|
146
146
|
{
|
|
147
147
|
"path": "templates/.claude/skills/feature-adr/modules/03.5-ideation-swarm.md",
|
|
148
|
-
"sha256": "
|
|
148
|
+
"sha256": "d48a8d6eebf9760cc8f1a4f19df0e6afc31fcc1284b5eacfb604ad8ced6a0b53"
|
|
149
149
|
},
|
|
150
150
|
{
|
|
151
151
|
"path": "templates/.claude/skills/feature-adr/modules/04-ddd.md",
|
|
152
|
-
"sha256": "
|
|
152
|
+
"sha256": "e9504cf1183bc0105167dc06108860882941fcf1b5be79d1978d8212c410ffbb"
|
|
153
153
|
},
|
|
154
154
|
{
|
|
155
155
|
"path": "templates/.claude/skills/feature-adr/modules/05-architecture.md",
|
|
156
|
-
"sha256": "
|
|
156
|
+
"sha256": "2ef7cf316903f0cbb1fabe1f0e1770c22b2cb3a11a4118cac0529c25074b5e8a"
|
|
157
157
|
},
|
|
158
158
|
{
|
|
159
159
|
"path": "templates/.claude/skills/feature-adr/modules/06-implementation-plan.md",
|
|
160
|
-
"sha256": "
|
|
160
|
+
"sha256": "c8fdd1877d8d9515ab29f52c3db49ddd9612b5797bc071e6208def860c02e6f2"
|
|
161
161
|
},
|
|
162
162
|
{
|
|
163
163
|
"path": "templates/.claude/skills/feature-adr/modules/07-code.md",
|
|
@@ -321,7 +321,7 @@
|
|
|
321
321
|
},
|
|
322
322
|
{
|
|
323
323
|
"path": "templates/.claude/workflows/feature-adr.js",
|
|
324
|
-
"sha256": "
|
|
324
|
+
"sha256": "d9cda8df501188c894d083c5c44c240c9ebe9ba7e2d418302c448d73b089e051"
|
|
325
325
|
},
|
|
326
326
|
{
|
|
327
327
|
"path": "templates/lib/memory-protocol.md",
|
|
@@ -349,5 +349,5 @@
|
|
|
349
349
|
}
|
|
350
350
|
]
|
|
351
351
|
},
|
|
352
|
-
"signature": "
|
|
352
|
+
"signature": "ZnkOOhYGfaIEp1W5L/Gphs0uniT0FieL/yn5KPl6cZ3zQeXkZcqDjfOta9b6zmPEgztZAclspZ0yf82VnjeHBQ=="
|
|
353
353
|
}
|
package/README.md
CHANGED
|
@@ -878,3 +878,38 @@ them inside the package's own monorepo is almost never what you want anyway.
|
|
|
878
878
|
- **npm:** [https://www.npmjs.com/package/@dzhechkov/skills-feature-adr](https://www.npmjs.com/package/@dzhechkov/skills-feature-adr)
|
|
879
879
|
- **Keysarium:** [https://www.npmjs.com/package/@dzhechkov/keysarium](https://www.npmjs.com/package/@dzhechkov/keysarium)
|
|
880
880
|
- **BTO:** [https://www.npmjs.com/package/@dzhechkov/skills-bto](https://www.npmjs.com/package/@dzhechkov/skills-bto)
|
|
881
|
+
|
|
882
|
+
## Write discipline — why the writing steps now build a skeleton first
|
|
883
|
+
|
|
884
|
+
MEASURED in the field on 2026-08-19 and 2026-08-20, two independent runs of the canonical pipeline
|
|
885
|
+
against a ~130-file repository: the steps that must produce a document — Step 5 (Architecture) and
|
|
886
|
+
Step 6 (Plan) — **never reached a write**. 18 attempts, zero file writes in every one. They died in
|
|
887
|
+
the READING phase: a shell result returns, the agent thinks about its next move, stays silent past
|
|
888
|
+
the runtime's 180-second inactivity watchdog, and is killed. One run cost ~4M tokens and 1h54m.
|
|
889
|
+
|
|
890
|
+
The failure is **deterministic, not unlucky**: thinking time grows with accumulated history, so on a
|
|
891
|
+
large enough repository unbounded exploration guarantees the kill. And the cause was in the
|
|
892
|
+
instructions, not the runtime — every writing step said, in effect, *"read the code, write the
|
|
893
|
+
document"*, with no reading budget and no order of operations. An agent obeying literally reads
|
|
894
|
+
until it dies.
|
|
895
|
+
|
|
896
|
+
The owner's control experiment is the whole evidence base, and it is n=1: same slice, same inputs,
|
|
897
|
+
same model, ONE added paragraph about write discipline → a 10-section skeleton on disk 8 minutes in,
|
|
898
|
+
first attempt, after six consecutive deaths.
|
|
899
|
+
|
|
900
|
+
So every document-producing step now carries:
|
|
901
|
+
|
|
902
|
+
1. the FIRST file write happens within the first ~12 tool calls — a skeleton of section headings
|
|
903
|
+
with one line of intent under each;
|
|
904
|
+
2. then fill it **one section per edit**, no edit longer than ~120 lines;
|
|
905
|
+
3. never go more than 2 minutes without a tool call;
|
|
906
|
+
4. when unsure whether to read more or to write — **write**.
|
|
907
|
+
|
|
908
|
+
**What this does not do**, stated plainly: it does not stop the deaths. The watchdog is unchanged.
|
|
909
|
+
It changes what survives one — previously nothing, now a skeleton on disk that the next attempt can
|
|
910
|
+
continue. The `~12` and `~120` are chosen parameters, not measured optima. Two possible regressions
|
|
911
|
+
were named by an independent reviewer and are **not measured**: an early skeleton may anchor a
|
|
912
|
+
structure chosen before understanding, and section-per-edit raises tool-call overhead.
|
|
913
|
+
|
|
914
|
+
Steps whose deliverable is a returned verdict rather than a document (the complexity router) are
|
|
915
|
+
deliberately excluded — "skeleton first" is nonsense there.
|
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.67",
|
|
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"
|
package/sbom.json
CHANGED
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"hashes": [
|
|
36
36
|
{
|
|
37
37
|
"alg": "SHA-256",
|
|
38
|
-
"content": "
|
|
38
|
+
"content": "1d123dcb15ac44b9adfe8266cb72d2dc69d5086f54003540795296c36e06e1b2"
|
|
39
39
|
}
|
|
40
40
|
]
|
|
41
41
|
},
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"hashes": [
|
|
66
66
|
{
|
|
67
67
|
"alg": "SHA-256",
|
|
68
|
-
"content": "
|
|
68
|
+
"content": "31de034ec7534b585ee99a2dac0105bc4e43dca0c5b419076e66c43e797509d3"
|
|
69
69
|
}
|
|
70
70
|
]
|
|
71
71
|
},
|
|
@@ -305,7 +305,7 @@
|
|
|
305
305
|
"hashes": [
|
|
306
306
|
{
|
|
307
307
|
"alg": "SHA-256",
|
|
308
|
-
"content": "
|
|
308
|
+
"content": "bdedfed69d985eb6969f158a72d92f63c6b1b993008c3661f7ffc2c6a7ccfbae"
|
|
309
309
|
}
|
|
310
310
|
]
|
|
311
311
|
},
|
|
@@ -335,7 +335,7 @@
|
|
|
335
335
|
"hashes": [
|
|
336
336
|
{
|
|
337
337
|
"alg": "SHA-256",
|
|
338
|
-
"content": "
|
|
338
|
+
"content": "e6ea3a224b555d5b7410cf2ddf02a3fb8d009fa01109463353e2b993c318270c"
|
|
339
339
|
}
|
|
340
340
|
]
|
|
341
341
|
},
|
|
@@ -345,7 +345,7 @@
|
|
|
345
345
|
"hashes": [
|
|
346
346
|
{
|
|
347
347
|
"alg": "SHA-256",
|
|
348
|
-
"content": "
|
|
348
|
+
"content": "e2506e42251c74485188473acc4586f841afbec3ae7c5eaa8a3d8f73f6e14cc5"
|
|
349
349
|
}
|
|
350
350
|
]
|
|
351
351
|
},
|
|
@@ -355,7 +355,7 @@
|
|
|
355
355
|
"hashes": [
|
|
356
356
|
{
|
|
357
357
|
"alg": "SHA-256",
|
|
358
|
-
"content": "
|
|
358
|
+
"content": "ea03eee136c89267888b8034baa1a1cb0057314a2e745df71654a9ebee5d46b6"
|
|
359
359
|
}
|
|
360
360
|
]
|
|
361
361
|
},
|
|
@@ -365,7 +365,7 @@
|
|
|
365
365
|
"hashes": [
|
|
366
366
|
{
|
|
367
367
|
"alg": "SHA-256",
|
|
368
|
-
"content": "
|
|
368
|
+
"content": "d48a8d6eebf9760cc8f1a4f19df0e6afc31fcc1284b5eacfb604ad8ced6a0b53"
|
|
369
369
|
}
|
|
370
370
|
]
|
|
371
371
|
},
|
|
@@ -375,7 +375,7 @@
|
|
|
375
375
|
"hashes": [
|
|
376
376
|
{
|
|
377
377
|
"alg": "SHA-256",
|
|
378
|
-
"content": "
|
|
378
|
+
"content": "e9504cf1183bc0105167dc06108860882941fcf1b5be79d1978d8212c410ffbb"
|
|
379
379
|
}
|
|
380
380
|
]
|
|
381
381
|
},
|
|
@@ -385,7 +385,7 @@
|
|
|
385
385
|
"hashes": [
|
|
386
386
|
{
|
|
387
387
|
"alg": "SHA-256",
|
|
388
|
-
"content": "
|
|
388
|
+
"content": "2ef7cf316903f0cbb1fabe1f0e1770c22b2cb3a11a4118cac0529c25074b5e8a"
|
|
389
389
|
}
|
|
390
390
|
]
|
|
391
391
|
},
|
|
@@ -395,7 +395,7 @@
|
|
|
395
395
|
"hashes": [
|
|
396
396
|
{
|
|
397
397
|
"alg": "SHA-256",
|
|
398
|
-
"content": "
|
|
398
|
+
"content": "c8fdd1877d8d9515ab29f52c3db49ddd9612b5797bc071e6208def860c02e6f2"
|
|
399
399
|
}
|
|
400
400
|
]
|
|
401
401
|
},
|
|
@@ -805,7 +805,7 @@
|
|
|
805
805
|
"hashes": [
|
|
806
806
|
{
|
|
807
807
|
"alg": "SHA-256",
|
|
808
|
-
"content": "
|
|
808
|
+
"content": "d9cda8df501188c894d083c5c44c240c9ebe9ba7e2d418302c448d73b089e051"
|
|
809
809
|
}
|
|
810
810
|
]
|
|
811
811
|
},
|
|
@@ -226,6 +226,14 @@ Execute protocol
|
|
|
226
226
|
→ Checkpoint N
|
|
227
227
|
```
|
|
228
228
|
|
|
229
|
+
**Write discipline — applies to EVERY step that produces a document.** Open the step's artifact within
|
|
230
|
+
your first ~12 tool calls as a SKELETON (its section headings, one line of intent each), then fill it one
|
|
231
|
+
section per edit, no edit longer than ~120 lines. Never go more than 2 minutes without a tool call, and
|
|
232
|
+
when you are unsure whether to read more or to write, WRITE. Reason: an executor silent for 180 seconds is
|
|
233
|
+
killed by the runtime, and thinking time grows with accumulated history — so unbounded exploration before
|
|
234
|
+
the first write is a deterministic death on a large repo, not bad luck. Each module restates this under
|
|
235
|
+
its own `## Write discipline (the 180-second rule)` heading.
|
|
236
|
+
|
|
229
237
|
### 4. Final Verification
|
|
230
238
|
After Step 8 (or Step 9 for L/XL) completes, verify:
|
|
231
239
|
- All mandatory artifacts exist per tier
|
|
@@ -616,6 +624,7 @@ npx @dzhechkov/skills-feature-adr init --with-learning --knowledge-extractor
|
|
|
616
624
|
| Ignore NO-GO verdict | Proceed despite Step 3.5 NO-GO | BLOCK — rework required |
|
|
617
625
|
| Skip gap loop | No gap detection in Step 8 | Missing requirements coverage check |
|
|
618
626
|
| Skip fleet QE for L/XL | No Step 9 for large features | BLOCK — fleet assessment mandatory |
|
|
627
|
+
| Unbounded reading before the first write | The step's artifact still does not exist after ~12 tool calls | BLOCK — write the skeleton now; a silent executor is killed at 180 s |
|
|
619
628
|
|
|
620
629
|
## Checkpoint Format
|
|
621
630
|
|
|
@@ -77,6 +77,32 @@ Explicitly state:
|
|
|
77
77
|
- **Dependencies:** What must exist before this feature works
|
|
78
78
|
- **Dependents:** What will break if this feature changes
|
|
79
79
|
|
|
80
|
+
## Write discipline (the 180-second rule)
|
|
81
|
+
|
|
82
|
+
An executor that returns from a tool call and then thinks in silence past **180 seconds** is killed by the
|
|
83
|
+
runtime. Thinking time grows with the history already accumulated, so on a large repo "read everything,
|
|
84
|
+
then write the document" is not a risk — it is a deterministic death, and nothing survives it, because
|
|
85
|
+
nothing was ever on disk.
|
|
86
|
+
|
|
87
|
+
MEASURED on this harness: the writing steps died **18 times out of 18** in the reading phase without ever
|
|
88
|
+
writing a file. The control — same slice, same model, one added instruction to write a skeleton early —
|
|
89
|
+
landed the skeleton 8 minutes in, on the first attempt, after six consecutive deaths.
|
|
90
|
+
|
|
91
|
+
So, in this step:
|
|
92
|
+
|
|
93
|
+
1. **Skeleton first — inside your first ~12 tool calls.** Write `features/<slug>/01_requirements.md` containing only the headings this step
|
|
94
|
+
requires (Stakeholders · Functional requirements · Non-functional requirements · Constraints ·
|
|
95
|
+
Scope boundaries · Open questions), one line of intent under each. (S-tier is inline and has no
|
|
96
|
+
file — this section does not apply to it.)
|
|
97
|
+
2. **Then fill it one section per edit.** No single edit longer than ~120 lines. Every edit leaves the
|
|
98
|
+
file readable; none of them is allowed to wait for the section after it.
|
|
99
|
+
3. **Never go more than 2 minutes without a tool call.** A thought that is getting long is the signal to
|
|
100
|
+
stop and write what you have — an edit is a checkpoint, not an interruption.
|
|
101
|
+
4. **When you are unsure whether to read more or to write, WRITE.** A thin section refined later survives;
|
|
102
|
+
a perfect section you never reached does not.
|
|
103
|
+
|
|
104
|
+
The skeleton is not a draft to apologise for. It is the artifact, opened early.
|
|
105
|
+
|
|
80
106
|
## Output
|
|
81
107
|
|
|
82
108
|
### For S-tier (inline)
|
|
@@ -73,6 +73,32 @@ Alternative considered: [Y], rejected because [reasons].
|
|
|
73
73
|
|
|
74
74
|
After both complete, synthesize results sequentially.
|
|
75
75
|
|
|
76
|
+
## Write discipline (the 180-second rule)
|
|
77
|
+
|
|
78
|
+
An executor that returns from a tool call and then thinks in silence past **180 seconds** is killed by the
|
|
79
|
+
runtime. Thinking time grows with the history already accumulated, so on a large repo "read everything,
|
|
80
|
+
then write the document" is not a risk — it is a deterministic death, and nothing survives it, because
|
|
81
|
+
nothing was ever on disk.
|
|
82
|
+
|
|
83
|
+
MEASURED on this harness: the writing steps died **18 times out of 18** in the reading phase without ever
|
|
84
|
+
writing a file. The control — same slice, same model, one added instruction to write a skeleton early —
|
|
85
|
+
landed the skeleton 8 minutes in, on the first attempt, after six consecutive deaths.
|
|
86
|
+
|
|
87
|
+
So, in this step:
|
|
88
|
+
|
|
89
|
+
1. **Skeleton first — inside your first ~12 tool calls.** Write `features/<slug>/02_research.md` containing only the headings this step
|
|
90
|
+
requires (Codebase patterns · External patterns · Library evaluation · Anti-patterns ·
|
|
91
|
+
Recommended approach), one line of intent under each — before the research agents report back,
|
|
92
|
+
not after.
|
|
93
|
+
2. **Then fill it one section per edit.** No single edit longer than ~120 lines. Every edit leaves the
|
|
94
|
+
file readable; none of them is allowed to wait for the section after it.
|
|
95
|
+
3. **Never go more than 2 minutes without a tool call.** A thought that is getting long is the signal to
|
|
96
|
+
stop and write what you have — an edit is a checkpoint, not an interruption.
|
|
97
|
+
4. **When you are unsure whether to read more or to write, WRITE.** A thin section refined later survives;
|
|
98
|
+
a perfect section you never reached does not.
|
|
99
|
+
|
|
100
|
+
The skeleton is not a draft to apologise for. It is the artifact, opened early.
|
|
101
|
+
|
|
76
102
|
## Output
|
|
77
103
|
|
|
78
104
|
Create `features/<slug>/02_research.md` with:
|
|
@@ -167,6 +167,32 @@ Each ADR must trace back to specific requirements:
|
|
|
167
167
|
| Placeholder text | Template hints or TODOs remain | Remove or fill before checkpoint |
|
|
168
168
|
| Supersession in-place | Existing ADR rewritten | Mint a new ADR and link it |
|
|
169
169
|
|
|
170
|
+
## Write discipline (the 180-second rule)
|
|
171
|
+
|
|
172
|
+
An executor that returns from a tool call and then thinks in silence past **180 seconds** is killed by the
|
|
173
|
+
runtime. Thinking time grows with the history already accumulated, so on a large repo "read everything,
|
|
174
|
+
then write the document" is not a risk — it is a deterministic death, and nothing survives it, because
|
|
175
|
+
nothing was ever on disk.
|
|
176
|
+
|
|
177
|
+
MEASURED on this harness: the writing steps died **18 times out of 18** in the reading phase without ever
|
|
178
|
+
writing a file. The control — same slice, same model, one added instruction to write a skeleton early —
|
|
179
|
+
landed the skeleton 8 minutes in, on the first attempt, after six consecutive deaths.
|
|
180
|
+
|
|
181
|
+
So, in this step:
|
|
182
|
+
|
|
183
|
+
1. **Skeleton first — inside your first ~12 tool calls.** For each decision you have identified, write
|
|
184
|
+
`features/<slug>/03_adr/NNN-{decision-slug}.md` containing only the invariant-core headings
|
|
185
|
+
(Status · Context · Decision Drivers · Considered Options · Decision · Rationale · Consequences ·
|
|
186
|
+
Confirmation), one line of intent under each. A named-but-empty option beats an unwritten ADR.
|
|
187
|
+
2. **Then fill it one section per edit.** No single edit longer than ~120 lines. Every edit leaves the
|
|
188
|
+
file readable; none of them is allowed to wait for the section after it.
|
|
189
|
+
3. **Never go more than 2 minutes without a tool call.** A thought that is getting long is the signal to
|
|
190
|
+
stop and write what you have — an edit is a checkpoint, not an interruption.
|
|
191
|
+
4. **When you are unsure whether to read more or to write, WRITE.** A thin section refined later survives;
|
|
192
|
+
a perfect section you never reached does not.
|
|
193
|
+
|
|
194
|
+
The skeleton is not a draft to apologise for. It is the artifact, opened early.
|
|
195
|
+
|
|
170
196
|
## Output
|
|
171
197
|
|
|
172
198
|
Create `features/<slug>/03_adr/` directory with:
|
|
@@ -154,6 +154,31 @@ AM-N (source): <change>. Confirmation: <property> → test `test_name` (fails if
|
|
|
154
154
|
an existence test and never fires in production.
|
|
155
155
|
- A cheap lint holds the shape: every `AM-N` line must contain a `→ test ` token naming a test that exists.
|
|
156
156
|
|
|
157
|
+
## Write discipline (the 180-second rule)
|
|
158
|
+
|
|
159
|
+
An executor that returns from a tool call and then thinks in silence past **180 seconds** is killed by the
|
|
160
|
+
runtime. Thinking time grows with the history already accumulated, so on a large repo "read everything,
|
|
161
|
+
then write the document" is not a risk — it is a deterministic death, and nothing survives it, because
|
|
162
|
+
nothing was ever on disk.
|
|
163
|
+
|
|
164
|
+
MEASURED on this harness: the writing steps died **18 times out of 18** in the reading phase without ever
|
|
165
|
+
writing a file. The control — same slice, same model, one added instruction to write a skeleton early —
|
|
166
|
+
landed the skeleton 8 minutes in, on the first attempt, after six consecutive deaths.
|
|
167
|
+
|
|
168
|
+
So, in this step:
|
|
169
|
+
|
|
170
|
+
1. **Skeleton first — inside your first ~12 tool calls.** Write `features/<slug>/03.5_ideation_report.md` containing only the eight
|
|
171
|
+
section headings of §5 (Executive summary … Amendments), one line of intent under each — while
|
|
172
|
+
the swarm is still running, not after every agent has returned.
|
|
173
|
+
2. **Then fill it one section per edit.** No single edit longer than ~120 lines. Every edit leaves the
|
|
174
|
+
file readable; none of them is allowed to wait for the section after it.
|
|
175
|
+
3. **Never go more than 2 minutes without a tool call.** A thought that is getting long is the signal to
|
|
176
|
+
stop and write what you have — an edit is a checkpoint, not an interruption.
|
|
177
|
+
4. **When you are unsure whether to read more or to write, WRITE.** A thin section refined later survives;
|
|
178
|
+
a perfect section you never reached does not.
|
|
179
|
+
|
|
180
|
+
The skeleton is not a draft to apologise for. It is the artifact, opened early.
|
|
181
|
+
|
|
157
182
|
## Output
|
|
158
183
|
|
|
159
184
|
Create `features/<slug>/03.5_ideation_report.md` with full QCSD report.
|
|
@@ -92,6 +92,31 @@ Check that proposed domain model is compatible with existing code:
|
|
|
92
92
|
- Can aggregates be implemented with existing ORM/framework?
|
|
93
93
|
- Do relationships align with existing data access patterns?
|
|
94
94
|
|
|
95
|
+
## Write discipline (the 180-second rule)
|
|
96
|
+
|
|
97
|
+
An executor that returns from a tool call and then thinks in silence past **180 seconds** is killed by the
|
|
98
|
+
runtime. Thinking time grows with the history already accumulated, so on a large repo "read everything,
|
|
99
|
+
then write the document" is not a risk — it is a deterministic death, and nothing survives it, because
|
|
100
|
+
nothing was ever on disk.
|
|
101
|
+
|
|
102
|
+
MEASURED on this harness: the writing steps died **18 times out of 18** in the reading phase without ever
|
|
103
|
+
writing a file. The control — same slice, same model, one added instruction to write a skeleton early —
|
|
104
|
+
landed the skeleton 8 minutes in, on the first attempt, after six consecutive deaths.
|
|
105
|
+
|
|
106
|
+
So, in this step:
|
|
107
|
+
|
|
108
|
+
1. **Skeleton first — inside your first ~12 tool calls.** Write `features/<slug>/04_domain_model.md` containing only the headings this step
|
|
109
|
+
requires (Bounded context map · Ubiquitous language · Aggregates/Entities/VOs · Relationships ·
|
|
110
|
+
Codebase mapping), one line of intent under each.
|
|
111
|
+
2. **Then fill it one section per edit.** No single edit longer than ~120 lines. Every edit leaves the
|
|
112
|
+
file readable; none of them is allowed to wait for the section after it.
|
|
113
|
+
3. **Never go more than 2 minutes without a tool call.** A thought that is getting long is the signal to
|
|
114
|
+
stop and write what you have — an edit is a checkpoint, not an interruption.
|
|
115
|
+
4. **When you are unsure whether to read more or to write, WRITE.** A thin section refined later survives;
|
|
116
|
+
a perfect section you never reached does not.
|
|
117
|
+
|
|
118
|
+
The skeleton is not a draft to apologise for. It is the artifact, opened early.
|
|
119
|
+
|
|
95
120
|
## Output
|
|
96
121
|
|
|
97
122
|
Create `features/<slug>/04_domain_model.md` with:
|
|
@@ -118,6 +118,32 @@ GET /api/v1/{resource}/:id
|
|
|
118
118
|
Errors: 401, 404
|
|
119
119
|
```
|
|
120
120
|
|
|
121
|
+
## Write discipline (the 180-second rule)
|
|
122
|
+
|
|
123
|
+
An executor that returns from a tool call and then thinks in silence past **180 seconds** is killed by the
|
|
124
|
+
runtime. Thinking time grows with the history already accumulated, so on a large repo "read everything,
|
|
125
|
+
then write the document" is not a risk — it is a deterministic death, and nothing survives it, because
|
|
126
|
+
nothing was ever on disk.
|
|
127
|
+
|
|
128
|
+
MEASURED on this harness: the writing steps died **18 times out of 18** in the reading phase without ever
|
|
129
|
+
writing a file. The control — same slice, same model, one added instruction to write a skeleton early —
|
|
130
|
+
landed the skeleton 8 minutes in, on the first attempt, after six consecutive deaths.
|
|
131
|
+
|
|
132
|
+
So, in this step:
|
|
133
|
+
|
|
134
|
+
1. **Skeleton first — inside your first ~12 tool calls.** Write `features/<slug>/05_architecture.md` containing only the headings this step
|
|
135
|
+
requires at your tier (C4 Context · C4 Container · C4 Component · Sequence flows · Data & storage ·
|
|
136
|
+
API design), one line of intent under each. An empty `mermaid` fence with a caption is a
|
|
137
|
+
heading; fill it later.
|
|
138
|
+
2. **Then fill it one section per edit.** No single edit longer than ~120 lines. Every edit leaves the
|
|
139
|
+
file readable; none of them is allowed to wait for the section after it.
|
|
140
|
+
3. **Never go more than 2 minutes without a tool call.** A thought that is getting long is the signal to
|
|
141
|
+
stop and write what you have — an edit is a checkpoint, not an interruption.
|
|
142
|
+
4. **When you are unsure whether to read more or to write, WRITE.** A thin section refined later survives;
|
|
143
|
+
a perfect section you never reached does not.
|
|
144
|
+
|
|
145
|
+
The skeleton is not a draft to apologise for. It is the artifact, opened early.
|
|
146
|
+
|
|
121
147
|
## Output
|
|
122
148
|
|
|
123
149
|
### M-tier
|
|
@@ -135,6 +135,32 @@ Before finalizing the plan, validate completeness:
|
|
|
135
135
|
|
|
136
136
|
This gap-check loop ensures the implementation plan is complete before coding begins.
|
|
137
137
|
|
|
138
|
+
## Write discipline (the 180-second rule)
|
|
139
|
+
|
|
140
|
+
An executor that returns from a tool call and then thinks in silence past **180 seconds** is killed by the
|
|
141
|
+
runtime. Thinking time grows with the history already accumulated, so on a large repo "read everything,
|
|
142
|
+
then write the document" is not a risk — it is a deterministic death, and nothing survives it, because
|
|
143
|
+
nothing was ever on disk.
|
|
144
|
+
|
|
145
|
+
MEASURED on this harness: the writing steps died **18 times out of 18** in the reading phase without ever
|
|
146
|
+
writing a file. The control — same slice, same model, one added instruction to write a skeleton early —
|
|
147
|
+
landed the skeleton 8 minutes in, on the first attempt, after six consecutive deaths.
|
|
148
|
+
|
|
149
|
+
So, in this step:
|
|
150
|
+
|
|
151
|
+
1. **Skeleton first — inside your first ~12 tool calls.** Write `features/<slug>/06_implementation_plan.md` containing only the headings
|
|
152
|
+
this step requires (Goal state · Tasks · Dependency order · Parallel groups · Checkpoints · Risk
|
|
153
|
+
assessment · Amendments · `EXPECTED_CODE_TARGETS:`), one line of intent under each. The K2 gate
|
|
154
|
+
reads this file — a plan that lives only in the conversation cannot pass it.
|
|
155
|
+
2. **Then fill it one section per edit.** No single edit longer than ~120 lines. Every edit leaves the
|
|
156
|
+
file readable; none of them is allowed to wait for the section after it.
|
|
157
|
+
3. **Never go more than 2 minutes without a tool call.** A thought that is getting long is the signal to
|
|
158
|
+
stop and write what you have — an edit is a checkpoint, not an interruption.
|
|
159
|
+
4. **When you are unsure whether to read more or to write, WRITE.** A thin section refined later survives;
|
|
160
|
+
a perfect section you never reached does not.
|
|
161
|
+
|
|
162
|
+
The skeleton is not a draft to apologise for. It is the artifact, opened early.
|
|
163
|
+
|
|
138
164
|
## Output
|
|
139
165
|
|
|
140
166
|
### S-tier (minimal file — NOT inline-only)
|
|
@@ -44,6 +44,20 @@ function absolutizeRepo(raw, cwd) {
|
|
|
44
44
|
}
|
|
45
45
|
const ABSOLUTE_PATH_NOTE = ' All artifact paths in this prompt are ABSOLUTE. Read and write them exactly as given; do not cd first and do not re-relativize them.'
|
|
46
46
|
|
|
47
|
+
// WRITE DISCIPLINE — the anti-watchdog clause for every step whose DELIVERABLE IS A DOCUMENT.
|
|
48
|
+
// MEASURED (field report P14, two independent runs, agent journals on disk): Steps 5 and 6 never
|
|
49
|
+
// reached a single write — 18/18 attempts ended with FILE_WRITES=0, all of them killed inside the
|
|
50
|
+
// READING phase after >180 s of silence between tool calls; ~4M tokens and 1h54m per run bought
|
|
51
|
+
// nothing. Thinking time grows with accumulated history, so on a large repo this is DETERMINISTIC,
|
|
52
|
+
// not unlucky. The prompts said 'READ the code. Write <file>' with no reading budget and no order of
|
|
53
|
+
// operations, and the executor obeyed literally. Control experiment (owner, same slice/inputs/model,
|
|
54
|
+
// ONE added paragraph on write discipline): a 10-section skeleton landed 8 minutes in, on the FIRST
|
|
55
|
+
// attempt, after six consecutive deaths. One variable changed, opposite outcome. NOT CLAIMED: that
|
|
56
|
+
// this removes the watchdog class — it is a layer-4 prompt instruction, so it is probabilistic by
|
|
57
|
+
// construction; the deterministic half is the layer-1 test that this clause is PRESENT in every
|
|
58
|
+
// writing-step prompt (harness-core/test/feature-adr-write-discipline.test.ts).
|
|
59
|
+
const WRITE_DISCIPLINE = ' WRITE DISCIPLINE (mandatory, not advice). 1. Your FIRST file write must happen within your first 12 tool calls: create the SKELETON of the artifact — every section heading plus one line of intent under each. 2. Then fill it in ONE SECTION PER EDIT; no single edit longer than ~120 lines. 3. Never go more than 2 minutes without a tool call. 4. If you are unsure whether to read more or to write, WRITE. Reason: an executor that shows no activity for 180 seconds is KILLED by the runtime, so unbounded exploration before the first write makes the step die having written nothing at all.'
|
|
60
|
+
|
|
47
61
|
const UNSAFE_PATH_CHARS = /[\u0000-\u001f\u007f]/
|
|
48
62
|
const DOT_DOT_SEGMENT = /(^|\/)\.\.(\/|$)/
|
|
49
63
|
function hasUnsafePathChars(p) { return UNSAFE_PATH_CHARS.test(String(p)) }
|
|
@@ -1450,19 +1464,19 @@ modelsUsed.ddd = modelLabel(archOpts)
|
|
|
1450
1464
|
// record the exact input each design agent received. designPairMeta[i] aligns with designThunks[i],
|
|
1451
1465
|
// which aligns with design[i] in the parallel result — one pair per design sub-stage.
|
|
1452
1466
|
const designPairMeta = []
|
|
1453
|
-
const reqPromptText = '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')
|
|
1467
|
+
const reqPromptText = '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') + WRITE_DISCIPLINE
|
|
1454
1468
|
designThunks.push(() => designStage(reqPromptText, reqOpts, FDIR + '/01_requirements.md', 'requirements'))
|
|
1455
1469
|
// the requirements prompt is where the Step-0 recalled lessons are INJECTED — recorded per pair
|
|
1456
1470
|
designPairMeta.push({ role: 'design:requirements', prompt: reqPromptText, model: modelLabel(reqOpts), lessons: (LEARNED && LEARNED !== 'none recalled') ? [String(LEARNED)] : [] })
|
|
1457
1471
|
if (isMplus) {
|
|
1458
|
-
const adrPromptText = '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.'
|
|
1472
|
+
const adrPromptText = '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.' + WRITE_DISCIPLINE
|
|
1459
1473
|
designThunks.push(() => designStage(adrPromptText, adrOpts, FDIR + '/03_adr/001-' + SLUG + '.md', 'adr'))
|
|
1460
1474
|
designPairMeta.push({ role: 'design:adr', prompt: adrPromptText, model: modelLabel(adrOpts), lessons: [] })
|
|
1461
|
-
const qcsdPromptText = '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.'
|
|
1475
|
+
const qcsdPromptText = '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.' + WRITE_DISCIPLINE
|
|
1462
1476
|
designThunks.push(() => designStage(qcsdPromptText, qcsdOpts, FDIR + '/03.5_ideation_report.md', 'qcsd'))
|
|
1463
1477
|
designPairMeta.push({ role: 'design:qcsd', prompt: qcsdPromptText, model: modelLabel(qcsdOpts), lessons: [] })
|
|
1464
1478
|
const archExtra = isLplus ? ' Also ' + FDIR + '/04_domain_model.md (DDD).' : ''
|
|
1465
|
-
const archPromptText = (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.'
|
|
1479
|
+
const archPromptText = (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.' + WRITE_DISCIPLINE
|
|
1466
1480
|
designThunks.push(() => designStage(archPromptText, archOpts, FDIR + '/05_architecture.md', 'architecture'))
|
|
1467
1481
|
designPairMeta.push({ role: 'design:architecture', prompt: archPromptText, model: modelLabel(archOpts), lessons: [] })
|
|
1468
1482
|
}
|
|
@@ -1487,7 +1501,7 @@ if (design) await capturePairs('design', 'Design', designPairMeta.map(function (
|
|
|
1487
1501
|
// unavailable/errors — the pipeline never blocks on Codex.
|
|
1488
1502
|
phase('Plan')
|
|
1489
1503
|
await usageProbe('Plan')
|
|
1490
|
-
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. END the plan with a trailing `EXPECTED_CODE_TARGETS:` block listing, one per line as `- <repo-relative path>`, EVERY production/test/config/doc file Step 7 is expected to create or modify. This block is machine-read by the Step-7.5 landing barrier: only paths it ESTABLISHES can ever count as landed, so an absent or unpollable block makes the barrier verdict INCONCLUSIVE. List only real targets outside features/, .dz/, .agentic-qe/ and roam/. 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
|
|
1504
|
+
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. END the plan with a trailing `EXPECTED_CODE_TARGETS:` block listing, one per line as `- <repo-relative path>`, EVERY production/test/config/doc file Step 7 is expected to create or modify. This block is machine-read by the Step-7.5 landing barrier: only paths it ESTABLISHES can ever count as landed, so an absent or unpollable block makes the barrier verdict INCONCLUSIVE. List only real targets outside features/, .dz/, .agentic-qe/ and roam/. 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 + WRITE_DISCIPLINE
|
|
1491
1505
|
// Resolve the plan model. args.models.plan wins; else the planner:'codex' knob (via routingRequested +
|
|
1492
1506
|
// DEFAULT_MODELS/coder-fold) or the DEFAULT_MODELS.plan ('sonnet') under routing; else {} (BC).
|
|
1493
1507
|
const planModel = resolveStageModel('plan')
|