devflow-kit 3.1.0 → 3.3.0

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.
Files changed (138) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/README.md +2 -2
  3. package/dist/cli/agents-view/render.js +69 -15
  4. package/dist/cli/agents-view/state.js +40 -14
  5. package/dist/cli/commands/agents.js +135 -45
  6. package/dist/cli/commands/init.js +128 -53
  7. package/dist/cli/commands/learning.js +61 -13
  8. package/dist/cli/commands/memory.js +35 -14
  9. package/dist/cli/commands/uninstall.js +163 -39
  10. package/dist/commands/code-review.md +1 -3
  11. package/dist/commands/debug.md +15 -12
  12. package/dist/commands/dynamic-build.md +172 -135
  13. package/dist/commands/dynamic-plan.md +9 -3
  14. package/dist/commands/explore.md +10 -4
  15. package/dist/commands/implement.md +149 -145
  16. package/dist/commands/plan.md +13 -9
  17. package/dist/commands/release.md +8 -2
  18. package/dist/commands/research.md +8 -2
  19. package/dist/commands/resolve.md +28 -19
  20. package/dist/commands/self-review.md +16 -13
  21. package/dist/core/agent-frontmatter.js +25 -0
  22. package/dist/core/agent-models.js +201 -36
  23. package/dist/core/agent-state.js +27 -5
  24. package/dist/core/assets.js +1 -1
  25. package/dist/core/feature-config.js +68 -10
  26. package/dist/core/flags.js +24 -0
  27. package/dist/core/learning-queue-cleanup.js +10 -11
  28. package/dist/core/learning-tuning-config.js +8 -0
  29. package/dist/core/linked-path.js +46 -0
  30. package/dist/core/plugins.js +16 -5
  31. package/dist/core/queue-drain.js +31 -0
  32. package/dist/hud/components/learning-counts.js +54 -8
  33. package/dist/skills/git/references/tracker/github/create-release.md +2 -2
  34. package/dist/skills/git/references/tracker/github/gather-release-evidence.md +1 -1
  35. package/dist/skills/git/references/tracker/jira/create-release.md +2 -2
  36. package/dist/skills/git/references/tracker/jira/gather-release-evidence.md +1 -1
  37. package/dist/skills/git/references/tracker/linear/create-release.md +2 -2
  38. package/dist/skills/git/references/tracker/linear/gather-release-evidence.md +1 -1
  39. package/dist/targets/claude-code/installer.js +36 -9
  40. package/dist/targets/claude-code/post-install.js +128 -38
  41. package/package.json +1 -1
  42. package/src/assets/agents/code.md +85 -35
  43. package/src/assets/agents/design.md +12 -0
  44. package/src/assets/agents/diagnose.md +18 -11
  45. package/src/assets/agents/evaluate.md +17 -24
  46. package/src/assets/agents/knowledge.md +7 -3
  47. package/src/assets/agents/learning.md +4 -6
  48. package/src/assets/agents/research.md +21 -0
  49. package/src/assets/agents/review.md +12 -0
  50. package/src/assets/agents/scrutinize.md +37 -9
  51. package/src/assets/agents/simplify.md +24 -0
  52. package/src/assets/agents/skim.md +6 -2
  53. package/src/assets/agents/synthesize.md +18 -0
  54. package/src/assets/agents/test.md +19 -11
  55. package/src/assets/agents/triage.md +8 -0
  56. package/src/assets/agents/validate.md +20 -11
  57. package/src/assets/commands/_partials/_engine.mds +36 -55
  58. package/src/assets/commands/_partials/_knowledge.mds +1 -3
  59. package/src/assets/commands/_partials/_plan_contract.mds +1 -1
  60. package/src/assets/commands/_partials/_tracker.mds +1 -1
  61. package/src/assets/commands/_partials/_wave.mds +8 -6
  62. package/src/assets/commands/code-review.mds +1 -3
  63. package/src/assets/commands/debug.mds +13 -8
  64. package/src/assets/commands/dynamic-build.mds +126 -72
  65. package/src/assets/commands/dynamic-plan.mds +7 -1
  66. package/src/assets/commands/explore.mds +9 -1
  67. package/src/assets/commands/implement.mds +147 -141
  68. package/src/assets/commands/plan.mds +12 -8
  69. package/src/assets/commands/release.md +8 -2
  70. package/src/assets/commands/research.mds +8 -2
  71. package/src/assets/commands/resolve.mds +27 -16
  72. package/src/assets/commands/self-review.mds +15 -10
  73. package/src/assets/mds/tracker/_common.mds +1 -1
  74. package/src/assets/mds/tracker/_github.mds +2 -2
  75. package/src/assets/mds/tracker/_jira.mds +2 -2
  76. package/src/assets/mds/tracker/_linear.mds +2 -2
  77. package/src/assets/scripts/ci-wait.cjs +636 -0
  78. package/src/assets/scripts/hooks/assets/orchestrator-charter.md +4 -3
  79. package/src/assets/scripts/hooks/background-memory-update +356 -17
  80. package/src/assets/scripts/hooks/capture-prompt +4 -3
  81. package/src/assets/scripts/hooks/capture-question +4 -3
  82. package/src/assets/scripts/hooks/capture-turn +4 -3
  83. package/src/assets/scripts/hooks/ensure-devflow-init +13 -1
  84. package/src/assets/scripts/hooks/ensure-root-gitignore +122 -10
  85. package/src/assets/scripts/hooks/git-marker +71 -0
  86. package/src/assets/scripts/hooks/json-helper.cjs +12 -145
  87. package/src/assets/scripts/hooks/json-parse +24 -129
  88. package/src/assets/scripts/hooks/lib/learning-store.cjs +169 -64
  89. package/src/assets/scripts/hooks/lib/render-decisions.cjs +1 -1
  90. package/src/assets/scripts/hooks/memory-worker +10 -0
  91. package/src/assets/scripts/hooks/pre-compact-memory +66 -14
  92. package/src/assets/scripts/hooks/preamble +9 -1
  93. package/src/assets/scripts/hooks/queue-append +53 -21
  94. package/src/assets/scripts/hooks/session-start-context +108 -29
  95. package/src/assets/scripts/hooks/session-start-memory +33 -11
  96. package/src/assets/scripts/release-trace.cjs +27 -10
  97. package/src/assets/skills/accessibility/SKILL.md +1 -1
  98. package/src/assets/skills/apply-decisions/SKILL.md +12 -82
  99. package/src/assets/skills/apply-feature-knowledge/SKILL.md +8 -42
  100. package/src/assets/skills/architecture/SKILL.md +1 -1
  101. package/src/assets/skills/boundary-validation/SKILL.md +1 -1
  102. package/src/assets/skills/complexity/SKILL.md +1 -1
  103. package/src/assets/skills/compliance/SKILL.md +1 -1
  104. package/src/assets/skills/consistency/SKILL.md +1 -1
  105. package/src/assets/skills/database/SKILL.md +1 -1
  106. package/src/assets/skills/dependencies/SKILL.md +1 -1
  107. package/src/assets/skills/dependency-research/SKILL.md +3 -6
  108. package/src/assets/skills/design-review/SKILL.md +1 -1
  109. package/src/assets/skills/docs-framework/SKILL.md +1 -1
  110. package/src/assets/skills/documentation/SKILL.md +1 -1
  111. package/src/assets/skills/gap-analysis/SKILL.md +1 -1
  112. package/src/assets/skills/git/SKILL.md +1 -1
  113. package/src/assets/skills/go/SKILL.md +1 -1
  114. package/src/assets/skills/java/SKILL.md +1 -1
  115. package/src/assets/skills/patterns/SKILL.md +1 -1
  116. package/src/assets/skills/performance/SKILL.md +1 -1
  117. package/src/assets/skills/python/SKILL.md +1 -1
  118. package/src/assets/skills/qa/SKILL.md +1 -3
  119. package/src/assets/skills/quality-gates/SKILL.md +9 -12
  120. package/src/assets/skills/quality-gates/references/report-template.md +20 -20
  121. package/src/assets/skills/react/SKILL.md +1 -1
  122. package/src/assets/skills/regression/SKILL.md +1 -1
  123. package/src/assets/skills/reliability/SKILL.md +1 -1
  124. package/src/assets/skills/research-codebase/SKILL.md +1 -1
  125. package/src/assets/skills/research-competitor/SKILL.md +1 -1
  126. package/src/assets/skills/research-external/SKILL.md +1 -1
  127. package/src/assets/skills/research-technology/SKILL.md +1 -1
  128. package/src/assets/skills/review-methodology/SKILL.md +1 -1
  129. package/src/assets/skills/rust/SKILL.md +1 -1
  130. package/src/assets/skills/security/SKILL.md +1 -1
  131. package/src/assets/skills/software-design/SKILL.md +1 -1
  132. package/src/assets/skills/test-driven-development/SKILL.md +15 -33
  133. package/src/assets/skills/testing/SKILL.md +1 -1
  134. package/src/assets/skills/typescript/SKILL.md +1 -1
  135. package/src/assets/skills/ui-design/SKILL.md +1 -1
  136. package/src/assets/skills/worktree-support/SKILL.md +3 -55
  137. package/src/assets/skills/worktree-support/references/discovery.md +48 -0
  138. package/src/assets/skills/worktree-support/references/roots.md +2 -2
@@ -18,13 +18,19 @@ The orchestrator only spawns agents and gates — all analytical work is done by
18
18
 
19
19
  ## Input
20
20
 
21
- `$ARGUMENTS` contains whatever follows `/plan`:
21
+ What follows `/plan` is bound once, here. Every later step names it `COMMAND_INPUT` and never restates it:
22
+
23
+ <command-input>
24
+ $ARGUMENTS
25
+ </command-input>
26
+
27
+ `COMMAND_INPUT` is one of:
22
28
  - Opens with a candidate issue reference → issue mode (one candidate = single-ref, more than one = multi-issue)
23
29
  - Path to existing `.md` file → **error**: "Use /implement with plan documents"
24
30
  - Other text → feature description
25
31
  - Empty → use conversation context
26
32
 
27
- **Issue-reference grammar (L1 — command layer, permissive and provider-blind):** scan `$ARGUMENTS` for candidate issue references — a `#`-prefixed token and a bare digit run are both candidates — and collect them in source order as the raw token list `ISSUE_REFS`. Forward that list to the Git agent **verbatim**: the command never renders, normalises, pads, strips or coerces a token, and never rules a candidate out. Under `github` a token matching `^#?[1-9][0-9]{0,8}$` **is** a reference and the Git agent renders it as `#{n}`.
33
+ **Issue-reference grammar (L1 — command layer, permissive and provider-blind):** scan `COMMAND_INPUT` for candidate issue references — a `#`-prefixed token and a bare digit run are both candidates — and collect them in source order as the raw token list `ISSUE_REFS`. Forward that list to the Git agent **verbatim**: the command never renders, normalises, pads, strips or coerces a token, and never rules a candidate out. Under `github` a token matching `^#?[1-9][0-9]{0,8}$` **is** a reference and the Git agent renders it as `#{n}`.
28
34
 
29
35
  **A token of any other shape is neither coerced nor dropped silently — and no producer-side grammar check rejects it before the fetch.** Adjudication belongs to the operation that runs, and each one answers in its own Output block: `fetch-issue` strips a leading `#` and takes the text branch, so a non-numeric token is used as a **search term** and the operation returns the first open match or nothing; `fetch-issues-batch` resolves each token to an issue number, drops the ones it cannot resolve, and names them in `NOT_FOUND ({refs})` beside the issues it did fetch. Read the outcome from the operation that ran — a token's shape is a verdict nowhere, and there is nothing upstream holding it back.
30
36
 
@@ -62,7 +68,7 @@ Explore the user's intent through focused Socratic questioning before spawning a
62
68
 
63
69
  **Step 0 — Fetch issue(s)** (issue mode only; skip for feature-description and empty modes):
64
70
 
65
- - **Single-ref** (one candidate ref in `$ARGUMENTS`):
71
+ - **Single-ref** (one candidate ref in `COMMAND_INPUT`):
66
72
 
67
73
  ```
68
74
  Agent(subagent_type="Git"):
@@ -106,8 +112,6 @@ If the user says "skip" or "just proceed" — skip remaining questions, present
106
112
  **Produces:** SKIM_CONTEXT, DECISIONS_CONTEXT, FEATURE_KNOWLEDGE
107
113
  **Requires:** CONFIRMED_SCOPE
108
114
 
109
- **Load Companion Skills** — Load via Skill tool: `devflow:test-driven-development`, `devflow:patterns`, `devflow:software-design`, `devflow:security`, `devflow:design-review`. If a skill fails to load, continue without it.
110
-
111
115
  Spawn Skim agent for codebase context:
112
116
 
113
117
  ```
@@ -212,7 +216,7 @@ Pass `FEATURE_KNOWLEDGE` alongside `DECISIONS_CONTEXT` to Explore and Design age
212
216
  **Produces:** EXPLORE_OUTPUTS
213
217
  **Requires:** SKIM_CONTEXT, DECISIONS_CONTEXT
214
218
 
215
- Spawn 4 Explore agents **in a single message**, each with Skim agent context, `DECISIONS_CONTEXT` (from Phase 2), and `FEATURE_KNOWLEDGE` (from Phase 2). Include instructions: "follow `devflow:apply-decisions` for DECISIONS_CONTEXT" and "The FEATURE_KNOWLEDGE is a baseline — VALIDATE, EXTEND, and CORRECT it, don't repeat it. Focus on areas the feature knowledge doesn't cover and changes since it was last updated."
219
+ Spawn 4 Explore agents **in a single message**, each with Skim agent context, `DECISIONS_CONTEXT` (from Phase 2), and `FEATURE_KNOWLEDGE` (from Phase 2). Include instructions: "follow `devflow:apply-decisions` for DECISIONS_CONTEXT" and "The FEATURE_KNOWLEDGE is a baseline — VALIDATE, EXTEND, and CORRECT it, don't repeat it. Focus on areas the feature knowledge doesn't cover and changes since it was last updated." Ask each agent for a final report of at most about 1,500 tokens: findings with file:line references, not file dumps.
216
220
 
217
221
  | Focus | Thoroughness | Find |
218
222
  |-------|-------------|------|
@@ -355,7 +359,7 @@ User can:
355
359
  **Produces:** IMPL_EXPLORE_OUTPUTS
356
360
  **Requires:** SKIM_CONTEXT, ACCEPTED_SCOPE
357
361
 
358
- Spawn 4 Explore agents **in a single message**, each with Skim agent context + accepted scope:
362
+ Spawn 4 Explore agents **in a single message**, each with Skim agent context + accepted scope. Ask each agent for a final report of at most about 1,500 tokens: findings with file:line references, not file dumps.
359
363
 
360
364
  | Focus | Thoroughness | Find |
361
365
  |-------|-------------|------|
@@ -384,7 +388,7 @@ Combine into: patterns to follow, integration points, reusable code, edge cases"
384
388
  **Produces:** PLAN_OUTPUTS
385
389
  **Requires:** IMPL_EXPLORATION_SYNTHESIS, GAP_SYNTHESIS, DECISIONS_CONTEXT
386
390
 
387
- Spawn 3 Plan agents **in a single message**, each with implementation exploration synthesis:
391
+ Spawn 3 Plan agents **in a single message**, each with implementation exploration synthesis. Ask each agent for a final report of at most about 1,500 tokens: the plan itself, not a restatement of the exploration.
388
392
 
389
393
  | Focus | Output |
390
394
  |-------|--------|
@@ -573,7 +577,7 @@ Spawn a Git agent with `OPERATION: ensure-traceable-issue`:
573
577
  ```
574
578
  Agent(subagent_type="Git"):
575
579
  "OPERATION: ensure-traceable-issue
576
- ISSUE_INPUT: {the raw candidate token from $ARGUMENTS if /plan was invoked with an issue reference, else omit}
580
+ ISSUE_INPUT: {the raw candidate token from COMMAND_INPUT if /plan was invoked with an issue reference, else omit}
577
581
  TASK_DESCRIPTION: {Gate 0 confirmed scope — one-line title}
578
582
  INITIAL_REQUEST: {the Gate 0 confirmed scope statement}
579
583
  REQUIREMENTS: {discovered requirements summary from Phase 6 gap synthesis}
@@ -17,13 +17,19 @@ Release the project using adaptive learned configuration. On first run, scans th
17
17
 
18
18
  ## Input
19
19
 
20
- `$ARGUMENTS` contains whatever follows `/release`:
20
+ What follows `/release` is bound once, here. Every later step names it `COMMAND_INPUT` and never restates it:
21
+
22
+ <command-input>
23
+ $ARGUMENTS
24
+ </command-input>
25
+
26
+ `COMMAND_INPUT` is one of:
21
27
  - Explicit version: `v1.2.3` or `1.2.3`
22
28
  - Bump type: `patch`, `minor`, `major`
23
29
  - Flag: `--dry-run`
24
30
  - Empty: interactive mode (will ask for version)
25
31
 
26
- Parse from $ARGUMENTS:
32
+ Parse from `COMMAND_INPUT`:
27
33
  - `VERSION`: explicit version string if present (strip leading `v`)
28
34
  - `BUMP_TYPE`: `patch | minor | major` if bump type provided
29
35
  - `DRY_RUN`: true if `--dry-run` present, false otherwise
@@ -16,7 +16,13 @@ Research a topic by spawning parallel Research agents across multiple research t
16
16
 
17
17
  ## Input
18
18
 
19
- `$ARGUMENTS` contains whatever follows `/research`:
19
+ What follows `/research` is bound once, here. Every later step names it `COMMAND_INPUT` and never restates it:
20
+
21
+ <command-input>
22
+ $ARGUMENTS
23
+ </command-input>
24
+
25
+ `COMMAND_INPUT` is one of:
20
26
  - Research question: "best caching strategies"
21
27
  - Comparison question: "compare React vs Svelte for our use case"
22
28
  - Empty: use conversation context
@@ -183,7 +189,7 @@ If external research was skipped due to tool unavailability: inform user.
183
189
  1. If `codebase` type was not in RESEARCH_PLAN → skip
184
190
  2. Check if matching feature knowledge already exists by reading `{worktree}/.devflow/features/index.md` (or globbing frontmatter if absent). If covered → skip
185
191
  3. Use AskUserQuestion: "No feature knowledge exists for {researched area}. Create one?"
186
- 4. If user accepts: spawn `Agent(subagent_type="Knowledge")` with researched area context + worktree root, instructing it to load `devflow:feature-knowledge`, write `KNOWLEDGE.md`, and update `index.md` directly
192
+ 4. If user accepts: spawn `Agent(subagent_type="Knowledge")` with researched area context + worktree root, instructing it to write `KNOWLEDGE.md` and update `index.md` directly
187
193
  5. Set FEATURE_KNOWLEDGE_STATUS = created or skipped
188
194
 
189
195
  **Failure handling**: Non-blocking. If Knowledge agent fails, log and continue.
@@ -24,7 +24,7 @@ Process issues from code review reports: triage every issue through the blast-ra
24
24
 
25
25
  1. **Discover resolvable worktrees** using the `devflow:worktree-support` skill discovery algorithm:
26
26
  - Run `git worktree list --porcelain` → parse, filter (skip protected/detached/mid-rebase), dedup by branch, sort by recent commit
27
- - See the `devflow:worktree-support` skill for the full 7-step algorithm and canonical protected branch list
27
+ - Invoke the `devflow:worktree-support` skill, then Read its `references/discovery.md` from the skill's base directory for the full 7-step algorithm; the canonical protected branch list stays in the skill
28
28
  - Additional filter: must have unresolved reviews (latest review directory has no `resolution-summary.md`)
29
29
  2. **If `--path` flag provided:** use only that worktree, skip discovery
30
30
  **`--path` validation**: Before proceeding, verify the path exists as a directory and appears in `git worktree list` output. If not: report error and stop.
@@ -302,8 +302,8 @@ For each batch, spawn Code agent with `OPERATION: issue-fix` and `PUSH: false`:
302
302
 
303
303
  ```
304
304
  Agent(subagent_type="Code"):
305
- "TASK_ID: resolve-{batch-id}
306
- OPERATION: issue-fix
305
+ "OPERATION: issue-fix
306
+ TASK_ID: resolve-{batch-id}
307
307
  ISSUES: {fix_now_issues_in_batch}
308
308
  SCOPE: {risk_tier_per_issue}
309
309
  PUSH: false
@@ -348,7 +348,8 @@ Agent(subagent_type="Simplify", run_in_background=false):
348
348
  "TASK_DESCRIPTION: Issue resolution fixes
349
349
  WORKTREE_PATH: {worktree_path} (omit if cwd)
350
350
  FILES_CHANGED: {list of files modified by Code agents}
351
- Simplify and refine the fixes for clarity and consistency"
351
+ Simplify and refine the fixes for clarity and consistency
352
+ Commit any improvements with a conventional-commit message."
352
353
  ```
353
354
 
354
355
  ### Phase 7: Verification Gate
@@ -361,7 +362,7 @@ If no fixes were made (CODE_AGENT_RESULTS contains 0 commits) → set VERIFICATI
361
362
  Otherwise, spawn Validate agent:
362
363
 
363
364
  ```
364
- Agent(subagent_type="Validate", model="haiku"):
365
+ Agent(subagent_type="Validate"):
365
366
  "FILES_CHANGED: {list of files from Code agent output}
366
367
  VALIDATION_SCOPE: full
367
368
  Run build, typecheck, lint, test. Report pass/fail with failure details."
@@ -376,8 +377,8 @@ Run build, typecheck, lint, test. Report pass/fail with failure details."
376
377
  - Spawn Code agent with fix context:
377
378
  ```
378
379
  Agent(subagent_type="Code"):
379
- "TASK_ID: resolve-{batch-id}-valfix-{count}
380
- OPERATION: validation-fix
380
+ "OPERATION: validation-fix
381
+ TASK_ID: resolve-{batch-id}-valfix-{count}
381
382
  VALIDATION_FAILURES: {parsed failures from Validate agent}
382
383
  SCOPE: Fix only the listed failures, no other changes
383
384
  PUSH: false
@@ -415,14 +416,24 @@ If `fork_no_push` is set → skip: "Cannot push to fork — skipping CI validati
415
416
 
416
417
  Otherwise, for each worktree with fixes:
417
418
 
418
- <!-- PATTERN: ci-status-gate — shared polling/classification/budget logic; context-specific preamble lives outside this block -->
419
- 1. Spawn `Agent(subagent_type="Git")` with `OPERATION: check-ci-status` and `WORKTREE_PATH`.
419
+ `PR_NUMBER` is the worktree's `pr_number` from Phase 0; when it is absent, skip: "No PR/CI configured, skipping CI validation."
420
+
421
+ **Push first, outside the gate block.** The gate waits on the pushed head, so push once more with the gate's own command — never forced, and no retry:
422
+
423
+ ```bash
424
+ git -C {worktree} push; echo "exit=$?"
425
+ ```
426
+
427
+ Phase 7 has pushed already, so this is a no-op unless the head moved since. `exit=0` continues to the gate. Any other result records `TRACEABILITY: DEGRADED (ci push failed)`, reports "CI status unknown — verify manually before merging" and skips the wait for this worktree. Pass `WORKTREE_PATH: {worktree_path}` on the fix spawn below.
428
+
429
+ <!-- PATTERN: ci-status-gate -->
430
+ 1. Wait: run `cd {worktree} && HEAD_SHA=$(git rev-parse HEAD) && node "$HOME/.devflow/scripts/ci-wait.cjs" --pr {PR_NUMBER} --head "$HEAD_SHA"` through the Bash tool with `timeout: 600000`. Each run is one wait of at most 570 seconds and prints one line, `CI <STATUS> pr=… head=… failing=… pending=… waited=…` (INDETERMINATE adds `reason=…`). A missing or unparseable line, a status outside the six below, or a non-zero exit is INDETERMINATE.
420
431
  2. **If PASSING** → proceed to next phase.
421
432
  3. **If NO_PR or NO_CI** → skip: "No PR/CI configured, skipping CI validation." Proceed to next phase.
422
- 4. **If PENDING** → poll every 60 seconds (global budget, see step 7). Re-spawn Git agent each poll. If PASSING → proceed. If still PENDING after budget exhausted → report "CI still running — verify manually before merging" and proceed.
423
- 5. **If INDETERMINATE** → poll as PENDING within the same budget. If still INDETERMINATE after budget exhausted → report "CI status unknown — verify manually before merging" and proceed.
424
- 6. **If FAILING** → report failing checks. Spawn `Agent(subagent_type="Code")` with `COMPLIANCE_FRAMEWORKS` to fix CI failures based on check names and failure context. After fix, push and re-check. Max 2 fix attempts. If still failing → report failures and proceed.
425
- 7. **Total budget**: max 10 polls and max 2 fix attempts across all check/fix cycles combined. If the budget is exhausted, report current status and proceed.
433
+ 4. **If PENDING** and fewer than 3 waits have run → wait again (step 1). After the third wait → report "CI still running — verify manually before merging" and proceed.
434
+ 5. **If INDETERMINATE** and fewer than 3 waits have run → wait again (step 1). After the third wait → report "CI status unknown — verify manually before merging" and proceed.
435
+ 6. **If FAILING** and fewer than 2 fixes have run → report the failing checks from the line. Spawn `Agent(subagent_type="Code")` whose prompt opens with `OPERATION: ci-fix`, with `COMPLIANCE_FRAMEWORKS`, `CI_FAILURES` and `PUSH: false`; `CI_FAILURES` holds the failing-check names from the line and nothing else, because the Code agent fetches the full names and reads the logs itself and this command reads none. After a fix, push with the command above and, if a wait remains, wait again (step 1); a failed push records `TRACEABILITY: DEGRADED (ci push failed)`, reports "CI status unknown — verify manually before merging" and stops waiting. After the second fix still FAILING → report the failing checks and proceed.
436
+ 7. **Budget**: at most 3 waits and 2 fixes in all, per worktree. When one is spent, report the current status and proceed.
426
437
  <!-- /PATTERN: ci-status-gate -->
427
438
 
428
439
  ### Phase 9: Manage Debt (Sequential)
@@ -455,7 +466,7 @@ After manage-debt completes:
455
466
 
456
467
  **Step 9b-0: Re-verify stale test-plan items**
457
468
 
458
- Run this step only when this run's Phase 7 push succeeded — the one way /resolve moves the PR head — and a PR is known; otherwise skip it and Step 9b-3, and record `STALE_REVERIFICATION` as `SKIPPED (head unchanged)`. Detection needs no Git agent: from the worktree root, run the evidence script, which re-derives every test-plan state at the new head and writes the stale TP lines whose text the PR's trusted evidence record vouches for:
469
+ Run this step only when a push of this run succeeded — Phase 7's, or the push of Phase 8's gate — and a PR is known; otherwise skip it and Step 9b-3, and record `STALE_REVERIFICATION` as `SKIPPED (head unchanged)`. Detection needs no Git agent: from the worktree root, run the evidence script, which re-derives every test-plan state at the new head and writes the stale TP lines whose text the PR's trusted evidence record vouches for:
459
470
 
460
471
  ```bash
461
472
  cd {worktree} && node "$HOME/.devflow/scripts/verify-evidence.cjs" verify --pr {pr_number} --stale-out "{TARGET_DIR_REL}/stale-plan.md"; echo "exit=$?"
@@ -607,7 +618,7 @@ Final gate: {PASS | FAILED after N attempts}
607
618
  - Resolution comment: {POSTED | POSTED+TRUNCATED | SKIPPED (already posted) | SKIPPED (publication off) | SKIPPED (no PR) | DEGRADED (reason)}
608
619
  - Publication: {FULL (private repo) | FULL (config override) | STUB (public repository) | OFF (publication disabled by config) | STUB (visibility undeterminable) | STUB (evidence policy)}
609
620
  - Thread replies: {COMPLETE | PARTIAL | TRUNCATED | SKIPPED (reason) | DEGRADED (reason)}
610
- - Push: {pushed | skipped (no fixes) | skipped (cannot push to fork)}
621
+ - Push: {pushed (Phase 7, a CI-fix push, or both) | skipped (no fixes) | skipped (cannot push to fork) | DEGRADED (ci push failed)}
611
622
  - Test-plan re-verification: {Test plan: n stale, m re-verified | SKIPPED (head unchanged) | DEGRADED (reason)}
612
623
  - Test-plan evidence: {the EVIDENCE line's VERIFIED-CI + ATTESTED-LOCAL / total, then the Body / Comment line | SKIPPED (reason) | DEGRADED (reason)}
613
624
 
@@ -648,7 +659,7 @@ If the settings line says `KNOWLEDGE=off`, skip write-back entirely. The machine
648
659
  **Step 2 — Evaluate whether write-back is warranted:**
649
660
 
650
661
  Only proceed if **at least one** of these is true:
651
- - This workflow changed files in a directory that is documented by an existing feature knowledge base (a documented area changed).
662
+ - This workflow changed files in a directory that is documented by an existing feature knowledge base (a documented area changed). Knowledge bases are written through at that point, never on a background schedule.
652
663
  - This workflow surfaced durable, cross-cutting knowledge about a codebase area that would help future agents working in the same area — patterns, anti-patterns, integration points, gotchas not visible from a single file read.
653
664
 
654
665
  **Never spawn unconditionally.** If neither condition is met, skip write-back silently.
@@ -665,8 +676,6 @@ DIRECTORIES: {list of primary directories touched by this workflow}
665
676
  FILES_CHANGED: {list of files changed}
666
677
  DECISIONS_CONTEXT: {DECISIONS_CONTEXT if available, else (none)}
667
678
 
668
- Load the devflow:feature-knowledge skill and follow its authoring process.
669
-
670
679
  Write the knowledge base to:
671
680
  {worktree}/.devflow/features/{slug}/KNOWLEDGE.md
672
681
 
@@ -720,7 +729,7 @@ When the Knowledge agent reports `KB_COMMIT: skipped (detached HEAD)`, the files
720
729
  ├─ Phase 7: Verification Gate [Validate agent, haiku] + push + Code agent validation-fix loop ≤2
721
730
  │
722
731
  ├─ Phase 8: CI Status Gate (conditional — skipped if no fixes or verification FAILED)
723
- │ └─ Git agent (check-ci-status) → poll/fix loop
732
+ │ └─ push, then ci-wait.cjs (inline, one wait ≤ 570 s) → Code agent on FAILING (3 waits + 2 fixes per worktree)
724
733
  │
725
734
  ├─ Phase 9: Git agent (manage-debt) — FIX_SEPARATE + TECH_DEBT → backfill Tracked={ISSUE_REF} (or TRACEABILITY: DEGRADED on failure)
726
735
  │ SEQUENTIAL across worktrees
@@ -14,7 +14,7 @@ Run Simplify agent and Scrutinize agent sequentially on changed files for post-i
14
14
 
15
15
  ### Phase 0: Context Gathering
16
16
 
17
- **Produces:** FILES_CHANGED, TASK_DESCRIPTION, DECISIONS_CONTEXT, FEATURE_KNOWLEDGE
17
+ **Produces:** FILES_CHANGED, TASK_DESCRIPTION, DECISIONS_CONTEXT, FEATURE_KNOWLEDGE, HEAD_BEFORE
18
18
 
19
19
  Detect changed files and build context:
20
20
 
@@ -22,6 +22,7 @@ Detect changed files and build context:
22
22
  2. Else run `git diff --name-only HEAD` + `git diff --name-only --cached` to get staged + unstaged
23
23
  3. If no changes found, report "No changes to review" and exit
24
24
  4. Build TASK_DESCRIPTION from recent commit messages or branch name
25
+ 5. Record `HEAD_BEFORE` (`git rev-parse HEAD`) now, before Simplify runs — Phase 3 compares against it
25
26
  ### Load DECISIONS_CONTEXT
26
27
 
27
28
  The decisions ledger belongs to the repository, not to one checkout: in a linked worktree it lives in the main worktree, and a session started in a subdirectory reads the copy at the repository root. Locate it with ONE git call, run from the start directory — `WORKTREE_PATH` if provided, otherwise cwd (`devflow:worktree-support`):
@@ -100,7 +101,7 @@ If no KBs exist, no KBs are relevant, or `.devflow/features/` is absent, set `FE
100
101
 
101
102
  Pass `FEATURE_KNOWLEDGE` to Scrutinize agent.
102
103
 
103
- **Extract:** FILES_CHANGED (list), TASK_DESCRIPTION (string), DECISIONS_CONTEXT (string, optional), FEATURE_KNOWLEDGE (string, optional)
104
+ **Extract:** FILES_CHANGED (list), TASK_DESCRIPTION (string), DECISIONS_CONTEXT (string, optional), FEATURE_KNOWLEDGE (string, optional), HEAD_BEFORE (40-hex SHA)
104
105
 
105
106
  ### Phase 1: Simplify agent (Code Refinement)
106
107
 
@@ -112,13 +113,14 @@ Spawn Simplify agent to refine code for clarity and consistency:
112
113
  Agent(subagent_type="Simplify", run_in_background=false):
113
114
  "TASK_DESCRIPTION: {task_description}
114
115
  FILES_CHANGED: {files_changed}
115
- Simplify and refine the code for clarity and consistency while preserving functionality."
116
+ Simplify and refine the code for clarity and consistency while preserving functionality.
117
+ Commit any improvements with a conventional-commit message."
116
118
 
117
119
  **Wait for completion.** Simplify agent commits changes directly.
118
120
 
119
121
  ### Phase 2: Scrutinize agent (9-Pillar Quality Gate)
120
122
 
121
- **Produces:** SCRUTINIZE_STATUS, SCRUTINIZE_CHANGES
123
+ **Produces:** SCRUTINIZE_STATUS
122
124
  **Requires:** FILES_CHANGED, TASK_DESCRIPTION, DECISIONS_CONTEXT
123
125
 
124
126
  Spawn Scrutinize agent for quality evaluation and fixing:
@@ -132,17 +134,19 @@ Evaluate against 9-pillar framework. Fix P0/P1 issues. Return structured report.
132
134
  Follow devflow:apply-decisions to scan DECISIONS_CONTEXT and Read full ADR/PF bodies on demand. Skip if (none).
133
135
  Follow devflow:apply-feature-knowledge for FEATURE_KNOWLEDGE. Skip if (none)."
134
136
 
135
- **Wait for completion.** Extract: STATUS (PASS|FIXED|BLOCKED), changes_made (bool)
137
+ **Wait for completion.** Extract: STATUS (PASS|FIXED|BLOCKED) from the `### Status` line
136
138
 
137
139
  ### Phase 3: Conditional Validation
138
140
 
139
141
  **Produces:** VALIDATION_RESULT
140
- **Requires:** SCRUTINIZE_CHANGES
142
+ **Requires:** HEAD_BEFORE, SCRUTINIZE_STATUS
141
143
 
142
- If Scrutinize agent made changes (STATUS == FIXED):
144
+ If STATUS is BLOCKED, skip this phase: the report (Phase 4) names the blocker.
145
+
146
+ Run this phase only if HEAD moved — `git rev-parse HEAD` differs from `HEAD_BEFORE`, meaning Simplify or Scrutinize committed (Simplify alone counts, whatever Scrutinize's STATUS is). Otherwise skip it. Its scope is changed-only over what the two agents changed:
143
147
 
144
148
  Agent(subagent_type="Validate", run_in_background=false):
145
- "FILES_CHANGED: {scrutinize_modified_files}
149
+ "FILES_CHANGED: {output of `git diff --name-only HEAD_BEFORE..HEAD`}
146
150
  VALIDATION_SCOPE: changed-only
147
151
  Run build, typecheck, lint, test on modified files"
148
152
 
@@ -208,7 +212,7 @@ If the settings line says `KNOWLEDGE=off`, skip write-back entirely. The machine
208
212
  **Step 2 — Evaluate whether write-back is warranted:**
209
213
 
210
214
  Only proceed if **at least one** of these is true:
211
- - This workflow changed files in a directory that is documented by an existing feature knowledge base (a documented area changed).
215
+ - This workflow changed files in a directory that is documented by an existing feature knowledge base (a documented area changed). Knowledge bases are written through at that point, never on a background schedule.
212
216
  - This workflow surfaced durable, cross-cutting knowledge about a codebase area that would help future agents working in the same area — patterns, anti-patterns, integration points, gotchas not visible from a single file read.
213
217
 
214
218
  **Never spawn unconditionally.** If neither condition is met, skip write-back silently.
@@ -225,8 +229,6 @@ DIRECTORIES: {list of primary directories touched by this workflow}
225
229
  FILES_CHANGED: {list of files changed}
226
230
  DECISIONS_CONTEXT: {DECISIONS_CONTEXT if available, else (none)}
227
231
 
228
- Load the devflow:feature-knowledge skill and follow its authoring process.
229
-
230
232
  Write the knowledge base to:
231
233
  {worktree}/.devflow/features/{slug}/KNOWLEDGE.md
232
234
 
@@ -254,6 +256,7 @@ When the Knowledge agent reports `KB_COMMIT: skipped (detached HEAD)`, the files
254
256
  │
255
257
  ├─ Phase 0: Context gathering
256
258
  │ ├─ Git diff for changed files
259
+ │ ├─ Record HEAD_BEFORE
257
260
  │ └─ Read index.md → DECISIONS_CONTEXT
258
261
  │
259
262
  ├─ Phase 1: Simplify agent
@@ -263,7 +266,7 @@ When the Knowledge agent reports `KB_COMMIT: skipped (detached HEAD)`, the files
263
266
  │ └─ 9-pillar quality gate (may fix and commit)
264
267
  │
265
268
  ├─ Phase 3: Validate agent (conditional)
266
- │ └─ If Scrutinize agent made changes, verify tests pass
269
+ │ └─ If HEAD moved since HEAD_BEFORE (Simplify or Scrutinize committed), changed-only Validate over HEAD_BEFORE..HEAD
267
270
  │
268
271
  └─ Phase 4: Report
269
272
  └─ Display summary with pillar status
@@ -282,6 +285,6 @@ When the Knowledge agent reports `KB_COMMIT: skipped (detached HEAD)`, the files
282
285
 
283
286
  1. **Orchestration only** - Command spawns agents, doesn't do the work
284
287
  2. **Sequential execution** - Simplify agent must complete before Scrutinize agent
285
- 3. **Validation gate** - If Scrutinize agent changes code, must pass validation
288
+ 3. **Validation gate** - If Simplify agent or Scrutinize agent committed, the changes must pass validation
286
289
  4. **Honest reporting** - Display actual agent outputs
287
290
  5. **Fail fast** - Stop on BLOCKED or validation failure
@@ -96,6 +96,31 @@ export function readFrontmatterModel(content) {
96
96
  const m = MODEL_RE.exec(parts.value.fmBody);
97
97
  return Ok(m ? m[1] : '');
98
98
  }
99
+ // ---------------------------------------------------------------------------
100
+ // readFrontmatterEffort
101
+ // ---------------------------------------------------------------------------
102
+ /**
103
+ * Read the `effort:` value from the first frontmatter block.
104
+ *
105
+ * D-SHIPPED-EFFORT: an agent's shipped effort is part of its shipped default,
106
+ * the same as its model, so the reader that answers "what did devflow ship?"
107
+ * must see both. This is the effort twin of readFrontmatterModel and has the
108
+ * same contract: it reads only the leading frontmatter block (an `effort:`
109
+ * line in the body is ignored), returns Ok('') when no `effort:` line exists,
110
+ * and returns an error for missing or unterminated frontmatter.
111
+ *
112
+ * The value is returned as written. Whether it is a valid effort level is the
113
+ * caller's decision (loadShippedAgentDefaults owns that check against
114
+ * EFFORT_LEVELS), so a typo in a shipped file is reported rather than hidden here.
115
+ */
116
+ export function readFrontmatterEffort(content) {
117
+ const parts = parseFrontmatter(content);
118
+ if (!parts.ok)
119
+ return Err(parts.error);
120
+ const EFFORT_RE = /^effort:[ \t]*(.*?)[ \t]*$/m;
121
+ const m = EFFORT_RE.exec(parts.value.fmBody);
122
+ return Ok(m ? m[1] : '');
123
+ }
99
124
  /**
100
125
  * Rewrite the `model:` and optionally `effort:` lines in the first
101
126
  * frontmatter block of `content`.