devflow-kit 3.8.0 → 3.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +120 -0
- package/README.md +5 -5
- package/dist/agents/code.md +4 -4
- package/dist/agents/fix.md +1 -1
- package/dist/agents/git.md +2 -2
- package/dist/agents/skim.md +1 -1
- package/dist/agents/triage.md +7 -0
- package/dist/cli/commands/curation.js +67 -16
- package/dist/cli/commands/gate-level-prompts.js +8 -6
- package/dist/cli/commands/gates.js +5 -4
- package/dist/cli/commands/init.js +8 -7
- package/dist/cli/commands/memory.js +59 -12
- package/dist/cli/commands/uninstall.js +77 -9
- package/dist/commands/bug-analysis.md +2 -2
- package/dist/commands/code-review.md +11 -11
- package/dist/commands/debug.md +2 -2
- package/dist/commands/dynamic-build.md +2 -2
- package/dist/commands/dynamic-plan.md +2 -2
- package/dist/commands/dynamic-profile.md +2 -2
- package/dist/commands/dynamic-tickets.md +2 -2
- package/dist/commands/explore.md +2 -2
- package/dist/commands/implement.md +2 -2
- package/dist/commands/plan.md +2 -2
- package/dist/commands/release.md +2 -2
- package/dist/commands/research.md +2 -2
- package/dist/commands/resolve.md +16 -16
- package/dist/commands/self-review.md +2 -2
- package/dist/core/area-pause-notice.js +44 -0
- package/dist/core/curation-move-skip.js +4 -5
- package/dist/core/curation-queue-cleanup.js +6 -5
- package/dist/core/curation-store.js +1 -0
- package/dist/core/evidence-policy.js +10 -8
- package/dist/core/plugins.js +4 -4
- package/dist/core/tracked-areas.js +138 -14
- package/dist/curation-off/agents/code.md +4 -4
- package/dist/curation-off/agents/fix.md +1 -1
- package/dist/curation-off/agents/triage.md +7 -0
- package/dist/curation-off/commands/code-review.md +11 -11
- package/dist/curation-off/commands/debug.md +2 -2
- package/dist/curation-off/commands/dynamic-build.md +2 -2
- package/dist/curation-off/commands/explore.md +2 -2
- package/dist/curation-off/commands/implement.md +2 -2
- package/dist/curation-off/commands/plan.md +2 -2
- package/dist/curation-off/commands/resolve.md +16 -16
- package/dist/curation-off/commands/self-review.md +2 -2
- package/dist/hud/components/curation-counts.js +27 -0
- package/dist/skills/git/references/pr/post-resolution-summary.md +12 -11
- package/dist/skills/git/references/pr/post-review-summary.md +12 -11
- package/dist/skills/git/references/pr/update-pr-evidence.md +2 -2
- package/dist/skills/git/references/publication-gate.md +6 -7
- package/dist/skills/git/references/tracker/github/manage-debt.md +6 -2
- package/dist/skills/git/references/tracker/jira/manage-debt.md +6 -2
- package/dist/skills/git/references/tracker/linear/manage-debt.md +6 -2
- package/package.json +1 -1
- package/src/assets/agents/code.mds +4 -4
- package/src/assets/agents/evaluate.md +6 -12
- package/src/assets/agents/fix.mds +1 -1
- package/src/assets/agents/git.mds +2 -2
- package/src/assets/agents/skim.mds +1 -1
- package/src/assets/agents/triage.mds +7 -0
- package/src/assets/agents/validate.md +20 -27
- package/src/assets/commands/_partials/_decisions.mds +10 -8
- package/src/assets/commands/_partials/_settings.mds +2 -2
- package/src/assets/commands/code-review.mds +9 -9
- package/src/assets/commands/resolve.mds +14 -14
- package/src/assets/mds/git/_ops.mds +6 -1
- package/src/assets/mds/git/_ops_pr.mds +20 -10
- package/src/assets/mds/git/_ops_steps.mds +10 -0
- package/src/assets/mds/git/_pr.mds +14 -14
- package/src/assets/mds/git/_references.mds +6 -7
- package/src/assets/mds/tracker/_github.mds +1 -4
- package/src/assets/mds/tracker/_jira.mds +1 -4
- package/src/assets/mds/tracker/_linear.mds +1 -4
- package/src/assets/scripts/ci-wait.cjs +389 -92
- package/src/assets/scripts/hooks/background-memory-update +79 -1
- package/src/assets/scripts/hooks/json-helper.cjs +44 -2
- package/src/assets/scripts/hooks/lib/curation-store.cjs +82 -20
- package/src/assets/scripts/hooks/lib/render-decisions.cjs +9 -1
- package/src/assets/scripts/hooks/lib/tracked-areas.cjs +226 -33
- package/src/assets/scripts/hooks/memory-permission +10 -2
- package/src/assets/scripts/hooks/memory-worker +11 -0
- package/src/assets/scripts/hooks/pre-compact-memory +11 -0
- package/src/assets/scripts/hooks/queue-append +218 -1
- package/src/assets/scripts/hooks/session-start-context +89 -37
- package/src/assets/scripts/hooks/session-start-memory +39 -0
- package/src/assets/scripts/pr-evidence.cjs +5 -2
- package/src/assets/scripts/resolve-settings.cjs +244 -30
- package/src/assets/scripts/verify-evidence.cjs +307 -75
- package/src/assets/skills/agent-references/SKILL.md +7 -1
- package/src/assets/skills/agent-references/references/commands/implement-levels.md +6 -4
- package/src/assets/skills/agent-references/references/commands/resolve-levels.md +3 -2
- package/src/assets/skills/agent-references/references/synthesize/review.md +4 -4
- package/src/assets/skills/agent-references/references/triage/severity-tiers.md +43 -0
- package/src/assets/skills/agent-references/references/validate/passed-alone.md +14 -0
|
@@ -30,13 +30,13 @@ $ARGUMENTS
|
|
|
30
30
|
|
|
31
31
|
### Phase 1: Resolve Settings
|
|
32
32
|
|
|
33
|
-
**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
|
|
33
|
+
**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 in a one-worktree run:
|
|
34
34
|
|
|
35
35
|
```bash
|
|
36
36
|
node "$HOME/.devflow/scripts/resolve-settings.cjs" "{root}" 2>/dev/null; echo "exit=$?"
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
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> CURATION=<on|off> KNOWLEDGE=<on|off> GATE_LEVEL=<full|standard|lean>` — 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=
|
|
39
|
+
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> CURATION=<on|off> KNOWLEDGE=<on|off> GATE_LEVEL=<full|standard|lean>` — 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=off CURATION=off KNOWLEDGE=off GATE_LEVEL=full` instead.
|
|
40
40
|
|
|
41
41
|
The accepted line is the only source of these values.
|
|
42
42
|
|
|
@@ -77,13 +77,13 @@ When a ticket requires multiple sequential Code agent phases, each Code agent ap
|
|
|
77
77
|
|
|
78
78
|
### Settings line
|
|
79
79
|
|
|
80
|
-
**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
|
|
80
|
+
**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 in a one-worktree run:
|
|
81
81
|
|
|
82
82
|
```bash
|
|
83
83
|
node "$HOME/.devflow/scripts/resolve-settings.cjs" "{root}" 2>/dev/null; echo "exit=$?"
|
|
84
84
|
```
|
|
85
85
|
|
|
86
|
-
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> CURATION=<on|off> KNOWLEDGE=<on|off> GATE_LEVEL=<full|standard|lean>` — 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=
|
|
86
|
+
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> CURATION=<on|off> KNOWLEDGE=<on|off> GATE_LEVEL=<full|standard|lean>` — 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=off CURATION=off KNOWLEDGE=off GATE_LEVEL=full` instead.
|
|
87
87
|
|
|
88
88
|
The accepted line is the only source of these values.
|
|
89
89
|
|
|
@@ -30,13 +30,13 @@ $ARGUMENTS
|
|
|
30
30
|
|
|
31
31
|
### Phase 1: Resolve Settings
|
|
32
32
|
|
|
33
|
-
**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
|
|
33
|
+
**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 in a one-worktree run:
|
|
34
34
|
|
|
35
35
|
```bash
|
|
36
36
|
node "$HOME/.devflow/scripts/resolve-settings.cjs" "{root}" 2>/dev/null; echo "exit=$?"
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
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> CURATION=<on|off> KNOWLEDGE=<on|off> GATE_LEVEL=<full|standard|lean>` — 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=
|
|
39
|
+
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> CURATION=<on|off> KNOWLEDGE=<on|off> GATE_LEVEL=<full|standard|lean>` — 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=off CURATION=off KNOWLEDGE=off GATE_LEVEL=full` instead.
|
|
40
40
|
|
|
41
41
|
The accepted line is the only source of these values.
|
|
42
42
|
|
|
@@ -144,13 +144,13 @@ node "$HOME/.devflow/scripts/verify-evidence.cjs" render --plan "{worktree}/.dev
|
|
|
144
144
|
|
|
145
145
|
- `EVIDENCE_FILE` — `{worktree}/.devflow/docs/evidence-{branch_slug}.md`, its `## Evidence Exceptions` section now a byte copy of `PR_EXCEPTIONS` (absent when that is `(none)`).
|
|
146
146
|
|
|
147
|
-
**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
|
|
147
|
+
**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 in a one-worktree run:
|
|
148
148
|
|
|
149
149
|
```bash
|
|
150
150
|
node "$HOME/.devflow/scripts/resolve-settings.cjs" "{root}" 2>/dev/null; echo "exit=$?"
|
|
151
151
|
```
|
|
152
152
|
|
|
153
|
-
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> CURATION=<on|off> KNOWLEDGE=<on|off> GATE_LEVEL=<full|standard|lean>` — 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=
|
|
153
|
+
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> CURATION=<on|off> KNOWLEDGE=<on|off> GATE_LEVEL=<full|standard|lean>` — 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=off CURATION=off KNOWLEDGE=off GATE_LEVEL=full` instead.
|
|
154
154
|
|
|
155
155
|
The accepted line is the only source of these values.
|
|
156
156
|
|
|
@@ -108,13 +108,13 @@ If the user says "skip" or "just proceed" — skip remaining questions, present
|
|
|
108
108
|
**Produces:** SKIM_CONTEXT, FEATURE_KNOWLEDGE, FEATURE_KNOWLEDGE_RULES, GATE_LEVEL
|
|
109
109
|
**Requires:** CONFIRMED_SCOPE
|
|
110
110
|
|
|
111
|
-
**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
|
|
111
|
+
**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 in a one-worktree run:
|
|
112
112
|
|
|
113
113
|
```bash
|
|
114
114
|
node "$HOME/.devflow/scripts/resolve-settings.cjs" "{root}" 2>/dev/null; echo "exit=$?"
|
|
115
115
|
```
|
|
116
116
|
|
|
117
|
-
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> CURATION=<on|off> KNOWLEDGE=<on|off> GATE_LEVEL=<full|standard|lean>` — 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=
|
|
117
|
+
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> CURATION=<on|off> KNOWLEDGE=<on|off> GATE_LEVEL=<full|standard|lean>` — 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=off CURATION=off KNOWLEDGE=off GATE_LEVEL=full` instead.
|
|
118
118
|
|
|
119
119
|
The accepted line is the only source of these values.
|
|
120
120
|
|
|
@@ -72,7 +72,7 @@ For each worktree:
|
|
|
72
72
|
2. **If `--review {timestamp}` provided:** use that specific directory (not supported in multi-worktree mode)
|
|
73
73
|
3. **Otherwise:** sort directories by name descending (timestamps are naturally sortable), scan the 10 most recent directories only. Select the first that contains `review-summary.md` (complete review)
|
|
74
74
|
4. **If latest directory already has `resolution-summary.md`:** the review is resolved — check bug-analysis fallback (step 5b).
|
|
75
|
-
5. **Legacy fallback:** if no timestamped subdirectories exist but flat `*.md` files do in `{worktree}/.devflow/docs/reviews/{branch-slug}/`, read them directly
|
|
75
|
+
5. **Legacy fallback:** if no timestamped subdirectories exist but flat `*.md` files do in `{worktree}/.devflow/docs/reviews/{branch-slug}/`, read them directly.
|
|
76
76
|
|
|
77
77
|
**5b. Bug analysis fallback** — if no qualifying review directory found (no reviews exist, or all resolved):
|
|
78
78
|
- List directories in `{worktree}/.devflow/docs/bug-analysis/{branch-slug}/`
|
|
@@ -88,13 +88,13 @@ Set `TARGET_DIR` to the selected review or bug-analysis directory path, and `TAR
|
|
|
88
88
|
|
|
89
89
|
**Produces:** FEATURE_KNOWLEDGE, FEATURE_KNOWLEDGE_RULES, EVIDENCE_POLICY, ISSUE_REQUIRED, APPLY_CONVENTIONS, REQUIRE_NON_AUTHOR_APPROVAL, REVIEW_PUBLICATION, RESOLUTION_TS, GATE_LEVEL
|
|
90
90
|
|
|
91
|
-
**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
|
|
91
|
+
**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 in a one-worktree run:
|
|
92
92
|
|
|
93
93
|
```bash
|
|
94
94
|
node "$HOME/.devflow/scripts/resolve-settings.cjs" "{root}" 2>/dev/null; echo "exit=$?"
|
|
95
95
|
```
|
|
96
96
|
|
|
97
|
-
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> CURATION=<on|off> KNOWLEDGE=<on|off> GATE_LEVEL=<full|standard|lean>` — 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=
|
|
97
|
+
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> CURATION=<on|off> KNOWLEDGE=<on|off> GATE_LEVEL=<full|standard|lean>` — 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=off CURATION=off KNOWLEDGE=off GATE_LEVEL=full` instead.
|
|
98
98
|
|
|
99
99
|
The accepted line is the only source of these values.
|
|
100
100
|
|
|
@@ -254,13 +254,15 @@ Follow devflow:apply-feature-knowledge for FEATURE_KNOWLEDGE."
|
|
|
254
254
|
|
|
255
255
|
Wait for Triage agent to complete before proceeding. Parse verdict ledger from Triage agent output:
|
|
256
256
|
- **ESCALATED**: Security issues requiring human escalation
|
|
257
|
-
- **FIX_NOW**: Valid issues assigned to Code agents (with risk tier: Standard | Careful)
|
|
257
|
+
- **FIX_NOW**: Valid issues assigned to Code agents (with risk tier: Standard | Careful | `Standard, prose only: edit text alone; agent instructions count as logic; if this issue needs a logic change, leave it unedited and name it`; any other value counts as Careful). SCOPE gives one `{id}: {tier}` line per issue.
|
|
258
258
|
- **FALSE_POSITIVE**: Issues the Review agent got wrong (with cited evidence)
|
|
259
259
|
- **BY_DESIGN**: Intentional code (with a recorded decision, stated in words, or a code doc citation)
|
|
260
260
|
- **FIX_SEPARATE**: Valid but out of blast-radius scope (must become manage-debt ticket)
|
|
261
261
|
- **TECH_DEBT**: Architectural overhaul only — LAST RESORT
|
|
262
262
|
- **DUPLICATE**: Collapsed duplicate issue — carries `duplicate_of: <primary-id>` referencing the non-DUPLICATE primary; inherits the primary's outcome
|
|
263
263
|
|
|
264
|
+
A ledger `### Summary` line `- Tiers: not applied (…)` is the level note.
|
|
265
|
+
|
|
264
266
|
**Triage agent completeness assertion:** Verify the parsed ledger against ISSUES before proceeding:
|
|
265
267
|
1. Every issue `id` from ISSUES must appear in exactly one verdict bucket — none may vanish, none may appear in multiple buckets. DUPLICATE is a valid bucket; a valid DUPLICATE entry must name its `duplicate_of` primary (the `Duplicate Of` column of the ledger's DUPLICATE table) and that primary must be a non-DUPLICATE issue id. A missing `duplicate_of` or one that chains to another DUPLICATE is a **Triage agent failure** (retry-then-abort as below).
|
|
266
268
|
2. If the Triage agent output is empty, contains a skill re-entrancy guard string (e.g., contains `already running`), or is missing any issue IDs from ISSUES: treat as a **Triage agent failure**:
|
|
@@ -308,19 +310,22 @@ Spawn distinct-file batch Code agents **in a single message** (parallel). Sequen
|
|
|
308
310
|
Collect from each Code agent:
|
|
309
311
|
- `{status, commitShas, unresolved}` per batch
|
|
310
312
|
- `## Verification` block (commands run + results)
|
|
313
|
+
- An unresolved prose-only issue that Code names as needing a logic change, and whose type is not `security` → FIX_SEPARATE in TRIAGE_RESULTS, Reason `needs a logic change`; every other unresolved issue stays Blocked
|
|
311
314
|
|
|
312
315
|
### Phase 5: Write resolution-summary.md
|
|
313
316
|
|
|
314
317
|
**Produces:** RESOLUTION_FILE (early write for compaction safety)
|
|
315
318
|
**Requires:** TRIAGE_RESULTS, CODE_AGENT_RESULTS, TARGET_DIR, TARGET_DIR_REL, BRANCH_INFO, RESOLUTION_TS, GATE_LEVEL
|
|
316
319
|
|
|
317
|
-
**Immediately write `resolution-summary.md`** to `{TARGET_DIR}` using the Write tool.
|
|
320
|
+
**Immediately write `resolution-summary.md`** to `{TARGET_DIR}` using the Write tool.
|
|
318
321
|
|
|
319
322
|
Set `Tracked` for FIX_SEPARATE and TECH_DEBT items to `(pending)` — to be backfilled after Phase 9 manage-debt (or `TRACEABILITY: DEGRADED ({reason})` if manage-debt degrades).
|
|
320
323
|
|
|
321
324
|
DUPLICATE issues are listed **only** in `## Duplicates` — never in `## Fixed Issues`, `## False Positives`, `## By Design`, `## Fix Separately`, `## Deferred to Tech Debt`, `## Escalations`, or `## Blocked`. A duplicate of a FALSE_POSITIVE primary therefore leaves only the primary in the `False Positive` row and the `## False Positives` section; the same holds for every other outcome the duplicate inherits.
|
|
322
325
|
|
|
323
|
-
|
|
326
|
+
Open each Issue cell with its severity in brackets when it has one, as `[HIGH]`.
|
|
327
|
+
|
|
328
|
+
Use the template from the Output Artifact section below. Put text not for public posting in a final `## Private notes` section.
|
|
324
329
|
|
|
325
330
|
### Phase 6: Polish
|
|
326
331
|
|
|
@@ -669,10 +674,7 @@ When the Knowledge agent reports `KB_COMMIT: skipped (detached HEAD)`, the files
|
|
|
669
674
|
├─ Phase 8: CI Status Gate (conditional)
|
|
670
675
|
├─ Phase 9: Git agent (manage-debt) — FIX_SEPARATE + TECH_DEBT → backfill Tracked={ISSUE_REF} (or TRACEABILITY: DEGRADED on failure)
|
|
671
676
|
│
|
|
672
|
-
├─ Phase 9b:
|
|
673
|
-
│ ├─ Step 9b-0: verify-evidence.cjs --stale-out → ≤1 Test agent on the stale TPs (wrapped) — only after this run's push
|
|
674
|
-
│ ├─ Step 9b-1: Git agent (resolve-review-threads) — evidence policy required
|
|
675
|
-
│ ├─ Step 9b-2: Git agent (post-resolution-summary, REVIEW_PUBLICATION) — always-on
|
|
677
|
+
├─ Phase 9b: 9b-0 Test agent (stale TPs), 9b-1/9b-2 Git agent (threads, resolution comment)
|
|
676
678
|
│ └─ Step 9b-3: verify-evidence.cjs publish (inline, no Git spawn) — only when the head moved
|
|
677
679
|
│
|
|
678
680
|
├─ Phase 9c: verify-evidence.cjs readiness (inline, no Git spawn) — non-author approval required, report-only
|
|
@@ -688,22 +690,20 @@ When the Knowledge agent reports `KB_COMMIT: skipped (detached HEAD)`, the files
|
|
|
688
690
|
| Fix attempt fails | Revert changes, mark BLOCKED, continue others |
|
|
689
691
|
| Issue dependencies | Sequential chain, skip dependents if predecessor blocked |
|
|
690
692
|
| No issues parsed | Report "No issues to resolve" |
|
|
691
|
-
| Latest review already resolved | Check bug-analysis fallback (Step 0c-5b); if also absent, skip worktree and suggest `/code-review` or `/bug-analysis` |
|
|
692
693
|
| `--review {timestamp}` in multi-worktree mode | Not supported — use `--path` + `--review` to target specific worktree + review |
|
|
693
694
|
| gh/GitHub absent | manage-debt degrades (`TRACEABILITY: DEGRADED ({reason})`); Tracked stays `(pending — TRACEABILITY: DEGRADED ({reason}))` — recorded, not dropped |
|
|
694
695
|
| `EVIDENCE_POLICY` is `standard` | Phases 1b and 9b-step-1 are skipped; post-resolution-summary (Phase 9b step 2) still runs if a PR is known |
|
|
695
696
|
| `REQUIRE_NON_AUTHOR_APPROVAL` is `false` | Phase 9c is skipped and reported as SKIPPED |
|
|
696
|
-
| Public repo (`auto` mode) | Git agent probes visibility, posts counts-only STUB comment; full resolution report stays local |
|
|
697
697
|
| `reviewPublication: off` | Git agent skips posting the resolution comment (OFF) — except that, only when `EVIDENCE_POLICY` is `required`, Step 0d passes `stub` and a counts-only STUB comment posts |
|
|
698
|
-
| Fork PR this run cannot push to
|
|
698
|
+
| Fork PR this run cannot push to | `TRACEABILITY: DEGRADED (cannot push to fork)` → `fork_no_push`: no push in Phase 7, Phase 8 skipped, 9b-1 records FIXED threads as DEGRADED, 9b-2 still posts; the head did not move, so 9b-0 and 9b-3 are skipped |
|
|
699
699
|
| The PR has no trusted evidence record | 9b-0 finds no vouched-for stale line, so no Test agent runs; 9b-3 still refreshes the block and comment, every TP without a claim reading `UNVERIFIED` |
|
|
700
700
|
| A CI run behind a claim has expired (~90 days) | The TP reads `INDETERMINATE` — never verified, never failed — until a claim at a newer SHA settles it |
|
|
701
701
|
|
|
702
702
|
## Principles
|
|
703
703
|
|
|
704
704
|
1. **Orchestration only** - Command spawns agents, doesn't do git/resolve work itself
|
|
705
|
-
2. **Git agent for git work** - All git operations go through Git agent;
|
|
706
|
-
3. **Traceability-aware** - Policy-gated ops
|
|
705
|
+
2. **Git agent for git work** - All git operations go through Git agent; inline scripts are plumbing
|
|
706
|
+
3. **Traceability-aware** - Policy-gated ops are skipped cleanly when the evidence policy does not ask for them; resolution comment (Phase 9b-2) is always-on; test-plan evidence is re-verified (≤1 Test agent) and refreshed only when this run moved the head (Steps 9b-0, 9b-3)
|
|
707
707
|
|
|
708
708
|
## Output Artifact
|
|
709
709
|
|
|
@@ -716,7 +716,7 @@ Written in Phase 5 (Collect Results) to `{TARGET_DIR}/resolution-summary.md`:
|
|
|
716
716
|
**Date**: {RESOLUTION_TS}
|
|
717
717
|
**Review**: {TARGET_DIR_REL}
|
|
718
718
|
**Command**: /resolve
|
|
719
|
-
**Gate level**: {GATE_LEVEL}
|
|
719
|
+
**Gate level**: {GATE_LEVEL, with any level note}
|
|
720
720
|
|
|
721
721
|
## Statistics
|
|
722
722
|
| Metric | Value |
|
|
@@ -24,13 +24,13 @@ Detect changed files and build context:
|
|
|
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 Polish runs — Phase 3 compares against it
|
|
26
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
|
|
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 in a one-worktree run:
|
|
28
28
|
|
|
29
29
|
```bash
|
|
30
30
|
node "$HOME/.devflow/scripts/resolve-settings.cjs" "{root}" 2>/dev/null; echo "exit=$?"
|
|
31
31
|
```
|
|
32
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> CURATION=<on|off> KNOWLEDGE=<on|off> GATE_LEVEL=<full|standard|lean>` — 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=
|
|
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> CURATION=<on|off> KNOWLEDGE=<on|off> GATE_LEVEL=<full|standard|lean>` — 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=off CURATION=off KNOWLEDGE=off GATE_LEVEL=full` instead.
|
|
34
34
|
|
|
35
35
|
The accepted line is the only source of these values.
|
|
36
36
|
|
|
@@ -6,6 +6,7 @@ import { formatMoveNotice, gatherMoveNotice } from '../../core/curation-move-not
|
|
|
6
6
|
import { isMoveSkipReason } from '../../core/curation-move-skip.js';
|
|
7
7
|
import { getLedgerRoot, LEDGER_ROOT_TIMEOUT_MS } from '../../core/ledger-root.js';
|
|
8
8
|
import { isActiveDecisionsStatus } from '../../core/observations.js';
|
|
9
|
+
import { probeTrackedArea } from '../../core/tracked-areas.js';
|
|
9
10
|
/**
|
|
10
11
|
* The largest ledger the statusline reads: 8 MiB, far above the roughly 0.5 MB
|
|
11
12
|
* real ledgers reach.
|
|
@@ -101,6 +102,16 @@ export function gatherCurationCounts(cwd) {
|
|
|
101
102
|
}
|
|
102
103
|
return parsedAny ? counts : null;
|
|
103
104
|
}
|
|
105
|
+
/** Whether anything stands at `ledgerPath`, a link included: the cheap test that keeps git out of a project with no ledger. */
|
|
106
|
+
async function ledgerPresent(ledgerPath) {
|
|
107
|
+
try {
|
|
108
|
+
await fs.promises.lstat(ledgerPath);
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
104
115
|
/**
|
|
105
116
|
* Count the ledger the hooks write for a session started in `cwd`: the ledger
|
|
106
117
|
* root (getLedgerRoot — the main checkout in a linked worktree, the repository
|
|
@@ -109,10 +120,26 @@ export function gatherCurationCounts(cwd) {
|
|
|
109
120
|
* status gather, not after it (D-LEDGER-MAIN-WORKTREE). Where the old ledger folder
|
|
110
121
|
* still stands it adds the move notice (gatherMoveNotice): any notice when both counts
|
|
111
122
|
* are zero, a skip notice only when a count is above zero.
|
|
123
|
+
*
|
|
124
|
+
* The ledger is read only where git tracks nothing in the curation folders: when it
|
|
125
|
+
* stands, the tracked-areas check asks git, and any answer other than `untracked` (git
|
|
126
|
+
* tracks files there, git did not answer, or the budget ran out) gives no counts and no
|
|
127
|
+
* notice. A project with no ledger makes no git call here. The root lookup and the check
|
|
128
|
+
* share one LEDGER_ROOT_TIMEOUT_MS deadline: the check gets what the lookup left, and when
|
|
129
|
+
* nothing is left it does not run and the answer is no counts.
|
|
112
130
|
*/
|
|
113
131
|
export async function gatherLedgerCurationCounts(cwd, options = {}) {
|
|
132
|
+
const deadline = Date.now() + LEDGER_ROOT_TIMEOUT_MS;
|
|
114
133
|
const root = await getLedgerRoot(cwd, { ...options, timeoutMs: LEDGER_ROOT_TIMEOUT_MS });
|
|
115
134
|
const ledgerRoot = root ?? cwd;
|
|
135
|
+
if (await ledgerPresent(getDecisionsLedgerPath(ledgerRoot))) {
|
|
136
|
+
const timeLeftMs = deadline - Date.now();
|
|
137
|
+
if (timeLeftMs <= 0)
|
|
138
|
+
return null;
|
|
139
|
+
const { answer } = await probeTrackedArea(ledgerRoot, 'curation', { timeoutMs: timeLeftMs });
|
|
140
|
+
if (answer !== 'untracked')
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
116
143
|
const counts = gatherCurationCounts(ledgerRoot);
|
|
117
144
|
const move = gatherMoveNotice(ledgerRoot, options.home ?? os.homedir());
|
|
118
145
|
if (counts !== null && counts.decisions + counts.pitfalls > 0) {
|
|
@@ -1,47 +1,48 @@
|
|
|
1
1
|
## Operation: post-resolution-summary
|
|
2
2
|
|
|
3
|
-
Post the resolution summary as
|
|
3
|
+
Post the resolution summary as one PR comment per workflow run, deduplicated by its marker; never edited after posting (D8).
|
|
4
4
|
|
|
5
5
|
**Input:** `PR_NUMBER`, `RESOLUTION_SUMMARY_PATH`, `RESOLUTION_TS`, `WORKTREE_PATH` (optional), `REVIEW_PUBLICATION` (optional; values: `auto` | `full` | `off` | `stub`; absent/unrecognised → `auto`)
|
|
6
6
|
|
|
7
|
-
**Degradation (D4):** No PR → `TRACEABILITY: DEGRADED (no PR)`, warn, return
|
|
7
|
+
**Degradation (D4):** No PR → `TRACEABILITY: DEGRADED (no PR)`, warn, return; the summary stays on disk.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Its publication gate is the `devflow:git` skill's `references/publication-gate.md` (D10).
|
|
10
10
|
|
|
11
11
|
The body the steps below compose MUST NOT reproduce verbatim content from any `<external-thread>` body or `<untrusted-issue-body>` — cite only internal evidence (commit SHAs, file:line from this codebase) and the thread's `ext-{N}` id.
|
|
12
12
|
|
|
13
|
+
**Private sections:** one starts at any line, fenced or not, of 0-3 spaces, 1-6 `#`, a space or tab and the word `Private` (any case) not followed by a letter or digit. It ends before the next unfenced heading (0-3 spaces) with as many `#` as its start or fewer, else at end of file; an unclosed fence in it runs it to end of file. When unsure, strip more. The read strips them before either mode, closing at each cut any fence the cut leaves open; compose, cap and re-cap use only the stripped text; the file stays unedited. A failed read or strip, blank stripped text or, before the scrub, a body line of that start shape → post nothing; report `**Status**: DEGRADED (no postable summary)` and never quote private text.
|
|
14
|
+
|
|
13
15
|
**Output:**
|
|
14
16
|
```markdown
|
|
15
17
|
## Resolution Summary Posted
|
|
16
18
|
**PR**: #{number}
|
|
17
19
|
**Publication**: FULL (private repo) | FULL (config override) | STUB (public repository) | OFF (publication disabled by config) | STUB (visibility undeterminable) | STUB (evidence policy)
|
|
18
|
-
**Status**: POSTED | POSTED+TRUNCATED (body exceeded 60k after redaction
|
|
20
|
+
**Status**: POSTED | POSTED+TRUNCATED (body exceeded 60k after redaction) | SKIPPED (already posted) | DEGRADED ({reason})
|
|
21
|
+
**Stripped**: {n} private sections
|
|
19
22
|
```
|
|
20
23
|
|
|
21
24
|
Load for `post-resolution-summary` under every tracker provider.
|
|
22
25
|
|
|
23
|
-
**PR mechanics held here:** the author-filtered marker dedup, the visibility probe, the FULL/STUB compose templates with the 60000-character cap, and the scrub-then-post call.
|
|
24
|
-
|
|
25
26
|
### Process
|
|
26
27
|
|
|
27
|
-
1. Check for existing marker (author-filtered
|
|
28
|
+
1. Check for an existing marker (author-filtered, so a third party's copy of it cannot suppress devflow's comment):
|
|
28
29
|
- Fetch viewer login: `gh api user --jq '.login'` → store as VIEWER_LOGIN
|
|
29
30
|
- `gh pr view {PR_NUMBER} --json comments --jq '[.comments[] | select(.author.login == "'"$VIEWER_LOGIN"'")] | .[].body'`
|
|
30
31
|
- Search the viewer-authored bodies only for the exact key `<!-- devflow:resolution-summary ts:{RESOLUTION_TS} -->`
|
|
31
32
|
- If found: skip — report `Skipped: already posted for ts:{RESOLUTION_TS}`
|
|
32
33
|
2. Load `references/publication-gate.md` and resolve `REVIEW_PUBLICATION` by its step 2; `off` ends the op without posting.
|
|
33
34
|
3. Probe (if mode not yet determined): `gh repo view --json visibility --jq '.visibility'`, case-insensitive. `PRIVATE`/`INTERNAL` → FULL; `PUBLIC` → `STUB (public repository)`; empty output, an error or any other value → `STUB (visibility undeterminable)`. **Fail-closed: on any error or unrecognised value, treat as PUBLIC (mode STUB).**
|
|
34
|
-
4. Read `RESOLUTION_SUMMARY_PATH`
|
|
35
|
+
4. Read `RESOLUTION_SUMMARY_PATH` (repo-relative) under `WORKTREE_PATH` (else cwd); strip it (above).
|
|
35
36
|
5. Compose body (where `{TS}` = `RESOLUTION_TS`):
|
|
36
37
|
- **FULL mode:**
|
|
37
38
|
```
|
|
38
39
|
<!-- devflow:resolution-summary ts:{TS} -->
|
|
39
|
-
{
|
|
40
|
+
{stripped resolution-summary.md}
|
|
40
41
|
|
|
41
42
|
---
|
|
42
43
|
*Posted by [devflow](https://github.com/dean0x/devflow)*
|
|
43
44
|
```
|
|
44
|
-
- **STUB mode** (excluded:
|
|
45
|
+
- **STUB mode** (stripped text only; excluded: all but the counts table):
|
|
45
46
|
```
|
|
46
47
|
<!-- devflow:resolution-summary ts:{TS} -->
|
|
47
48
|
## Resolution Summary
|
|
@@ -53,6 +54,6 @@ Load for `post-resolution-summary` under every tracker provider.
|
|
|
53
54
|
Full report: {RESOLUTION_SUMMARY_PATH} (not committed; ask the author)
|
|
54
55
|
*Posted by [devflow](https://github.com/dean0x/devflow)*
|
|
55
56
|
```
|
|
56
|
-
Cap body at 60000 characters
|
|
57
|
+
Cap body at 60000 characters; truncate lowest-value sections first (Suggestions, then Pre-existing), keeping the counts table and every Blocking entry; end with `…truncated — full report in the local review artifact {RESOLUTION_SUMMARY_PATH} (not committed; ask the author)`.
|
|
57
58
|
6. Write body to `$DEVFLOW_BODY_RAW`; apply the Comment-sink scrub (D11) — non-zero exit or missing script → DO NOT POST. Re-check the 60000-char cap on the scrubbed body (redaction may grow it; truncate at a line boundary below 59,800 chars, keeping the truncation pointer sentence; if truncation fires here: emit `NOTE: body exceeded 60k after redaction — truncated/stub posted` in op output and prepend that notice to the body). Post: `gh pr comment {PR_NUMBER} --body-file "$DEVFLOW_BODY"`.
|
|
58
59
|
7. On 5xx: retry once. If still 5xx: `TRACEABILITY: DEGRADED (5xx on post-resolution-summary)`, warn, return.
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
## Operation: post-review-summary
|
|
2
2
|
|
|
3
|
-
Post a consolidated code review summary as
|
|
3
|
+
Post a consolidated code review summary as one PR comment per review run (D7), deduplicated by its cycle+timestamp marker; never edited after posting.
|
|
4
4
|
|
|
5
5
|
**Input:** `PR_NUMBER`, `REVIEW_SUMMARY_PATH`, `CYCLE_NUMBER`, `REVIEW_TIMESTAMP`, `WORKTREE_PATH` (optional), `REVIEW_PUBLICATION` (optional; values: `auto` | `full` | `off` | `stub`; absent/unrecognised → `auto`)
|
|
6
6
|
|
|
7
|
-
- `REVIEW_TIMESTAMP`: the review directory timestamp slug (e.g., `2026-08-20_1030`)
|
|
7
|
+
- `REVIEW_TIMESTAMP`: the review directory's timestamp slug (e.g., `2026-08-20_1030`), the run half of the dedup key, so a re-review posts its own comment
|
|
8
8
|
|
|
9
|
-
**Degradation (D4):** No PR / `gh` unauthenticated → `TRACEABILITY: DEGRADED (no PR)`, warn
|
|
9
|
+
**Degradation (D4):** No PR / `gh` unauthenticated → `TRACEABILITY: DEGRADED (no PR)`, warn, return; the summary stays on disk.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Its publication gate is the `devflow:git` skill's `references/publication-gate.md` (D10).
|
|
12
|
+
|
|
13
|
+
**Private sections:** one starts at any line, fenced or not, of 0-3 spaces, 1-6 `#`, a space or tab and the word `Private` (any case) not followed by a letter or digit. It ends before the next unfenced heading (0-3 spaces) with as many `#` as its start or fewer, else at end of file; an unclosed fence in it runs it to end of file. When unsure, strip more. The read strips them before either mode, closing at each cut any fence the cut leaves open; compose, cap and re-cap use only the stripped text; the file stays unedited. A failed read or strip, blank stripped text or, before the scrub, a body line of that start shape → post nothing; report `**Status**: DEGRADED (no postable summary)` and never quote private text.
|
|
12
14
|
|
|
13
15
|
**Output:**
|
|
14
16
|
```markdown
|
|
@@ -17,35 +19,34 @@ The publication gate this operation applies is the `devflow:git` skill's `refere
|
|
|
17
19
|
**Cycle**: {CYCLE_NUMBER}
|
|
18
20
|
**Review timestamp**: {REVIEW_TIMESTAMP}
|
|
19
21
|
**Publication**: FULL (private repo) | FULL (config override) | STUB (public repository) | OFF (publication disabled by config) | STUB (visibility undeterminable) | STUB (evidence policy)
|
|
20
|
-
**Status**: POSTED | POSTED+TRUNCATED (body exceeded 60k after redaction
|
|
22
|
+
**Status**: POSTED | POSTED+TRUNCATED (body exceeded 60k after redaction) | SKIPPED (already posted for cycle {N} ts:{REVIEW_TIMESTAMP}) | DEGRADED ({reason})
|
|
23
|
+
**Stripped**: {n} private sections
|
|
21
24
|
```
|
|
22
25
|
|
|
23
26
|
Load for `post-review-summary` under every tracker provider.
|
|
24
27
|
|
|
25
|
-
**PR mechanics held here:** the author-filtered marker dedup, the visibility probe, the FULL/STUB compose templates with the 60000-character cap, and the scrub-then-post call.
|
|
26
|
-
|
|
27
28
|
### Process
|
|
28
29
|
|
|
29
|
-
1. Check for existing comment with this run's marker (author-filtered
|
|
30
|
+
1. Check for existing comment with this run's marker (author-filtered, so a third party's copy of the marker cannot suppress it):
|
|
30
31
|
- Fetch viewer login: `gh api user --jq '.login'` → store as VIEWER_LOGIN
|
|
31
32
|
- `gh pr view {PR_NUMBER} --json comments --jq '[.comments[] | select(.author.login == "'"$VIEWER_LOGIN"'")] | .[].body'`
|
|
32
33
|
- Search for `<!-- devflow:review-summary cycle:{CYCLE_NUMBER} ts:{REVIEW_TIMESTAMP}` in the viewer-authored comment bodies only (full pair match)
|
|
33
34
|
- If found: skip — report `Skipped: already posted for cycle {CYCLE_NUMBER} ts:{REVIEW_TIMESTAMP}`
|
|
34
35
|
2. Load `references/publication-gate.md` and resolve `REVIEW_PUBLICATION` by its step 2; `off` ends the op without posting.
|
|
35
36
|
3. Probe (if mode not yet determined): `gh repo view --json visibility --jq '.visibility'`, case-insensitive. `PRIVATE`/`INTERNAL` → FULL; `PUBLIC` → `STUB (public repository)`; empty output, an error or any other value → `STUB (visibility undeterminable)`. **Fail-closed: on any error or unrecognised value, treat as PUBLIC (mode STUB).**
|
|
36
|
-
4. Read `REVIEW_SUMMARY_PATH`
|
|
37
|
+
4. Read `REVIEW_SUMMARY_PATH` (repo-relative) under `WORKTREE_PATH` (else cwd); strip it (above).
|
|
37
38
|
5. Compose body:
|
|
38
39
|
- **FULL mode:**
|
|
39
40
|
```
|
|
40
41
|
<!-- devflow:review-summary cycle:{CYCLE_NUMBER} ts:{REVIEW_TIMESTAMP} -->
|
|
41
42
|
## Code Review — Cycle {CYCLE_NUMBER}
|
|
42
43
|
|
|
43
|
-
{
|
|
44
|
+
{stripped review-summary.md}
|
|
44
45
|
|
|
45
46
|
---
|
|
46
47
|
*Posted by [devflow](https://github.com/dean0x/devflow) · cycle {CYCLE_NUMBER}*
|
|
47
48
|
```
|
|
48
|
-
- **STUB mode** (
|
|
49
|
+
- **STUB mode** (stripped text only; excluded: all but the counts table):
|
|
49
50
|
```
|
|
50
51
|
<!-- devflow:review-summary cycle:{CYCLE_NUMBER} ts:{REVIEW_TIMESTAMP} -->
|
|
51
52
|
## Code Review — Cycle {CYCLE_NUMBER}
|
|
@@ -10,7 +10,7 @@ Update the PR's test-plan block and evidence comment.
|
|
|
10
10
|
```markdown
|
|
11
11
|
## PR Evidence
|
|
12
12
|
{the script's EVIDENCE line}
|
|
13
|
-
**Body**: EDITED | UNCHANGED | SKIPPED | DEGRADED ({reason}) · **Comment**: POSTED | SKIPPED | OFF | DEGRADED ({reason})
|
|
13
|
+
**Body**: EDITED | UNCHANGED | SKIPPED | DEGRADED ({reason}) · **Comment**: POSTED | SKIPPED | OFF | EDITED | DEGRADED ({reason})
|
|
14
14
|
```
|
|
15
15
|
|
|
16
16
|
Load for `update-pr-evidence` under every tracker provider.
|
|
@@ -22,4 +22,4 @@ Load for `update-pr-evidence` under every tracker provider.
|
|
|
22
22
|
1. From `WORKTREE_PATH` (else cwd), run `node "$HOME/.devflow/scripts/verify-evidence.cjs" publish --pr {PR_NUMBER}; echo "exit=$?"`, adding `--publication {REVIEW_PUBLICATION}` only when that is `auto`, `full`, `off` or `stub`, and `--evidence "{EVIDENCE_FILE}"` when given — only a value matching `^[A-Za-z0-9._/-]{1,255}$` reaches the shell; any other is a failed run. Set the Bash `timeout` to 180000.
|
|
23
23
|
2. Print the script's stdout and nothing else. On exit 0 it is the `## PR Evidence` block: the heading, the line `EVIDENCE pr:<n> head:<sha> total:<n> VERIFIED-CI:<n> ATTESTED-LOCAL:<n> UNVERIFIED:<n> STALE:<n> FAILED:<n> INDETERMINATE:<n> stale:<ids|none> exceptions:<kinds|none> approval:<yes|no|unchecked> key:<hex> posted:<yes|no|n/a> body:<same|changed>`, and the `**Body**:` / `**Comment**:` line, then one `TRACEABILITY: DEGRADED ({reason})` line for each part that degraded, such as `DEGRADED (concurrent edit)` (the body edit then reads `SKIPPED`), `DEGRADED (body read-back mismatch)` or `DEGRADED (redaction unavailable)`: a body the script cannot scrub is never posted. On exit 2 it is `TRACEABILITY: DEGRADED (evidence unavailable)`. Any other exit, or empty stdout, is a failed run: emit that same line.
|
|
24
24
|
|
|
25
|
-
Run nothing else: the script makes the one PR read, the compare-and-swap body edit, its read-back and the
|
|
25
|
+
Run nothing else: the script makes the one PR read, the compare-and-swap body edit, its read-back and the evidence comment itself, edited in place when the viewer's own is the newest evidence comment, and posts nothing it could not scrub.
|
|
@@ -2,12 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
Applies to **`post-review-summary` and `post-resolution-summary` only.** No other op probes repo visibility.
|
|
4
4
|
|
|
5
|
-
**Step order
|
|
6
|
-
1. Dedup check (D7/D8 marker
|
|
5
|
+
**Step order:**
|
|
6
|
+
1. Dedup check (D7/D8 marker; stays first).
|
|
7
7
|
2. Resolve `REVIEW_PUBLICATION` input: `off` → report `**Publication**: OFF (publication disabled by config)`, op ends without posting. `full` → mode FULL, skip probe. `auto` or absent/unrecognised → probe.
|
|
8
8
|
- `stub` (never unrecognised) → mode STUB, skip probe; report `STUB (evidence policy)`.
|
|
9
|
-
3. Probe once: `gh repo view --json visibility --jq '.visibility'
|
|
10
|
-
4. Compose body (
|
|
11
|
-
5. Scrub per D11 (both modes
|
|
12
|
-
6.
|
|
13
|
-
7. Post; 5xx retry-once (unchanged).
|
|
9
|
+
3. Probe once: `gh repo view --json visibility --jq '.visibility'`, case-insensitive. `PRIVATE` or `INTERNAL` → mode FULL; anything else → mode STUB. **Fail-closed rule: on any error or unrecognised value, treat as PUBLIC (mode STUB).**
|
|
10
|
+
4. Compose body (defined per op).
|
|
11
|
+
5. Scrub per D11 (both modes), then re-check the 60000-char cap **after** the scrub.
|
|
12
|
+
6. Post; 5xx retry-once.
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
## Operation: manage-debt
|
|
2
2
|
|
|
3
|
-
Update tech debt backlog
|
|
3
|
+
Update tech debt backlog from `{REVIEW_DIR}/resolution-summary.md`:
|
|
4
|
+
- Add only entries of `## Fix Separately` (FIX_SEPARATE) and `## Deferred to Tech Debt` (TECH_DEBT). A section ends at the next heading.
|
|
5
|
+
- An empty section adds none.
|
|
6
|
+
- If `resolution-summary.md` is missing, return `TRACEABILITY: DEGRADED (resolution summary missing)` and do not update the backlog.
|
|
7
|
+
- Never add an item that also has an entry in `## Escalations`, `## Blocked` or `## Fixed Issues`.
|
|
8
|
+
- Read no review report: in `{REVIEW_DIR}`, read only `resolution-summary.md`.
|
|
4
9
|
|
|
5
10
|
**Input:** `REVIEW_DIR`, `TIMESTAMP`, `WORKTREE_PATH` (optional)
|
|
6
11
|
|
|
@@ -31,7 +36,6 @@ Load when the resolved tracker provider is `github` and the operation is `manage
|
|
|
31
36
|
3. Extract items to add:
|
|
32
37
|
- `## Fix Separately` entries from `{REVIEW_DIR}/resolution-summary.md` (FIX_SEPARATE from Triage agent)
|
|
33
38
|
- `## Deferred to Tech Debt` entries from `{REVIEW_DIR}/resolution-summary.md` (TECH_DEBT from Triage agent)
|
|
34
|
-
- Pre-existing issues (Category 3) from review reports
|
|
35
39
|
4. Deduplicate against existing items using semantic matching
|
|
36
40
|
5. Remove items that have been fixed (verify in codebase)
|
|
37
41
|
6. Compose updated issue body to `$DEVFLOW_BODY_RAW`; apply the Comment-sink scrub (D11) and post via `gh issue edit {number} --body-file "$DEVFLOW_BODY"`
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
## Operation: manage-debt
|
|
2
2
|
|
|
3
|
-
Update tech debt backlog
|
|
3
|
+
Update tech debt backlog from `{REVIEW_DIR}/resolution-summary.md`:
|
|
4
|
+
- Add only entries of `## Fix Separately` (FIX_SEPARATE) and `## Deferred to Tech Debt` (TECH_DEBT). A section ends at the next heading.
|
|
5
|
+
- An empty section adds none.
|
|
6
|
+
- If `resolution-summary.md` is missing, return `TRACEABILITY: DEGRADED (resolution summary missing)` and do not update the backlog.
|
|
7
|
+
- Never add an item that also has an entry in `## Escalations`, `## Blocked` or `## Fixed Issues`.
|
|
8
|
+
- Read no review report: in `{REVIEW_DIR}`, read only `resolution-summary.md`.
|
|
4
9
|
|
|
5
10
|
**Input:** `REVIEW_DIR`, `TIMESTAMP`, `WORKTREE_PATH` (optional)
|
|
6
11
|
|
|
@@ -31,7 +36,6 @@ Load when the resolved tracker provider is `jira` and the operation is `manage-d
|
|
|
31
36
|
3. Extract items to add:
|
|
32
37
|
- `## Fix Separately` entries from `{REVIEW_DIR}/resolution-summary.md` (FIX_SEPARATE from Triage agent)
|
|
33
38
|
- `## Deferred to Tech Debt` entries from `{REVIEW_DIR}/resolution-summary.md` (TECH_DEBT from Triage agent)
|
|
34
|
-
- Pre-existing issues (Category 3) from review reports
|
|
35
39
|
4. Deduplicate against existing items using semantic matching.
|
|
36
40
|
5. Remove items that have been fixed (verify in codebase).
|
|
37
41
|
6. Compose the updated description and post it through the gate in `### Posting gate` below, using the *update description* capability.
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
## Operation: manage-debt
|
|
2
2
|
|
|
3
|
-
Update tech debt backlog
|
|
3
|
+
Update tech debt backlog from `{REVIEW_DIR}/resolution-summary.md`:
|
|
4
|
+
- Add only entries of `## Fix Separately` (FIX_SEPARATE) and `## Deferred to Tech Debt` (TECH_DEBT). A section ends at the next heading.
|
|
5
|
+
- An empty section adds none.
|
|
6
|
+
- If `resolution-summary.md` is missing, return `TRACEABILITY: DEGRADED (resolution summary missing)` and do not update the backlog.
|
|
7
|
+
- Never add an item that also has an entry in `## Escalations`, `## Blocked` or `## Fixed Issues`.
|
|
8
|
+
- Read no review report: in `{REVIEW_DIR}`, read only `resolution-summary.md`.
|
|
4
9
|
|
|
5
10
|
**Input:** `REVIEW_DIR`, `TIMESTAMP`, `WORKTREE_PATH` (optional)
|
|
6
11
|
|
|
@@ -31,7 +36,6 @@ Load when the resolved tracker provider is `linear` and the operation is `manage
|
|
|
31
36
|
3. Extract items to add:
|
|
32
37
|
- `## Fix Separately` entries from `{REVIEW_DIR}/resolution-summary.md` (FIX_SEPARATE from Triage agent)
|
|
33
38
|
- `## Deferred to Tech Debt` entries from `{REVIEW_DIR}/resolution-summary.md` (TECH_DEBT from Triage agent)
|
|
34
|
-
- Pre-existing issues (Category 3) from review reports
|
|
35
39
|
4. Deduplicate against existing items using semantic matching.
|
|
36
40
|
5. Remove items that have been fixed (verify in codebase).
|
|
37
41
|
6. Compose the updated description and post it through the gate in `### Posting gate` below, using the *update description* capability.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "devflow-kit",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.9.0",
|
|
4
4
|
"description": "A meta-harness for Claude Code — turns a single coding agent into an engineering team: orchestration, parallel review, persistent memory, curated decisions, and graph workflows",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -53,9 +53,9 @@ You receive from orchestrator:
|
|
|
53
53
|
- **BASE_BRANCH**: Branch this feature branch was created from
|
|
54
54
|
- **EXECUTION_PLAN**: Synthesized plan with steps, files, tests
|
|
55
55
|
- **PATTERNS**: Codebase patterns to follow
|
|
56
|
-
- **OPERATION** (optional): `implement` (default when absent) | `issue-fix` — selects operating mode
|
|
57
|
-
- **ISSUES** (when OPERATION: issue-fix): Pre-classified issues from Triage agent with disposition FIX_NOW
|
|
58
|
-
- **SCOPE** (when OPERATION: issue-fix): Blast-radius scope hint (Standard | Careful) per issue
|
|
56
|
+
- **OPERATION** (optional): `implement` (default when absent) | `issue-fix` — selects operating mode; every spawn passes it as the first prompt line. Any other value returns BLOCKED, naming it, and changes nothing.
|
|
57
|
+
- **ISSUES** (when OPERATION: issue-fix): Pre-classified issues from Triage agent with disposition FIX_NOW
|
|
58
|
+
- **SCOPE** (when OPERATION: issue-fix): Blast-radius scope hint (Standard | Careful | `Standard, prose only`) per issue
|
|
59
59
|
- **FEATURE_KNOWLEDGE** (optional): Per KB, the Rules bullets most relevant to the task (anti-patterns, gotchas, invariants), the KB path and a heading index; sections are read on demand
|
|
60
60
|
|
|
61
61
|
**Worktree Support**: If `WORKTREE_PATH` is provided, follow the `devflow:worktree-support` skill for path resolution. If omitted, use cwd.
|
|
@@ -92,7 +92,7 @@ You receive from orchestrator:
|
|
|
92
92
|
|
|
93
93
|
When `OPERATION: issue-fix`, you are fixing pre-classified issues assigned FIX_NOW by the Triage agent. Do not re-litigate dispositions.
|
|
94
94
|
|
|
95
|
-
**Inputs:** `ISSUES` (pre-classified FIX_NOW issues), `SCOPE` (Standard | Careful per issue; absent means Standard), `PUSH: false` (always for issue-fix; the orchestrator pushes after its final validation gate)
|
|
95
|
+
**Inputs:** `ISSUES` (pre-classified FIX_NOW issues), `SCOPE` (Standard | Careful | `Standard, prose only` per issue; absent means Standard), `PUSH: false` (always for issue-fix; the orchestrator pushes after its final validation gate)
|
|
96
96
|
|
|
97
97
|
**Protocol:**
|
|
98
98
|
1. Same-file issues → one commit (never two Code agents editing the same file concurrently)
|