@dzhechkov/skills-feature-adr 1.3.24 → 1.3.28

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
@@ -106,6 +106,41 @@ ARCHITECTURE → IMPLEMENTATION → CODE → QE → FLEET QE
106
106
  # Full protocols + 6 extra skills, up to 7 fleet QE agents
107
107
  ```
108
108
 
109
+ ### Codex model routing (optional)
110
+
111
+ If [Codex](https://developers.openai.com/codex) is installed + logged in, the pipeline can route work to
112
+ Codex — **always asking first, always with a Claude fallback** (it never blocks on Codex). Three opt-in
113
+ knobs (via the workflow `args`, or offered interactively at the planning checkpoint):
114
+
115
+ | Knob | Step | What it does |
116
+ |---|---|---|
117
+ | `planner: 'codex'` | 6 Plan | plan on Codex's top model (Claude fallback) |
118
+ | `coder: 'codex-fallback'` | 7 Code | Claude first; **if the Claude Code limit is exhausted mid-run → retry on Codex** |
119
+ | `qeReviewer: 'codex-fallback'` | 8 QE/tests | same fallback for the review/testing stage |
120
+ | `codexModel: 'gpt-5-codex'` | — | which Codex model (`gpt-5-codex` default · `gpt-5` · `o3` · `auto`) |
121
+
122
+ **Scenario — never stall on a rate limit:** a long L/XL feature hits the Claude Code session limit while
123
+ writing code. Without this the run stalls; with `coder: 'codex-fallback'` the pipeline logs *"Claude
124
+ unavailable (limit?) — falling back to Codex gpt-5-codex"* and finishes the code + tests on Codex, no
125
+ restart and no lost work.
126
+
127
+ ```bash
128
+ # Headless login on a VPS (no browser):
129
+ codex login --device-auth # prints a code + URL you approve on another device
130
+ # — or —
131
+ printenv OPENAI_API_KEY | codex login --with-api-key
132
+ ```
133
+
134
+ ```js
135
+ // ultracode (the deterministic workflow form): plan on Codex, code+QE fall back to Codex on Claude-limit:
136
+ Workflow({ scriptPath: '.claude/workflows/feature-adr.js',
137
+ args: { slug: 'add-oauth', description: '…', tier: 'M',
138
+ planner: 'codex', coder: 'codex-fallback', qeReviewer: 'codex-fallback', codexModel: 'gpt-5-codex' } })
139
+ ```
140
+
141
+ Omit the Codex knobs entirely for today's all-Claude behavior. The run result reports
142
+ `plannerUsed` / `coderUsed` / `qeReviewerUsed` / `codexModel` so you can see who did what.
143
+
109
144
  ---
110
145
 
111
146
  ## Spec-Driven Development (SDD)
@@ -170,6 +170,27 @@ for load-bearing judgment). Models are **overridable defaults**.
170
170
  > steps and compare reward patterns / rework counts vs your `sonnet` baseline. This table is a
171
171
  > starting heuristic, not a benchmark — tune per project.
172
172
 
173
+ ### Codex routing (optional — cross-model + limit resilience)
174
+
175
+ In the **ultracode workflow form**, feature-adr can hand steps to [Codex](https://developers.openai.com/codex)
176
+ — opt-in, always with a Claude fallback (never blocks). Two reasons teams turn it on:
177
+
178
+ 1. **Cross-model planning** — plan Step 6 on Codex's top model: `planner: 'codex'`.
179
+ 2. **Never stall on a rate limit** — the killer feature: `coder: 'codex-fallback'` +
180
+ `qeReviewer: 'codex-fallback'`. Claude writes the code/tests as usual; but if a long L/XL run hits
181
+ the **Claude Code session limit mid-Step-7/8**, the pipeline auto-retries that step on Codex
182
+ (`gpt-5-codex` by default) instead of stalling — no restart, no lost work.
183
+
184
+ ```bash
185
+ # one-time headless login (VPS, no browser):
186
+ codex login --device-auth # approve the printed code+URL on your phone/laptop
187
+
188
+ # then, when launching a run, pass the knobs (or accept the interactive pre-flight offer):
189
+ # planner: 'codex' | coder: 'codex-fallback' | qeReviewer: 'codex-fallback' | codexModel: 'gpt-5-codex'
190
+ ```
191
+
192
+ Omit the knobs for the all-Claude default. Full reference: `.claude/rules/feature-adr-ultracode.md`.
193
+
173
194
  ---
174
195
 
175
196
  ## 7. QE modes cheat-sheet
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dzhechkov/skills-feature-adr",
3
- "version": "1.3.24",
3
+ "version": "1.3.28",
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"
@@ -25,6 +25,55 @@ The pipeline ALWAYS runs the feature-adr Pattern memory loop **in-process** —
25
25
  - **Step 0** recalls learned patterns (`dz recall`) → folds the top ones into requirements/ADR as `{LEARNED_PATTERNS}` + records the recalled count in the live panel (`dz statusline --fa-record`).
26
26
  - **Step 8** teaches the durable lessons back (`dz teach`) + records the stored count. The loop pays off (recall) and grows (teach) every run.
27
27
 
28
+ ## Optional Codex routing (opt-in, pre-flight ASK)
29
+
30
+ feature-adr can route work to Codex's models. **All of it is opt-in and graceful** — absent / declined /
31
+ Codex-unavailable → the default Claude agent runs; the pipeline NEVER blocks on Codex. Three knobs, all
32
+ overridable via `args`:
33
+
34
+ | Knob (`args.*`) | Step | Values | Effect |
35
+ |---|---|---|---|
36
+ | `planner` | 6 (Plan) | `claude` (default) · `codex` | `codex` → Step-6 plans on Codex, Claude fallback |
37
+ | `coder` | 7 (Code) | `claude` (default) · `codex` · `codex-fallback` | `codex-fallback` → Claude first, **on limit-exhaustion (null) → Codex** |
38
+ | `qeReviewer` | 8 (QE/tests) | `claude` (default) · `codex` · `codex-fallback` | same fallback, for the QE/testing stage |
39
+ | `codexModel` | — | `gpt-5-codex` (default) · `gpt-5` · `o3` · `auto` | which Codex model to use |
40
+
41
+ The result reports `plannerUsed` / `coderUsed` / `qeReviewerUsed` / `codexModel` so you can see who did what.
42
+
43
+ **Pre-flight — detect + ASK (do this BEFORE launching a run):**
44
+ ```bash
45
+ node "<codex-plugin>/scripts/codex-companion.mjs" setup --json # → { "ready": true }
46
+ ```
47
+ If `ready`, ASK the user once (skip all of this if not ready — Claude does everything):
48
+ 1. *"Plan (Step 6) on the top Codex model?"* → set `planner: 'codex'`.
49
+ 2. *"Fall back to Codex for code + tests/QE (Step 7/8) if the Claude Code limit is exhausted?"* →
50
+ set `coder: 'codex-fallback'`, `qeReviewer: 'codex-fallback'`.
51
+ 3. *"Which Codex model?"* (`gpt-5-codex` / `gpt-5` / `o3` / `auto`) → **write it into codex config so the
52
+ `codex:codex-rescue` runtime picks it up**, then pass `codexModel`:
53
+ ```bash
54
+ printf '\nmodel = "gpt-5-codex"\n' >> ~/.codex/config.toml # or -c model=... per invocation
55
+ ```
56
+ For the interactive SKILL (plain `/feature-adr`), make the same three offers at the planning checkpoint.
57
+
58
+ **Scenario (the reason this exists):** a long L/XL run hits the Claude Code session limit mid-Step-7.
59
+ Without this, the Code agent returns null and the run stalls. With `coder: 'codex-fallback'`, feature-adr
60
+ detects the null, logs *"Claude unavailable (limit?) — falling back to Codex gpt-5-codex"*, and finishes
61
+ the code + tests on Codex — no restart, no lost work.
62
+
63
+ **Example invocations:**
64
+ ```js
65
+ // Plan on Codex, code+QE fall back to Codex only if Claude runs out, gpt-5-codex:
66
+ Workflow({ scriptPath: '.claude/workflows/feature-adr.js',
67
+ args: { slug: 'add-x', description: '…', tier: 'M',
68
+ planner: 'codex', coder: 'codex-fallback', qeReviewer: 'codex-fallback', codexModel: 'gpt-5-codex' } })
69
+
70
+ // All-Claude (the default — omit the Codex knobs entirely):
71
+ Workflow({ scriptPath: '.claude/workflows/feature-adr.js', args: { slug: 'add-x', description: '…', tier: 'M' } })
72
+ ```
73
+
74
+ **Headless Codex login on a VPS (no browser):** `codex login --device-auth` (prints a code + URL you
75
+ approve on another device) or `printenv OPENAI_API_KEY | codex login --with-api-key`.
76
+
28
77
  ## Hybrid checkpoints (router decides)
29
78
 
30
79
  - **S / M** → run autonomously to completion; present a final consolidated review (ADR + plan + QE).
@@ -355,6 +355,26 @@ Step 0 (Complexity Router) checks:
355
355
  description, code, tier, stopAfter, repo, dzBin } })`. Hybrid checkpoints: S/M autonomous; L/XL return
356
356
  after the Plan phase for your steer. See `.claude/rules/feature-adr-ultracode.md`.
357
357
 
358
+ **Optional Codex routing (opt-in).** When Codex is installed + logged in (`codex login --device-auth`
359
+ on a headless VPS, or `printenv OPENAI_API_KEY | codex login --with-api-key`), the pipeline can route work
360
+ to Codex — always ASKING first, always with a Claude fallback (never blocks):
361
+
362
+ - **Planning (Step 6)** on Codex's top model → `args.planner: 'codex'`.
363
+ - **Code (Step 7) + tests/QE (Step 8) FALLBACK** → `args.coder: 'codex-fallback'`, `args.qeReviewer:
364
+ 'codex-fallback'`: Claude runs first, and only if the **Claude Code limit is exhausted mid-run** (the
365
+ agent returns null) does the SAME task retry on Codex — so a long build never stalls on a rate limit.
366
+ - **Model choice** → `args.codexModel` (`gpt-5-codex` default · `gpt-5` · `o3` · `auto`).
367
+
368
+ *Scenario:* an L/XL run hits the session limit during coding → with `coder: 'codex-fallback'` feature-adr
369
+ logs *"Claude unavailable (limit?) — falling back to Codex gpt-5-codex"* and finishes on Codex, no restart.
370
+
371
+ *Example:* `Workflow({ scriptPath: '.claude/workflows/feature-adr.js', args: { slug, description, tier:
372
+ 'M', planner: 'codex', coder: 'codex-fallback', qeReviewer: 'codex-fallback', codexModel: 'gpt-5-codex' } })`.
373
+
374
+ Pre-flight, if Codex is `ready` (`codex-companion setup --json`), the orchestrator asks these three
375
+ before launching; plain `/feature-adr` offers the same at the planning checkpoint. Omit the Codex knobs
376
+ for today's all-Claude behavior. See `.claude/rules/feature-adr-ultracode.md`.
377
+
358
378
  ### Pattern memory loop (self-learning — runs in ALL modes)
359
379
 
360
380
  **Self-learning is MANDATORY on EVERY `/feature-adr` run — including plain `/feature-adr` without any
@@ -1,7 +1,7 @@
1
1
  export const meta = {
2
2
  name: 'feature-adr',
3
- description: 'Canonical /feature-adr --full-qe-extended pipeline as a reusable workflow: router+RECALL then design(ADR, applies learned patterns) then plan then code then agentic-qe QE+TEACH, producing features/<slug>/00-09 artifacts. MANDATORY in-process self-learning loop (Step-0 recall, apply, Step-8 teach). Hybrid checkpoints (S/M autonomous; L/XL stop-after-plan).',
4
- whenToUse: 'ultracode + a feature implementation. Invoke via Workflow({scriptPath:".claude/workflows/feature-adr.js", args:{slug, description, code, tier, stopAfter}}) instead of an ad-hoc orchestration, so every feature ships with an ADR + inline agentic-qe QE + self-learning.',
3
+ description: 'Canonical /feature-adr --full-qe-extended pipeline as a reusable workflow: router+RECALL then design(ADR, applies learned patterns) then plan then code then agentic-qe QE+TEACH, producing features/<slug>/00-09 artifacts. MANDATORY in-process self-learning loop (Step-0 recall, apply, Step-8 teach). OPTIONAL Codex routing: args.planner=codex (Step-6), args.coder/qeReviewer='codex-fallback' (Step-7/8 fall back to Codex gpt-5-codex when Claude limits exhaust; args.codexModel picks the model). Hybrid checkpoints (S/M autonomous; L/XL stop-after-plan).',
4
+ whenToUse: 'ultracode + a feature implementation. Invoke via Workflow({scriptPath:".claude/workflows/feature-adr.js", args:{slug, description, code, tier, stopAfter, planner, coder, qeReviewer, codexModel}}) instead of an ad-hoc orchestration, so every feature ships with an ADR + inline agentic-qe QE + self-learning.',
5
5
  phases: [
6
6
  { title: 'Router', detail: 'Step 0 - classify + self-learning recall' },
7
7
  { title: 'Design', detail: 'Steps 1-5 - requirements, ADR, QCSD, architecture (tier-gated)' },
@@ -58,24 +58,73 @@ if (isMplus) {
58
58
  }
59
59
  const design = await parallel(designThunks)
60
60
 
61
- // Step 6: Plan
61
+ // Step 6: Plan — optionally routed to Codex's top model (opt-in via args.planner='codex').
62
+ // The user opts in at pre-flight ('use the top Codex model for planning?'); we route the Plan step to
63
+ // the codex:codex-rescue runtime and GRACEFULLY FALL BACK to the default (Claude) planner if Codex is
64
+ // unavailable/errors — the pipeline never blocks on Codex.
62
65
  phase('Plan')
63
- const plan = await agent('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.', { label: 'plan', phase: 'Plan', schema: ARTIFACT })
66
+ const PLANNER = (A.planner === 'codex') ? 'codex' : 'claude'
67
+ 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.'
68
+ let plan = null
69
+ if (PLANNER === 'codex') {
70
+ const codexPlan = await agent(planPrompt, { label: 'plan:codex', phase: 'Plan', agentType: 'codex:codex-rescue' })
71
+ if (codexPlan) {
72
+ plan = { wrote: [FDIR + '/06_implementation_plan.md'], summary: String(codexPlan).slice(0, 500), planner: 'codex' }
73
+ log('Plan: Codex (top model)')
74
+ } else {
75
+ log('Plan: Codex unavailable — falling back to the default planner')
76
+ }
77
+ }
78
+ if (plan === null) {
79
+ const claudePlan = await agent(planPrompt, { label: 'plan', phase: 'Plan', schema: ARTIFACT })
80
+ plan = claudePlan ? { wrote: claudePlan.wrote, summary: claudePlan.summary, planner: PLANNER === 'codex' ? 'claude-fallback' : 'claude' } : null
81
+ }
64
82
 
65
83
  // Hybrid checkpoint for L/XL
66
84
  const stopHere = STOP_AFTER === 'plan' || (isLplus && STOP_AFTER !== 'none')
67
85
  if (stopHere) {
68
- return { tier: tier, phase: 'checkpoint-after-plan', artifactsDir: FDIR, plan: (plan ? plan.summary : null), note: 'L/XL checkpoint - review the ADR + plan, then re-invoke with args.stopAfter="none" to implement + QE.' }
86
+ return { tier: tier, phase: 'checkpoint-after-plan', artifactsDir: FDIR, planner: (plan ? plan.planner : null), plan: (plan ? plan.summary : null), note: 'L/XL checkpoint - review the ADR + plan, then re-invoke with args.stopAfter="none" to implement + QE.' }
69
87
  }
70
88
 
71
- // Step 7: Code
89
+ // Codex fallback config (opt-in). CODER/QE_REVIEWER ∈ 'claude'|'codex'|'codex-fallback'. On
90
+ // 'codex-fallback' the Claude agent runs FIRST; if it returns null (e.g. the Claude Code session limit
91
+ // is exhausted mid-code/mid-QE — exactly the failure we hit before), the SAME task is retried on the
92
+ // codex:codex-rescue runtime (model = args.codexModel, default gpt-5-codex). The model is set into
93
+ // ~/.codex/config.toml by the orchestrator at pre-flight; the hint below reinforces it.
94
+ const CODEX_MODEL = A.codexModel || 'gpt-5-codex'
95
+ const CODEX_HINT = ' (If you are the Codex runtime, prefer the ' + CODEX_MODEL + ' model.)'
96
+ const CODER = (A.coder === 'codex' || A.coder === 'codex-fallback') ? A.coder : 'claude'
97
+ const QE_REVIEWER = (A.qeReviewer === 'codex' || A.qeReviewer === 'codex-fallback') ? A.qeReviewer : 'claude'
98
+
99
+ // Step 7: Code (optional Codex fallback on Claude-limit exhaustion)
72
100
  phase('Code')
73
- const code = await agent('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.', { label: 'code', phase: 'Code', schema: ARTIFACT, effort: 'high' })
101
+ 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.'
102
+ let code = null
103
+ let coderUsed = 'claude'
104
+ if (CODER !== 'codex') {
105
+ code = await agent(codePrompt, { label: 'code', phase: 'Code', schema: ARTIFACT, effort: 'high' })
106
+ if (code) coderUsed = 'claude'
107
+ }
108
+ if (code === null && (CODER === 'codex' || CODER === 'codex-fallback')) {
109
+ if (CODER === 'codex-fallback') log('Code: Claude unavailable (limit?) — falling back to Codex ' + CODEX_MODEL)
110
+ const codexCode = await agent(codePrompt + CODEX_HINT, { label: 'code:codex', phase: 'Code', agentType: 'codex:codex-rescue' })
111
+ if (codexCode) { code = { wrote: [FDIR + '/07_code_changes/change_manifest.md'], summary: String(codexCode).slice(0, 500) }; coderUsed = CODER === 'codex' ? 'codex' : 'codex-fallback' }
112
+ }
74
113
 
75
114
  // Step 8: QE (brutal-honesty, agentic-qe) + MANDATORY teach
76
115
  phase('QE')
77
116
  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). Grade A/B/C/D honestly. Assess code-test adequacy + doc-test presence. List CONFIRMED gaps with severity. Write ' + FDIR + '/08_qe_report.md. MANDATORY SELF-LEARNING STORE (close the loop, never skip): via Bash run `dz teach "<a durable reusable lesson from this feature - a rule/pattern/pitfall, NOT a checkpoint echo>" --reward <0.7-0.95> --domain <area>` for each genuine lesson (1-3 max, high-signal), then run `' + DZ + ' statusline --fa-record --slug ' + SLUG + ' --step "Step 8 QE" --recalled 3 --stored <count taught> --mode ' + MODE + ' --project ' + REPO + '` (run it verbatim via Bash, do not skip). Do NOT teach trivia or invent gaps. Return {grade, gaps, codeTestsAdequate, docTestsPresent}.'
78
- const qe = await agent(qePrompt, { label: 'qe:brutal', phase: 'QE', agentType: 'qe-code-reviewer', schema: QE })
117
+ let qe = null
118
+ let qeReviewerUsed = 'claude'
119
+ if (QE_REVIEWER !== 'codex') {
120
+ qe = await agent(qePrompt, { label: 'qe:brutal', phase: 'QE', agentType: 'qe-code-reviewer', schema: QE })
121
+ if (qe) qeReviewerUsed = 'claude'
122
+ }
123
+ if (qe === null && (QE_REVIEWER === 'codex' || QE_REVIEWER === 'codex-fallback')) {
124
+ if (QE_REVIEWER === 'codex-fallback') log('QE: Claude unavailable (limit?) — falling back to Codex ' + CODEX_MODEL)
125
+ const codexQe = await agent(qePrompt + CODEX_HINT, { label: 'qe:codex', phase: 'QE', agentType: 'codex:codex-rescue' })
126
+ if (codexQe) { qe = { grade: 'codex-review', gaps: [], codeTestsAdequate: null, docTestsPresent: null, summary: String(codexQe).slice(0, 500) }; qeReviewerUsed = QE_REVIEWER === 'codex' ? 'codex' : 'codex-fallback' }
127
+ }
79
128
 
80
129
  // Step 9: Fleet QE (L/XL)
81
130
  let fleet = 'skipped (S/M)'
@@ -100,6 +149,10 @@ return {
100
149
  codeTestsAdequate: qe ? qe.codeTestsAdequate : null,
101
150
  docTestsPresent: qe ? qe.docTestsPresent : null,
102
151
  fleetQE: fleet,
152
+ plannerUsed: plan ? plan.planner : null,
153
+ coderUsed: coderUsed,
154
+ qeReviewerUsed: qeReviewerUsed,
155
+ codexModel: CODEX_MODEL,
103
156
  selfLearning: 'recall@Step0 + teach@Step8 (mandatory)',
104
157
  promiseTags: tags,
105
158
  }