@dzhechkov/skills-feature-adr 1.3.59 → 1.3.60

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 CHANGED
@@ -44,7 +44,7 @@ After installation, open Claude Code in your project directory and use `/feature
44
44
  | Component | Count | Description |
45
45
  |-----------|-------|-------------|
46
46
  | **Skill** | 1 | `feature-adr` — 11-step pipeline with complexity routing |
47
- | **Modules** | 11 | Steps 00-09 + 03.5: Router → Requirements → Research → ADR → QCSD → DDD → Architecture → Plan → Code → QE → Fleet QE |
47
+ | **Modules** | 12 | Steps 00-09 + 03.5 + opt-in 10: Router → Requirements → Research → ADR → QCSD → DDD → Architecture → Plan → Code → QE → Fleet QE → Delivery Gate (opt-in) |
48
48
  | **References** | 4+15 | Complexity matrix, ADR/C4/QE templates + 15 agentic-qe skill protocols |
49
49
  | **Examples** | 1 | Sample M-tier feature output |
50
50
  | **Command** | 1 | `/feature-adr` — orchestrator (supports `--full-qe` and `--full-qe-extended`) |
@@ -503,6 +503,26 @@ gate > reviewer judgment > memory). A miss usually means a check lived one layer
503
503
  Both forms carry all of it: the interactive skill (step modules + banner template) and the deterministic
504
504
  workflow (stage prompts + derived `gates` in its returns) — same shapes, same vocabulary.
505
505
 
506
+ ### Step 10 — Delivery Gate (opt-in, v1.3.60)
507
+
508
+ Step 8 reviews the code as the coder's counterpart; **Step 10 reviews the feature as a PUBLISHED entity** —
509
+ the landed diff, its docs, its claims. Four orthogonal planes run in parallel on the **cross-family of the
510
+ coder** (regressions ‖ security ‖ code-quality ‖ **product-honesty** — the plane Step 8 lacks: fabricated
511
+ completeness, features that do less than their description, misleading degradation text), every BLOCKER/HIGH
512
+ is cross-validated **by index**, and the result is a machine-checkable hand-off verdict in
513
+ `10_delivery_review.md` (`ready` ⇔ 0 BLOCKER + 0 unwaived HIGH).
514
+
515
+ ```js
516
+ Workflow({ scriptPath: '.claude/workflows/feature-adr.js',
517
+ args: { slug, description, tier: 'L', deliveryGate: true } }) // or models: { delivery: 'codex:gpt-5.5:high' }
518
+ ```
519
+
520
+ Extensibility guarantees (deliberate): **strictly opt-in** — no `deliveryGate`/`models.delivery` ⇒
521
+ byte-identical, zero agents, no artifact; **zero VCS-host specifics** — no merge-request/CI API calls; an
522
+ MR-flow project's extra criteria (`CI terminal`, `draft→ready`) are document rows the owner fills;
523
+ **advisory** — `hand-off: blocked` is a report, nothing auto-aborts, findings are NEVER auto-posted
524
+ anywhere. Promise tag `FEATURE_ADR_DELIVERY_GATED`; the `🚦 Gates:` line gains `delivery ready|blocked|n/a`.
525
+
506
526
  ### The `Model` / `Fable?` columns — read this before swapping models
507
527
 
508
528
  The `Model` column is the **default recommendation, fully overridable** — the routing rule is
package/bin/cli.js CHANGED
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dzhechkov/skills-feature-adr",
3
- "version": "1.3.59",
3
+ "version": "1.3.60",
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"
@@ -13,10 +13,6 @@
13
13
  "CHANGELOG.md",
14
14
  "docs/"
15
15
  ],
16
- "scripts": {
17
- "test": "node --test \"test/**/*.test.js\"",
18
- "prepack": "node -e \"const fs=require('fs');const bad=['.claude','.skills-feature-adr.json'].filter(p=>fs.existsSync(p));if(bad.length){console.error('prepack guard: stray init artifacts in package dir: '+bad.join(', ')+' — remove before packing');process.exit(1)}\""
19
- },
20
16
  "keywords": [
21
17
  "claude",
22
18
  "claude-code",
@@ -61,5 +57,8 @@
61
57
  },
62
58
  "publishConfig": {
63
59
  "access": "public"
60
+ },
61
+ "scripts": {
62
+ "test": "node --test \"test/**/*.test.js\""
64
63
  }
65
- }
64
+ }
@@ -53,7 +53,8 @@ Trigger on:
53
53
  │ ├── 06-implementation-plan.md ← Step 6: SPARC-GOAP planning (enhanced)
54
54
  │ ├── 07-code.md ← Step 7: Code generation
55
55
  │ ├── 08-qe.md ← Step 8: QE + brutal-honesty review (enhanced)
56
- └── 09-fleet-qe.md ← Step 9: Fleet QE assessment (NEW)
56
+ ├── 09-fleet-qe.md ← Step 9: Fleet QE assessment (NEW)
57
+ │ └── 10-delivery-gate.md ← Step 10: Delivery Gate (opt-in, post-implementation)
57
58
  ├── references/
58
59
  │ ├── complexity-matrix.md ← S/M/L/XL criteria & step activation
59
60
  │ ├── adr-template.md ← ADR document template
@@ -140,6 +141,7 @@ Step | S | M | L | XL | Model | Agentic QE Skill
140
141
  7 Code | ✓ | ✓ | ✓ | ✓ | opus | — |
141
142
  8 QE + Brutal Honesty | ✓ | ✓ | ✓ | ✓ | sonnet | brutal-honesty-review |
142
143
  9 Fleet QE Assessment | - | - | ✓ | ✓ | sonnet | qe-req-val + risk-based + integration + regression + coverage |
144
+ 10 Delivery Gate (OPT-IN) | o | o | o | o | cross-family of coder | 4 planes: regressions ‖ security ‖ code-quality ‖ product-honesty (o = runs only when explicitly requested; absent ⇒ byte-identical) |
143
145
  ```
144
146
 
145
147
  ## DAG Dependencies
@@ -271,6 +273,7 @@ features/<feature-slug>/
271
273
  | Step 7 | `<promise>FEATURE_ADR_IMPLEMENTED</promise>` |
272
274
  | Step 8 | `<promise>FEATURE_ADR_VERIFIED</promise>` |
273
275
  | Step 9 | `<promise>FEATURE_ADR_FLEET_VERIFIED</promise>` |
276
+ | Step 10 (opt-in) | `<promise>FEATURE_ADR_DELIVERY_GATED</promise>` |
274
277
 
275
278
  ## External Skills (loaded as needed)
276
279
 
@@ -589,7 +592,7 @@ npx @dzhechkov/skills-feature-adr init --with-learning --knowledge-extractor
589
592
  <promise>[PROMISE_TAG]</promise>
590
593
  Tier: {COMPLEXITY_TIER} | Active Steps: {ACTIVE_STEPS}
591
594
  🎓 Learning: {recalled} patterns recalled for this feature, {stored} new stored this run
592
- 🚦 Gates: challenge-panel ✓ · claim-check ✓ · discrimination not-run · amendments ✓ · fleet —
595
+ 🚦 Gates: challenge-panel ✓ · claim-check ✓ · discrimination not-run · amendments ✓ · fleet — · delivery n/a
593
596
 
594
597
  [2-3 line summary]
595
598
  Artifacts: [list] ✅
@@ -0,0 +1,63 @@
1
+ # Step 10: Delivery Gate (opt-in) — review the feature as a PUBLISHED ENTITY
2
+
3
+ > **Opt-in.** This step runs only when explicitly requested (the user asks for a delivery gate, or the
4
+ > workflow form receives `args.deliveryGate: true` / `args.models.delivery`). Absent ⇒ the pipeline is
5
+ > byte-identical to a run without Step 10 — no agents, no artifact.
6
+
7
+ ## Why a separate step (not more Step-8)
8
+
9
+ Step 8 reviews the code as the coder's counterpart — pre-hand-off, working-tree view. Step 10 reviews the
10
+ feature as a **published entity**: the landed diff, its docs and claims, its behavior as a consumer will
11
+ meet it. Its distinctive plane — **product honesty** — is absent from Step 8 entirely: fabricated
12
+ completeness (output presented as complete when a source was unavailable), a feature that does less than
13
+ its description, misleading user-facing text. Origin: a real incident where a 2-agent fresh-eyes pass said
14
+ SHIP and only the full multi-plane review found the fabricated-completeness and cap-violation defects.
15
+
16
+ ## Protocol
17
+
18
+ ### 1. Four orthogonal planes (parallel, cross-family of the coder)
19
+
20
+ Each plane reads `07_code_changes/change_manifest.md` + the actual changed files (+ `git diff` for anything
21
+ uncommitted), calibrating on `architecture/vision.md` / `architecture/degradations.md` **when present** (an
22
+ accepted degradation is NOT a finding) and staying generic when absent:
23
+
24
+ | Plane | Hunts |
25
+ |---|---|
26
+ | **Regressions** | broken consumers/contracts; NEW I/O on previously-pure startup/lifespan/health paths without a negative resource-down test; removed/weakened tests (fixture-swap); silent semantic changes to shared surfaces |
27
+ | **Security** | injection via interpolated paths/refs/commands; secrets in code/artifacts; path traversal/symlink escapes; fail-open where the contract says fail-closed |
28
+ | **Code quality** | god-object growth; parallel implementations vs the reuse map; structurally-dead safeguards; swallowed errors |
29
+ | **Product honesty + common sense** | claims not backed by behavior; fabricated completeness; docs/READMEs promising more than the code does; misleading degradation/limits text |
30
+
31
+ Findings shape: `{severity: BLOCKER|HIGH|MED|LOW, title, where (file:line), why}` — confirmed only.
32
+
33
+ ### 2. Cross-validation (BLOCKER/HIGH, by index)
34
+
35
+ Every BLOCKER/HIGH is independently cross-validated by a second agent, matched **positionally by index —
36
+ never by title** (duplicate titles cross-contaminate). Default-to-FP when uncertain. A validator outage
37
+ surfaces the findings **UNVALIDATED** — never silently dropped, never silently confirmed.
38
+
39
+ ### 3. Machine-checkable hand-off criterion
40
+
41
+ Write `features/<slug>/10_delivery_review.md`:
42
+ - **## Verdict** — `hand-off: ready | blocked` (ready ⇔ 0 BLOCKER and 0 unwaived HIGH, cross-validation complete)
43
+ - **## Findings** — table: severity | plane | title | where | why | crossValidated
44
+ - **## Hand-off criterion** — machine-checkable rows: `0 BLOCKER: PASS/FAIL(n)`, `0 unwaived HIGH: PASS/FAIL(n)`.
45
+ Projects with a merge-request flow add THEIR OWN rows here (`CI terminal: …`, `draft→ready: …`) — these are
46
+ **document rows the owner fills**, never API calls made by the pipeline. No merge-request flow ⇒ the rows
47
+ stay `—`.
48
+ - **## Note** — ADVISORY: the owner decides; nothing auto-aborts.
49
+
50
+ ### Hard rules
51
+
52
+ 1. **Findings only.** Step 10 NEVER posts to a VCS host, tracker, or any external service. Publishing a
53
+ review anywhere is a separate, explicit user instruction.
54
+ 2. **Advisory.** `hand-off: blocked` is a report, not an abort (a false gate kills trust).
55
+ 3. **Cross-family.** The planes run on the other model family than the coder (the Step-8 rule) — a model
56
+ must not deliver-gate its own code.
57
+ 4. **Cost control.** One gate per hand-off, not per commit. A stack of related changes gets one Step-10 pass
58
+ on the combined diff.
59
+
60
+ ## Promise tag
61
+
62
+ `<promise>FEATURE_ADR_DELIVERY_GATED</promise>` — and the `🚦 Gates:` line gains `delivery ready|blocked`
63
+ (derived from the review doc's Verdict, `n/a` when the gate was not requested).
@@ -8,6 +8,7 @@ export const meta = {
8
8
  { title: 'Plan', detail: 'Step 6 - SPARC-GOAP plan' },
9
9
  { title: 'Code', detail: 'Step 7 - implement per plan+ADR' },
10
10
  { title: 'QE', detail: 'Step 8 - brutal-honesty (agentic-qe) + teach' },
11
+ { title: 'Delivery', detail: 'Step 10 - delivery gate: 4-plane review of the landed feature (opt-in)' },
11
12
  { title: 'FleetQE', detail: 'Step 9 - traceability/coverage (L/XL)' },
12
13
  ],
13
14
  }
@@ -957,6 +958,74 @@ if (isLplus) {
957
958
  fleet = 'run'
958
959
  }
959
960
 
961
+ // ── Step 10 (OPT-IN): Delivery Gate — post-implementation full review of the LANDED feature ──
962
+ // P1 of fa-improvements, adapted to dz: Step 8 reviews the code as the coder's counterpart; Step 10 reviews
963
+ // the feature as a PUBLISHED ENTITY across 4 orthogonal planes (regressions ‖ security ‖ code-quality ‖
964
+ // product-honesty — the plane Step-8 lacks entirely), then cross-validates BLOCKER/HIGH positionally (the
965
+ // challenge-panel lesson) and emits a MACHINE-CHECKABLE hand-off verdict. EXTENSIBILITY GUARANTEES: strictly
966
+ // opt-in (`args.deliveryGate: true` or `args.models.delivery` — absent ⇒ byte-identical, zero agents, no
967
+ // artifact); ZERO VCS-host specifics (no MR/undraft/CI API calls — an MR-flow project's extra criteria are
968
+ // documented rows the orchestrator fills, not code); planes calibrate on architecture/vision.md when present,
969
+ // generic otherwise (the R5 pattern). ADVISORY: `handoff: blocked` is a report — nothing auto-aborts, and
970
+ // findings are NEVER auto-posted anywhere (findings-only hard rule).
971
+ const DELIVERY_ON = A.deliveryGate === true || !!(A.models && typeof A.models === 'object' && A.models.delivery)
972
+ let delivery = null
973
+ if (DELIVERY_ON) {
974
+ try {
975
+ phase('Delivery')
976
+ await usageProbe('Delivery')
977
+ // Planes run on the CROSS-FAMILY of the coder (the same load-bearing rule as Step-8 QE): an explicit
978
+ // args.models.delivery wins; else mirror the qe resolution (which already derives the other family).
979
+ const dModel = (A.models && A.models.delivery) ? resolveStageModel('delivery') : resolveStageModel('qe')
980
+ modelsUsed.delivery = modelLabel(mergeOpts({}, dModel))
981
+ const DELIVERY_SCHEMA = { type: 'object', additionalProperties: false, required: ['findings'], properties: { findings: { type: 'array', items: { type: 'object', additionalProperties: false, required: ['severity', 'title', 'where', 'why'], properties: { severity: { type: 'string' }, title: { type: 'string' }, where: { type: 'string' }, why: { type: 'string' } } } } } }
982
+ const D_SEVS = new Set(['BLOCKER', 'HIGH', 'MED', 'LOW'])
983
+ const dBase = 'You are a Step-10 Delivery Gate reviewer for the LANDED feature "' + DESC + '" (' + SLUG + ', repo ' + REPO + '). Review the feature as a PUBLISHED ENTITY: read ' + FDIR + '/07_code_changes/change_manifest.md and the actual changed files (plus `git status`/`git diff` for anything uncommitted). Calibrate on architecture/vision.md + architecture/degradations.md when they exist (an accepted degradation is NOT a finding); stay generic when they do not. Report ONLY confirmed findings as {severity: BLOCKER|HIGH|MED|LOW, title, where (file:line), why}. FINDINGS ONLY — do NOT post to any VCS host, tracker, or external service. '
984
+ const planePrompts = [
985
+ ['regressions', 'PLANE 1 — REGRESSIONS: behavior changes that break existing consumers/contracts; NEW I/O added to previously-pure startup/lifespan/health paths without a negative resource-down test; removed/weakened tests (fixture-swap); silent semantic changes to shared surfaces.'],
986
+ ['security', 'PLANE 2 — SECURITY: injection via interpolated paths/refs/commands; secrets in code/lessons/artifacts; key custody; path traversal/symlink escapes; fail-open where the contract says fail-closed.'],
987
+ ['code-quality', 'PLANE 3 — CODE QUALITY: god-object growth, duplicated parallel implementations vs the reuse map, dead/unreachable safeguards (code paths that can never fire), error handling that swallows, complexity without a named reason.'],
988
+ ['product-honesty', 'PLANE 4 — PRODUCT HONESTY + COMMON SENSE (the plane Step-8 lacks): claims in docs/READMEs/reports not backed by behavior; FABRICATED COMPLETENESS (output presented as complete when a source was unavailable); a feature that does less than its description; user-facing text that misleads about limits or degradation.'],
989
+ ]
990
+ const planeThunks = planePrompts.map(([pl, focus]) => () => agent(dBase + focus + ' Return the findings object.' + codexEffortHint(dModel), mergeOpts({ label: stageLabel('delivery:' + pl, dModel), phase: 'Delivery', schema: DELIVERY_SCHEMA }, dModel)))
991
+ const planeResults = await parallel(planeThunks)
992
+ const all = []
993
+ planeResults.forEach((r, pi) => {
994
+ const fs = (r && Array.isArray(r.findings)) ? r.findings : []
995
+ for (const f of fs) { if (f && typeof f === 'object' && D_SEVS.has(String(f.severity)) && typeof f.title === 'string' && f.title !== '') all.push({ plane: planePrompts[pi][0], severity: String(f.severity), title: f.title, where: String(f.where || ''), why: String(f.why || '') }) }
996
+ })
997
+ // Cross-validate BLOCKER/HIGH by INDEX (never title). Validator outage ⇒ surface UNVALIDATED, never drop.
998
+ const dRank = { BLOCKER: 4, HIGH: 3, MED: 2, LOW: 1 }
999
+ const bh = all.filter((f) => f.severity === 'BLOCKER' || f.severity === 'HIGH').sort((a, b) => (dRank[b.severity] - dRank[a.severity]) || (a.plane < b.plane ? -1 : 1))
1000
+ let confirmed = all.filter((f) => f.severity === 'MED' || f.severity === 'LOW')
1001
+ let dStatus = 'ok'
1002
+ if (bh.length > 0) {
1003
+ const numbered = bh.map((f, i) => ({ i: i, plane: f.plane, severity: f.severity, title: f.title, where: f.where, why: f.why }))
1004
+ const CV_SCHEMA = { type: 'object', additionalProperties: false, required: ['results'], properties: { results: { type: 'array', items: { type: 'object', additionalProperties: false, required: ['i', 'real'], properties: { i: { type: 'number' }, real: { type: 'boolean' } } } } } }
1005
+ const cv = await agent('Independently CROSS-VALIDATE these delivery-gate findings against the ACTUAL code in repo ' + REPO + ' (read the files). For EACH by its "i" index decide real (reachable, evidenced) vs FP/theory; default real=false when uncertain. Findings: ' + JSON.stringify(numbered), mergeOpts({ label: stageLabel('delivery:cross-validate', dModel), phase: 'Delivery', schema: CV_SCHEMA }, dModel))
1006
+ const realByIndex = new Map((cv && Array.isArray(cv.results) ? cv.results : []).map((r) => [Number(r.i), r.real === true]))
1007
+ if (!bh.every((_, i) => realByIndex.has(i))) {
1008
+ dStatus = 'cross-validation-incomplete'
1009
+ log('Delivery gate: cross-validator did not cover every BLOCKER/HIGH — surfacing them UNVALIDATED (not dropped)')
1010
+ for (const f of bh) confirmed.push(Object.assign({}, f, { crossValidated: false, unvalidated: true }))
1011
+ } else {
1012
+ bh.forEach((f, i) => { if (realByIndex.get(i) === true) confirmed.push(Object.assign({}, f, { crossValidated: true })) })
1013
+ }
1014
+ }
1015
+ confirmed.sort((a, b) => (dRank[b.severity] - dRank[a.severity]) || (a.plane < b.plane ? -1 : 1))
1016
+ const blockers = confirmed.filter((f) => f.severity === 'BLOCKER').length
1017
+ const highs = confirmed.filter((f) => f.severity === 'HIGH').length
1018
+ const handoff = (dStatus === 'ok' && blockers === 0 && highs === 0) ? 'ready' : 'blocked'
1019
+ // Consolidation (cheap): write the review artifact incl. the machine-checkable hand-off criterion. The
1020
+ // MR-flow rows (CI terminal, draft→ready) are DOCUMENT rows the orchestrator/owner fills — never API calls.
1021
+ await agent('Write ' + FDIR + '/10_delivery_review.md consolidating this Step-10 Delivery Gate result (do not re-review): status=' + dStatus + ', hand-off=' + handoff + ', findings JSON: ' + JSON.stringify(confirmed) + '. Structure: ## Verdict (hand-off: ' + handoff + '), ## Findings (a table: severity | plane | title | where | why | crossValidated), ## Hand-off criterion (machine-checkable rows: "0 BLOCKER: ' + (blockers === 0 ? 'PASS' : 'FAIL (' + blockers + ')') + '", "0 unwaived HIGH: ' + (highs === 0 ? 'PASS' : 'FAIL (' + highs + ')') + '", plus rows the owner fills ONLY if an MR flow exists: "CI terminal: —", "draft→ready: —"), ## Note (ADVISORY — findings only; nothing was posted anywhere; the owner decides).', { label: 'delivery:consolidate', phase: 'Delivery', effort: 'low' })
1022
+ delivery = { handoff: handoff, status: dStatus, blockers: blockers, highs: highs, findings: confirmed }
1023
+ } catch (e) {
1024
+ log('Delivery gate errored (advisory, ignored): ' + (e && e.message ? e.message : String(e)))
1025
+ delivery = { handoff: 'errored', status: 'error', blockers: 0, highs: 0, findings: [] }
1026
+ }
1027
+ }
1028
+
960
1029
  // R1 product-architecture-lens (FR-3): refresh architecture/map.json at the END of a COMPLETE run so the
961
1030
  // NEXT feature's Step-0 сверка sees what this run added. Best-effort, non-blocking. (Not reached on the
962
1031
  // L/XL checkpoint-after-plan return above — no code has landed there yet.)
@@ -964,6 +1033,7 @@ await agent('Run EXACTLY this one shell command via your Bash tool and report it
964
1033
 
965
1034
  const tags = ['FEATURE_ADR_ROUTED', 'FEATURE_ADR_DESIGNED', 'FEATURE_ADR_PLANNED', 'FEATURE_ADR_IMPLEMENTED', 'FEATURE_ADR_VERIFIED']
966
1035
  if (isLplus) tags.push('FEATURE_ADR_FLEET_VERIFIED')
1036
+ if (delivery) tags.push('FEATURE_ADR_DELIVERY_GATED')
967
1037
  return {
968
1038
  slug: SLUG, tier: tier, mode: MODE, artifactsDir: FDIR,
969
1039
  design: design.filter(Boolean).map((d) => d.wrote).flat(),
@@ -991,6 +1061,8 @@ return {
991
1061
  qe: (qe ? (qe.grade || 'ran') : 'not-run'),
992
1062
  claimCheck: (qe && qe.claimCheck ? (qe.claimCheck.high > 0 ? 'high-findings' : 'clean') : 'not-run'),
993
1063
  fleet: (isLplus ? (fleet ? 'ran' : 'not-run') : 'n/a'),
1064
+ delivery: (DELIVERY_ON ? (delivery ? delivery.handoff : 'errored') : 'n/a'),
994
1065
  },
1066
+ delivery: delivery,
995
1067
  promiseTags: tags,
996
1068
  }