devflow-kit 2.3.0 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/CHANGELOG.md +177 -0
  2. package/README.md +86 -18
  3. package/dist/agents/git.md +824 -0
  4. package/dist/cli/commands/agents.js +6 -1
  5. package/dist/cli/commands/attribution-prompts.js +144 -0
  6. package/dist/cli/commands/compliance-prompts.js +7 -11
  7. package/dist/cli/commands/compliance.js +23 -1
  8. package/dist/cli/commands/init-seed.js +69 -30
  9. package/dist/cli/commands/init.js +551 -77
  10. package/dist/cli/commands/install-report.js +205 -0
  11. package/dist/cli/commands/knowledge/index.js +2 -2
  12. package/dist/cli/commands/knowledge/toggle.js +27 -37
  13. package/dist/cli/commands/learning.js +37 -30
  14. package/dist/cli/commands/memory.js +79 -69
  15. package/dist/cli/commands/prompt-io.js +38 -0
  16. package/dist/cli/commands/proxy.js +91 -31
  17. package/dist/cli/commands/security.js +76 -16
  18. package/dist/cli/commands/skills.js +53 -7
  19. package/dist/cli/commands/tracker-prompts.js +145 -0
  20. package/dist/cli/commands/tracker.js +405 -0
  21. package/dist/cli/commands/uninstall.js +233 -77
  22. package/dist/cli.js +2 -0
  23. package/dist/commands/bug-analysis.md +22 -4
  24. package/dist/commands/code-review.md +44 -15
  25. package/dist/commands/debug.md +20 -6
  26. package/dist/commands/dynamic-build.md +289 -67
  27. package/dist/commands/dynamic-plan.md +60 -21
  28. package/dist/commands/dynamic-profile.md +1 -1
  29. package/dist/commands/dynamic-tickets.md +58 -8
  30. package/dist/commands/explore.md +2 -2
  31. package/dist/commands/implement.md +241 -53
  32. package/dist/commands/plan.md +88 -17
  33. package/dist/commands/release.md +64 -17
  34. package/dist/commands/resolve.md +138 -58
  35. package/dist/commands/self-review.md +2 -2
  36. package/dist/core/agent-models.js +55 -12
  37. package/dist/core/assets.js +58 -2
  38. package/dist/core/evidence-policy.js +147 -0
  39. package/dist/core/feature-config.js +130 -64
  40. package/dist/core/feature-switch.js +112 -0
  41. package/dist/core/flags.js +149 -8
  42. package/dist/core/manifest.js +33 -7
  43. package/dist/core/mds-variants.js +861 -0
  44. package/dist/core/model-discovery.js +12 -1
  45. package/dist/core/plugins.js +357 -9
  46. package/dist/core/project-paths.js +1 -1
  47. package/dist/core/proxy-log.js +8 -4
  48. package/dist/core/proxy-state.js +100 -43
  49. package/dist/core/reference-sweep.js +136 -0
  50. package/dist/core/tracker.js +407 -0
  51. package/dist/skills/git/references/decision-markers.md +19 -0
  52. package/dist/skills/git/references/learn-conventions.md +56 -0
  53. package/dist/skills/git/references/pr/check-ci-status.md +14 -0
  54. package/dist/skills/git/references/pr/check-merge-readiness.md +28 -0
  55. package/dist/skills/git/references/pr/ensure-pr-ready.md +24 -0
  56. package/dist/skills/git/references/pr/fetch-review-threads.md +22 -0
  57. package/dist/skills/git/references/pr/post-resolution-summary.md +40 -0
  58. package/dist/skills/git/references/pr/post-review-summary.md +42 -0
  59. package/dist/skills/git/references/pr/resolve-review-threads.md +35 -0
  60. package/dist/skills/git/references/pr/update-pr-evidence.md +14 -0
  61. package/dist/skills/git/references/pr/validate-branch.md +18 -0
  62. package/dist/skills/git/references/publication-gate.md +13 -0
  63. package/dist/skills/git/references/tracker/_mcp.md +153 -0
  64. package/dist/skills/git/references/tracker/github/associate-release.md +18 -0
  65. package/dist/skills/git/references/tracker/github/backlink-shipped-issues.md +40 -0
  66. package/dist/skills/git/references/tracker/github/create-release.md +11 -0
  67. package/dist/skills/git/references/tracker/github/ensure-pr-ready.md +16 -0
  68. package/dist/skills/git/references/tracker/github/ensure-traceable-issue.md +69 -0
  69. package/dist/skills/git/references/tracker/github/fetch-issue.md +32 -0
  70. package/dist/skills/git/references/tracker/github/fetch-issues-batch.md +17 -0
  71. package/dist/skills/git/references/tracker/github/gather-release-evidence.md +19 -0
  72. package/dist/skills/git/references/tracker/github/manage-debt.md +101 -0
  73. package/dist/skills/git/references/tracker/github/post-wave-report.md +28 -0
  74. package/dist/skills/git/references/tracker/github/setup-task.md +26 -0
  75. package/dist/skills/git/references/tracker/jira/associate-release.md +18 -0
  76. package/dist/skills/git/references/tracker/jira/backlink-shipped-issues.md +49 -0
  77. package/dist/skills/git/references/tracker/jira/create-release.md +17 -0
  78. package/dist/skills/git/references/tracker/jira/ensure-pr-ready.md +22 -0
  79. package/dist/skills/git/references/tracker/jira/ensure-traceable-issue.md +53 -0
  80. package/dist/skills/git/references/tracker/jira/fetch-issue.md +14 -0
  81. package/dist/skills/git/references/tracker/jira/fetch-issues-batch.md +15 -0
  82. package/dist/skills/git/references/tracker/jira/gather-release-evidence.md +18 -0
  83. package/dist/skills/git/references/tracker/jira/manage-debt.md +37 -0
  84. package/dist/skills/git/references/tracker/jira/post-wave-report.md +33 -0
  85. package/dist/skills/git/references/tracker/jira/setup-task.md +31 -0
  86. package/dist/skills/git/references/tracker/linear/associate-release.md +18 -0
  87. package/dist/skills/git/references/tracker/linear/backlink-shipped-issues.md +53 -0
  88. package/dist/skills/git/references/tracker/linear/create-release.md +17 -0
  89. package/dist/skills/git/references/tracker/linear/ensure-pr-ready.md +22 -0
  90. package/dist/skills/git/references/tracker/linear/ensure-traceable-issue.md +53 -0
  91. package/dist/skills/git/references/tracker/linear/fetch-issue.md +14 -0
  92. package/dist/skills/git/references/tracker/linear/fetch-issues-batch.md +15 -0
  93. package/dist/skills/git/references/tracker/linear/gather-release-evidence.md +18 -0
  94. package/dist/skills/git/references/tracker/linear/manage-debt.md +37 -0
  95. package/dist/skills/git/references/tracker/linear/post-wave-report.md +33 -0
  96. package/dist/skills/git/references/tracker/linear/setup-task.md +32 -0
  97. package/dist/skills/git/references/trust-rule.md +7 -0
  98. package/dist/targets/claude-code/installer.js +1213 -31
  99. package/dist/targets/claude-code/legacy.js +5 -0
  100. package/dist/targets/claude-code/post-install.js +303 -104
  101. package/dist/targets/claude-code/tracker-install.js +161 -0
  102. package/package.json +4 -3
  103. package/src/assets/agents/code.md +42 -4
  104. package/src/assets/agents/design.md +1 -1
  105. package/src/assets/agents/git.mds +827 -0
  106. package/src/assets/agents/knowledge.md +1 -1
  107. package/src/assets/agents/learning.md +11 -0
  108. package/src/assets/agents/synthesize.md +1 -1
  109. package/src/assets/agents/test.md +16 -5
  110. package/src/assets/agents/tracker.md +467 -0
  111. package/src/assets/agents/validate.md +7 -5
  112. package/src/assets/commands/_partials/_engine.mds +11 -9
  113. package/src/assets/commands/_partials/_evidence_policy.mds +30 -0
  114. package/src/assets/commands/_partials/_knowledge.mds +2 -2
  115. package/src/assets/commands/_partials/_plan_contract.mds +22 -7
  116. package/src/assets/commands/_partials/_preamble.mds +1 -1
  117. package/src/assets/commands/_partials/_publication.mds +3 -1
  118. package/src/assets/commands/_partials/_ticket_template.mds +3 -2
  119. package/src/assets/commands/_partials/_tracker.mds +18 -0
  120. package/src/assets/commands/_partials/_wave.mds +16 -10
  121. package/src/assets/commands/bug-analysis.mds +15 -5
  122. package/src/assets/commands/code-review.mds +34 -14
  123. package/src/assets/commands/debug.mds +11 -4
  124. package/src/assets/commands/dynamic-build.mds +227 -41
  125. package/src/assets/commands/dynamic-plan.mds +35 -13
  126. package/src/assets/commands/dynamic-tickets.mds +47 -5
  127. package/src/assets/commands/implement.mds +206 -52
  128. package/src/assets/commands/plan.mds +70 -17
  129. package/src/assets/commands/release.md +64 -17
  130. package/src/assets/commands/resolve.mds +126 -56
  131. package/src/assets/mds/git/_pr.mds +331 -0
  132. package/src/assets/mds/git/_references.mds +135 -0
  133. package/src/assets/mds/tracker/_common.mds +156 -0
  134. package/src/assets/mds/tracker/_github.mds +472 -0
  135. package/src/assets/mds/tracker/_jira.mds +407 -0
  136. package/src/assets/mds/tracker/_linear.mds +449 -0
  137. package/src/assets/mds/tracker/_mcp.mds +299 -0
  138. package/src/assets/scripts/hooks/assets/orchestrator-charter.md +5 -8
  139. package/src/assets/scripts/hooks/background-memory-update +14 -9
  140. package/src/assets/scripts/hooks/capture-prompt +6 -2
  141. package/src/assets/scripts/hooks/capture-question +6 -2
  142. package/src/assets/scripts/hooks/capture-turn +6 -2
  143. package/src/assets/scripts/hooks/ensure-devflow-init +1 -1
  144. package/src/assets/scripts/hooks/ensure-proxy +64 -5
  145. package/src/assets/scripts/hooks/ensure-root-gitignore +161 -60
  146. package/src/assets/scripts/hooks/hook-log-init +3 -1
  147. package/src/assets/scripts/hooks/json-helper.cjs +223 -5
  148. package/src/assets/scripts/hooks/lib/project-paths.cjs +1 -1
  149. package/src/assets/scripts/hooks/memory-worker +15 -8
  150. package/src/assets/scripts/hooks/pre-compact-memory +12 -8
  151. package/src/assets/scripts/hooks/preamble +1 -4
  152. package/src/assets/scripts/hooks/queue-append +68 -24
  153. package/src/assets/scripts/hooks/session-start-context +355 -8
  154. package/src/assets/scripts/hooks/session-start-memory +12 -8
  155. package/src/assets/scripts/pr-evidence.cjs +1961 -0
  156. package/src/assets/scripts/redact-secrets.cjs +490 -62
  157. package/src/assets/scripts/release-trace.cjs +1143 -0
  158. package/src/assets/scripts/resolve-evidence-policy.cjs +1065 -0
  159. package/src/assets/scripts/verify-evidence.cjs +1822 -0
  160. package/src/assets/skills/compliance/SKILL.md +2 -0
  161. package/src/assets/skills/docs-framework/SKILL.md +5 -3
  162. package/src/assets/skills/git/SKILL.md +8 -82
  163. package/src/assets/skills/git/references/github-api.md +179 -141
  164. package/src/assets/skills/git/references/patterns.md +11 -12
  165. package/src/assets/skills/review-methodology/SKILL.md +1 -1
  166. package/src/assets/skills/review-methodology/references/patterns.md +6 -61
  167. package/src/assets/skills/review-methodology/references/violations.md +14 -22
  168. package/src/targets/claude-code/templates/settings.json +0 -4
  169. package/src/assets/agents/git.md +0 -938
@@ -0,0 +1,161 @@
1
+ /**
2
+ * Tracker artifact installer for the Claude Code target.
3
+ *
4
+ * Convergence function for the ONE artifact whose presence advertises the
5
+ * selected tracker provider: the Tracker agent file. The generated reference
6
+ * subtree converges too, but through {@link overlayInstalledReferences} in
7
+ * installer.ts — that is the installer's one overlay spelling, and a mode flag
8
+ * on this function would have made it a second (design review M2).
9
+ *
10
+ * Applies ADR-013: I/O orchestration in src/targets/; pure helpers in src/core/.
11
+ * Applies PF-009: warn-not-throw, so one failing artifact never aborts an install.
12
+ * Applies PF-015: the biconditional converges in BOTH directions — selecting a
13
+ * provider installs the agent, returning to github removes it.
14
+ */
15
+ import { promises as fs } from 'fs';
16
+ import * as path from 'path';
17
+ import { agentSourceDirs } from '../../core/assets.js';
18
+ import { mdFileName } from '../../core/orphan-sweep.js';
19
+ /**
20
+ * The agent whose presence is conditional on the provider.
21
+ *
22
+ * It stays DECLARED in `devflow-core-skills.agents` and is filtered at install
23
+ * time rather than being lifted into a feature-owned set: the compliance
24
+ * precedent does not transfer, because compliance's plugin was deleted while
25
+ * `devflow-core-skills` is a live, non-optional owner. A feature-owned set would
26
+ * cost three new union sites and a rewrite of the pinned agent-roster floor to
27
+ * solve a problem the agent SWEEP does not have — the sweep keys on the full
28
+ * registry, so it never sees this file as an orphan.
29
+ *
30
+ * Exported because the filter has more than one reader and may have only one
31
+ * authority (D-TRACKER-AGENT-OWNER): {@link convergeTrackerArtifacts} below,
32
+ * which decides whether the file exists, and, in installer.ts, both the generic
33
+ * agent copy loop — which has to skip the one agent it does not own — and the
34
+ * full-install pre-clean, which has to empty the agent directory around it. A
35
+ * second literal at any of those sites is the shape this export exists to forbid.
36
+ */
37
+ export const TRACKER_AGENT_NAME = 'tracker';
38
+ // ── Internals ──────────────────────────────────────────────────────────────
39
+ /**
40
+ * The provider whose mechanics need no Tracker agent.
41
+ *
42
+ * GitHub conventions are not inferred: the Git agent runs `gh`, whose issue
43
+ * grammar this repo already speaks. The agent exists to infer conventions from a
44
+ * connected tool-call server, which is a thing only the other providers have.
45
+ */
46
+ const AGENTLESS_PROVIDER = 'github';
47
+ function agentTarget(claudeDir) {
48
+ return path.join(claudeDir, 'agents', 'devflow', mdFileName(TRACKER_AGENT_NAME));
49
+ }
50
+ async function pathExists(p) {
51
+ try {
52
+ await fs.access(p);
53
+ return true;
54
+ }
55
+ catch {
56
+ return false;
57
+ }
58
+ }
59
+ /** First path in `candidates` that exists, or undefined when none do. */
60
+ async function firstExisting(candidates) {
61
+ for (const candidate of candidates) {
62
+ if (await pathExists(candidate))
63
+ return candidate;
64
+ }
65
+ return undefined;
66
+ }
67
+ /**
68
+ * Would copying `source` over `target` change anything?
69
+ *
70
+ * Asked once, between resolving the source and copying it, so a run that would write a
71
+ * byte-identical copy of the installed agent reports `unchanged` instead of `installed`
72
+ * — the same question the reference overlay asks per unit, for the same reason: a
73
+ * summary that can only ever say "installed" says nothing, and a steady-state re-init
74
+ * announcing "tracker agent installed" is the noise this closes (QA S2).
75
+ *
76
+ * It does NOT weaken the self-heal. A hand-edited or truncated agent differs from its
77
+ * source, so it is copied and reported as written; only an identical file is skipped,
78
+ * and skipping a copy of what is already there changes nothing on disk.
79
+ *
80
+ * Any error — an absent target, an unreadable one — answers "no". The fallback is the
81
+ * copy that was going to happen anyway, so a failure to compare costs a write, never
82
+ * correctness.
83
+ */
84
+ async function copyWouldChangeNothing(source, target) {
85
+ try {
86
+ const [from, to] = await Promise.all([fs.readFile(source), fs.readFile(target)]);
87
+ return from.equals(to);
88
+ }
89
+ catch {
90
+ return false;
91
+ }
92
+ }
93
+ // ── Convergence ────────────────────────────────────────────────────────────
94
+ /**
95
+ * Converge the Tracker agent file onto the resolved provider.
96
+ *
97
+ * Convergence matrix:
98
+ * provider !== github → copy the agent in, unless the installed file is already
99
+ * byte-identical to the source. Compared rather than trusted
100
+ * for existing, so a truncated or hand-edited file self-heals;
101
+ * compared rather than re-copied blind, so a run that changes
102
+ * nothing reports `unchanged` and the summary stays quiet
103
+ * (see {@link copyWouldChangeNothing})
104
+ * provider === github → remove it, absent or not
105
+ *
106
+ * Never throws. A caller gates on `converged`; it does not catch. The one
107
+ * refusal that is not an I/O degradation — a claudeDir that is not absolute —
108
+ * is reported the same way rather than thrown, because it reaches here from a
109
+ * manifest read and an install must not die on it.
110
+ */
111
+ export async function convergeTrackerArtifacts(opts) {
112
+ const { claudeDir, provider, warn } = opts;
113
+ // Precondition, asserted in production code rather than only in tests: an
114
+ // empty or relative claudeDir would make the target resolve somewhere
115
+ // unexpected, and the removal branch runs fs.rm against it.
116
+ if (!path.isAbsolute(claudeDir)) {
117
+ warn(`tracker: claudeDir is not an absolute path ("${claudeDir}") — skipping convergence`);
118
+ return { converged: false, agentPresent: false, agent: 'unchanged' };
119
+ }
120
+ const target = agentTarget(claudeDir);
121
+ if (provider === AGENTLESS_PROVIDER) {
122
+ const existed = await pathExists(target);
123
+ if (!existed)
124
+ return { converged: true, agentPresent: false, agent: 'unchanged' };
125
+ try {
126
+ await fs.rm(target, { force: true });
127
+ }
128
+ catch (err) {
129
+ warn(`tracker: failed to remove the Tracker agent (${target}) — ${String(err)}`);
130
+ return { converged: false, agentPresent: true, agent: 'unchanged' };
131
+ }
132
+ return { converged: true, agentPresent: false, agent: 'removed' };
133
+ }
134
+ const dirs = opts.agentSourceDirs ?? agentSourceDirs();
135
+ const candidates = dirs.map(dir => path.join(dir, mdFileName(TRACKER_AGENT_NAME)));
136
+ const source = await firstExisting(candidates);
137
+ if (source === undefined) {
138
+ warn(`tracker: agent source not found for "${TRACKER_AGENT_NAME}" (searched: ${candidates.join(', ')}) — ` +
139
+ `run \`npm run build:mds\` if it is compiled from an .mds generator host`);
140
+ // Probed rather than assumed: a previous run may have left a copy that is
141
+ // still spawnable, and that is the difference between "this run did nothing"
142
+ // and "there is nothing there".
143
+ return { converged: false, agentPresent: await pathExists(target), agent: 'unchanged' };
144
+ }
145
+ // Already converged — nothing to write, and nothing for the summary to announce.
146
+ // The directory is not created either: an identical file at the target means it is
147
+ // already there (see {@link copyWouldChangeNothing}).
148
+ if (await copyWouldChangeNothing(source, target)) {
149
+ return { converged: true, agentPresent: true, agent: 'unchanged' };
150
+ }
151
+ try {
152
+ await fs.mkdir(path.dirname(target), { recursive: true });
153
+ await fs.copyFile(source, target);
154
+ }
155
+ catch (err) {
156
+ warn(`tracker: failed to install the Tracker agent (${target}) — ${String(err)}`);
157
+ return { converged: false, agentPresent: await pathExists(target), agent: 'unchanged' };
158
+ }
159
+ return { converged: true, agentPresent: true, agent: 'installed' };
160
+ }
161
+ //# sourceMappingURL=tracker-install.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devflow-kit",
3
- "version": "2.3.0",
3
+ "version": "2.5.0",
4
4
  "description": "A meta-harness for Claude Code — turns a single coding agent into an engineering team: orchestration, parallel review, persistent memory, self-learning, and graph workflows",
5
5
  "type": "module",
6
6
  "bin": {
@@ -26,7 +26,8 @@
26
26
  "version:bump": "npx tsx scripts/bump-version.ts",
27
27
  "test": "vitest run",
28
28
  "test:watch": "vitest",
29
- "test:integration": "vitest run --config vitest.integration.config.ts"
29
+ "test:integration": "vitest run --config vitest.integration.config.ts",
30
+ "test:golden:update": "npx tsx scripts/update-golden.ts"
30
31
  },
31
32
  "keywords": [
32
33
  "claude",
@@ -63,7 +64,7 @@
63
64
  "@clack/prompts": "^0.9.1",
64
65
  "commander": "^12.0.0",
65
66
  "picocolors": "^1.1.1",
66
- "subswitch": "0.2.0"
67
+ "subswitch": "0.5.0"
67
68
  },
68
69
  "devDependencies": {
69
70
  "@mdscript/mds": "0.2.0",
@@ -28,11 +28,14 @@ You receive from orchestrator:
28
28
  - **EXECUTION_PLAN**: Synthesized plan with steps, files, tests
29
29
  - **PATTERNS**: Codebase patterns to follow
30
30
  - **CREATE_PR**: Whether to create PR when done (true/false)
31
- - **OPERATION** (optional): `implement` (default) | `issue-fix` | `validation-fix` | `alignment-fix` | `qa-fix` — selects operating mode (see below)
31
+ - **OPERATION** (optional): `implement` (default) | `issue-fix` | `validation-fix` | `alignment-fix` | `qa-fix` | `pr-create` — selects operating mode (see below)
32
32
  - **ISSUES** (when OPERATION: issue-fix): Pre-classified issues from Triage agent with disposition FIX_NOW; do not re-litigate
33
33
  - **SCOPE** (when OPERATION: issue-fix): Blast-radius scope hint (Standard | Careful) per issue from Triage agent
34
34
  - **PUSH** (optional): `true` (default) | `false` — when false, commit only; orchestrator owns push/CI gate
35
- - **ISSUE_NUMBER** (optional): GitHub issue number linked to this task — when provided, include `## Related Issues` / `Closes #{n}` in the PR body
35
+ - **ISSUE_NUMBER** (optional): the provider-canonical identifier of the issue linked to this task — the same value the Git agent emits as `- **Issue ID**: {ISSUE_ID}` under `### Handoff Values`. When provided, include a `## Related Issues` section in the PR body, closed by the line Responsibility 7's paste gate admits
36
+ - **ISSUE_PR_LINK** (optional): the already-rendered closing line for `## Related Issues`, forwarded verbatim from the Git agent's `- **PR link line**: {rendered}` under `### Handoff Values`. `(none)`, or absent, means no rendered line was captured — the section then carries its heading and no reference. Paste it only after the shape re-check in Responsibility 7; it is never a substitute for `ISSUE_NUMBER`, which stays the spawn key
37
+ - **PR_EXCEPTIONS** (optional): the pre-rendered `## Evidence Exceptions` section — a self-attested evidence exception /implement recorded when no ticket was linked — forwarded verbatim from its handoff file. `(none)`, or absent, means none was recorded and the body carries no such section. Paste it only after the shape re-check in Responsibility 7
38
+ - **PR_TEST_PLAN_BLOCK** (optional): the pre-rendered test-plan block — the task's test plan as /implement rendered it with `verify-evidence.cjs render --plan` — forwarded verbatim. `(none)`, or absent, means there is no test plan to show and the body carries no block. Paste it only after the `check block` gate in Responsibility 7
36
39
 
37
40
  **Domain hint** (optional):
38
41
  - **DOMAIN**: `backend` | `frontend` | `tests` | `fullstack` - Load/apply relevant domain skills
@@ -90,9 +93,33 @@ When you apply a decision from `.devflow/learning/decisions.md` or avoid a pitfa
90
93
  | Key Changes to Highlight | Changes |
91
94
  | Breaking Changes | Breaking Changes |
92
95
  | Reviewer Focus Areas | Reviewer Focus Areas |
93
- | Related Issues (ISSUE_NUMBER provided) | `## Related Issues` · `Closes #{n}` |
96
+ | Related Issues (ISSUE_NUMBER provided) | `## Related Issues` · the admitted link line |
94
97
 
95
- When `ISSUE_NUMBER` is provided, always include `## Related Issues` / `Closes #{n}` in the PR body — whether composing from guidance or generating from context.
98
+ When `ISSUE_NUMBER` is provided, always include a `## Related Issues` section in the PR body — whether composing from guidance or generating from context.
99
+
100
+ **Pasting the handoff values.** The Git agent's `setup-task` and `fetch-issue` Output blocks end with a `### Handoff Values` block: `- **PR link line**: {rendered}` is the already-rendered closing line for `## Related Issues`, and `- **Branch token**:` is the branch name it created or suggested. Paste `ISSUE_PR_LINK` verbatim — **after re-checking its shape against the tracker reference grammars**: paste it only if it matches **one row** of this table as the WHOLE line:
101
+
102
+ | Tracker grammar | `ISSUE_PR_LINK` must match |
103
+ |---|---|
104
+ | `github` | `^Closes #[1-9][0-9]{0,8}$` |
105
+ | `jira` | `^Refs [A-Z][A-Z0-9_]{1,9}-[1-9][0-9]{0,8}$` |
106
+ | `linear` | `^Refs [A-Z][A-Z0-9]{0,9}-[1-9][0-9]{0,8}$` |
107
+
108
+ This is a sink check, not a provider check: the Git agent resolved the provider and rendered the line, you are not told which provider it was, and you never decide it. Two bounds sit outside the pattern because an anchor cannot express them, and you apply both: the value is **rejected if it carries a newline** — anchors are read as end-of-LINE by some engines, and everything after the first line would land in the PR body as free text — and rejected if it exceeds **60 characters**, which no valid line approaches.
109
+
110
+ `(none)`, or an absent `### Handoff Values` block, is **not a mismatch**: it means no line was captured, so emit the `## Related Issues` heading with no reference — never compose one from `ISSUE_NUMBER`. A bare issue number is not a reference at all — the same digits name a different issue under each provider — which is why `TRACEABILITY: DEGRADED (ambiguous issue reference)` exists rather than a `#`-prefixed guess. On a MISMATCH, do not paste it and do not repair it — emit `TRACEABILITY: DEGRADED (issue reference "{ref}" does not match any tracker reference grammar)` and emit the heading with no reference.
111
+
112
+ This re-check is the only gate on that value — no operation checks the rendered line's shape before returning it — and it belongs here because a value that was well-formed when it was produced is still attacker-influenceable text by the time it reaches a GitHub-visible sink. Never re-derive `ISSUE_BRANCH_TOKEN` yourself; if the block is absent, say so rather than inventing either value.
113
+
114
+ **Pasting `PR_EXCEPTIONS`.** When `PR_EXCEPTIONS` is provided (not `(none)`), append it verbatim as the body's last section — it is scrubbed with the body. Re-check its shape first: its first line must be exactly `## Evidence Exceptions`, and every line after it must match this pattern as the WHOLE line:
115
+
116
+ ```
117
+ ^- `(ticket-link|test-plan)` self-attested by (@[A-Za-z0-9][A-Za-z0-9-]{0,38}|\(login unavailable\)) at [0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z: [!"%'()*+,.0-9:;=?A-Z^_a-z{|}~-][ !"%'()*+,.0-9:;=?A-Z^_a-z{|}~-]{0,199}$
118
+ ```
119
+
120
+ The value holds that heading and one or more such lines, and nothing else — no blank line, no second heading, no free text — with each kind at most once. The pattern bounds every line: the reason is at most 200 characters, and it admits no `<`, `>`, backtick, bracket, backslash, `/`, `#`, `@`, `&`, `$` or non-ASCII character, so no markup, mention, issue reference (a full issue URL included), marker or shell expansion rides in on it. `(none)`, or absent, is **not a mismatch**: add no section. On a MISMATCH anywhere, paste none of it and do not repair it — emit `TRACEABILITY: DEGRADED (evidence exception does not match its grammar)`. The scrubber-failure minimal body below never carries the section.
121
+
122
+ **Pasting `PR_TEST_PLAN_BLOCK`.** When `PR_TEST_PLAN_BLOCK` is provided (not `(none)`), save it byte for byte to a fresh `mktemp` file with the Write tool — never through an interpolated shell string — and run `node "${DEVFLOW_DIR:-$HOME/.devflow}/scripts/verify-evidence.cjs" check block <that file>; echo "exit=$?"`. The script holds the block's whole grammar; only `exit=0` admits the value. Then append it verbatim, before any `## Evidence Exceptions` section — it is scrubbed with the body. Any other result is a MISMATCH: omit the block, never repair or partly paste it, and emit `TRACEABILITY: DEGRADED (test-plan block does not match its grammar)`. `(none)`, or absent, is **not a mismatch**: add no block. The scrubber-failure minimal body below never carries the block.
96
123
 
97
124
  If `PR_DESCRIPTION_GUIDANCE` is absent, generate the PR body from implementation context.
98
125
 
@@ -170,6 +197,17 @@ When `OPERATION: qa-fix`, you are fixing scenario-based acceptance test failures
170
197
  1. Fix only what is listed in `QA_FAILURES` — no scope expansion
171
198
  2. Commit and push; orchestrator re-runs Validate agent then Test agent after each attempt (max 2 attempts total)
172
199
 
200
+ ## Mode: pr-create
201
+
202
+ When `OPERATION: pr-create`, earlier Code agents have already committed the implementation and you only open the pull request. Make no code changes.
203
+
204
+ **Inputs:** `TASK_ID`, `BASE_BRANCH`, `CREATE_PR: true`, `PR_DESCRIPTION_GUIDANCE`, `ISSUE_NUMBER`, `ISSUE_PR_LINK`, `PR_EXCEPTIONS`, `PR_TEST_PLAN_BLOCK`
205
+
206
+ **Protocol:**
207
+ 1. Push the current feature branch.
208
+ 2. Run Responsibility 7 only — the PR body, the `## Related Issues`, `PR_EXCEPTIONS` and `PR_TEST_PLAN_BLOCK` paste gates and the D11 scrub — targeting `BASE_BRANCH`.
209
+ 3. Return the PR URL.
210
+
173
211
  ## Principles
174
212
 
175
213
  1. **Work on feature branch** - All operations happen on the current feature branch
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: Design
3
- description: Design analysis agent with preloaded mode skills. Modes: gap-analysis (completeness, architecture, security, performance, compliance, consistency, dependencies), design-review (anti-pattern detection).
3
+ description: "Design analysis agent with preloaded mode skills. Modes: gap-analysis (completeness, architecture, security, performance, compliance, consistency, dependencies), design-review (anti-pattern detection)."
4
4
  model: opus
5
5
  skills:
6
6
  - devflow:worktree-support