devflow-kit 3.3.0 → 3.4.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 +18 -0
- package/dist/agents/code.md +330 -0
- package/{src/assets → dist}/agents/design.md +1 -1
- package/{src/assets → dist}/agents/diagnose.md +1 -2
- package/dist/agents/git.md +29 -56
- package/{src/assets → dist}/agents/knowledge.md +4 -3
- package/{src/assets → dist}/agents/research.md +2 -2
- package/{src/assets → dist}/agents/review.md +8 -7
- package/{src/assets → dist}/agents/scrutinize.md +1 -1
- package/dist/agents/skim.md +148 -0
- package/{src/assets → dist}/agents/triage.md +1 -1
- package/dist/cli/commands/init.js +62 -0
- package/dist/cli/commands/learning.js +38 -3
- package/dist/cli/commands/uninstall.js +42 -1
- package/dist/commands/bug-analysis.md +30 -8
- package/dist/commands/code-review.md +141 -60
- package/dist/commands/debug.md +14 -12
- package/dist/commands/dynamic-build.md +37 -38
- package/dist/commands/dynamic-plan.md +30 -18
- package/dist/commands/dynamic-profile.md +27 -13
- package/dist/commands/dynamic-tickets.md +28 -14
- package/dist/commands/explore.md +15 -13
- package/dist/commands/implement.md +33 -28
- package/dist/commands/plan.md +37 -24
- package/dist/commands/release.md +69 -4
- package/dist/commands/research.md +33 -11
- package/dist/commands/resolve.md +35 -32
- package/dist/commands/self-review.md +36 -23
- package/dist/core/agent-models.js +43 -0
- package/dist/core/assets.js +55 -10
- package/dist/core/claude-md-audit.js +190 -0
- package/dist/core/feature-switch.js +20 -1
- package/dist/core/flags.js +28 -0
- package/dist/core/fs-atomic.js +8 -3
- package/dist/core/learning-variants.js +213 -0
- package/dist/core/manifest.js +62 -0
- package/dist/core/mds-variants.js +38 -1
- package/dist/core/plugins.js +71 -9
- package/{src/assets → dist/learning-off}/agents/code.md +6 -10
- package/dist/learning-off/agents/design.md +119 -0
- package/dist/learning-off/agents/diagnose.md +210 -0
- package/dist/learning-off/agents/knowledge.md +90 -0
- package/dist/learning-off/agents/research.md +149 -0
- package/dist/learning-off/agents/review.md +228 -0
- package/dist/learning-off/agents/scrutinize.md +117 -0
- package/{src/assets → dist/learning-off}/agents/skim.md +1 -8
- package/dist/learning-off/agents/triage.md +163 -0
- package/dist/learning-off/commands/bug-analysis.md +420 -0
- package/dist/learning-off/commands/code-review.md +525 -0
- package/dist/learning-off/commands/debug.md +294 -0
- package/dist/learning-off/commands/dynamic-build.md +1255 -0
- package/dist/learning-off/commands/dynamic-plan.md +424 -0
- package/dist/learning-off/commands/dynamic-profile.md +214 -0
- package/dist/learning-off/commands/dynamic-tickets.md +632 -0
- package/dist/learning-off/commands/explore.md +210 -0
- package/dist/learning-off/commands/implement.md +808 -0
- package/dist/learning-off/commands/plan.md +664 -0
- package/dist/learning-off/commands/release.md +310 -0
- package/dist/learning-off/commands/research.md +222 -0
- package/dist/learning-off/commands/resolve.md +837 -0
- package/dist/learning-off/commands/self-review.md +266 -0
- package/dist/skills/git/references/tracker/_contract.md +33 -0
- package/dist/skills/git/references/tracker/github/fetch-issue.md +2 -0
- package/dist/skills/git/references/tracker/github/fetch-issues-batch.md +2 -0
- package/dist/skills/git/references/tracker/github/gather-release-evidence.md +4 -0
- package/dist/skills/git/references/tracker/github/post-wave-report.md +2 -0
- package/dist/skills/git/references/tracker/github/setup-task.md +12 -0
- package/dist/skills/git/references/tracker/jira/associate-release.md +1 -1
- package/dist/skills/git/references/tracker/jira/fetch-issue.md +2 -0
- package/dist/skills/git/references/tracker/jira/fetch-issues-batch.md +2 -0
- package/dist/skills/git/references/tracker/jira/gather-release-evidence.md +4 -0
- package/dist/skills/git/references/tracker/jira/post-wave-report.md +2 -0
- package/dist/skills/git/references/tracker/jira/setup-task.md +14 -2
- package/dist/skills/git/references/tracker/linear/associate-release.md +1 -1
- package/dist/skills/git/references/tracker/linear/fetch-issue.md +2 -0
- package/dist/skills/git/references/tracker/linear/fetch-issues-batch.md +2 -0
- package/dist/skills/git/references/tracker/linear/gather-release-evidence.md +4 -0
- package/dist/skills/git/references/tracker/linear/post-wave-report.md +2 -0
- package/dist/skills/git/references/tracker/linear/setup-task.md +14 -2
- package/dist/targets/claude-code/installer.js +72 -36
- package/dist/targets/claude-code/language-stamp.js +185 -0
- package/dist/targets/claude-code/learning-install.js +489 -0
- package/package.json +1 -1
- package/src/assets/agents/code.mds +339 -0
- package/src/assets/agents/design.mds +149 -0
- package/src/assets/agents/diagnose.mds +225 -0
- package/src/assets/agents/evaluate.md +1 -3
- package/src/assets/agents/git.mds +29 -56
- package/src/assets/agents/knowledge.mds +125 -0
- package/src/assets/agents/research.mds +176 -0
- package/src/assets/agents/review.mds +286 -0
- package/src/assets/agents/scrutinize.mds +132 -0
- package/src/assets/agents/skim.mds +161 -0
- package/src/assets/agents/triage.mds +194 -0
- package/src/assets/agents/validate.md +8 -6
- package/src/assets/commands/_partials/_compliance.mds +5 -4
- package/src/assets/commands/_partials/_decisions.mds +31 -0
- package/src/assets/commands/_partials/_engine.mds +9 -1
- package/src/assets/commands/_partials/_knowledge.mds +25 -12
- package/src/assets/commands/_partials/_preamble.mds +33 -9
- package/src/assets/commands/_partials/_publication.mds +5 -4
- package/src/assets/commands/_partials/_settings.mds +13 -5
- package/src/assets/commands/_partials/_wave.mds +8 -0
- package/src/assets/commands/bug-analysis.mds +24 -2
- package/src/assets/commands/code-review.mds +147 -44
- package/src/assets/commands/debug.mds +17 -1
- package/src/assets/commands/dynamic-build.mds +33 -2
- package/src/assets/commands/dynamic-plan.mds +36 -6
- package/src/assets/commands/dynamic-profile.mds +9 -1
- package/src/assets/commands/dynamic-tickets.mds +16 -2
- package/src/assets/commands/explore.mds +27 -1
- package/src/assets/commands/implement.mds +41 -8
- package/src/assets/commands/plan.mds +47 -8
- package/src/assets/commands/{release.md → release.mds} +27 -24
- package/src/assets/commands/research.mds +28 -4
- package/src/assets/commands/resolve.mds +43 -2
- package/src/assets/commands/self-review.mds +30 -5
- package/src/assets/mds/tracker/_contract.mds +72 -0
- package/src/assets/mds/tracker/_github.mds +13 -2
- package/src/assets/mds/tracker/_jira.mds +17 -5
- package/src/assets/mds/tracker/_linear.mds +17 -5
- package/src/assets/mds/tracker/_mcp.mds +2 -2
- package/src/assets/mds/tracker/_steps.mds +97 -0
- package/src/assets/rules/context-economy.md +10 -0
- package/src/assets/rules/go.md +1 -0
- package/src/assets/rules/java.md +1 -0
- package/src/assets/rules/python.md +1 -0
- package/src/assets/rules/rust.md +1 -0
- package/src/assets/rules/typescript.md +1 -0
- package/src/assets/scripts/claude-md-audit.cjs +611 -0
- package/src/assets/scripts/hooks/assets/orchestrator-charter.md +1 -2
- package/src/assets/scripts/hooks/json-helper.cjs +13 -5
- package/src/assets/scripts/hooks/json-parse +34 -10
- package/src/assets/scripts/hooks/session-start-context +315 -7
- package/src/assets/skills/apply-decisions/SKILL.md +1 -1
- package/src/assets/skills/apply-feature-knowledge/SKILL.md +5 -5
- package/src/assets/skills/feature-knowledge/SKILL.md +43 -12
- package/src/assets/skills/quality-gates/SKILL.md +1 -1
package/dist/commands/release.md
CHANGED
|
@@ -52,7 +52,19 @@ Read `.release/RELEASE-FLOW.md`:
|
|
|
52
52
|
|
|
53
53
|
### Phase 1b: Load Context
|
|
54
54
|
|
|
55
|
-
**Produces:** DECISIONS_CONTEXT, FEATURE_KNOWLEDGE
|
|
55
|
+
**Produces:** DECISIONS_CONTEXT, FEATURE_KNOWLEDGE, FEATURE_KNOWLEDGE_RULES
|
|
56
|
+
|
|
57
|
+
**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:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
node "$HOME/.devflow/scripts/resolve-settings.cjs" "{root}" 2>/dev/null; echo "exit=$?"
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
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.
|
|
64
|
+
|
|
65
|
+
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.
|
|
66
|
+
|
|
67
|
+
When the settings line says `LEARNING=off`, set `DECISIONS_CONTEXT` to `(none)` and skip this step, locating no ledger and reading no index.
|
|
56
68
|
|
|
57
69
|
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`):
|
|
58
70
|
|
|
@@ -70,9 +82,62 @@ This is the rule the learning hooks apply (D-LEDGER-MAIN-WORKTREE, D-PROMPT-ROOT
|
|
|
70
82
|
|
|
71
83
|
Read `{ledger}/.devflow/learning/index.md`. If the file is absent or empty, set `DECISIONS_CONTEXT` to `(none)`; otherwise use the file content as `DECISIONS_CONTEXT`.
|
|
72
84
|
|
|
73
|
-
Load
|
|
85
|
+
### Load Feature Knowledge
|
|
86
|
+
|
|
87
|
+
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
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
git -C "{start}" rev-parse --show-toplevel
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
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}`.
|
|
94
|
+
|
|
95
|
+
**Step 1 — Read the index cache:**
|
|
96
|
+
|
|
97
|
+
Attempt to read `{worktree}/.devflow/features/index.md`. Each line follows the format:
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
- **{slug}** — {areas} — {Use-when description}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
If `index.md` exists and contains at least one entry line, use it for relevance matching.
|
|
104
|
+
|
|
105
|
+
**Step 2 — Fallback: glob frontmatter (if `index.md` is absent or empty):**
|
|
106
|
+
|
|
107
|
+
Glob `{worktree}/.devflow/features/*/KNOWLEDGE.md`. For each file found, read only its YAML frontmatter block (between the opening and closing `---` delimiters). The frontmatter fields `name`, `description`, and `directories` are the authoritative relevance surface — `index.md` is only a cache.
|
|
108
|
+
|
|
109
|
+
**Step 3 — Pick relevant KBs:**
|
|
110
|
+
|
|
111
|
+
Match the current task area and description against each index line (or frontmatter `description` + `directories` on fallback). Select entries whose documented area overlaps the current task. This is a relevance judgment — prefer specificity over breadth.
|
|
112
|
+
|
|
113
|
+
**Step 4 — Read each selected KB's Rules:**
|
|
114
|
+
|
|
115
|
+
For each selected entry, `{kb}` is `{worktree}/.devflow/features/{slug}/KNOWLEDGE.md`:
|
|
116
|
+
|
|
117
|
+
1. List its `##` headings with line numbers through Bash: `command grep -n '^## ' "{kb}"`. This only locates sections; the text of a KB comes from the Read view alone.
|
|
118
|
+
2. Read the `## Rules` range (its line to the next heading) with the Read tool, using `offset` and `limit`, and choose the one to three bullets most relevant to the current task. The choice is yours, made per KB.
|
|
119
|
+
3. If the KB has no `## Rules` section, choose one to three entries from its `## Anti-Patterns` or `## Gotchas` range the same way, and label them by that section's name instead of an ID.
|
|
120
|
+
|
|
121
|
+
When a KB contradicts the code you observe, **trust the code** — the code is the freshness mechanism; the KB may lag behind. A missing Rules section, a missing heading list and `(none)` are legitimate states, not errors.
|
|
122
|
+
|
|
123
|
+
**Step 5 — Set FEATURE_KNOWLEDGE and FEATURE_KNOWLEDGE_RULES:**
|
|
124
|
+
|
|
125
|
+
Write one block per selected KB. Paste each bullet verbatim from the Read view, never from a shell view. The path is relative to the checkout root; an agent resolves it under `WORKTREE_PATH` when one is provided.
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
--- Feature knowledge: {slug} ---
|
|
129
|
+
KB: .devflow/features/{slug}/KNOWLEDGE.md
|
|
130
|
+
Rules:
|
|
131
|
+
- **KB-AP-2** {bullet text, verbatim}
|
|
132
|
+
- **KB-INV-1** {bullet text, verbatim}
|
|
133
|
+
Headings: L5 Rules · L40 Overview · L62 Anti-Patterns · L118 Key Files
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
A KB with no Rules section labels its entries `Rules ({section name}):` and gives them no ID. `FEATURE_KNOWLEDGE` is these blocks; `FEATURE_KNOWLEDGE_RULES` is the same blocks without the `Headings:` line. Both come from this one selection, and each spawn names the variable its recipient takes. If no KBs exist, no KBs are relevant, or `.devflow/features/` is absent, set both to `(none)`.
|
|
137
|
+
|
|
138
|
+
**One git call, then direct reads — no `.cjs` script.** After resolving `{worktree}`, this step is 1 index read (or N frontmatter reads on fallback), plus one heading listing and one Rules read per selected KB, bounded by KB count.
|
|
74
139
|
|
|
75
|
-
Pass
|
|
140
|
+
Pass `DECISIONS_CONTEXT` and `FEATURE_KNOWLEDGE` only to agents whose contract declares them; the Validate and Git agents this command spawns do not.
|
|
76
141
|
|
|
77
142
|
### Phase 1c: Resolve the Evidence Policy
|
|
78
143
|
|
|
@@ -230,7 +295,7 @@ On completion:
|
|
|
230
295
|
│ └─ Read .release/RELEASE-FLOW.md (learned) or proceed to detect (fresh)
|
|
231
296
|
│
|
|
232
297
|
├─ Phase 1b: Load Context
|
|
233
|
-
│ └─ Load DECISIONS_CONTEXT and FEATURE_KNOWLEDGE for
|
|
298
|
+
│ └─ Load DECISIONS_CONTEXT and FEATURE_KNOWLEDGE for the agents that declare them
|
|
234
299
|
│
|
|
235
300
|
├─ Phase 2: Detect Release Process (first run only)
|
|
236
301
|
│ └─ Tiered scan: package.json, CI workflows, git history
|
|
@@ -31,7 +31,7 @@ $ARGUMENTS
|
|
|
31
31
|
|
|
32
32
|
### Phase 1: Load Decisions (Orchestrator-Local)
|
|
33
33
|
|
|
34
|
-
**Produces:** DECISIONS_CONTEXT, FEATURE_KNOWLEDGE
|
|
34
|
+
**Produces:** DECISIONS_CONTEXT, FEATURE_KNOWLEDGE, FEATURE_KNOWLEDGE_RULES
|
|
35
35
|
|
|
36
36
|
**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
|
|
37
37
|
|
|
@@ -41,8 +41,20 @@ git -C "{start}" rev-parse --show-toplevel
|
|
|
41
41
|
|
|
42
42
|
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.
|
|
43
43
|
|
|
44
|
+
**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:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
node "$HOME/.devflow/scripts/resolve-settings.cjs" "{root}" 2>/dev/null; echo "exit=$?"
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
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.
|
|
51
|
+
|
|
52
|
+
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.
|
|
53
|
+
|
|
44
54
|
### Load DECISIONS_CONTEXT
|
|
45
55
|
|
|
56
|
+
When the settings line says `LEARNING=off`, set `DECISIONS_CONTEXT` to `(none)` and skip this step, locating no ledger and reading no index.
|
|
57
|
+
|
|
46
58
|
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`):
|
|
47
59
|
|
|
48
60
|
```bash
|
|
@@ -100,22 +112,32 @@ Glob `{worktree}/.devflow/features/*/KNOWLEDGE.md`. For each file found, read on
|
|
|
100
112
|
|
|
101
113
|
Match the current task area and description against each index line (or frontmatter `description` + `directories` on fallback). Select entries whose documented area overlaps the current task. This is a relevance judgment — prefer specificity over breadth.
|
|
102
114
|
|
|
103
|
-
**Step 4 — Read selected
|
|
115
|
+
**Step 4 — Read each selected KB's Rules:**
|
|
116
|
+
|
|
117
|
+
For each selected entry, `{kb}` is `{worktree}/.devflow/features/{slug}/KNOWLEDGE.md`:
|
|
104
118
|
|
|
105
|
-
|
|
119
|
+
1. List its `##` headings with line numbers through Bash: `command grep -n '^## ' "{kb}"`. This only locates sections; the text of a KB comes from the Read view alone.
|
|
120
|
+
2. Read the `## Rules` range (its line to the next heading) with the Read tool, using `offset` and `limit`, and choose the one to three bullets most relevant to the current task. The choice is yours, made per KB.
|
|
121
|
+
3. If the KB has no `## Rules` section, choose one to three entries from its `## Anti-Patterns` or `## Gotchas` range the same way, and label them by that section's name instead of an ID.
|
|
106
122
|
|
|
107
|
-
**
|
|
123
|
+
When a KB contradicts the code you observe, **trust the code** — the code is the freshness mechanism; the KB may lag behind. A missing Rules section, a missing heading list and `(none)` are legitimate states, not errors.
|
|
108
124
|
|
|
109
|
-
|
|
125
|
+
**Step 5 — Set FEATURE_KNOWLEDGE and FEATURE_KNOWLEDGE_RULES:**
|
|
126
|
+
|
|
127
|
+
Write one block per selected KB. Paste each bullet verbatim from the Read view, never from a shell view. The path is relative to the checkout root; an agent resolves it under `WORKTREE_PATH` when one is provided.
|
|
110
128
|
|
|
111
129
|
```
|
|
112
130
|
--- Feature knowledge: {slug} ---
|
|
113
|
-
{
|
|
131
|
+
KB: .devflow/features/{slug}/KNOWLEDGE.md
|
|
132
|
+
Rules:
|
|
133
|
+
- **KB-AP-2** {bullet text, verbatim}
|
|
134
|
+
- **KB-INV-1** {bullet text, verbatim}
|
|
135
|
+
Headings: L5 Rules · L40 Overview · L62 Anti-Patterns · L118 Key Files
|
|
114
136
|
```
|
|
115
137
|
|
|
116
|
-
If no KBs exist, no KBs are relevant, or `.devflow/features/` is absent, set
|
|
138
|
+
A KB with no Rules section labels its entries `Rules ({section name}):` and gives them no ID. `FEATURE_KNOWLEDGE` is these blocks; `FEATURE_KNOWLEDGE_RULES` is the same blocks without the `Headings:` line. Both come from this one selection, and each spawn names the variable its recipient takes. If no KBs exist, no KBs are relevant, or `.devflow/features/` is absent, set both to `(none)`.
|
|
117
139
|
|
|
118
|
-
**One git call, then direct
|
|
140
|
+
**One git call, then direct reads — no `.cjs` script.** After resolving `{worktree}`, this step is 1 index read (or N frontmatter reads on fallback), plus one heading listing and one Rules read per selected KB, bounded by KB count.
|
|
119
141
|
|
|
120
142
|
Use `FEATURE_KNOWLEDGE` **locally** for research framing. Pass to each Research agent in Phase 4.
|
|
121
143
|
|
|
@@ -138,7 +160,7 @@ Generate topic slug from the research question (kebab-case, lowercase, no articl
|
|
|
138
160
|
|
|
139
161
|
Only if `codebase` type is in RESEARCH_PLAN.
|
|
140
162
|
|
|
141
|
-
Spawn `Agent(subagent_type="Skim")` targeting codebase areas relevant to the research question.
|
|
163
|
+
Spawn `Agent(subagent_type="Skim")` with `LEARNING` from the settings line, targeting codebase areas relevant to the research question.
|
|
142
164
|
|
|
143
165
|
Skip and set ORIENT_OUTPUT = "(none)" if `codebase` type is not in RESEARCH_PLAN.
|
|
144
166
|
|
|
@@ -152,7 +174,7 @@ Spawn 2-5 `Agent(subagent_type="Research")` agents **in a single message** (para
|
|
|
152
174
|
Each Research agent receives:
|
|
153
175
|
- `RESEARCH_TYPE`, `RESEARCH_QUESTION`, `OUTPUT_PATH` from RESEARCH_PLAN
|
|
154
176
|
- `DECISIONS_CONTEXT`: From Phase 1
|
|
155
|
-
- `FEATURE_KNOWLEDGE`:
|
|
177
|
+
- `FEATURE_KNOWLEDGE`: `{feature_knowledge}` from Phase 1
|
|
156
178
|
- `ORIENT_OUTPUT`: Only for `codebase` type
|
|
157
179
|
- `WORKTREE_PATH`: If in a worktree context
|
|
158
180
|
|
|
@@ -183,7 +205,7 @@ If external research was skipped due to tool unavailability: inform user.
|
|
|
183
205
|
|
|
184
206
|
### Phase 7: Feature Knowledge Creation (Conditional)
|
|
185
207
|
|
|
186
|
-
**Requires:** RESEARCH_SUMMARY
|
|
208
|
+
**Requires:** RESEARCH_SUMMARY
|
|
187
209
|
**Produces:** FEATURE_KNOWLEDGE_STATUS (created | skipped)
|
|
188
210
|
|
|
189
211
|
1. If `codebase` type was not in RESEARCH_PLAN → skip
|
package/dist/commands/resolve.md
CHANGED
|
@@ -85,10 +85,22 @@ Set `TARGET_DIR` to the selected review or bug-analysis directory path, and `TAR
|
|
|
85
85
|
|
|
86
86
|
#### Step 0d: Load Project Decisions
|
|
87
87
|
|
|
88
|
-
**Produces:** DECISIONS_CONTEXT, FEATURE_KNOWLEDGE, EVIDENCE_POLICY, ISSUE_REQUIRED, APPLY_CONVENTIONS, REQUIRE_NON_AUTHOR_APPROVAL, REVIEW_PUBLICATION, RESOLUTION_TS
|
|
88
|
+
**Produces:** DECISIONS_CONTEXT, FEATURE_KNOWLEDGE, FEATURE_KNOWLEDGE_RULES, EVIDENCE_POLICY, ISSUE_REQUIRED, APPLY_CONVENTIONS, REQUIRE_NON_AUTHOR_APPROVAL, REVIEW_PUBLICATION, RESOLUTION_TS
|
|
89
|
+
|
|
90
|
+
**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:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
node "$HOME/.devflow/scripts/resolve-settings.cjs" "{root}" 2>/dev/null; echo "exit=$?"
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
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.
|
|
97
|
+
|
|
98
|
+
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.
|
|
89
99
|
|
|
90
100
|
### Load DECISIONS_CONTEXT
|
|
91
101
|
|
|
102
|
+
When the settings line says `LEARNING=off`, set `DECISIONS_CONTEXT` to `(none)` and skip this step, locating no ledger and reading no index.
|
|
103
|
+
|
|
92
104
|
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`):
|
|
93
105
|
|
|
94
106
|
```bash
|
|
@@ -146,22 +158,32 @@ Glob `{worktree}/.devflow/features/*/KNOWLEDGE.md`. For each file found, read on
|
|
|
146
158
|
|
|
147
159
|
Match the current task area and description against each index line (or frontmatter `description` + `directories` on fallback). Select entries whose documented area overlaps the current task. This is a relevance judgment — prefer specificity over breadth.
|
|
148
160
|
|
|
149
|
-
**Step 4 — Read selected
|
|
161
|
+
**Step 4 — Read each selected KB's Rules:**
|
|
162
|
+
|
|
163
|
+
For each selected entry, `{kb}` is `{worktree}/.devflow/features/{slug}/KNOWLEDGE.md`:
|
|
164
|
+
|
|
165
|
+
1. List its `##` headings with line numbers through Bash: `command grep -n '^## ' "{kb}"`. This only locates sections; the text of a KB comes from the Read view alone.
|
|
166
|
+
2. Read the `## Rules` range (its line to the next heading) with the Read tool, using `offset` and `limit`, and choose the one to three bullets most relevant to the current task. The choice is yours, made per KB.
|
|
167
|
+
3. If the KB has no `## Rules` section, choose one to three entries from its `## Anti-Patterns` or `## Gotchas` range the same way, and label them by that section's name instead of an ID.
|
|
150
168
|
|
|
151
|
-
|
|
169
|
+
When a KB contradicts the code you observe, **trust the code** — the code is the freshness mechanism; the KB may lag behind. A missing Rules section, a missing heading list and `(none)` are legitimate states, not errors.
|
|
152
170
|
|
|
153
|
-
**Step 5 — Set FEATURE_KNOWLEDGE:**
|
|
171
|
+
**Step 5 — Set FEATURE_KNOWLEDGE and FEATURE_KNOWLEDGE_RULES:**
|
|
154
172
|
|
|
155
|
-
|
|
173
|
+
Write one block per selected KB. Paste each bullet verbatim from the Read view, never from a shell view. The path is relative to the checkout root; an agent resolves it under `WORKTREE_PATH` when one is provided.
|
|
156
174
|
|
|
157
175
|
```
|
|
158
176
|
--- Feature knowledge: {slug} ---
|
|
159
|
-
{
|
|
177
|
+
KB: .devflow/features/{slug}/KNOWLEDGE.md
|
|
178
|
+
Rules:
|
|
179
|
+
- **KB-AP-2** {bullet text, verbatim}
|
|
180
|
+
- **KB-INV-1** {bullet text, verbatim}
|
|
181
|
+
Headings: L5 Rules · L40 Overview · L62 Anti-Patterns · L118 Key Files
|
|
160
182
|
```
|
|
161
183
|
|
|
162
|
-
If no KBs exist, no KBs are relevant, or `.devflow/features/` is absent, set
|
|
184
|
+
A KB with no Rules section labels its entries `Rules ({section name}):` and gives them no ID. `FEATURE_KNOWLEDGE` is these blocks; `FEATURE_KNOWLEDGE_RULES` is the same blocks without the `Headings:` line. Both come from this one selection, and each spawn names the variable its recipient takes. If no KBs exist, no KBs are relevant, or `.devflow/features/` is absent, set both to `(none)`.
|
|
163
185
|
|
|
164
|
-
**One git call, then direct
|
|
186
|
+
**One git call, then direct reads — no `.cjs` script.** After resolving `{worktree}`, this step is 1 index read (or N frontmatter reads on fallback), plus one heading listing and one Rules read per selected KB, bounded by KB count.
|
|
165
187
|
|
|
166
188
|
Pass `FEATURE_KNOWLEDGE` to the Triage agent in Phase 2.
|
|
167
189
|
|
|
@@ -176,17 +198,7 @@ Accept the output only when it is exactly two lines: `exit=0` last and, before i
|
|
|
176
198
|
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.
|
|
177
199
|
Reuse this result for every worktree.
|
|
178
200
|
|
|
179
|
-
**Resolve
|
|
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.
|
|
201
|
+
**Resolve `REVIEW_PUBLICATION` per worktree:** take `REVIEW_PUBLICATION` from that worktree's settings line — the line resolved above for `{root}`, the worktree's root, by the settings block when this run has not yet resolved that 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.
|
|
190
202
|
|
|
191
203
|
**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.
|
|
192
204
|
|
|
@@ -384,6 +396,7 @@ Run build, typecheck, lint, test. Report pass/fail with failure details."
|
|
|
384
396
|
PUSH: false
|
|
385
397
|
CREATE_PR: false
|
|
386
398
|
WORKTREE_PATH: {worktree_path} (omit if cwd)
|
|
399
|
+
DECISIONS_CONTEXT: {decisions_context}
|
|
387
400
|
COMPLIANCE_FRAMEWORKS: {COMPLIANCE_FRAMEWORKS}"
|
|
388
401
|
```
|
|
389
402
|
- Loop back to re-validate
|
|
@@ -432,7 +445,7 @@ Phase 7 has pushed already, so this is a no-op unless the head moved since. `exi
|
|
|
432
445
|
3. **If NO_PR or NO_CI** → skip: "No PR/CI configured, skipping CI validation." Proceed to next phase.
|
|
433
446
|
4. **If PENDING** and fewer than 3 waits have run → wait again (step 1). After the third wait → report "CI still running — verify manually before merging" and proceed.
|
|
434
447
|
5. **If INDETERMINATE** and fewer than 3 waits have run → wait again (step 1). After the third wait → report "CI status unknown — verify manually before merging" and proceed.
|
|
435
|
-
6. **If FAILING** and fewer than 2 fixes have run → report the failing checks from the line. Spawn `Agent(subagent_type="Code")` whose prompt opens with `OPERATION: ci-fix`, with `COMPLIANCE_FRAMEWORKS`, `CI_FAILURES` and `PUSH: false`; `CI_FAILURES` holds the failing-check names from the line and nothing else, because the Code agent fetches the full names and reads the logs itself and this command reads none. After a fix, push with the command above and, if a wait remains, wait again (step 1); a failed push records `TRACEABILITY: DEGRADED (ci push failed)`, reports "CI status unknown — verify manually before merging" and stops waiting. After the second fix still FAILING → report the failing checks and proceed.
|
|
448
|
+
6. **If FAILING** and fewer than 2 fixes have run → report the failing checks from the line. Spawn `Agent(subagent_type="Code")` whose prompt opens with `OPERATION: ci-fix`, with `COMPLIANCE_FRAMEWORKS`, `CI_FAILURES`, `DECISIONS_CONTEXT` and `PUSH: false`; `CI_FAILURES` holds the failing-check names from the line and nothing else, because the Code agent fetches the full names and reads the logs itself and this command reads none. After a fix, push with the command above and, if a wait remains, wait again (step 1); a failed push records `TRACEABILITY: DEGRADED (ci push failed)`, reports "CI status unknown — verify manually before merging" and stops waiting. After the second fix still FAILING → report the failing checks and proceed.
|
|
436
449
|
7. **Budget**: at most 3 waits and 2 fixes in all, per worktree. When one is spent, report the current status and proceed.
|
|
437
450
|
<!-- /PATTERN: ci-status-gate -->
|
|
438
451
|
|
|
@@ -642,17 +655,7 @@ git -C "{start}" rev-parse --show-toplevel
|
|
|
642
655
|
|
|
643
656
|
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}`.
|
|
644
657
|
|
|
645
|
-
**Step 1 — Check the opt-out gate, with `{root}` = `{worktree}`:**
|
|
646
|
-
|
|
647
|
-
**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:
|
|
648
|
-
|
|
649
|
-
```bash
|
|
650
|
-
node "$HOME/.devflow/scripts/resolve-settings.cjs" "{root}" 2>/dev/null; echo "exit=$?"
|
|
651
|
-
```
|
|
652
|
-
|
|
653
|
-
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.
|
|
654
|
-
|
|
655
|
-
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.
|
|
658
|
+
**Step 1 — Check the opt-out gate, with `{root}` = `{worktree}`:** take the settings line resolved above for that root, resolving it with the settings block when this run has not yet.
|
|
656
659
|
|
|
657
660
|
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.
|
|
658
661
|
|
|
@@ -682,7 +685,7 @@ Write the knowledge base to:
|
|
|
682
685
|
Then update the index cache by performing a read-modify-write on:
|
|
683
686
|
{worktree}/.devflow/features/index.md
|
|
684
687
|
|
|
685
|
-
Index line format: `- **{slug}** — {areas} — {Use-when description}`
|
|
688
|
+
Index line format: `- **{slug}** — {areas} — {Use-when description}` — at most 300 characters, the description at most 220; reword a longer one, never cut it.
|
|
686
689
|
|
|
687
690
|
If the line for this slug already exists in index.md, replace it. If it does not exist, append it. If index.md does not exist, create it with just this line.
|
|
688
691
|
|
|
@@ -14,7 +14,7 @@ Run Simplify agent and Scrutinize agent sequentially on changed files for post-i
|
|
|
14
14
|
|
|
15
15
|
### Phase 0: Context Gathering
|
|
16
16
|
|
|
17
|
-
**Produces:** FILES_CHANGED, TASK_DESCRIPTION, DECISIONS_CONTEXT, FEATURE_KNOWLEDGE, HEAD_BEFORE
|
|
17
|
+
**Produces:** FILES_CHANGED, TASK_DESCRIPTION, DECISIONS_CONTEXT, FEATURE_KNOWLEDGE, FEATURE_KNOWLEDGE_RULES, HEAD_BEFORE
|
|
18
18
|
|
|
19
19
|
Detect changed files and build context:
|
|
20
20
|
|
|
@@ -23,8 +23,21 @@ Detect changed files and build context:
|
|
|
23
23
|
3. If no changes found, report "No changes to review" and exit
|
|
24
24
|
4. Build TASK_DESCRIPTION from recent commit messages or branch name
|
|
25
25
|
5. Record `HEAD_BEFORE` (`git rev-parse HEAD`) now, before Simplify runs — Phase 3 compares against it
|
|
26
|
+
|
|
27
|
+
**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:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
node "$HOME/.devflow/scripts/resolve-settings.cjs" "{root}" 2>/dev/null; echo "exit=$?"
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
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.
|
|
34
|
+
|
|
35
|
+
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.
|
|
36
|
+
|
|
26
37
|
### Load DECISIONS_CONTEXT
|
|
27
38
|
|
|
39
|
+
When the settings line says `LEARNING=off`, set `DECISIONS_CONTEXT` to `(none)` and skip this step, locating no ledger and reading no index.
|
|
40
|
+
|
|
28
41
|
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`):
|
|
29
42
|
|
|
30
43
|
```bash
|
|
@@ -82,26 +95,36 @@ Glob `{worktree}/.devflow/features/*/KNOWLEDGE.md`. For each file found, read on
|
|
|
82
95
|
|
|
83
96
|
Match the current task area and description against each index line (or frontmatter `description` + `directories` on fallback). Select entries whose documented area overlaps the current task. This is a relevance judgment — prefer specificity over breadth.
|
|
84
97
|
|
|
85
|
-
**Step 4 — Read selected
|
|
98
|
+
**Step 4 — Read each selected KB's Rules:**
|
|
86
99
|
|
|
87
|
-
For each selected entry,
|
|
100
|
+
For each selected entry, `{kb}` is `{worktree}/.devflow/features/{slug}/KNOWLEDGE.md`:
|
|
88
101
|
|
|
89
|
-
|
|
102
|
+
1. List its `##` headings with line numbers through Bash: `command grep -n '^## ' "{kb}"`. This only locates sections; the text of a KB comes from the Read view alone.
|
|
103
|
+
2. Read the `## Rules` range (its line to the next heading) with the Read tool, using `offset` and `limit`, and choose the one to three bullets most relevant to the current task. The choice is yours, made per KB.
|
|
104
|
+
3. If the KB has no `## Rules` section, choose one to three entries from its `## Anti-Patterns` or `## Gotchas` range the same way, and label them by that section's name instead of an ID.
|
|
90
105
|
|
|
91
|
-
|
|
106
|
+
When a KB contradicts the code you observe, **trust the code** — the code is the freshness mechanism; the KB may lag behind. A missing Rules section, a missing heading list and `(none)` are legitimate states, not errors.
|
|
107
|
+
|
|
108
|
+
**Step 5 — Set FEATURE_KNOWLEDGE and FEATURE_KNOWLEDGE_RULES:**
|
|
109
|
+
|
|
110
|
+
Write one block per selected KB. Paste each bullet verbatim from the Read view, never from a shell view. The path is relative to the checkout root; an agent resolves it under `WORKTREE_PATH` when one is provided.
|
|
92
111
|
|
|
93
112
|
```
|
|
94
113
|
--- Feature knowledge: {slug} ---
|
|
95
|
-
{
|
|
114
|
+
KB: .devflow/features/{slug}/KNOWLEDGE.md
|
|
115
|
+
Rules:
|
|
116
|
+
- **KB-AP-2** {bullet text, verbatim}
|
|
117
|
+
- **KB-INV-1** {bullet text, verbatim}
|
|
118
|
+
Headings: L5 Rules · L40 Overview · L62 Anti-Patterns · L118 Key Files
|
|
96
119
|
```
|
|
97
120
|
|
|
98
|
-
If no KBs exist, no KBs are relevant, or `.devflow/features/` is absent, set
|
|
121
|
+
A KB with no Rules section labels its entries `Rules ({section name}):` and gives them no ID. `FEATURE_KNOWLEDGE` is these blocks; `FEATURE_KNOWLEDGE_RULES` is the same blocks without the `Headings:` line. Both come from this one selection, and each spawn names the variable its recipient takes. If no KBs exist, no KBs are relevant, or `.devflow/features/` is absent, set both to `(none)`.
|
|
99
122
|
|
|
100
|
-
**One git call, then direct
|
|
123
|
+
**One git call, then direct reads — no `.cjs` script.** After resolving `{worktree}`, this step is 1 index read (or N frontmatter reads on fallback), plus one heading listing and one Rules read per selected KB, bounded by KB count.
|
|
101
124
|
|
|
102
|
-
Pass `
|
|
125
|
+
Pass `FEATURE_KNOWLEDGE_RULES` to Scrutinize agent.
|
|
103
126
|
|
|
104
|
-
**Extract:** FILES_CHANGED (list), TASK_DESCRIPTION (string), DECISIONS_CONTEXT (string, optional), FEATURE_KNOWLEDGE (string, optional), HEAD_BEFORE (40-hex SHA)
|
|
127
|
+
**Extract:** FILES_CHANGED (list), TASK_DESCRIPTION (string), DECISIONS_CONTEXT (string, optional), FEATURE_KNOWLEDGE (string, optional), FEATURE_KNOWLEDGE_RULES (string, optional), HEAD_BEFORE (40-hex SHA)
|
|
105
128
|
|
|
106
129
|
### Phase 1: Simplify agent (Code Refinement)
|
|
107
130
|
|
|
@@ -129,7 +152,7 @@ Agent(subagent_type="Scrutinize", run_in_background=false):
|
|
|
129
152
|
"TASK_DESCRIPTION: {task_description}
|
|
130
153
|
FILES_CHANGED: {files_changed}
|
|
131
154
|
DECISIONS_CONTEXT: {decisions_context}
|
|
132
|
-
FEATURE_KNOWLEDGE: {
|
|
155
|
+
FEATURE_KNOWLEDGE: {feature_knowledge_rules}
|
|
133
156
|
Evaluate against 9-pillar framework. Fix P0/P1 issues. Return structured report.
|
|
134
157
|
Follow devflow:apply-decisions to scan DECISIONS_CONTEXT and Read full ADR/PF bodies on demand. Skip if (none).
|
|
135
158
|
Follow devflow:apply-feature-knowledge for FEATURE_KNOWLEDGE. Skip if (none)."
|
|
@@ -195,17 +218,7 @@ git -C "{start}" rev-parse --show-toplevel
|
|
|
195
218
|
|
|
196
219
|
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}`.
|
|
197
220
|
|
|
198
|
-
**Step 1 — Check the opt-out gate, with `{root}` = `{worktree}`:**
|
|
199
|
-
|
|
200
|
-
**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:
|
|
201
|
-
|
|
202
|
-
```bash
|
|
203
|
-
node "$HOME/.devflow/scripts/resolve-settings.cjs" "{root}" 2>/dev/null; echo "exit=$?"
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
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.
|
|
207
|
-
|
|
208
|
-
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.
|
|
221
|
+
**Step 1 — Check the opt-out gate, with `{root}` = `{worktree}`:** take the settings line resolved above for that root, resolving it with the settings block when this run has not yet.
|
|
209
222
|
|
|
210
223
|
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.
|
|
211
224
|
|
|
@@ -235,7 +248,7 @@ Write the knowledge base to:
|
|
|
235
248
|
Then update the index cache by performing a read-modify-write on:
|
|
236
249
|
{worktree}/.devflow/features/index.md
|
|
237
250
|
|
|
238
|
-
Index line format: `- **{slug}** — {areas} — {Use-when description}`
|
|
251
|
+
Index line format: `- **{slug}** — {areas} — {Use-when description}` — at most 300 characters, the description at most 220; reword a longer one, never cut it.
|
|
239
252
|
|
|
240
253
|
If the line for this slug already exists in index.md, replace it. If it does not exist, append it. If index.md does not exist, create it with just this line.
|
|
241
254
|
|
|
@@ -599,6 +599,49 @@ export async function loadShippedAgentDefaults(dirs = agentSourceDirs(), opts) {
|
|
|
599
599
|
}
|
|
600
600
|
return defaults;
|
|
601
601
|
}
|
|
602
|
+
// ---------------------------------------------------------------------------
|
|
603
|
+
// carryAgentOverrides — the frontmatter a converge keeps
|
|
604
|
+
// ---------------------------------------------------------------------------
|
|
605
|
+
/**
|
|
606
|
+
* D-AGENT-OVERRIDE-CARRY: the text a prompt converge installs for an agent is the
|
|
607
|
+
* variant `source` wearing the installed copy's `model:` and `effort:`.
|
|
608
|
+
*
|
|
609
|
+
* Those two lines are the only frontmatter keys reapplyAgentMapping manages, and
|
|
610
|
+
* `devflow agents` and the proxy put their values there. A converge that installed
|
|
611
|
+
* the bare variant would write every overridden agent back to its shipped model
|
|
612
|
+
* and effort and leave reapplyAgentMapping to restore it: a window with default
|
|
613
|
+
* models, and a no-op converge that rewrites everything. Carrying the two lines
|
|
614
|
+
* keeps that window shut, so a copy already holding the right variant and its
|
|
615
|
+
* overrides compares byte-equal and is not touched.
|
|
616
|
+
*
|
|
617
|
+
* The carry is an optimisation, never the authority: reapplyAgentMapping reads
|
|
618
|
+
* agent-models.json and decides what the installed frontmatter must say. It
|
|
619
|
+
* agrees with the carry whenever the installed copy was last written by it, and
|
|
620
|
+
* where they disagree the later reapply wins. Both go through
|
|
621
|
+
* rewriteAgentFrontmatter, so the model-name charset guard, the first-block scope
|
|
622
|
+
* and the EOL handling are the ones the reapply uses.
|
|
623
|
+
*
|
|
624
|
+
* `source` is returned unchanged when there is nothing safe to carry: either side
|
|
625
|
+
* has no well-formed frontmatter, the installed copy has no model, its model
|
|
626
|
+
* fails the model-name charset or its effort is not an EFFORT_LEVELS member. An
|
|
627
|
+
* installed copy with no `effort:` line carries no effort (a mapping effort of
|
|
628
|
+
* `inherit` yields exactly that).
|
|
629
|
+
*
|
|
630
|
+
* Pure function — no I/O.
|
|
631
|
+
*/
|
|
632
|
+
export function carryAgentOverrides(source, installed) {
|
|
633
|
+
const model = readFrontmatterModel(installed);
|
|
634
|
+
const effort = readFrontmatterEffort(installed);
|
|
635
|
+
if (!model.ok || !effort.ok || model.value === '')
|
|
636
|
+
return source;
|
|
637
|
+
if (effort.value !== '' && !isEffortLevel(effort.value))
|
|
638
|
+
return source;
|
|
639
|
+
const carried = rewriteAgentFrontmatter(source, {
|
|
640
|
+
model: model.value,
|
|
641
|
+
effort: effort.value === '' ? null : effort.value,
|
|
642
|
+
});
|
|
643
|
+
return carried.ok ? carried.value.content : source;
|
|
644
|
+
}
|
|
602
645
|
/**
|
|
603
646
|
* Idempotent convergence function: walk every installed agent file and
|
|
604
647
|
* rewrite frontmatter model/effort to match the effective mapping.
|
package/dist/core/assets.js
CHANGED
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
import { join } from 'path';
|
|
2
2
|
import { getPackageRoot } from './paths.js';
|
|
3
3
|
import { SKILL_REFS_OUTPUT_DIR } from './mds-variants.js';
|
|
4
|
+
import { LEARNING_OFF_OUTPUT_DIR } from './learning-variants.js';
|
|
4
5
|
/**
|
|
5
6
|
* Flat skills source directory: src/assets/skills/{name}/
|
|
6
7
|
* All plugins' skills live here directly (no per-plugin subdirectory).
|
|
8
|
+
*
|
|
9
|
+
* @param root - Package root to resolve against. Injectable so a caller working
|
|
10
|
+
* on a temp tree (the learning converge) reads the skill source from the same
|
|
11
|
+
* root as the rest of its sources.
|
|
7
12
|
*/
|
|
8
|
-
export function skillsDir() {
|
|
9
|
-
return join(
|
|
13
|
+
export function skillsDir(root = getPackageRoot()) {
|
|
14
|
+
return join(root, 'src', 'assets', 'skills');
|
|
10
15
|
}
|
|
11
16
|
/**
|
|
12
|
-
* Flat agents source directory: src/assets/agents/{name}.md
|
|
13
|
-
* All plugins' agents live here directly.
|
|
17
|
+
* Flat agents source directory: src/assets/agents/{name}.md, or {name}.mds for a
|
|
18
|
+
* generator host. All plugins' agents live here directly.
|
|
14
19
|
*
|
|
15
20
|
* @param root - Package root to resolve against. Injectable so a caller working
|
|
16
21
|
* on a temp tree (the test harness) reads the layout from here rather than
|
|
@@ -35,17 +40,49 @@ export function scriptsDir() {
|
|
|
35
40
|
}
|
|
36
41
|
/**
|
|
37
42
|
* Compiled commands directory: dist/commands/
|
|
38
|
-
* Single lookup directory for installed commands
|
|
39
|
-
*
|
|
43
|
+
* Single lookup directory for installed commands: one compiled file per `.mds`
|
|
44
|
+
* command host in src/assets/commands/. A host that carries a learning arm also
|
|
45
|
+
* has a learning-off variant (see learningOffDir).
|
|
40
46
|
*/
|
|
41
47
|
export function commandsDir() {
|
|
42
48
|
return join(getPackageRoot(), 'dist', 'commands');
|
|
43
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Learning-off variant directory: dist/learning-off/{commands,agents}/
|
|
52
|
+
*
|
|
53
|
+
* Holds the learning-off variant of each prompt that carries a learning arm
|
|
54
|
+
* (D-LEARNING-VARIANTS), and only those. Absent until the build has run, so every
|
|
55
|
+
* reader tolerates its absence.
|
|
56
|
+
*
|
|
57
|
+
* The spelling comes from LEARNING_OFF_OUTPUT_DIR in learning-variants.ts, the
|
|
58
|
+
* build's own destination, rather than being retyped here.
|
|
59
|
+
*
|
|
60
|
+
* @param kind - Which prompt kind's variants.
|
|
61
|
+
* @param root - Package root to resolve against (see agentsDir).
|
|
62
|
+
*/
|
|
63
|
+
export function learningOffDir(kind, root = getPackageRoot()) {
|
|
64
|
+
return join(root, ...LEARNING_OFF_OUTPUT_DIR.split('/'), kind);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Command source directories, MOST-PREFERRED FIRST.
|
|
68
|
+
*
|
|
69
|
+
* D-LEARNING-VARIANT-INSTALL: with learning off the learning-off variant comes
|
|
70
|
+
* first, so a host with an arm installs its off variant and a host with none falls
|
|
71
|
+
* through to the one compiled file; with learning on the order is the normal
|
|
72
|
+
* single-directory lookup.
|
|
73
|
+
*
|
|
74
|
+
* @param learning - The machine's settled learning switch.
|
|
75
|
+
* @param root - Package root to resolve against (see agentsDir).
|
|
76
|
+
*/
|
|
77
|
+
export function commandSourceDirs(learning, root = getPackageRoot()) {
|
|
78
|
+
const normal = join(root, 'dist', 'commands');
|
|
79
|
+
return learning ? [normal] : [learningOffDir('commands', root), normal];
|
|
80
|
+
}
|
|
44
81
|
/**
|
|
45
82
|
* Compiled agents directory: dist/agents/{name}.md
|
|
46
83
|
*
|
|
47
|
-
* Output of the .mds generator hosts. The directory is absent until
|
|
48
|
-
*
|
|
84
|
+
* Output of the .mds generator hosts. The directory is absent until the build has
|
|
85
|
+
* run, so every reader must tolerate its absence.
|
|
49
86
|
*
|
|
50
87
|
* @param root - Package root to resolve against (see agentsDir).
|
|
51
88
|
*/
|
|
@@ -87,9 +124,17 @@ export function compiledSkillRefsDir(root = getPackageRoot()) {
|
|
|
87
124
|
* The non-empty tuple makes an empty list a compile error at every call site:
|
|
88
125
|
* an empty list would survive a `??` default and resolve to nothing.
|
|
89
126
|
*
|
|
127
|
+
* D-LEARNING-VARIANT-INSTALL: `learning: false` puts dist/learning-off/agents first,
|
|
128
|
+
* for the installer and the converge only. The default (learning on) is the order
|
|
129
|
+
* every other reader wants: the shipped defaults (model, effort) are the same in
|
|
130
|
+
* both variants, so loadShippedAgentDefaults and the test harness keep reading the
|
|
131
|
+
* learning-on tree.
|
|
132
|
+
*
|
|
90
133
|
* @param root - Package root to resolve against (see agentsDir).
|
|
134
|
+
* @param learning - The machine's settled learning switch; on by default.
|
|
91
135
|
*/
|
|
92
|
-
export function agentSourceDirs(root = getPackageRoot()) {
|
|
93
|
-
|
|
136
|
+
export function agentSourceDirs(root = getPackageRoot(), learning = true) {
|
|
137
|
+
const normal = [compiledAgentsDir(root), agentsDir(root)];
|
|
138
|
+
return learning ? normal : [learningOffDir('agents', root), ...normal];
|
|
94
139
|
}
|
|
95
140
|
//# sourceMappingURL=assets.js.map
|