devflow-kit 3.7.0 → 3.9.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.
- package/CHANGELOG.md +479 -1
- package/README.md +15 -15
- package/dist/agents/code.md +6 -8
- package/dist/agents/design.md +1 -1
- package/dist/agents/fix.md +7 -8
- package/dist/agents/git.md +3 -3
- package/dist/agents/harden.md +1 -1
- package/dist/agents/refactor.md +2 -4
- package/dist/agents/review.md +4 -4
- package/dist/agents/skim.md +2 -2
- package/dist/agents/triage.md +9 -2
- package/dist/cli/commands/capture.js +1 -1
- package/dist/cli/commands/curation-move-io.js +102 -0
- package/dist/cli/commands/curation-move-step.js +374 -0
- package/dist/cli/commands/curation.js +808 -0
- package/dist/cli/commands/gate-level-prompts.js +428 -0
- package/dist/cli/commands/gates.js +35 -11
- package/dist/cli/commands/init-seed.js +11 -8
- package/dist/cli/commands/init.js +244 -57
- package/dist/cli/commands/memory.js +60 -13
- package/dist/cli/commands/prompt-io.js +37 -0
- package/dist/cli/commands/uninstall.js +157 -17
- package/dist/cli.js +2 -2
- package/dist/commands/bug-analysis.md +25 -36
- package/dist/commands/code-review.md +40 -44
- package/dist/commands/debug.md +5 -5
- package/dist/commands/dynamic-build.md +26 -25
- package/dist/commands/dynamic-plan.md +5 -5
- package/dist/commands/dynamic-profile.md +5 -5
- package/dist/commands/dynamic-tickets.md +5 -5
- package/dist/commands/explore.md +6 -6
- package/dist/commands/implement.md +53 -82
- package/dist/commands/plan.md +6 -6
- package/dist/commands/release.md +5 -5
- package/dist/commands/research.md +6 -6
- package/dist/commands/resolve.md +39 -41
- package/dist/commands/self-review.md +5 -13
- package/dist/core/area-pause-notice.js +44 -0
- package/dist/core/assets.js +20 -20
- package/dist/core/curate-tuning-config.js +5 -6
- package/dist/core/curation-move-notice.js +84 -0
- package/dist/core/curation-move-skip.js +35 -0
- package/dist/core/curation-move.js +35 -0
- package/dist/core/curation-queue-cleanup.js +135 -0
- package/dist/core/curation-store.js +99 -0
- package/dist/core/{learning-variants.js → curation-variants.js} +65 -41
- package/dist/core/echo-value.js +11 -5
- package/dist/core/evidence-policy.js +11 -9
- package/dist/core/feature-switch.js +95 -19
- package/dist/core/fs-atomic.js +1 -1
- package/dist/core/gate-level.js +10 -2
- package/dist/core/git.js +16 -14
- package/dist/core/ledger-root.js +82 -22
- package/dist/core/linked-path.js +4 -4
- package/dist/core/manifest-lock.js +238 -0
- package/dist/core/manifest.js +58 -14
- package/dist/core/migrations.js +1 -13
- package/dist/core/observations.js +2 -2
- package/dist/core/plugins.js +19 -19
- package/dist/core/pool.js +26 -0
- package/dist/core/project-paths.js +103 -34
- package/dist/core/queue-drain.js +2 -2
- package/dist/core/tracked-areas.js +159 -0
- package/dist/core/tracker.js +1 -1
- package/dist/{learning-off → curation-off}/agents/code.md +6 -8
- package/dist/{learning-off → curation-off}/agents/fix.md +7 -8
- package/dist/{learning-off → curation-off}/agents/refactor.md +2 -4
- package/dist/{learning-off → curation-off}/agents/review.md +3 -3
- package/dist/{learning-off → curation-off}/agents/triage.md +8 -1
- package/dist/{learning-off → curation-off}/commands/bug-analysis.md +20 -31
- package/dist/{learning-off → curation-off}/commands/code-review.md +37 -41
- package/dist/{learning-off → curation-off}/commands/debug.md +2 -2
- package/dist/{learning-off → curation-off}/commands/dynamic-build.md +23 -22
- package/dist/{learning-off → curation-off}/commands/explore.md +2 -2
- package/dist/{learning-off → curation-off}/commands/implement.md +50 -79
- package/dist/{learning-off → curation-off}/commands/plan.md +2 -2
- package/dist/{learning-off → curation-off}/commands/resolve.md +36 -38
- package/dist/{learning-off → curation-off}/commands/self-review.md +2 -10
- package/dist/hud/components/{learning-counts.js → curation-counts.js} +63 -17
- package/dist/hud/config.js +1 -1
- package/dist/hud/index.js +6 -6
- package/dist/hud/render.js +3 -3
- package/dist/skills/git/references/pr/post-resolution-summary.md +12 -11
- package/dist/skills/git/references/pr/post-review-summary.md +12 -11
- package/dist/skills/git/references/pr/update-pr-evidence.md +2 -2
- package/dist/skills/git/references/pr/validate-branch.md +8 -5
- package/dist/skills/git/references/publication-gate.md +6 -7
- package/dist/skills/git/references/tracker/github/ensure-pr-ready.md +13 -5
- package/dist/skills/git/references/tracker/github/manage-debt.md +6 -2
- package/dist/skills/git/references/tracker/jira/ensure-pr-ready.md +13 -5
- package/dist/skills/git/references/tracker/jira/manage-debt.md +6 -2
- package/dist/skills/git/references/tracker/linear/ensure-pr-ready.md +13 -5
- package/dist/skills/git/references/tracker/linear/manage-debt.md +6 -2
- package/dist/targets/claude-code/{learning-install.js → curation-install.js} +85 -65
- package/dist/targets/claude-code/installer.js +15 -15
- package/dist/targets/claude-code/language-stamp.js +5 -5
- package/dist/targets/claude-code/post-install.js +2 -2
- package/dist/targets/claude-code/tracker-servers.js +1 -1
- package/package.json +3 -2
- package/src/assets/agents/_partials/_code.mds +11 -11
- package/src/assets/agents/code.mds +6 -6
- package/src/assets/agents/curate.md +8 -8
- package/src/assets/agents/debug.mds +6 -6
- package/src/assets/agents/design.mds +18 -18
- package/src/assets/agents/evaluate.md +6 -12
- package/src/assets/agents/fix.mds +7 -6
- package/src/assets/agents/git.mds +3 -3
- package/src/assets/agents/harden.mds +7 -7
- package/src/assets/agents/knowledge.mds +23 -23
- package/src/assets/agents/refactor.mds +2 -2
- package/src/assets/agents/research.mds +15 -15
- package/src/assets/agents/review.mds +43 -43
- package/src/assets/agents/skim.mds +11 -11
- package/src/assets/agents/triage.mds +29 -22
- package/src/assets/agents/validate.md +30 -50
- package/src/assets/commands/_partials/_decisions.mds +22 -20
- package/src/assets/commands/_partials/_engine.mds +8 -8
- package/src/assets/commands/_partials/_knowledge.mds +29 -15
- package/src/assets/commands/_partials/_preamble.mds +4 -4
- package/src/assets/commands/_partials/_settings.mds +3 -3
- package/src/assets/commands/_partials/_wave.mds +7 -7
- package/src/assets/commands/bug-analysis.mds +37 -48
- package/src/assets/commands/code-review.mds +53 -57
- package/src/assets/commands/debug.mds +14 -14
- package/src/assets/commands/dynamic-build.mds +38 -37
- package/src/assets/commands/dynamic-plan.mds +22 -22
- package/src/assets/commands/dynamic-profile.mds +2 -2
- package/src/assets/commands/dynamic-tickets.mds +8 -8
- package/src/assets/commands/explore.mds +20 -20
- package/src/assets/commands/implement.mds +77 -98
- package/src/assets/commands/plan.mds +27 -27
- package/src/assets/commands/release.mds +12 -12
- package/src/assets/commands/research.mds +19 -19
- package/src/assets/commands/resolve.mds +66 -60
- package/src/assets/commands/self-review.mds +20 -20
- package/src/assets/mds/git/_ops.mds +9 -2
- package/src/assets/mds/git/_ops_pr.mds +21 -11
- package/src/assets/mds/git/_ops_steps.mds +20 -4
- package/src/assets/mds/git/_pr.mds +21 -18
- package/src/assets/mds/git/_references.mds +6 -7
- package/src/assets/mds/tracker/_github.mds +1 -4
- package/src/assets/mds/tracker/_jira.mds +1 -4
- package/src/assets/mds/tracker/_linear.mds +1 -4
- package/src/assets/rules/quality.md +1 -0
- package/src/assets/scripts/ci-wait.cjs +389 -92
- package/src/assets/scripts/hooks/background-memory-update +81 -3
- package/src/assets/scripts/hooks/capture-prompt +12 -12
- package/src/assets/scripts/hooks/capture-question +11 -11
- package/src/assets/scripts/hooks/capture-turn +12 -12
- package/src/assets/scripts/hooks/{learning-lock → curation-lock} +2 -2
- package/src/assets/scripts/hooks/curation-move +293 -0
- package/src/assets/scripts/hooks/ensure-devflow-init +45 -13
- package/src/assets/scripts/hooks/ensure-proxy +4 -4
- package/src/assets/scripts/hooks/ensure-root-gitignore +4 -4
- package/src/assets/scripts/hooks/git-marker +81 -0
- package/src/assets/scripts/hooks/json-helper.cjs +176 -51
- package/src/assets/scripts/hooks/json-parse +1 -1
- package/src/assets/scripts/hooks/lib/curation-move.cjs +1582 -0
- package/src/assets/scripts/hooks/lib/{learning-store.cjs → curation-store.cjs} +308 -122
- package/src/assets/scripts/hooks/lib/decisions-format.cjs +3 -3
- package/src/assets/scripts/hooks/lib/mkdir-lock.cjs +24 -7
- package/src/assets/scripts/hooks/lib/project-paths.cjs +132 -39
- package/src/assets/scripts/hooks/lib/render-decisions.cjs +42 -22
- package/src/assets/scripts/hooks/lib/tracked-areas.cjs +452 -0
- package/src/assets/scripts/hooks/memory-permission +10 -2
- package/src/assets/scripts/hooks/memory-worker +12 -1
- package/src/assets/scripts/hooks/pre-compact-memory +17 -16
- package/src/assets/scripts/hooks/queue-append +444 -102
- package/src/assets/scripts/hooks/resolve-project-root +2 -2
- package/src/assets/scripts/hooks/session-start-context +198 -72
- package/src/assets/scripts/hooks/session-start-memory +42 -43
- package/src/assets/scripts/lib/project-config.cjs +12 -5
- package/src/assets/scripts/pr-evidence.cjs +5 -2
- package/src/assets/scripts/resolve-base.cjs +1043 -0
- package/src/assets/scripts/resolve-settings.cjs +283 -45
- package/src/assets/scripts/verify-evidence.cjs +307 -75
- package/src/assets/skills/agent-references/SKILL.md +11 -2
- package/src/assets/skills/agent-references/references/commands/implement-levels.md +29 -0
- package/src/assets/skills/agent-references/references/commands/implement-revalidate.md +6 -4
- package/src/assets/skills/agent-references/references/commands/resolve-levels.md +25 -0
- package/src/assets/skills/agent-references/references/synthesize/review.md +4 -4
- package/src/assets/skills/agent-references/references/triage/severity-tiers.md +43 -0
- package/src/assets/skills/agent-references/references/validate/passed-alone.md +14 -0
- package/src/assets/skills/apply-decisions/SKILL.md +1 -1
- package/src/assets/skills/docs-framework/SKILL.md +7 -7
- package/src/assets/skills/docs-framework/references/patterns.md +3 -4
- package/src/assets/skills/quality-gates/SKILL.md +1 -1
- package/src/assets/skills/worktree-support/references/roots.md +2 -2
- package/templates/lint-pack/.lint-pack.conf +86 -0
- package/templates/lint-pack/README.md +190 -0
- package/templates/lint-pack/lint-pack.sh +905 -0
- package/dist/cli/commands/learning.js +0 -554
- package/dist/core/learning-queue-cleanup.js +0 -27
- package/dist/core/learning-store.js +0 -61
- /package/dist/{learning-off → curation-off}/agents/debug.md +0 -0
- /package/dist/{learning-off → curation-off}/agents/design.md +0 -0
- /package/dist/{learning-off → curation-off}/agents/harden.md +0 -0
- /package/dist/{learning-off → curation-off}/agents/knowledge.md +0 -0
- /package/dist/{learning-off → curation-off}/agents/research.md +0 -0
- /package/dist/{learning-off → curation-off}/agents/skim.md +0 -0
- /package/dist/{learning-off → curation-off}/commands/dynamic-plan.md +0 -0
- /package/dist/{learning-off → curation-off}/commands/dynamic-profile.md +0 -0
- /package/dist/{learning-off → curation-off}/commands/dynamic-tickets.md +0 -0
- /package/dist/{learning-off → curation-off}/commands/release.md +0 -0
- /package/dist/{learning-off → curation-off}/commands/research.md +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,482 @@ All notable changes to Devflow will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [3.9.0] - 2026-10-22
|
|
9
|
+
|
|
10
|
+
### Upgrade notes — Evaluate by level
|
|
11
|
+
|
|
12
|
+
**What you must do:**
|
|
13
|
+
- At `standard`, the default, and at `lean`, `/implement` now runs one Evaluate pass and at most one alignment Fix round, with no second Evaluate. Run `devflow gates --set full` to keep up to two Fix rounds, each checked again.
|
|
14
|
+
|
|
15
|
+
**Stale-install window:**
|
|
16
|
+
- Until you run `devflow init`, your installed level reference has no Evaluate row, so Evaluate runs as at `full`. If the reference is new and the installed Evaluate agent is old, `/implement` runs one pass at the full report scope.
|
|
17
|
+
|
|
18
|
+
### Upgrade notes — Severity tiers by level
|
|
19
|
+
|
|
20
|
+
**What changes:**
|
|
21
|
+
- At `standard`, the default, and at `lean`, `/resolve` no longer fixes every finding that the matrix sends to FIX_NOW. Triage sorts each kept item into a severity tier. `full` keeps today's triage and fixes. At every level, each issue cell in `resolution-summary.md` starts with its severity in brackets.
|
|
22
|
+
- CRITICAL, HIGH and severe MEDIUM findings in the branch's own code stay FIX_NOW.
|
|
23
|
+
- A prose-only MEDIUM finding is fixed with text edits alone. If Code must change logic to fix it, Code leaves it unedited and the item goes to Fix Separately.
|
|
24
|
+
- Lower MEDIUM and LOW findings go to Fix Separately. One backlog issue records them.
|
|
25
|
+
- A pre-existing finding that is not a security finding goes to Fix Separately, also when the branch touched its file.
|
|
26
|
+
- A security finding stays FIX_NOW or ESCALATED at every severity, LOW and pre-existing included.
|
|
27
|
+
- Run `devflow gates --set full` to keep today's `/resolve`: Triage applies no tiers, every FIX_NOW item is fixed, and a pre-existing finding in a touched file is fixed.
|
|
28
|
+
|
|
29
|
+
**Stale-install window:**
|
|
30
|
+
- Until you run `devflow init`, your installed `/resolve` and Triage agent have no tiers, so they behave as at `full`. If Triage is new and the installed reference is missing or unreadable, Triage applies no tier, keeps every verdict and reports `Tiers: not applied (reference unreadable)`.
|
|
31
|
+
|
|
32
|
+
### Changed
|
|
33
|
+
|
|
34
|
+
- **`/resolve` applies severity tiers at `standard` and `lean`** ([#484](https://github.com/dean0x/devflow/issues/484)).
|
|
35
|
+
- At `standard` and `lean`, Triage reads a new reference, `triage/severity-tiers.md`, once, after its normal checks. It runs a nine-step checklist in order, and the first step that matches decides.
|
|
36
|
+
The checklist only narrows. It never changes a FALSE_POSITIVE, BY_DESIGN or ESCALATED verdict, and it never moves a finding up.
|
|
37
|
+
A duplicate group takes the highest tier of its members. At `full`, Triage skips the new section, and the rest of the Triage agent text is byte-for-byte what it was.
|
|
38
|
+
- Triage judges a security finding by its label and also by the defect that it reads in the code, at every severity. A security control that fails open or is weakened, and a false security or safety claim, count as security at every severity.
|
|
39
|
+
- A prose-only fix goes to Code `issue-fix` with the Risk Tier `Standard, prose only`. No new agent is spawned. If Code leaves an item unedited for a logic change, `/resolve` records it as Fix Separately with the Reason `needs a logic change`.
|
|
40
|
+
- A DEFER item goes to Fix Separately with the Reason `severity tier: DEFER`. The manage-debt step puts the items of one run in one shared backlog issue.
|
|
41
|
+
- At every level, each issue cell in `resolution-summary.md` starts with its severity in brackets when the issue has one, for example `[HIGH]`. The `**Gate level**` header can carry a level note.
|
|
42
|
+
- The gate level hints, the effect text of `devflow gates`, `README.md`, `docs/cli-reference.md` and `docs/commands.md` name the tiers.
|
|
43
|
+
- Residual risk: the tiers rest on the Triage classification, and no live test checks it. The guards pin the text that the agents read. A finding that Triage ranks too low waits in the backlog issue until a later review brings it back.
|
|
44
|
+
- **The level references state that a waiting phase starts at once** ([#600](https://github.com/dean0x/devflow/issues/600)).
|
|
45
|
+
- The Skipped line of `resolve-levels.md` and `implement-levels.md` now says: a phase that waits for a skipped phase starts at once.
|
|
46
|
+
- The `harden-scope` bullet of `implement-levels.md` no longer says `, and Phase 5 starts at once`, because the Skipped line now covers it.
|
|
47
|
+
- Behaviour is unchanged. Only the wording moved.
|
|
48
|
+
- **Validate re-runs each failed test file alone** ([#477](https://github.com/dean0x/devflow/issues/477)).
|
|
49
|
+
- After a failed test run, Validate re-runs each failed test file alone, once, with verbose output.
|
|
50
|
+
The bound is 20 files.
|
|
51
|
+
Validate waits at most 120 seconds for each re-run, so the worst case is 40 minutes for each Validate run.
|
|
52
|
+
The 120 seconds is a bound on the wait, not on the re-run: the platform moves a foreground command that reaches its timeout to the background, where it runs to the end (see `docs/reference/platform-assumptions.md`).
|
|
53
|
+
A re-run that times out makes the file REAL.
|
|
54
|
+
A re-run starts only after the path passes a strict check, and it uses the full run's own test command with only that file added.
|
|
55
|
+
- Only the Phase 6 validation in `/implement` labels files, because only that run is given the branch base.
|
|
56
|
+
In every other run, including the re-validation after QA fixes, the re-runs give failure detail and every failure is REAL.
|
|
57
|
+
- A file is PASSED-ALONE only if all of these hold:
|
|
58
|
+
the path is checked and tracked, neither the branch nor the working tree changed the file, its failure was a timeout, a spawn error or a resource error,
|
|
59
|
+
the re-run used only that file with no name filter, it exited 0, and the tests that failed in the full run ran and passed.
|
|
60
|
+
Every other failure is REAL and goes to Fix.
|
|
61
|
+
- The cause is the failure that the test runner reports.
|
|
62
|
+
An assertion failure is REAL, also when its message names a timeout.
|
|
63
|
+
A child-process timeout that a test reports as a failed assertion is therefore REAL.
|
|
64
|
+
Issue [#332](https://github.com/dean0x/devflow/issues/332) tracks the repair of such tests.
|
|
65
|
+
- The gate and its `gate:validate` claim pass only when the PASSED-ALONE files explain every failure.
|
|
66
|
+
Only Validate's own report lists them, on one `Passed alone:` line.
|
|
67
|
+
The `/implement` summary and the PR body do not show that line.
|
|
68
|
+
- The re-run steps are in the agent reference `validate/passed-alone.md`.
|
|
69
|
+
After updating, run `devflow init`.
|
|
70
|
+
- **`/implement` runs one Evaluate pass at `standard` and `lean`** ([#483](https://github.com/dean0x/devflow/issues/483)).
|
|
71
|
+
- At `standard` and `lean`, Phase 5 runs Evaluate once and spawns Fix at most once. It never spawns Evaluate again. `full` is unchanged.
|
|
72
|
+
If Fix returns COMPLETE, the report shows `MISALIGNED (fixed once, not re-checked)` and Phase 6 starts. Any other Fix report sends the misalignments to you for a decision.
|
|
73
|
+
- Evaluate keeps every criterion and plan step in scope, security, data handling, negative and docs ones included. It drops only docs, KB, CHANGELOG, comment or cosmetic items that no criterion or step names.
|
|
74
|
+
`/dynamic-build` and `/dynamic-plan` keep the full scope.
|
|
75
|
+
- Evaluate reads the level only from line 1 of its prompt. The level line goes first in every spawn prompt of the phase, right after a leading `OPERATION:` line.
|
|
76
|
+
The Fix agent no longer says that the command runs Evaluate again after each attempt.
|
|
77
|
+
- Expected effect: about 25-30% less spend on Evaluate and its fixes. This figure comes from the studied episodes and is not measured here.
|
|
78
|
+
- Residual risk: at `standard` and `lean`, nothing checks the one Fix round against the criteria again. Phase 6 Validate and Phase 7 QA cover behaviour. A non-behavioural criterion or the removal of unrequested code has no later check before the PR opens.
|
|
79
|
+
- Known limit: no CI test checks where the level line lands in a spawn prompt at run time.
|
|
80
|
+
- **devflow ignores curation and memory files that git tracks, and says so at session start** ([#626](https://github.com/dean0x/devflow/issues/626)). When git tracks a file in a curation or memory data folder, or does not answer, devflow reads and writes no file in that folder. One fixed notice at session start says what to run to untrack the files. `devflow curation`, `devflow memory`, the HUD and `devflow uninstall` leave such a folder alone.
|
|
81
|
+
- On a paused project, `devflow curation --list`, `--show`, `--clear`, `--reset`, `--restore` and `--configure` (project scope) print the pause notice and exit 1. `devflow curation --status` and `devflow memory --status` print the notice and exit 0.
|
|
82
|
+
- The settings line that `resolve-settings.cjs` prints when it fails now reads `MEMORY=off CURATION=off`.
|
|
83
|
+
- A direct Skim delegation that passes no `CURATION` value now reports `(none)` under "Active Decisions". An absent value now reads as `off`.
|
|
84
|
+
- A checkout where a `.git` entry exists but git does not answer now pauses both features.
|
|
85
|
+
|
|
86
|
+
### Fixed
|
|
87
|
+
|
|
88
|
+
- **Sections marked private stay out of posted summaries** ([#567](https://github.com/dean0x/devflow/issues/567)).
|
|
89
|
+
- A review or resolution summary can hold a section whose heading starts with the word `Private`, in any letter case, for example `## Private notes`. A heading line inside a code block counts too.
|
|
90
|
+
- The PR comment leaves that section out, up to the next heading of the same or a higher level. This holds for the full report and for the stub.
|
|
91
|
+
- If no public text remains, devflow posts no comment and reports `**Status**: DEGRADED (no postable summary)`.
|
|
92
|
+
- The review and resolution writers now put text that must stay out of the PR comment in a final `## Private notes` section.
|
|
93
|
+
- The strip does not edit your local summary file.
|
|
94
|
+
- Run `devflow init` after you update.
|
|
95
|
+
- **`/resolve` adds only triaged items to the tech debt backlog** ([#630](https://github.com/dean0x/devflow/issues/630)).
|
|
96
|
+
- Under GitHub, Linear and Jira, the `manage-debt` operation takes backlog items only from the `## Fix Separately` and `## Deferred to Tech Debt` sections of `resolution-summary.md`.
|
|
97
|
+
- If `resolution-summary.md` is missing, the operation returns `TRACEABILITY: DEGRADED (resolution summary missing)` and leaves the backlog unchanged.
|
|
98
|
+
- Run `devflow init` after you update.
|
|
99
|
+
- **The evidence comment is edited in place** ([#504](https://github.com/dean0x/devflow/issues/504)).
|
|
100
|
+
- A PR keeps one evidence comment across pushes.
|
|
101
|
+
`update-pr-evidence` edits your own evidence comment in place for each new head.
|
|
102
|
+
- It posts a new comment only when you have none, or when an evidence comment from another user is newer.
|
|
103
|
+
- After the edit, it reads the comment back and prints `**Comment**: EDITED`.
|
|
104
|
+
If the text read back differs or cannot be read, it prints `TRACEABILITY: DEGRADED (comment read-back mismatch)`.
|
|
105
|
+
- A refused edit prints `DEGRADED (comment edit failed)`.
|
|
106
|
+
An own comment with no readable id prints `DEGRADED (comment id unreadable)`.
|
|
107
|
+
A failed edit never falls back to a new post.
|
|
108
|
+
- **CI PASSING needs a passing GitHub Actions check on a mergeable PR** ([#618](https://github.com/dean0x/devflow/issues/618)).
|
|
109
|
+
- The CI wait and the merge-readiness report now read CI as passing only when at least one GitHub Actions check passed on the PR head, no check is pending or failing, and GitHub reports the PR mergeable.
|
|
110
|
+
- These cases now read "status unknown" instead of a pass or "no CI":
|
|
111
|
+
a PR with only external checks (`reason=no-workflow-check`), a PR with a merge conflict (`reason=merge-conflict`), and a repository with active workflows but no run on the head (`reason=no-workflow-check`).
|
|
112
|
+
A PR with a merge conflict reads `reason=merge-conflict` even when a check fails or is pending.
|
|
113
|
+
The gate does not report those checks until you resolve the conflict.
|
|
114
|
+
A merge state that GitHub does not report in time ends the wait with `reason=deadline`.
|
|
115
|
+
A PR that is merged or closed ends the wait at once with `reason=not-open`. It does not wait for a merge state.
|
|
116
|
+
- "No CI" needs a mergeable PR with no checks and no active workflow file under `.github/workflows/`. A repository with no workflow file still reads "no CI".
|
|
117
|
+
When a PR has no checks and the token cannot read Actions workflows, the wait ends with `reason=gh-failed`.
|
|
118
|
+
- The merge-readiness report reads CI for the PR head. It counts a pass or "no CI" only when the PR head it read is the head of the evidence.
|
|
119
|
+
It reads CI once and does not wait, so right after a push or a base move it can say "status unknown".
|
|
120
|
+
- If your CI is not GitHub Actions, or your workflow does not run on the PR (stacked PRs, `paths` filters, release-only workflows, fork PRs that wait for approval), check the CI result on the PR page before merging.
|
|
121
|
+
The gate then reports "CI status unknown — verify manually before merging".
|
|
122
|
+
- Known limit: a passing result shows that a GitHub Actions check passed, not that the test workflow ran by name.
|
|
123
|
+
- Run `devflow init` after you update.
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## [3.8.0] - 2026-10-21
|
|
128
|
+
|
|
129
|
+
### Upgrade notes — Curation rename
|
|
130
|
+
|
|
131
|
+
The learning feature is now called curation ([#529](https://github.com/dean0x/devflow/issues/529)).
|
|
132
|
+
This is a breaking change. It releases as a minor version (3.8.0).
|
|
133
|
+
Devflow keeps no alias for the old command and the old init flags. The old switch keys stay readable, as the table shows. Read the steps that you must do by hand.
|
|
134
|
+
|
|
135
|
+
**Superseding statement for 3.6.0:** The 3.6.0 notes say that `devflow learning`, `features.learning`,
|
|
136
|
+
`.devflow/learning/` and the learning ops do not change. That statement is no longer true.
|
|
137
|
+
This release changes all of them. The 3.6.0 text stays as released.
|
|
138
|
+
|
|
139
|
+
**What you must do:**
|
|
140
|
+
- Run `devflow init` after you update.
|
|
141
|
+
- Replace `devflow learning` and the old init flags in your scripts.
|
|
142
|
+
- Delete each backup folder after `devflow curation --status` shows 0 pending rows for it.
|
|
143
|
+
A backup made on re-upgrade can hold the only copy of entries that 3.7 wrote. Check them before you delete it.
|
|
144
|
+
- Delete the leftover `.devflow/learning/` folder in each linked worktree whose main checkout has a `.devflow/` folder
|
|
145
|
+
and is not your home folder.
|
|
146
|
+
A worktree whose main checkout has no `.devflow/` folder, or is your home folder, keeps a live ledger.
|
|
147
|
+
That ledger moves like any project.
|
|
148
|
+
- Run `devflow curation --enable` if the machine switch is off and you want it on.
|
|
149
|
+
|
|
150
|
+
**Renamed names:**
|
|
151
|
+
|
|
152
|
+
| Old name | New name |
|
|
153
|
+
|----------|----------|
|
|
154
|
+
| `devflow learning` | `devflow curation` |
|
|
155
|
+
| `devflow init --learning` and `--no-learning` | `devflow init --curation` and `--no-curation` |
|
|
156
|
+
| `features.learning` in `~/.devflow/manifest.json` | `features.curation` (the old key stays as a mirror) |
|
|
157
|
+
| `features.learning` in a repository `project.json` or `config.json` | `features.curation` (the old key is still read) |
|
|
158
|
+
| `.devflow/learning/` | `.devflow/curation/` |
|
|
159
|
+
| `learning.json` (in the project folder and in `~/.devflow/`) | `curation.json` |
|
|
160
|
+
| Settings line field `LEARNING=` | `CURATION=` |
|
|
161
|
+
| Prompt markers `<!-- learning:on -->` and the build output `dist/learning-off/` | `<!-- curation:on -->` and `dist/curation-off/` |
|
|
162
|
+
| HUD label `Learning:` | `Curation:` |
|
|
163
|
+
| Session start headers `--- LEARNING MAINTENANCE ---` and `--- LEARNING PAUSED ---` | `--- CURATION MAINTENANCE ---` and `--- CURATION PAUSED ---` |
|
|
164
|
+
| Hook files `learning-lock` and `lib/learning-store.cjs` | `curation-lock` and `lib/curation-store.cjs` (init removes the old files) |
|
|
165
|
+
|
|
166
|
+
These names do not change: the `self-learning:` source stamp in rendered rows, the design-decision IDs,
|
|
167
|
+
the `decisions-*.jsonl` files, the `apply-decisions` skill, the learn-conventions family and the
|
|
168
|
+
`agents.learning.model` key (it stays an older name for the Curate agent model).
|
|
169
|
+
|
|
170
|
+
**Breaking change:**
|
|
171
|
+
- `devflow learning`, `devflow init --learning` and `devflow init --no-learning` now fail.
|
|
172
|
+
They give the unknown command or option error, and the exit code is 1.
|
|
173
|
+
- Change every script, alias and note that uses an old name.
|
|
174
|
+
|
|
175
|
+
**What the migration does:**
|
|
176
|
+
- `devflow init` moves the learning data of each project that it finds, and of the project where you run it.
|
|
177
|
+
The move takes the ledger files, the queue and the project tuning file. Entry IDs do not change.
|
|
178
|
+
Devflow renders the index again at the new path.
|
|
179
|
+
- Init also renames `~/.devflow/learning.json` to `curation.json`.
|
|
180
|
+
If both names exist, the new one wins, the old one stays, and init logs one line.
|
|
181
|
+
- The session start hook makes the same move for the project of each session.
|
|
182
|
+
It also runs when the curation switch is off.
|
|
183
|
+
- If a project already has both folders, one rule decides which folder stays.
|
|
184
|
+
If `.devflow/curation/` has a non-empty log, it wins and the old folder becomes the backup.
|
|
185
|
+
If not, the old ledger set moves in and the rest of the old folder becomes the backup.
|
|
186
|
+
Devflow never merges one ledger into the other.
|
|
187
|
+
- After an upgrade, the first `devflow` command that loads the whole manifest
|
|
188
|
+
(for example `devflow init` or `devflow flags --status`) heals `~/.devflow/manifest.json`.
|
|
189
|
+
The file then carries both `features.curation` and `features.learning` with the same value.
|
|
190
|
+
Every later write keeps the two keys equal.
|
|
191
|
+
The `--status` commands of curation, memory, knowledge and gates write nothing.
|
|
192
|
+
|
|
193
|
+
**Upgrade, downgrade and re-upgrade:**
|
|
194
|
+
- Upgrade: run `devflow init` (a full init, not `--hud-only`). Until you do, the installed prompts and agents are still the old version.
|
|
195
|
+
`devflow init --hud-only` and a plugin-only update install the new hooks and settings script, but not the new prompts.
|
|
196
|
+
The old prompts do not accept the `CURATION=` field, so they use their fail-closed settings until you run a full `devflow init`.
|
|
197
|
+
- Downgrade to 3.7: 3.7 does not read `.devflow/curation/`. It starts a new empty ledger in `.devflow/learning/`.
|
|
198
|
+
Your moved data stays in `.devflow/curation/`. The mirror key `features.learning` keeps a 3.8 opt-out in force.
|
|
199
|
+
- Re-upgrade to 3.8: the next init or session start finds both folders and applies the rule above.
|
|
200
|
+
When the folder `.devflow/curation/` has a non-empty log, it wins.
|
|
201
|
+
The queue rows of the 3.7 folder merge into the winner. The entries that 3.7 wrote stay in the backup only.
|
|
202
|
+
- The Curate model in the global tuning file: init renames `~/.devflow/learning.json` to `~/.devflow/curation.json`,
|
|
203
|
+
and 3.7 reads only the old name. After a downgrade, set the Curate model again with `devflow learning --configure`.
|
|
204
|
+
Choose the global scope. On re-upgrade, an existing `curation.json` wins and init logs one line.
|
|
205
|
+
To keep a value that you set on 3.7, delete `curation.json` first.
|
|
206
|
+
|
|
207
|
+
**The machine switch:**
|
|
208
|
+
- If `features.curation` and `features.learning` in the manifest disagree, the switch is off.
|
|
209
|
+
A reader never treats a disagreement as on.
|
|
210
|
+
- To turn it on again, run `devflow curation --enable`. This writes both keys.
|
|
211
|
+
- A 3.7 toggle writes only the old key. An opt-out made on 3.7 stays in force after you upgrade again.
|
|
212
|
+
If you ran no 3.7 `devflow init`, an enable made on 3.7 after a 3.8 disable stays off until you run `devflow curation --enable`.
|
|
213
|
+
- A 3.7 `devflow init` removes the key `features.curation`. After that, only the old key carries the opt-out.
|
|
214
|
+
A 3.7 enable made after that init then takes effect when you upgrade again.
|
|
215
|
+
- Between the package update and `devflow init`, `devflow curation --enable` and `--disable` write both keys
|
|
216
|
+
and move nothing. Only `--disable` drains the queue among these toggles. The commands `--restore`, `--clear`, `--reset`
|
|
217
|
+
and `--configure` (project scope) refuse until you run `devflow init`.
|
|
218
|
+
|
|
219
|
+
**The backup:**
|
|
220
|
+
- Where: `.devflow/learning.backup-<stamp>-<8 hex>` in the project, one folder for each move.
|
|
221
|
+
A move makes a backup only where a project had both folders.
|
|
222
|
+
- No devflow command deletes a backup, except `devflow uninstall`.
|
|
223
|
+
Uninstall removes the backups of the project at the git root of your current directory, with that project's data, after you confirm.
|
|
224
|
+
`devflow curation --reset` and `devflow curation --clear` leave the backup in place.
|
|
225
|
+
- A disable drains the queue files in the backups. `devflow curation --disable`, and `devflow init` with curation switched off,
|
|
226
|
+
remove the queue, claim, private and overflow files in each backup folder (at most 500 folders, and 200 files in each).
|
|
227
|
+
The ledger files, the swept files and the claim owner file stay in the backup.
|
|
228
|
+
Without this drain, a later `--enable` and init would merge those rows into the live queue.
|
|
229
|
+
The drain deletes nothing when a backup folder, or one of its queue files, is a symbolic link, and it says so.
|
|
230
|
+
The drain also deletes nothing when git tracks any entry under a data folder or a backup folder, or when a `.git` entry stands and git does not answer.
|
|
231
|
+
It then prints the notice that the git check shows (see Outcomes that need action).
|
|
232
|
+
If the backups cannot be listed for another reason, the drain still removes the queue files of the live and the old folder, and prints a warning that the backups were not drained.
|
|
233
|
+
- `devflow curation --status` prints one `Backup:` line for each backup folder.
|
|
234
|
+
The line shows how many pending rows the backup still holds.
|
|
235
|
+
For the first 50 folders it prints one line each. One more line counts the folders from the 51st to the 500th and their pending rows.
|
|
236
|
+
If there are more than 500 backup folders, a last line counts the folders after the 500th. Status does not read them, and no init or drain reaches them.
|
|
237
|
+
- Delete a backup folder only when `devflow curation --status` shows 0 pending rows for it.
|
|
238
|
+
Until then, a later init can still merge the rows.
|
|
239
|
+
A backup made on re-upgrade can hold the only copy of entries that 3.7 wrote. Check them before you delete it.
|
|
240
|
+
- An init merges rows from at most 50 backup folders in one run. It passes over a folder that holds no pending rows,
|
|
241
|
+
so a later folder is reached when the earlier ones are done.
|
|
242
|
+
|
|
243
|
+
**The queue cap:**
|
|
244
|
+
- A merge fills a pending queue up to 100 lines and no further.
|
|
245
|
+
A capture trim keeps the newest 100 lines and starts only above 200 lines, so a merge never causes a trim.
|
|
246
|
+
- Rows that do not fit wait in overflow files in the backup. A later init merges them as room appears.
|
|
247
|
+
Status counts them as pending rows, so the delete step waits for zero pending rows.
|
|
248
|
+
- The move drops no row, and it never causes a trim.
|
|
249
|
+
A queue that holds more than 200 lines is still trimmed to its newest 100 lines when a capture arrives.
|
|
250
|
+
This is the rule from before 3.8.0, and the move does not change it.
|
|
251
|
+
- `devflow init` drains the queue of a project where curation is off, as it did before 3.8.0.
|
|
252
|
+
|
|
253
|
+
**Outcomes that need action:**
|
|
254
|
+
- Busy: another run holds the move lock. Init prints `Ledger move skipped for <root>: a lock is held.`
|
|
255
|
+
A curation command prints `Another run is moving this project's curation data.`
|
|
256
|
+
Nothing is written. Wait a moment, then run the command again. A session start retries by itself.
|
|
257
|
+
When a queue claim holds the move, init prints `Ledger move skipped for <root>: a queue claim holds the move.`
|
|
258
|
+
A curation command prints `A Curate run holds this project's curation queue, and the move waits for it.`
|
|
259
|
+
The move runs after Curate finishes, which can take up to 15 minutes. Run the command again after that.
|
|
260
|
+
- Refused: a symbolic link sits on the path, or a private, swept or overflow queue file sits directly in the old folder.
|
|
261
|
+
Nothing moves. Init prints `Ledger move refused for <root>`.
|
|
262
|
+
The HUD and `devflow curation --status` print `Curation: move refused, see the hook log`.
|
|
263
|
+
Remove the cause, then run `devflow init` or start a new session.
|
|
264
|
+
- Skipped by the git check: git tracks any entry under `.devflow/learning/`, `.devflow/curation/` or a backup folder
|
|
265
|
+
(`.devflow/learning.backup-*`), or tracks an entry named `.devflow` ([#598](https://github.com/dean0x/devflow/issues/598)). The same outcome applies when a `.git` entry stands and git does not answer.
|
|
266
|
+
Nothing in the project changes. Init prints `Ledger move skipped for <root>` and a fixed notice that holds nothing from the repository.
|
|
267
|
+
The HUD prints `Curation: move skipped, git tracks files in the .devflow data folders`
|
|
268
|
+
or `Curation: move skipped, git did not answer`.
|
|
269
|
+
`devflow curation --status`, `--list` and `--show` print the whole notice. The HUD and these commands print the skip also when `.devflow/curation/` exists.
|
|
270
|
+
While the old folder is there, `--restore`, `--clear`, `--reset` and `--configure` (project scope) print the notice, change nothing and exit 1.
|
|
271
|
+
`--enable` and `--disable` print the notice as a warning, and their exit code does not change.
|
|
272
|
+
`--disable`, `--clear` and an init with curation off delete no queue file in these cases, and each prints the notice once.
|
|
273
|
+
When init has printed the notice in its `Ledger move skipped for <root>` line, its drain adds only `The curation queue was not drained.`
|
|
274
|
+
When git tracks files, the notice tells you to run `git ls-files .devflow`, and then `git rm --cached <file>`, in the checkout that holds the folders.
|
|
275
|
+
When git does not answer, the notice tells you to check that git runs in the project. The move runs again at the next session start or the next init.
|
|
276
|
+
A session start runs the check again in both cases.
|
|
277
|
+
- Not yet moved: `devflow curation --status`, `--list`, `--show` and the HUD print
|
|
278
|
+
`Curation: run devflow init, or open Claude Code in this project after it`.
|
|
279
|
+
They do not read the old folder.
|
|
280
|
+
- Failed: init prints `Ledger move failed for <root>` and copies nothing. The next init tries again.
|
|
281
|
+
A move that fails at session start shows the same `Curation: move refused, see the hook log` line as a refusal.
|
|
282
|
+
The hook log names the cause. The next session start tries again.
|
|
283
|
+
- Skipped, no repository: git did not name the project's repository within one second, for example on a hung mount.
|
|
284
|
+
Init prints `Ledger move skipped for <root>: git did not answer in time.` and does not count the project as moved.
|
|
285
|
+
The other projects move. The next init tries again, and a session start in the project moves it too.
|
|
286
|
+
|
|
287
|
+
**What stays behind:**
|
|
288
|
+
- Reach: a project that neither `devflow init` nor a Claude Code session reaches keeps its old
|
|
289
|
+
`.devflow/learning/` folder untouched. It moves at its next session start.
|
|
290
|
+
- Linked worktrees: if the main checkout has a `.devflow/` folder and is not your home folder,
|
|
291
|
+
the ledger of a linked worktree is the ledger of the main checkout.
|
|
292
|
+
Devflow does not move a `.devflow/learning/` folder that sits inside that worktree.
|
|
293
|
+
Delete that leftover folder by hand when you do not need it.
|
|
294
|
+
If the main checkout does not meet this condition, the `.devflow/learning/` folder of the worktree is a live ledger.
|
|
295
|
+
It moves like any project.
|
|
296
|
+
- First session: the first session start in a project with an old folder runs the move.
|
|
297
|
+
This adds a short delay to that one start. Later starts add nothing.
|
|
298
|
+
|
|
299
|
+
**Mixed-version teams:**
|
|
300
|
+
- A 3.7 install reads only `features.learning` in a committed `.devflow/project.json`.
|
|
301
|
+
A 3.8 install reads both keys and narrows when either key is `false`.
|
|
302
|
+
- Keep the old key in committed files, or set both keys, until every team member runs 3.8.
|
|
303
|
+
|
|
304
|
+
### Upgrade notes — Lint pack
|
|
305
|
+
|
|
306
|
+
**Stale-install window:**
|
|
307
|
+
- Until you run `devflow init`, the installed `/implement` and Validate do not run the lint pack.
|
|
308
|
+
|
|
309
|
+
### Upgrade notes — Base resolver
|
|
310
|
+
|
|
311
|
+
The base resolver ([#495](https://github.com/dean0x/devflow/issues/495)) adds stops and a script call.
|
|
312
|
+
Do the step below after you update.
|
|
313
|
+
|
|
314
|
+
**What you must do:**
|
|
315
|
+
- Run `devflow init` after you update. A full init installs `resolve-base.cjs` and the updated commands.
|
|
316
|
+
|
|
317
|
+
**Stops:**
|
|
318
|
+
- `/implement` stops when no usable base exists, for example in a shallow clone without the base history. `/code-review` and `/bug-analysis` stop in that case on a full-range run. The message names the cause and the fix: `git fetch --unshallow`, `git fetch origin <base>`, or a re-run (and `devflow init` if the re-run repeats the stop).
|
|
319
|
+
- The same three commands stop on a base branch name outside the allowed set, or one that git refuses. The message states the set.
|
|
320
|
+
- In `/code-review` multi-worktree mode, a rejected base blocks only that worktree.
|
|
321
|
+
- `/code-review` and `/bug-analysis` stop when the branch name does not fit the allowed characters and length. The message states the allowed characters. In `/code-review` multi-worktree mode, this blocks only that worktree.
|
|
322
|
+
- The Git agent's `validate-branch` returns BLOCKED in the same cases. `/resolve` takes its branch diff from it.
|
|
323
|
+
- The Git agent's `ensure-pr-ready` stops only on a base name outside the allowed set, or one that git refuses. For any other base stop it prints `TRACEABILITY: DEGRADED (base {REASON}; fix: {fix})` and goes on.
|
|
324
|
+
- `/dynamic-build`: a ticket whose setup reports no base commit stops with the `base-missing` escalation. Check the setup output, then re-run.
|
|
325
|
+
|
|
326
|
+
**New resolver call:**
|
|
327
|
+
- `ensure-pr-ready` calls `resolve-base.cjs` in `pr` mode with the base branch of the PR, or with the default branch when no PR applies. The call makes at most one fetch of the base branch.
|
|
328
|
+
- `/implement` passes the base ref that it resolved in Phase 1, so a normal `/implement` run makes one fetch.
|
|
329
|
+
- The `/dynamic-build` wave PR step runs `ensure-pr-ready` with no base ref, so that step makes this call.
|
|
330
|
+
- The base resolver reads the base name from standard input (`--name-stdin`), so the name is not part of shell command text ([#561](https://github.com/dean0x/devflow/issues/561)).
|
|
331
|
+
- The Git agent's `ensure-pr-ready` and `validate-branch` write the base name to a file. The step checks the status of both `gh` calls. It treats `gh` as failed when either status is not 0.
|
|
332
|
+
- In `ensure-pr-ready` and `validate-branch`, a name file whose only content is an empty line counts as empty. The default-branch path then takes `main`, or else `master`.
|
|
333
|
+
- `validate-branch` takes the default branch as the base when no PR applies: the branch has none, `gh` is missing or logged out, or the repository has no GitHub remote.
|
|
334
|
+
|
|
335
|
+
**Stale-install window:**
|
|
336
|
+
- Until you run `devflow init`, the installed commands and Git agent do not call the resolver.
|
|
337
|
+
|
|
338
|
+
**Known limits:**
|
|
339
|
+
- A fetch that stops at its 45-second bound can leave a `refs/remotes/origin/<name>.lock` file in the git directory. Later runs then report `fetch-failed` until you delete the file.
|
|
340
|
+
- The fetch needs git 2.29 or newer. With an older git, every run reports `fetch-failed` and prints the base warning.
|
|
341
|
+
- The fetch runs no askpass program. Where an askpass program is the only credential source, a remote that needs credentials gives `fetch-failed` on every run, with the base warning.
|
|
342
|
+
|
|
343
|
+
### Upgrade notes — Review markers
|
|
344
|
+
|
|
345
|
+
**What changes:**
|
|
346
|
+
- Incremental review and analysis markers are stored under the git directory of each worktree; the first run after the update covers the full branch.
|
|
347
|
+
|
|
348
|
+
### Upgrade notes — Review ranges
|
|
349
|
+
|
|
350
|
+
**What changes:**
|
|
351
|
+
- `/dynamic-build`: in single-ticket mode, the review covers the diff from the commit the ticket branch was forked from to HEAD. On a non-default start branch, that is the ticket's own commits.
|
|
352
|
+
- `/dynamic-build`: the wave evidence step lists the changed files with a diff from the base ref of the wave PR. The base ref must be a commit ID of 40 or 64 lowercase hex digits, and the diff must exit 0. If not, the step is skipped, and the run summary holds `TRACEABILITY: DEGRADED (wave base unusable)`.
|
|
353
|
+
- A Review agent with no patch file and no usable diff range returns `reviewed: false`. After one retry, the engine records a coverage gap, and the run verdict is never PASS.
|
|
354
|
+
|
|
355
|
+
### Upgrade notes — Level readers
|
|
356
|
+
|
|
357
|
+
**Stale-install window:**
|
|
358
|
+
- If an installed `/implement` or `/resolve` is newer than its installed level reference, the reference stays unreadable until you run `devflow init`.
|
|
359
|
+
|
|
360
|
+
### Upgrade notes — Polish by level
|
|
361
|
+
|
|
362
|
+
**What you must do:**
|
|
363
|
+
- The default level, `standard`, now skips Polish in `/implement` and `/resolve`. Run `devflow gates --set full` to keep Polish.
|
|
364
|
+
- A quality rule that you keep at `~/.devflow/rules/quality.md` replaces the shipped one. At `standard` and `lean`, you then lose Polish and do not get the new bullet. Add the bullet to your copy. Or run `devflow rules unshadow quality`, which deletes your copy, and then run `devflow init`.
|
|
365
|
+
|
|
366
|
+
**Stale-install window:**
|
|
367
|
+
- Until you run `devflow init`, your install has no level row that skips Polish, so Polish still runs at every level. An install from 3.7.0 has no level reference at all. The installed quality rule also lacks its new bullet.
|
|
368
|
+
|
|
369
|
+
### Upgrade notes — Harden by level
|
|
370
|
+
|
|
371
|
+
**What you must do:**
|
|
372
|
+
- At `lean`, `/implement` now skips Harden on a docs-only diff. Run `devflow gates --set standard` or `--set full` to keep Harden on every diff.
|
|
373
|
+
|
|
374
|
+
**Stale-install window:**
|
|
375
|
+
- Until you run `devflow init`, your installed level reference has no Harden row, so Harden runs at every level.
|
|
376
|
+
|
|
377
|
+
### Added
|
|
378
|
+
|
|
379
|
+
- **`devflow init` asks for the gate level** ([#543](https://github.com/dean0x/devflow/issues/543), [#507](https://github.com/dean0x/devflow/issues/507)).
|
|
380
|
+
- `devflow gates --set <level>` and `devflow init` set the machine gate level, so a user who runs `init` learns that the level exists.
|
|
381
|
+
An interactive `init` asks for it: `full`, `standard` or `lean`, each with a one-line effect.
|
|
382
|
+
On a first install the prompt starts on `standard`.
|
|
383
|
+
On a re-init it shows the current value and starts on it, so Enter keeps a valid level.
|
|
384
|
+
A malformed or `null` stored value starts the prompt on `full`, and if you accept it, init writes `full` in its place. The machine level that applies does not change.
|
|
385
|
+
- `devflow init --gate-level <full|standard|lean>` sets the machine level with no prompt, in an interactive or a non-interactive run.
|
|
386
|
+
A bad value, or no value, exits 1 before `init` writes anything and names the valid levels. The flag cannot be combined with `--hud-only`.
|
|
387
|
+
`devflow init --recommended` and a non-interactive `init` show no prompt and keep the stored value.
|
|
388
|
+
- The Recommended settings note has a `Gate level:` row.
|
|
389
|
+
The summary at the end of `init` shows the level that is set, and adds `(was X)` when the run changes the machine level that applies.
|
|
390
|
+
`init` writes the same machine default as `devflow gates --set`, and a personal `gateLevel` in a repository's `.devflow/config.json` still wins there.
|
|
391
|
+
- If `~/.devflow/manifest.json` is valid JSON with a `features` object that devflow rejects (a field is missing or mistyped, or a byte-order mark leads), a promptless `init` and `init --hud-only` keep the gate level stored in it, as it is stored, and warn that they kept the level while they replaced the file.
|
|
392
|
+
When the prompt runs, your answer is the level. If you accept a malformed or `null` value, init writes `full`.
|
|
393
|
+
- If the manifest is corrupt, is not JSON, has no `features` object, or is over 1 MiB and also one that devflow rejects, `init` cannot read the level.
|
|
394
|
+
The prompt shows `Current setting: unknown` and starts on `standard`.
|
|
395
|
+
A promptless `init` or `init --hud-only` records no level and warns that `standard` applies and that `devflow gates --set <level>` sets it again.
|
|
396
|
+
`devflow gates --status` words its manifest warning for each case.
|
|
397
|
+
- `devflow init --reset` removes the stored level, and over a rejected manifest the summary names the level it removed, as in `(was full)`.
|
|
398
|
+
A bare `devflow gates --set` names the levels in its error, as `devflow init --gate-level` does.
|
|
399
|
+
- **A lint pack template, and a lean lint pack in Validate** ([#475](https://github.com/dean0x/devflow/issues/475)).
|
|
400
|
+
- The package ships a template in `templates/lint-pack/`: a script, an example config and a README.
|
|
401
|
+
You copy it into your repository and own the copy.
|
|
402
|
+
devflow does not install, update or run the template itself.
|
|
403
|
+
- At `lean`, Phase 6 of `/implement` has Validate run your root `lint-pack` script last, after the build, typecheck, lint and test commands pass.
|
|
404
|
+
Validate finds it as a `package.json` script, else as a `Makefile` target.
|
|
405
|
+
The script reads the lines the branch changed.
|
|
406
|
+
It finds a removed flag that a doc still names, a plan ID or a tombstone phrase in new text, and an oversized function (through your own linter).
|
|
407
|
+
A match fails validation and reaches Fix as a file and line reference.
|
|
408
|
+
- Fix does not edit the lint pack, its config, its build-file entry or any `.gitattributes` to clear a match.
|
|
409
|
+
Fix does not silence the linter to clear a match, with a disable comment or a linter-config change.
|
|
410
|
+
It reports the match under Blockers.
|
|
411
|
+
To clear a match that you judge false, add an allow glob to `.lint-pack.conf`, commit it, and ask `/implement` to re-validate.
|
|
412
|
+
- A pack error does not change the validation result.
|
|
413
|
+
A git older than 2.30, a config that the script cannot read, a linter that did not run and a run that a timeout stops are pack errors, never a clean run.
|
|
414
|
+
A pack error reads `UNVERIFIED` in the `/implement` final report and in the Testing part of the PR body.
|
|
415
|
+
The pack also prints a `pack-changed` line for a changed build-file line in the compared range that names `lint-pack` or `BASE`, a `pack-dirty` line for an uncommitted change to a pack file, and the base it compared.
|
|
416
|
+
Known limit: the pack prints the base it compared (`base <sha>`), but Validate does not check that base yet, and issue [#537](https://github.com/dean0x/devflow/issues/537) adds that check.
|
|
417
|
+
If the project has no `lint-pack` script or target, Validate prints one "not configured" line.
|
|
418
|
+
- The re-validation that you ask `/implement` for runs the pack.
|
|
419
|
+
The re-validation after QA fixes, `/resolve`, `/self-review`, `/release` and `/dynamic-build` do not run it, and no level below `lean` runs it.
|
|
420
|
+
|
|
421
|
+
### Changed
|
|
422
|
+
|
|
423
|
+
- **`/implement` skips Harden at `lean` on a docs-only diff** ([#482](https://github.com/dean0x/devflow/issues/482)). At `lean`, `/implement` skips Phase 4 Harden when the diff is docs-only. The decision reads path names only. It reads no diff content and runs no detection script. Harden is skipped only when all of these hold: the compliance lens is exactly `off`; the branch diff list is not empty; no Code report names a deleted, renamed or moved path; and every changed path is the root `README.md`, the root `CHANGELOG.md` or a `.md` file under the root `docs/`. A path on that list has no segment that starts with a dot, no double quote in its name and no file name that agents load as instructions, in any letter case. No loaded instruction, rules or imported file names the path. A tests-only diff runs Harden. When the decision is unclear, Harden runs. The run report says `Harden: ran` or `Harden: SKIPPED (docs-only diff)` at `lean` only. `full` and `standard` do not change. When Harden runs, it reads the whole branch diff. `/code-review` security runs at every level. The README, the CLI reference and the command reference state the rule. Known limits at `lean` on a docs-only diff: stub and wiring detection does not run; the pitfall check of public text in README and CHANGELOG does not run; a path that only a not-yet-loaded instruction file, such as a nested one, names is not seen; and Harden does not review a delete or a rename that no Code report names ([#571](https://github.com/dean0x/devflow/issues/571)). The docs-only check reads path names. It does not look at symlinks, file-type changes, or docs files that a site generator compiles. Run `devflow gates --set standard` or `--set full` to keep Harden on every diff.
|
|
424
|
+
- **`/implement` and `/resolve` skip Polish at `standard` and `lean`** ([#481](https://github.com/dean0x/devflow/issues/481)).
|
|
425
|
+
- At `standard` and `lean`, `/implement` skips Phase 3 Polish, and `/resolve` skips Phase 6 Polish in each worktree at that level.
|
|
426
|
+
At `full`, both spawn Polish.
|
|
427
|
+
`/self-review`, `/debug` and `/dynamic-build` keep Polish at every level and read no level.
|
|
428
|
+
Harden still reads the whole branch diff, and Validate does not depend on Polish.
|
|
429
|
+
- The quality rule has one bullet that holds a subset of Polish's cleanup list: leftover debug statements, unused imports, unnecessary variables used once right after assignment, nested ternaries, checks the types enforce and catches around code that cannot throw.
|
|
430
|
+
The bullet cuts debug statements everywhere, but it keeps checks and catches at a trust boundary or a fail-closed path.
|
|
431
|
+
The Code agent applies it while it writes.
|
|
432
|
+
At `full` and `standard`, `/code-review` can report these items.
|
|
433
|
+
`devflow gates`, the `devflow init` level hints, the README, `docs/cli-reference.md` and `docs/commands.md` state the effect.
|
|
434
|
+
- Accepted risk: at `standard` and `lean`, no `/implement` agent grades naming and consistency, and Harden reports both as `SKIP (Polish agent)`.
|
|
435
|
+
No rule holds two other Polish items: language-behavior tests and verbose names.
|
|
436
|
+
Harden's test pillar partly covers language-behavior tests.
|
|
437
|
+
- At `standard` and `lean`, `/resolve` skips Polish and never spawns Harden, so debug statements in its fixes that hold no secret or token get no later pass beyond the quality rule and the review.
|
|
438
|
+
At `lean`, `/code-review` does not report the cleanup items.
|
|
439
|
+
Ticket [#568](https://github.com/dean0x/devflow/issues/568) tracks the Harden wording.
|
|
440
|
+
Run `devflow gates --set full` to keep Polish.
|
|
441
|
+
- **`/implement` and `/resolve` read the gate level** ([#480](https://github.com/dean0x/devflow/issues/480)).
|
|
442
|
+
- At `standard` and `lean`, each command reads its level reference one time for each run. At `full`, it reads no reference.
|
|
443
|
+
`/implement` reads it at the start of Phase 3.
|
|
444
|
+
`/resolve` reads it in Step 0d when any worktree is at `standard` or `lean`.
|
|
445
|
+
The references hold the phase rows, and the [#481](https://github.com/dean0x/devflow/issues/481) entry lists the rows that this release adds.
|
|
446
|
+
- The `/implement` report and the `/resolve` display name the level at every level.
|
|
447
|
+
`/resolve` also names it in `resolution-summary.md`.
|
|
448
|
+
`devflow gates` says that `/implement` and `/resolve` read the level.
|
|
449
|
+
- If a reference cannot be read, the command says `level reference unreadable: no level rows applied`.
|
|
450
|
+
It applies no row and keeps the level, so at `lean` the lint pack still runs.
|
|
451
|
+
- No level removes Validate, the CI gate, the evidence claims, the Verification Gate or the compliance directive.
|
|
452
|
+
No level changes the Triage security gate or the ESCALATED route.
|
|
453
|
+
- **Code, Fix and Refactor check the staged diff for secrets or tokens in logs or debug output before each commit** ([#584](https://github.com/dean0x/devflow/issues/584)).
|
|
454
|
+
- Each of these agents checks the staged diff of every file it commits.
|
|
455
|
+
The check runs at every level, wherever `/resolve`, `/implement`, `/debug`, `/dynamic-build` (and dynamic workflows that spawn them) or ambient mode spawn these agents.
|
|
456
|
+
Run `devflow init` to install the updated agents.
|
|
457
|
+
- **`/implement`, `/code-review`, `/bug-analysis` and `/resolve` check branch names against an allowed set** ([#495](https://github.com/dean0x/devflow/issues/495)).
|
|
458
|
+
- A base branch name outside the allowed set, or one that git refuses, stops the run. The message states the set.
|
|
459
|
+
In `/code-review` multi-worktree mode, a rejected base blocks only that worktree.
|
|
460
|
+
- An incremental `/code-review` or `/bug-analysis` run takes the full range when it cannot use the stored review head.
|
|
461
|
+
A failed patch write in `/code-review` stops the run.
|
|
462
|
+
|
|
463
|
+
### Fixed
|
|
464
|
+
|
|
465
|
+
- **`/implement`, `/code-review`, `/bug-analysis` and `/resolve` use a fresh base for branch diffs** ([#495](https://github.com/dean0x/devflow/issues/495)).
|
|
466
|
+
- A new script, `resolve-base.cjs`, makes at most one fetch of the base branch, picks the base by one stated rule and prints one status line.
|
|
467
|
+
The fetch updates only the remote-tracking ref of the base branch, and credential prompts are off for it.
|
|
468
|
+
The branch diff starts at the fork point of that base and `HEAD`.
|
|
469
|
+
- The fetch stops after 45 seconds, each local git call stops after 30 seconds, and one run has a budget of 100 seconds.
|
|
470
|
+
A local git call that gives no answer reports `resolver-unavailable`.
|
|
471
|
+
A normal `/implement` run fetches the base branch once, and a re-validation that you ask for can add one more fetch.
|
|
472
|
+
- When the fetch fails or times out, `/implement`, `/code-review` and `/bug-analysis` use the best base they have and print a warning.
|
|
473
|
+
Known limit: `/resolve` uses that base without a warning.
|
|
474
|
+
- When no usable base exists, for example in a shallow clone without the base history, `/implement` stops, and `/code-review` and `/bug-analysis` stop on a full-range run.
|
|
475
|
+
Each names the cause and a fix.
|
|
476
|
+
`/resolve` takes its branch diff from the Git agent's `validate-branch`, which returns BLOCKED in that case.
|
|
477
|
+
- Run `devflow init` after you update, to install the script and the updated commands.
|
|
478
|
+
- **SessionStart loads the current working memory once** ([#591](https://github.com/dean0x/devflow/issues/591)).
|
|
479
|
+
- It does not load pre-compaction memory snapshots, also when a snapshot is newer or the current memory is missing.
|
|
480
|
+
- SessionStart does not delete or move the existing `backup.json` file. The next PreCompact writes it again with Git state only.
|
|
481
|
+
|
|
482
|
+
---
|
|
483
|
+
|
|
8
484
|
## [3.7.0] - 2026-10-16
|
|
9
485
|
|
|
10
486
|
### Upgrade notes — Gate level
|
|
@@ -1751,7 +2227,9 @@ devflow init
|
|
|
1751
2227
|
|
|
1752
2228
|
---
|
|
1753
2229
|
|
|
1754
|
-
[Unreleased]: https://github.com/dean0x/devflow/compare/v3.
|
|
2230
|
+
[Unreleased]: https://github.com/dean0x/devflow/compare/v3.8.0...HEAD
|
|
2231
|
+
[3.9.0]: https://github.com/dean0x/devflow/compare/v3.8.0...v3.9.0
|
|
2232
|
+
[3.8.0]: https://github.com/dean0x/devflow/compare/v3.7.0...v3.8.0
|
|
1755
2233
|
[3.7.0]: https://github.com/dean0x/devflow/compare/v3.6.0...v3.7.0
|
|
1756
2234
|
[3.6.0]: https://github.com/dean0x/devflow/compare/v3.5.0...v3.6.0
|
|
1757
2235
|
[3.5.0]: https://github.com/dean0x/devflow/compare/v3.4.0...v3.5.0
|