devflow-kit 2.5.0 → 3.0.1
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 +82 -0
- package/README.md +44 -19
- package/dist/agents/git.md +13 -15
- package/dist/cli/commands/ambient.js +160 -145
- package/dist/cli/commands/capture.js +29 -55
- package/dist/cli/commands/compliance.js +32 -61
- package/dist/cli/commands/context.js +17 -32
- package/dist/cli/commands/debug.js +65 -26
- package/dist/cli/commands/flags.js +3 -3
- package/dist/cli/commands/hud.js +34 -10
- package/dist/cli/commands/init-seed.js +40 -4
- package/dist/cli/commands/init.js +249 -271
- package/dist/cli/commands/install-report.js +10 -15
- package/dist/cli/commands/knowledge/index.js +1 -1
- package/dist/cli/commands/knowledge/toggle.js +11 -3
- package/dist/cli/commands/learning.js +52 -37
- package/dist/cli/commands/legacy-hooks.js +11 -14
- package/dist/cli/commands/memory.js +67 -78
- package/dist/cli/commands/proxy.js +23 -41
- package/dist/cli/commands/security.js +5 -13
- package/dist/cli/commands/skills.js +21 -3
- package/dist/cli/commands/tracker.js +100 -228
- package/dist/cli/commands/uninstall.js +343 -138
- package/dist/commands/bug-analysis.md +38 -12
- package/dist/commands/code-review.md +70 -21
- package/dist/commands/debug.md +37 -7
- package/dist/commands/dynamic-build.md +66 -17
- package/dist/commands/dynamic-plan.md +19 -8
- package/dist/commands/dynamic-profile.md +24 -10
- package/dist/commands/dynamic-tickets.md +22 -11
- package/dist/commands/explore.md +37 -7
- package/dist/commands/implement.md +96 -32
- package/dist/commands/plan.md +62 -19
- package/dist/commands/release.md +2 -2
- package/dist/commands/research.md +34 -8
- package/dist/commands/resolve.md +65 -17
- package/dist/commands/self-review.md +45 -9
- package/dist/core/compliance-compose.js +27 -27
- package/dist/core/evidence-policy.js +240 -24
- package/dist/core/feature-config.js +94 -25
- package/dist/core/feature-switch.js +1 -1
- package/dist/core/flags.js +30 -2
- package/dist/core/fs-atomic.js +27 -0
- package/dist/core/hook-log-dirs.js +104 -0
- package/dist/core/learning-tuning-config.js +5 -3
- package/dist/core/ledger-root.js +102 -0
- package/dist/core/manifest.js +6 -4
- package/dist/core/mds-variants.js +34 -97
- package/dist/core/migrations.js +49 -23
- package/dist/core/plugins.js +5 -4
- package/dist/core/project-paths.js +0 -17
- package/dist/core/same-location.js +25 -0
- package/dist/core/tracker.js +226 -139
- package/dist/hud/components/config-counts.js +15 -4
- package/dist/hud/components/learning-counts.js +14 -0
- package/dist/hud/config.js +2 -1
- package/dist/hud/cost-history.js +2 -4
- package/dist/hud/git.js +52 -7
- package/dist/hud/index.js +7 -9
- package/dist/skills/git/references/pr/check-merge-readiness.md +1 -1
- package/dist/skills/git/references/pr/ensure-pr-ready.md +1 -1
- package/dist/skills/git/references/pr/update-pr-evidence.md +1 -1
- package/dist/skills/git/references/tracker/_mcp.md +1 -1
- package/dist/skills/git/references/tracker/github/backlink-shipped-issues.md +1 -1
- package/dist/skills/git/references/tracker/github/ensure-traceable-issue.md +1 -1
- package/dist/skills/git/references/tracker/github/gather-release-evidence.md +2 -2
- package/dist/skills/git/references/tracker/github/manage-debt.md +3 -3
- package/dist/skills/git/references/tracker/jira/backlink-shipped-issues.md +1 -1
- package/dist/skills/git/references/tracker/jira/ensure-traceable-issue.md +1 -1
- package/dist/skills/git/references/tracker/jira/gather-release-evidence.md +2 -2
- package/dist/skills/git/references/tracker/jira/manage-debt.md +1 -1
- package/dist/skills/git/references/tracker/jira/post-wave-report.md +1 -1
- package/dist/skills/git/references/tracker/jira/setup-task.md +1 -1
- package/dist/skills/git/references/tracker/linear/backlink-shipped-issues.md +1 -1
- package/dist/skills/git/references/tracker/linear/ensure-traceable-issue.md +1 -1
- package/dist/skills/git/references/tracker/linear/gather-release-evidence.md +2 -2
- package/dist/skills/git/references/tracker/linear/manage-debt.md +1 -1
- package/dist/skills/git/references/tracker/linear/post-wave-report.md +1 -1
- package/dist/skills/git/references/tracker/linear/setup-task.md +1 -1
- package/dist/targets/claude-code/claude-paths.js +59 -57
- package/dist/targets/claude-code/compliance-install.js +49 -65
- package/dist/targets/claude-code/hooks.js +108 -3
- package/dist/targets/claude-code/installer.js +30 -57
- package/dist/targets/claude-code/post-install.js +246 -139
- package/dist/targets/claude-code/tracker-install.js +38 -65
- package/package.json +5 -4
- package/src/assets/agents/code.md +4 -3
- package/src/assets/agents/design.md +1 -0
- package/src/assets/agents/git.mds +55 -57
- package/src/assets/agents/knowledge.md +2 -2
- package/src/assets/agents/review.md +3 -1
- package/src/assets/agents/tracker.md +37 -30
- package/src/assets/commands/_partials/_compliance.mds +19 -1
- package/src/assets/commands/_partials/_decisions.mds +15 -3
- package/src/assets/commands/_partials/_docs_root.mds +35 -0
- package/src/assets/commands/_partials/_engine.mds +2 -2
- package/src/assets/commands/_partials/_evidence_policy.mds +3 -3
- package/src/assets/commands/_partials/_factory.mds +1 -1
- package/src/assets/commands/_partials/_knowledge.mds +27 -9
- package/src/assets/commands/_partials/_plan_contract.mds +2 -2
- package/src/assets/commands/_partials/_preamble.mds +1 -1
- package/src/assets/commands/_partials/_publication.mds +6 -2
- package/src/assets/commands/_partials/_settings.mds +28 -0
- package/src/assets/commands/_partials/_ticket_template.mds +3 -3
- package/src/assets/commands/_partials/_tracker.mds +4 -4
- package/src/assets/commands/_partials/_wave.mds +4 -4
- package/src/assets/commands/bug-analysis.mds +19 -17
- package/src/assets/commands/code-review.mds +39 -33
- package/src/assets/commands/debug.mds +4 -5
- package/src/assets/commands/dynamic-build.mds +75 -53
- package/src/assets/commands/dynamic-plan.mds +20 -15
- package/src/assets/commands/dynamic-profile.mds +24 -11
- package/src/assets/commands/dynamic-tickets.mds +25 -20
- package/src/assets/commands/explore.mds +4 -5
- package/src/assets/commands/implement.mds +58 -45
- package/src/assets/commands/plan.mds +34 -29
- package/src/assets/commands/release.md +2 -2
- package/src/assets/commands/research.mds +11 -9
- package/src/assets/commands/resolve.mds +41 -39
- package/src/assets/commands/self-review.mds +24 -25
- package/src/assets/mds/git/_pr.mds +61 -61
- package/src/assets/mds/git/_references.mds +19 -19
- package/src/assets/mds/tracker/_common.mds +8 -8
- package/src/assets/mds/tracker/_github.mds +71 -71
- package/src/assets/mds/tracker/_jira.mds +74 -74
- package/src/assets/mds/tracker/_linear.mds +75 -75
- package/src/assets/mds/tracker/_mcp.mds +23 -17
- package/src/assets/scripts/hooks/background-memory-update +35 -19
- package/src/assets/scripts/hooks/capture-prompt +18 -12
- package/src/assets/scripts/hooks/capture-question +18 -12
- package/src/assets/scripts/hooks/capture-turn +27 -17
- package/src/assets/scripts/hooks/debug-trace +11 -6
- package/src/assets/scripts/hooks/ensure-devflow-init +33 -6
- package/src/assets/scripts/hooks/ensure-proxy +9 -8
- package/src/assets/scripts/hooks/ensure-root-gitignore +111 -36
- package/src/assets/scripts/hooks/git-marker +48 -0
- package/src/assets/scripts/hooks/json-helper.cjs +6 -1
- package/src/assets/scripts/hooks/lib/project-paths.cjs +0 -19
- package/src/assets/scripts/hooks/log-paths +80 -0
- package/src/assets/scripts/hooks/memory-worker +17 -15
- package/src/assets/scripts/hooks/pre-compact-memory +41 -16
- package/src/assets/scripts/hooks/queue-append +104 -30
- package/src/assets/scripts/hooks/resolve-project-root +101 -7
- package/src/assets/scripts/hooks/session-start-context +289 -122
- package/src/assets/scripts/hooks/session-start-memory +35 -16
- package/src/assets/scripts/lib/project-config.cjs +633 -0
- package/src/assets/scripts/resolve-evidence-policy.cjs +300 -220
- package/src/assets/scripts/resolve-settings.cjs +1054 -0
- package/src/assets/scripts/verify-evidence.cjs +1 -1
- package/src/assets/skills/compliance/SKILL.md +2 -2
- package/src/assets/skills/docs-framework/SKILL.md +6 -7
- package/src/assets/skills/docs-framework/references/patterns.md +10 -17
- package/src/assets/skills/gap-analysis/SKILL.md +2 -2
- package/src/assets/skills/git/references/github-api.md +9 -9
- package/src/assets/skills/git/references/patterns.md +1 -1
- package/src/assets/skills/worktree-support/SKILL.md +1 -1
- package/src/assets/skills/worktree-support/references/roots.md +29 -0
- package/src/targets/claude-code/templates/managed-settings.json +25 -9
|
@@ -22,19 +22,27 @@ Run a proactive bug analysis on the current branch by combining static analysis
|
|
|
22
22
|
**Resolve the evidence policy once per run**, from the repository root, before any step reads the values:
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
|
-
node "$
|
|
25
|
+
node "$HOME/.devflow/scripts/resolve-evidence-policy.cjs" 2>/dev/null; echo "exit=$?"
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
Accept the output only when it is exactly two lines: `exit=0` last and, before it, one line of the form `EVIDENCE_POLICY=<required|standard> SOURCE=<file|worktree|default|invalid|error> REF=<branch|none>[ WARN=<remote-unavailable|invalid-file|raised-by-compliance|pr-changes-policy>[,…]] ISSUE_REQUIRED=<true|false> APPLY_CONVENTIONS=<true|false> REQUIRE_NON_AUTHOR_APPROVAL=<true|false>` — these fields, in this order, nothing else, where `<branch>` is a branch name such as `main`. **Anything else** (a non-zero exit, no line, extra text, or a missing, reordered or unlisted field or value) ⇒ use `EVIDENCE_POLICY=required SOURCE=error REF=none ISSUE_REQUIRED=true APPLY_CONVENTIONS=true REQUIRE_NON_AUTHOR_APPROVAL=true` instead.
|
|
29
29
|
|
|
30
30
|
Set `EVIDENCE_POLICY`, `ISSUE_REQUIRED`, `APPLY_CONVENTIONS` and `REQUIRE_NON_AUTHOR_APPROVAL` from the accepted line. Pass agents only the three mechanism inputs, never `EVIDENCE_POLICY`. Report `Evidence policy: {EVIDENCE_POLICY} (source: {SOURCE})`, plus any `WARN` tokens as advisory, once in the final report.
|
|
31
31
|
|
|
32
|
+
**Docs root (D-DOCS-ROOT).** Every `.devflow/docs/` path this command reads or writes lives at the checkout's toplevel, never under the directory the session started in. Resolve `{worktree}` from the start directory — `WORKTREE_PATH` if provided, otherwise cwd (`devflow:worktree-support`) — by running
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
git -C "{start}" rev-parse --show-toplevel
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
and using its one-line output. If the command fails (outside a git repository), `{worktree}` is the start directory itself. Every docs path below is written `{worktree}/.devflow/docs/…`; a repo-relative docs path handed to an agent always travels with a `WORKTREE_PATH` naming the checkout it is relative to.
|
|
39
|
+
|
|
32
40
|
Render the test-plan block from `/implement`'s evidence file, and from nothing else:
|
|
33
41
|
1. `branch_slug` is `git branch --show-current` with every `/` replaced by `-`.
|
|
34
42
|
2. Only when `branch_slug` matches `^[A-Za-z0-9._-]{1,200}$` and the file exists, run (the path double-quoted):
|
|
35
43
|
|
|
36
44
|
```bash
|
|
37
|
-
node "$
|
|
45
|
+
node "$HOME/.devflow/scripts/verify-evidence.cjs" render --plan "{worktree}/.devflow/docs/evidence-{branch_slug}.md"; echo "exit=$?"
|
|
38
46
|
```
|
|
39
47
|
|
|
40
48
|
3. On `exit=0`, `PR_TEST_PLAN_BLOCK` is its stdout byte for byte without that `exit=` line; in every other case it is `(none)`. Nothing here waits on it: the Git agent pastes it only behind its own check, and only into a PR it creates.
|
|
@@ -67,7 +75,7 @@ If `pr_number` is absent or the command fails, set `PR_DESCRIPTION` to `(none)`.
|
|
|
67
75
|
**Produces:** DIFF_RANGE, ANALYSIS_DIR
|
|
68
76
|
**Requires:** BRANCH_INFO
|
|
69
77
|
|
|
70
|
-
1. Check
|
|
78
|
+
1. Check `{worktree}/.devflow/docs/bug-analysis/{branch-slug}/.last-analysis-head`:
|
|
71
79
|
- **If exists AND `--full` NOT set:**
|
|
72
80
|
- Read the SHA from the file
|
|
73
81
|
- Verify reachable: `git cat-file -t {sha}` — if exit code non-zero (rebase invalidated SHA), fall through to full
|
|
@@ -76,7 +84,7 @@ If `pr_number` is absent or the command fails, set `PR_DESCRIPTION` to `(none)`.
|
|
|
76
84
|
- **If not exists, unreachable SHA, or `--full`:**
|
|
77
85
|
- Set `DIFF_RANGE` to `{base_branch}...HEAD`
|
|
78
86
|
2. Generate timestamp: `YYYY-MM-DD_HHMM`. If directory already exists (same-minute collision), append seconds (`YYYY-MM-DD_HHMMSS`).
|
|
79
|
-
3. Create timestamped analysis directory: `mkdir -p
|
|
87
|
+
3. Create timestamped analysis directory: `mkdir -p "{worktree}/.devflow/docs/bug-analysis/{branch-slug}/{timestamp}/"`
|
|
80
88
|
4. Set `ANALYSIS_DIR` to that path.
|
|
81
89
|
|
|
82
90
|
#### Step 2b: Check Changed Files
|
|
@@ -175,16 +183,28 @@ If no tool produced findings: set `STATIC_FINDINGS` to `(none)`.
|
|
|
175
183
|
|
|
176
184
|
### Load DECISIONS_CONTEXT
|
|
177
185
|
|
|
178
|
-
|
|
186
|
+
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`):
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
git -C "{start}" rev-parse --path-format=absolute --show-toplevel --git-common-dir
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Line 1 is the checkout's toplevel, line 2 the repository's common git directory. A git older than 2.31 echoes `--path-format=absolute` back as a line of its own first. `{ledger}` is the first of these that applies:
|
|
193
|
+
|
|
194
|
+
1. **The main worktree** — line 2 without its trailing `/.git`, when the output is exactly two lines each beginning with `/`, line 2 ends in `/.git`, and the directory left once it is removed is not your home directory and contains a `.devflow/` directory.
|
|
195
|
+
2. **The toplevel** — line 1, or on an older git the line after the echoed flag.
|
|
196
|
+
3. **The start directory itself** — when the command failed or printed no absolute toplevel (outside a git repository).
|
|
197
|
+
|
|
198
|
+
This is the rule the learning hooks apply (D-LEDGER-MAIN-WORKTREE, D-PROMPT-ROOT), so you read the index the Learning agent writes.
|
|
179
199
|
|
|
180
200
|
**Step 1 — Read the pre-rendered index:**
|
|
181
201
|
|
|
182
|
-
Attempt to read `{
|
|
202
|
+
Attempt to read `{ledger}/.devflow/learning/index.md`.
|
|
183
203
|
|
|
184
204
|
- If the file exists and contains non-empty content: use that content as `DECISIONS_CONTEXT`.
|
|
185
205
|
- If the file is absent or empty: set `DECISIONS_CONTEXT` to `(none)`.
|
|
186
206
|
|
|
187
|
-
|
|
207
|
+
The index is one direct file read, written at render time by `render-decisions.cjs` alongside `decisions.md`/`pitfalls.md` — no `.cjs` script runs here, and the index's own footer names the files that hold each entry's full body.
|
|
188
208
|
|
|
189
209
|
**Step 2 — Apply decisions using `devflow:apply-decisions`:**
|
|
190
210
|
|
|
@@ -194,7 +214,13 @@ When `DECISIONS_CONTEXT` is not `(none)`, follow `devflow:apply-decisions` to sc
|
|
|
194
214
|
|
|
195
215
|
### Load Feature Knowledge
|
|
196
216
|
|
|
197
|
-
Resolve the
|
|
217
|
+
Resolve `{worktree}` as the checkout's toplevel, because feature knowledge bases are committed with the branch (D-PROMPT-ROOT): from the start directory — `WORKTREE_PATH` if provided, otherwise cwd (`devflow:worktree-support`) — run
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
git -C "{start}" rev-parse --show-toplevel
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
and use its one-line output. If the command fails (outside a git repository), `{worktree}` is the start directory itself. All paths below are relative to `{worktree}`.
|
|
198
224
|
|
|
199
225
|
**Step 1 — Read the index cache:**
|
|
200
226
|
|
|
@@ -229,11 +255,11 @@ Concatenate the selected KNOWLEDGE.md files under slug headers:
|
|
|
229
255
|
|
|
230
256
|
If no KBs exist, no KBs are relevant, or `.devflow/features/` is absent, set `FEATURE_KNOWLEDGE` to `(none)`.
|
|
231
257
|
|
|
232
|
-
**
|
|
258
|
+
**One git call, then direct file reads — no `.cjs` script.** After resolving `{worktree}`, this step is 1 index read (or N frontmatter reads on fallback), bounded by KB count.
|
|
233
259
|
|
|
234
260
|
#### Plan Artifact
|
|
235
261
|
|
|
236
|
-
1. List
|
|
262
|
+
1. List `{worktree}/.devflow/docs/design/*.md` — sort descending by filename (timestamps are naturally sortable), scan the 10 most recent
|
|
237
263
|
2. Read the most recent file if it exists
|
|
238
264
|
3. Extract `## Acceptance Criteria` section → parse into table: `| ID | Criterion | Type | Testable Condition |`
|
|
239
265
|
4. Set `PLAN_CONTEXT` to plan summary; `ACCEPTANCE_RULES` to the table
|
|
@@ -303,7 +329,7 @@ Output: {ANALYSIS_DIR}/bug-analysis-summary.md"
|
|
|
303
329
|
|
|
304
330
|
**Requires:** BRANCH_INFO, ANALYSIS_DIR
|
|
305
331
|
|
|
306
|
-
1. Write current HEAD SHA to
|
|
332
|
+
1. Write current HEAD SHA to `{worktree}/.devflow/docs/bug-analysis/{branch-slug}/.last-analysis-head`
|
|
307
333
|
2. Report to user:
|
|
308
334
|
|
|
309
335
|
```
|
|
@@ -354,7 +380,7 @@ Run `/resolve` to process and fix these findings.
|
|
|
354
380
|
├─ Phase 3: Context Loading
|
|
355
381
|
│ ├─ index.md (pre-rendered) → DECISIONS_CONTEXT
|
|
356
382
|
│ ├─ Feature knowledge load → FEATURE_KNOWLEDGE
|
|
357
|
-
│ └─
|
|
383
|
+
│ └─ {worktree}/.devflow/docs/design/*.md → PLAN_CONTEXT + ACCEPTANCE_RULES
|
|
358
384
|
│
|
|
359
385
|
├─ Phase 4: File Analysis
|
|
360
386
|
│ └─ Detect active focuses (security + functional always; integration + usability conditional)
|
|
@@ -24,18 +24,32 @@ Run a comprehensive code review of the current branch by spawning parallel revie
|
|
|
24
24
|
|
|
25
25
|
1. **Discover reviewable 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
|
|
27
|
+
- See the `devflow:worktree-support` skill for the full 7-step algorithm and canonical protected branch list
|
|
28
28
|
2. **If `--path` flag provided:** use only that worktree, skip discovery
|
|
29
29
|
**`--path` validation**: Before proceeding, verify the path exists as a directory and appears in `git worktree list` output. If not: report error and stop.
|
|
30
30
|
3. **If only 1 reviewable worktree** (the common case): proceed as single-worktree flow — zero behavior change
|
|
31
31
|
4. **If multiple reviewable worktrees:** report "Found N worktrees with reviewable branches: {list with paths and branches}" and proceed with multi-worktree flow
|
|
32
32
|
|
|
33
|
-
#### Step 0b: Resolve
|
|
33
|
+
#### Step 0b: Resolve the compliance lens
|
|
34
34
|
|
|
35
|
-
**Produces:**
|
|
35
|
+
**Produces:** COMPLIANCE_ACTIVE, COMPLIANCE_FRAMEWORKS
|
|
36
36
|
|
|
37
|
-
**Resolve
|
|
38
|
-
|
|
37
|
+
**Resolve the compliance lens** for each worktree root, from its settings line (every framework reference is installed on every machine, so no file check decides it):
|
|
38
|
+
|
|
39
|
+
**Resolve the settings line** once per worktree root, reusing a line this run already resolved for the same root. `{root}` is the worktree the values are for — the repository root when the run has one worktree:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
node "$HOME/.devflow/scripts/resolve-settings.cjs" "{root}" 2>/dev/null; echo "exit=$?"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Accept the output only when it is exactly two lines: `exit=0` last and, before it, one line of the form `TRACKER=<github|jira|linear> TRACKER_SOURCE=<project|personal|machine|default> TRACKER_WARN=<none|mismatch|invalid> SITE=<none|https://<host>> KEY=<none|<key>> REVIEW_PUBLICATION=<off|auto|full> COMPLIANCE=<off|generic|<id>[,<id>…]> MEMORY=<on|off> LEARNING=<on|off> KNOWLEDGE=<on|off>` — these fields, in this order, nothing else, where `<host>` is a lowercase dotted host name alone, `<key>` is 2–10 of `A-Z`, `0-9` and `_` starting with a letter, and each `<id>` is one of `gdpr`, `hipaa`, `pci-dss`, `soc2`, `iso-27001`, `sox`. **Anything else** (a non-zero exit, no line, extra text, or a missing, reordered or unlisted field or value) ⇒ use `TRACKER=github TRACKER_SOURCE=default TRACKER_WARN=invalid SITE=none KEY=none REVIEW_PUBLICATION=off COMPLIANCE=generic MEMORY=on LEARNING=on KNOWLEDGE=off` instead.
|
|
46
|
+
|
|
47
|
+
The accepted line is the only source of these values: the script alone folds the committed `.devflow/project.json`, the personal `.devflow/config.json` and the machine manifest.
|
|
48
|
+
|
|
49
|
+
**Set the compliance lens** from that line: `COMPLIANCE_FRAMEWORKS` is the settings line's `COMPLIANCE` with `generic` written `none`: `off`, `none`, or the framework ids the machine and this repository declare.
|
|
50
|
+
|
|
51
|
+
`COMPLIANCE_ACTIVE` is `true` unless `COMPLIANCE_FRAMEWORKS` is `off`.
|
|
52
|
+
Keep each worktree's values for every downstream phase of that worktree.
|
|
39
53
|
|
|
40
54
|
#### Step 0b-ii: Resolve the evidence policy
|
|
41
55
|
|
|
@@ -44,7 +58,7 @@ Reuse this result for every worktree and every downstream phase.
|
|
|
44
58
|
**Resolve the evidence policy once per run**, from the repository root, before any step reads the values:
|
|
45
59
|
|
|
46
60
|
```bash
|
|
47
|
-
node "$
|
|
61
|
+
node "$HOME/.devflow/scripts/resolve-evidence-policy.cjs" 2>/dev/null; echo "exit=$?"
|
|
48
62
|
```
|
|
49
63
|
|
|
50
64
|
Accept the output only when it is exactly two lines: `exit=0` last and, before it, one line of the form `EVIDENCE_POLICY=<required|standard> SOURCE=<file|worktree|default|invalid|error> REF=<branch|none>[ WARN=<remote-unavailable|invalid-file|raised-by-compliance|pr-changes-policy>[,…]] ISSUE_REQUIRED=<true|false> APPLY_CONVENTIONS=<true|false> REQUIRE_NON_AUTHOR_APPROVAL=<true|false>` — these fields, in this order, nothing else, where `<branch>` is a branch name such as `main`. **Anything else** (a non-zero exit, no line, extra text, or a missing, reordered or unlisted field or value) ⇒ use `EVIDENCE_POLICY=required SOURCE=error REF=none ISSUE_REQUIRED=true APPLY_CONVENTIONS=true REQUIRE_NON_AUTHOR_APPROVAL=true` instead.
|
|
@@ -67,7 +81,7 @@ Render the test-plan block (per worktree) from `/implement`'s evidence file, and
|
|
|
67
81
|
2. Only when `branch_slug` matches `^[A-Za-z0-9._-]{1,200}$` and the file exists, run (the path double-quoted):
|
|
68
82
|
|
|
69
83
|
```bash
|
|
70
|
-
node "$
|
|
84
|
+
node "$HOME/.devflow/scripts/verify-evidence.cjs" render --plan "{worktree}/.devflow/docs/evidence-{branch_slug}.md"; echo "exit=$?"
|
|
71
85
|
```
|
|
72
86
|
|
|
73
87
|
3. On `exit=0`, `PR_TEST_PLAN_BLOCK` is its stdout byte for byte without that `exit=` line; in every other case it is `(none)`. Nothing here waits on it: the Git agent pastes it only behind its own check, and only into a PR it creates.
|
|
@@ -162,16 +176,26 @@ MAX_REVIEW_CYCLES = 10
|
|
|
162
176
|
|
|
163
177
|
For each reviewable worktree, call:
|
|
164
178
|
|
|
165
|
-
**Resolve
|
|
179
|
+
**Resolve the settings line** once per worktree root, reusing a line this run already resolved for the same root. `{root}` is the worktree the values are for — the repository root when the run has one worktree:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
node "$HOME/.devflow/scripts/resolve-settings.cjs" "{root}" 2>/dev/null; echo "exit=$?"
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Accept the output only when it is exactly two lines: `exit=0` last and, before it, one line of the form `TRACKER=<github|jira|linear> TRACKER_SOURCE=<project|personal|machine|default> TRACKER_WARN=<none|mismatch|invalid> SITE=<none|https://<host>> KEY=<none|<key>> REVIEW_PUBLICATION=<off|auto|full> COMPLIANCE=<off|generic|<id>[,<id>…]> MEMORY=<on|off> LEARNING=<on|off> KNOWLEDGE=<on|off>` — these fields, in this order, nothing else, where `<host>` is a lowercase dotted host name alone, `<key>` is 2–10 of `A-Z`, `0-9` and `_` starting with a letter, and each `<id>` is one of `gdpr`, `hipaa`, `pci-dss`, `soc2`, `iso-27001`, `sox`. **Anything else** (a non-zero exit, no line, extra text, or a missing, reordered or unlisted field or value) ⇒ use `TRACKER=github TRACKER_SOURCE=default TRACKER_WARN=invalid SITE=none KEY=none REVIEW_PUBLICATION=off COMPLIANCE=generic MEMORY=on LEARNING=on KNOWLEDGE=off` instead.
|
|
186
|
+
|
|
187
|
+
The accepted line is the only source of these values: the script alone folds the committed `.devflow/project.json`, the personal `.devflow/config.json` and the machine manifest.
|
|
188
|
+
|
|
189
|
+
**Resolve `REVIEW_PUBLICATION` per worktree:** take `REVIEW_PUBLICATION` from that worktree's settings line, with `{root}` the worktree's root — multi-worktree repos may resolve different values per worktree. The line already caps the personal choice at the team's (D-PUBLICATION-CEILING), so it is `off`, `auto` or `full`, and `off` when the line was unresolvable.
|
|
166
190
|
|
|
167
|
-
**Evidence stub:** only when `EVIDENCE_POLICY` is `required`, a resolved `off` becomes `stub`, so a counts-only record still reaches the PR. `stub` is never a config value:
|
|
191
|
+
**Evidence stub:** only when `EVIDENCE_POLICY` is `required`, a resolved `off` becomes `stub`, so a counts-only record still reaches the PR. `stub` is never a config value: the settings line never carries it.
|
|
168
192
|
|
|
169
193
|
Note: `auto` is NOT fail-open — under `auto`, the Git agent probes the repository visibility and treats any error or unrecognised value as PUBLIC (mode STUB). What each value does is decided by the Git agent's publication gate (`references/publication-gate.md` step 2); this partial only resolves the value.
|
|
170
194
|
|
|
171
195
|
### Phase 1: Analyze Changed Files
|
|
172
196
|
|
|
173
197
|
**Produces:** REVIEW_FOCUS_LIST
|
|
174
|
-
**Requires:** DIFF_RANGE,
|
|
198
|
+
**Requires:** DIFF_RANGE, COMPLIANCE_ACTIVE (from Step 0b)
|
|
175
199
|
|
|
176
200
|
Per worktree, detect file types in diff using `DIFF_RANGE` to determine conditional reviews.
|
|
177
201
|
|
|
@@ -188,30 +212,48 @@ Per worktree, detect file types in diff using `DIFF_RANGE` to determine conditio
|
|
|
188
212
|
| DB/migration files | database |
|
|
189
213
|
| Dependency files changed | dependencies |
|
|
190
214
|
| Docs or significant code | documentation |
|
|
191
|
-
|
|
|
215
|
+
| COMPLIANCE_ACTIVE AND diff touches regulated surface | compliance |
|
|
192
216
|
|
|
193
|
-
If `
|
|
217
|
+
If `COMPLIANCE_ACTIVE` AND the diff touches regulated surface (data models, auth flows, logging/observability, payments, IaC, retention): add `compliance` to REVIEW_FOCUS_LIST for this worktree.
|
|
194
218
|
|
|
195
|
-
**Language focus presence gate.** The eight language focuses — `typescript`, `react`, `accessibility`, `ui-design`, `go`, `java`, `python`, `rust` — ship with optional plugins, so their pattern skills are installed only when the user selected that plugin. Gate them
|
|
219
|
+
**Language focus presence gate.** The eight language focuses — `typescript`, `react`, `accessibility`, `ui-design`, `go`, `java`, `python`, `rust` — ship with optional plugins, so their pattern skills are installed only when the user selected that plugin. Gate them by presence: for each language focus the table above would add, check whether `{claude_dir}/skills/devflow:{focus}/SKILL.md` exists, `{claude_dir}` being Claude Code's directory as the installer resolves it — `CLAUDE_CONFIG_DIR` when that is set to an absolute path, else `$HOME/.claude` (D-CLAUDE-DIR-PROMPTS). Run one read-only, silent check per candidate focus:
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
d="${CLAUDE_CONFIG_DIR:-}"; case "$d" in /*) ;; *) d="$HOME/.claude" ;; esac; test -f "$d/skills/devflow:{focus}/SKILL.md"; echo "exit=$?"
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Only `exit=0` means the skill is installed. On any other result, do NOT add that focus to `REVIEW_FOCUS_LIST` and do NOT spawn a Review agent for it — the file-type condition alone never spawns a language focus. The eight core focuses are unconditional and are never presence-gated.
|
|
196
226
|
|
|
197
227
|
### Phase 1b: Load Decisions Index
|
|
198
228
|
|
|
199
|
-
**Produces:** DECISIONS_CONTEXT, FEATURE_KNOWLEDGE,
|
|
229
|
+
**Produces:** DECISIONS_CONTEXT, FEATURE_KNOWLEDGE, COMPLIANCE_FRAMEWORKS (carried from Step 0b)
|
|
200
230
|
|
|
201
231
|
**Load Companion Skills** — Load via Skill tool: `devflow:quality-gates`, `devflow:software-design`. If a skill fails to load, continue without it.
|
|
202
232
|
|
|
203
233
|
### Load DECISIONS_CONTEXT
|
|
204
234
|
|
|
205
|
-
|
|
235
|
+
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`):
|
|
236
|
+
|
|
237
|
+
```bash
|
|
238
|
+
git -C "{start}" rev-parse --path-format=absolute --show-toplevel --git-common-dir
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Line 1 is the checkout's toplevel, line 2 the repository's common git directory. A git older than 2.31 echoes `--path-format=absolute` back as a line of its own first. `{ledger}` is the first of these that applies:
|
|
242
|
+
|
|
243
|
+
1. **The main worktree** — line 2 without its trailing `/.git`, when the output is exactly two lines each beginning with `/`, line 2 ends in `/.git`, and the directory left once it is removed is not your home directory and contains a `.devflow/` directory.
|
|
244
|
+
2. **The toplevel** — line 1, or on an older git the line after the echoed flag.
|
|
245
|
+
3. **The start directory itself** — when the command failed or printed no absolute toplevel (outside a git repository).
|
|
246
|
+
|
|
247
|
+
This is the rule the learning hooks apply (D-LEDGER-MAIN-WORKTREE, D-PROMPT-ROOT), so you read the index the Learning agent writes.
|
|
206
248
|
|
|
207
249
|
**Step 1 — Read the pre-rendered index:**
|
|
208
250
|
|
|
209
|
-
Attempt to read `{
|
|
251
|
+
Attempt to read `{ledger}/.devflow/learning/index.md`.
|
|
210
252
|
|
|
211
253
|
- If the file exists and contains non-empty content: use that content as `DECISIONS_CONTEXT`.
|
|
212
254
|
- If the file is absent or empty: set `DECISIONS_CONTEXT` to `(none)`.
|
|
213
255
|
|
|
214
|
-
|
|
256
|
+
The index is one direct file read, written at render time by `render-decisions.cjs` alongside `decisions.md`/`pitfalls.md` — no `.cjs` script runs here, and the index's own footer names the files that hold each entry's full body.
|
|
215
257
|
|
|
216
258
|
**Step 2 — Apply decisions using `devflow:apply-decisions`:**
|
|
217
259
|
|
|
@@ -221,7 +263,13 @@ This produces a compact index of active ADR/PF entries. Pass `DECISIONS_CONTEXT`
|
|
|
221
263
|
|
|
222
264
|
### Load Feature Knowledge
|
|
223
265
|
|
|
224
|
-
Resolve the
|
|
266
|
+
Resolve `{worktree}` as the checkout's toplevel, because feature knowledge bases are committed with the branch (D-PROMPT-ROOT): from the start directory — `WORKTREE_PATH` if provided, otherwise cwd (`devflow:worktree-support`) — run
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
git -C "{start}" rev-parse --show-toplevel
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
and use its one-line output. If the command fails (outside a git repository), `{worktree}` is the start directory itself. All paths below are relative to `{worktree}`.
|
|
225
273
|
|
|
226
274
|
**Step 1 — Read the index cache:**
|
|
227
275
|
|
|
@@ -256,7 +304,7 @@ Concatenate the selected KNOWLEDGE.md files under slug headers:
|
|
|
256
304
|
|
|
257
305
|
If no KBs exist, no KBs are relevant, or `.devflow/features/` is absent, set `FEATURE_KNOWLEDGE` to `(none)`.
|
|
258
306
|
|
|
259
|
-
**
|
|
307
|
+
**One git call, then direct file reads — no `.cjs` script.** After resolving `{worktree}`, this step is 1 index read (or N frontmatter reads on fallback), bounded by KB count.
|
|
260
308
|
|
|
261
309
|
Pass `FEATURE_KNOWLEDGE` to all Review agents alongside `DECISIONS_CONTEXT`.
|
|
262
310
|
|
|
@@ -304,6 +352,7 @@ DECISIONS_CONTEXT: {decisions_context}
|
|
|
304
352
|
FEATURE_KNOWLEDGE: {feature_knowledge}
|
|
305
353
|
PR_DESCRIPTION: <pr-description>{pr_description}</pr-description>
|
|
306
354
|
PRIOR_RESOLUTIONS: <prior-resolution-summary>{prior_resolutions}</prior-resolution-summary>
|
|
355
|
+
COMPLIANCE_FRAMEWORKS: {COMPLIANCE_FRAMEWORKS} (compliance focus only)
|
|
307
356
|
If PRIOR_RESOLUTIONS is not (none), follow Cross-Cycle Awareness in review.md.
|
|
308
357
|
Follow devflow:apply-decisions to scan the index and Read full ADR/PF bodies on demand.
|
|
309
358
|
Follow devflow:apply-feature-knowledge for FEATURE_KNOWLEDGE — feature-specific patterns and anti-patterns inform findings.
|
|
@@ -368,7 +417,7 @@ In multi-worktree mode, report results per worktree.
|
|
|
368
417
|
│
|
|
369
418
|
├─ Phase 0: Worktree Discovery & Pre-flight
|
|
370
419
|
│ ├─ Step 0a: git worktree list → filter reviewable
|
|
371
|
-
│ ├─ Step 0b: Resolve
|
|
420
|
+
│ ├─ Step 0b: Resolve the compliance lens
|
|
372
421
|
│ ├─ Step 0c: Git agent (ensure-pr-ready) per worktree [parallel]
|
|
373
422
|
│ ├─ Step 0d: Incremental detection + timestamp setup per worktree
|
|
374
423
|
│ ├─ Step 0e-i: Load prior resolution-summary.md
|
|
@@ -419,7 +468,7 @@ In multi-worktree mode, report results per worktree.
|
|
|
419
468
|
## Backwards Compatibility
|
|
420
469
|
|
|
421
470
|
- **Single worktree**: Auto-discovery finds only one worktree → proceeds exactly as before. Zero behavior change.
|
|
422
|
-
- **Legacy flat layout**: If
|
|
471
|
+
- **Legacy flat layout**: If `{worktree}/.devflow/docs/reviews/{branch-slug}/` contains flat `*.md` files (no timestamped subdirectories), new runs create timestamped subdirectories. Old flat files remain untouched.
|
|
423
472
|
|
|
424
473
|
## Principles
|
|
425
474
|
|
package/dist/commands/debug.md
CHANGED
|
@@ -30,16 +30,28 @@ Investigate bugs by spawning parallel agents, each pursuing a different hypothes
|
|
|
30
30
|
|
|
31
31
|
### Load DECISIONS_CONTEXT
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
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`):
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
git -C "{start}" rev-parse --path-format=absolute --show-toplevel --git-common-dir
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Line 1 is the checkout's toplevel, line 2 the repository's common git directory. A git older than 2.31 echoes `--path-format=absolute` back as a line of its own first. `{ledger}` is the first of these that applies:
|
|
40
|
+
|
|
41
|
+
1. **The main worktree** — line 2 without its trailing `/.git`, when the output is exactly two lines each beginning with `/`, line 2 ends in `/.git`, and the directory left once it is removed is not your home directory and contains a `.devflow/` directory.
|
|
42
|
+
2. **The toplevel** — line 1, or on an older git the line after the echoed flag.
|
|
43
|
+
3. **The start directory itself** — when the command failed or printed no absolute toplevel (outside a git repository).
|
|
44
|
+
|
|
45
|
+
This is the rule the learning hooks apply (D-LEDGER-MAIN-WORKTREE, D-PROMPT-ROOT), so you read the index the Learning agent writes.
|
|
34
46
|
|
|
35
47
|
**Step 1 — Read the pre-rendered index:**
|
|
36
48
|
|
|
37
|
-
Attempt to read `{
|
|
49
|
+
Attempt to read `{ledger}/.devflow/learning/index.md`.
|
|
38
50
|
|
|
39
51
|
- If the file exists and contains non-empty content: use that content as `DECISIONS_CONTEXT`.
|
|
40
52
|
- If the file is absent or empty: set `DECISIONS_CONTEXT` to `(none)`.
|
|
41
53
|
|
|
42
|
-
|
|
54
|
+
The index is one direct file read, written at render time by `render-decisions.cjs` alongside `decisions.md`/`pitfalls.md` — no `.cjs` script runs here, and the index's own footer names the files that hold each entry's full body.
|
|
43
55
|
|
|
44
56
|
**Step 2 — Apply decisions using `devflow:apply-decisions`:**
|
|
45
57
|
|
|
@@ -202,13 +214,27 @@ Ask user via AskUserQuestion: "Want me to implement this fix?"
|
|
|
202
214
|
|
|
203
215
|
### Feature Knowledge Write-Back (Conditional)
|
|
204
216
|
|
|
205
|
-
Resolve the
|
|
217
|
+
Resolve `{worktree}` as the checkout's toplevel, because feature knowledge bases are committed with the branch (D-PROMPT-ROOT): from the start directory — `WORKTREE_PATH` if provided, otherwise cwd (`devflow:worktree-support`) — run
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
git -C "{start}" rev-parse --show-toplevel
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
and use its one-line output. If the command fails (outside a git repository), `{worktree}` is the start directory itself. All paths below are relative to `{worktree}`.
|
|
224
|
+
|
|
225
|
+
**Step 1 — Check the opt-out gate, with `{root}` = `{worktree}`:**
|
|
206
226
|
|
|
207
|
-
**
|
|
227
|
+
**Resolve the settings line** once per worktree root, reusing a line this run already resolved for the same root. `{root}` is the worktree the values are for — the repository root when the run has one worktree:
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
node "$HOME/.devflow/scripts/resolve-settings.cjs" "{root}" 2>/dev/null; echo "exit=$?"
|
|
231
|
+
```
|
|
208
232
|
|
|
209
|
-
|
|
233
|
+
Accept the output only when it is exactly two lines: `exit=0` last and, before it, one line of the form `TRACKER=<github|jira|linear> TRACKER_SOURCE=<project|personal|machine|default> TRACKER_WARN=<none|mismatch|invalid> SITE=<none|https://<host>> KEY=<none|<key>> REVIEW_PUBLICATION=<off|auto|full> COMPLIANCE=<off|generic|<id>[,<id>…]> MEMORY=<on|off> LEARNING=<on|off> KNOWLEDGE=<on|off>` — these fields, in this order, nothing else, where `<host>` is a lowercase dotted host name alone, `<key>` is 2–10 of `A-Z`, `0-9` and `_` starting with a letter, and each `<id>` is one of `gdpr`, `hipaa`, `pci-dss`, `soc2`, `iso-27001`, `sox`. **Anything else** (a non-zero exit, no line, extra text, or a missing, reordered or unlisted field or value) ⇒ use `TRACKER=github TRACKER_SOURCE=default TRACKER_WARN=invalid SITE=none KEY=none REVIEW_PUBLICATION=off COMPLIANCE=generic MEMORY=on LEARNING=on KNOWLEDGE=off` instead.
|
|
210
234
|
|
|
211
|
-
|
|
235
|
+
The accepted line is the only source of these values: the script alone folds the committed `.devflow/project.json`, the personal `.devflow/config.json` and the machine manifest.
|
|
236
|
+
|
|
237
|
+
If the settings line says `KNOWLEDGE=off`, skip write-back entirely. The machine switch (`devflow knowledge --disable`), the repository and the personal settings can each turn knowledge off, and none can turn it back on (D-FEATURES-NARROW-ONLY). The fail-closed line says `KNOWLEDGE=off` too, so an unresolvable line skips write-back.
|
|
212
238
|
|
|
213
239
|
**Step 2 — Evaluate whether write-back is warranted:**
|
|
214
240
|
|
|
@@ -247,6 +273,10 @@ The frontmatter in KNOWLEDGE.md is the source of truth — index.md is only a ca
|
|
|
247
273
|
After writing, commit the two files to the current worktree branch yourself by running git via your Bash tool (do not use a script). Stage ONLY .devflow/features/index.md and .devflow/features/{slug}/KNOWLEDGE.md, then commit just those paths with a docs(knowledge): message. Do NOT push, do NOT force, do NOT stage anything else. Follow your Commit Protocol — it is non-blocking, so if any git step fails, report KB_COMMIT and finish normally."
|
|
248
274
|
```
|
|
249
275
|
|
|
276
|
+
**Step 4 — Surface an uncommitted knowledge base:**
|
|
277
|
+
|
|
278
|
+
When the Knowledge agent reports `KB_COMMIT: skipped (detached HEAD)`, the files were written but deliberately not committed — a commit on a detached HEAD becomes unreachable once HEAD moves. Tell the user in the workflow's final report, in one line, that the knowledge base was written but not committed, and name the uncommitted paths the agent listed, so they can commit them on a branch before the worktree is removed. Never commit them yourself.
|
|
279
|
+
|
|
250
280
|
**Failure handling**: Non-blocking. If the Knowledge agent fails, log the failure and continue — the workflow outcome is not affected by write-back success.
|
|
251
281
|
|
|
252
282
|
## Architecture
|