intentdna 1.7.4 → 1.8.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 (152) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/LICENSE +201 -0
  4. package/README.md +143 -194
  5. package/dist/assets/candidates.d.ts +124 -0
  6. package/dist/assets/candidates.js +1249 -0
  7. package/dist/assets/catalog.d.ts +101 -0
  8. package/dist/assets/catalog.js +311 -0
  9. package/dist/assets/evidence.d.ts +93 -0
  10. package/dist/assets/evidence.js +391 -0
  11. package/dist/assets/index.d.ts +4 -0
  12. package/dist/assets/index.js +4 -0
  13. package/dist/assets/metadata.d.ts +19 -0
  14. package/dist/assets/metadata.js +227 -0
  15. package/dist/cli/commands/assets.d.ts +65 -0
  16. package/dist/cli/commands/assets.js +2871 -0
  17. package/dist/cli/commands/auth.d.ts +322 -0
  18. package/dist/cli/commands/auth.js +1592 -0
  19. package/dist/cli/commands/cloud-auth-guidance.d.ts +2 -0
  20. package/dist/cli/commands/cloud-auth-guidance.js +4 -0
  21. package/dist/cli/commands/cloud.d.ts +1359 -0
  22. package/dist/cli/commands/cloud.js +8364 -0
  23. package/dist/cli/commands/evolve.js +18 -2
  24. package/dist/cli/commands/generate.js +25 -2
  25. package/dist/cli/commands/guard.d.ts +1 -1
  26. package/dist/cli/commands/guard.js +1 -1
  27. package/dist/cli/commands/guide.d.ts +15 -0
  28. package/dist/cli/commands/guide.js +1747 -0
  29. package/dist/cli/commands/init.d.ts +12 -0
  30. package/dist/cli/commands/init.js +95 -60
  31. package/dist/cli/commands/org.d.ts +16 -0
  32. package/dist/cli/commands/org.js +2393 -0
  33. package/dist/cli/commands/release.d.ts +59 -0
  34. package/dist/cli/commands/release.js +716 -0
  35. package/dist/cli/commands/report.d.ts +82 -0
  36. package/dist/cli/commands/report.js +1516 -0
  37. package/dist/cli/commands/run.d.ts +6 -1
  38. package/dist/cli/commands/run.js +95 -26
  39. package/dist/cli/commands/sync.d.ts +8 -1
  40. package/dist/cli/commands/sync.js +436 -141
  41. package/dist/cli/commands/templates.d.ts +64 -0
  42. package/dist/cli/commands/templates.js +2151 -1
  43. package/dist/cli/commands/workflow.d.ts +26 -0
  44. package/dist/cli/commands/workflow.js +3053 -0
  45. package/dist/cli/index.js +719 -42
  46. package/dist/compiler/cascade.js +4 -9
  47. package/dist/compiler/compile.js +1 -0
  48. package/dist/governance/evidence-capture-attribution.d.ts +12 -0
  49. package/dist/governance/evidence-capture-attribution.js +46 -0
  50. package/dist/governance/index.d.ts +2 -0
  51. package/dist/governance/index.js +1 -0
  52. package/dist/hooks/cli.d.ts +6 -0
  53. package/dist/hooks/cli.js +168 -12
  54. package/dist/hooks/enforce.d.ts +1 -0
  55. package/dist/hooks/protocol.d.ts +1 -1
  56. package/dist/hooks/protocol.js +1 -1
  57. package/dist/hooks/state.d.ts +41 -0
  58. package/dist/hooks/state.js +126 -2
  59. package/dist/index.d.ts +3 -0
  60. package/dist/index.js +3 -0
  61. package/dist/mcp/tools-state.js +2 -0
  62. package/dist/organization/index.d.ts +121 -0
  63. package/dist/organization/index.js +413 -0
  64. package/dist/runtime/claude-sync-target.d.ts +49 -0
  65. package/dist/runtime/claude-sync-target.js +280 -0
  66. package/dist/runtime/codex-adapter.d.ts +254 -0
  67. package/dist/runtime/codex-adapter.js +1204 -0
  68. package/dist/runtime/codex-sync-target.d.ts +33 -0
  69. package/dist/runtime/codex-sync-target.js +241 -0
  70. package/dist/runtime/index.d.ts +8 -0
  71. package/dist/runtime/index.js +4 -0
  72. package/dist/runtime/output-artifact-registry.d.ts +1 -1
  73. package/dist/runtime/output-artifact-registry.js +2 -0
  74. package/dist/runtime/settings-adapter.d.ts +1 -1
  75. package/dist/runtime/settings-adapter.js +1 -1
  76. package/dist/runtime/skill-adapter.d.ts +5 -1
  77. package/dist/runtime/skill-adapter.js +120 -34
  78. package/dist/runtime/sync-artifact-registry.d.ts +99 -0
  79. package/dist/runtime/sync-artifact-registry.js +194 -0
  80. package/dist/runtime/sync-target-plan.d.ts +45 -0
  81. package/dist/runtime/sync-target-plan.js +19 -0
  82. package/dist/schema/controller-registry.d.ts +8 -1
  83. package/dist/schema/controller-registry.js +8 -0
  84. package/dist/schema/types.d.ts +35 -23
  85. package/dist/schema/types.js +10 -1
  86. package/dist/schema/validate.js +22 -22
  87. package/dist/schema/validators/controllers.js +38 -20
  88. package/dist/schema/workflow-authoring-contract.d.ts +29 -0
  89. package/dist/schema/workflow-authoring-contract.js +109 -0
  90. package/dist/schema/yaml-parser.js +18 -0
  91. package/dist/templates/api-backend.dna.yaml +19 -0
  92. package/dist/templates/brainstorming-first.dna.yaml +19 -0
  93. package/dist/templates/code-cleanup.dna.yaml +19 -0
  94. package/dist/templates/code-review-pipeline.dna.yaml +18 -0
  95. package/dist/templates/documentation-writer.dna.yaml +19 -0
  96. package/dist/templates/flutter-behavior-lock.dna.yaml +19 -0
  97. package/dist/templates/flutter-refactoring-rescue.dna.yaml +19 -0
  98. package/dist/templates/flutter-rewrite-diagnosis-review.dna.yaml +210 -0
  99. package/dist/templates/flutter-rewrite-fix-review-loop.dna.yaml +260 -0
  100. package/dist/templates/flutter-rewrite-new.dna.yaml +506 -0
  101. package/dist/templates/flutter-rewrite.dna.yaml +20 -0
  102. package/dist/templates/frontend-quality.dna.yaml +19 -0
  103. package/dist/templates/full-pipeline.dna.yaml +20 -0
  104. package/dist/templates/marketplace.d.ts +92 -0
  105. package/dist/templates/marketplace.js +502 -0
  106. package/dist/templates/metadata.d.ts +25 -0
  107. package/dist/templates/metadata.js +136 -3
  108. package/dist/templates/mobile-dev.dna.yaml +19 -0
  109. package/dist/templates/multi-agent-handoff-coordination.dna.yaml +156 -0
  110. package/dist/templates/multi-perspective-review.dna.yaml +19 -0
  111. package/dist/templates/persistent-executor.dna.yaml +19 -0
  112. package/dist/templates/qa-loop.dna.yaml +18 -0
  113. package/dist/templates/release-evidence-gate.dna.yaml +131 -0
  114. package/dist/templates/requirements-gate.dna.yaml +19 -0
  115. package/dist/templates/research-orchestration.dna.yaml +19 -0
  116. package/dist/templates/root-cause-analysis.dna.yaml +19 -0
  117. package/dist/templates/safe-refactoring.dna.yaml +321 -0
  118. package/dist/templates/secure-dev.dna.yaml +19 -0
  119. package/dist/templates/subagent-parallel.dna.yaml +19 -0
  120. package/dist/templates/systematic-debugging.dna.yaml +19 -0
  121. package/dist/templates/tdd-strict.dna.yaml +19 -0
  122. package/dist/templates/ui-visual-regression-qa.dna.yaml +133 -0
  123. package/dist/templates/workflow-author.dna.yaml +302 -0
  124. package/dist/templates/workflow-blocked-scope-triage.dna.yaml +242 -0
  125. package/dist/templates/workflow-completion-audit.dna.yaml +254 -0
  126. package/dist/templates/workflow-cross-boundary-resource-approval.dna.yaml +249 -0
  127. package/dist/templates/workflow-evidence-review.dna.yaml +198 -0
  128. package/dist/templates/workflow-module-inventory.dna.yaml +257 -0
  129. package/dist/templates/workflow-runtime-smoke-review.dna.yaml +252 -0
  130. package/dist/templates/workflow-verification-command-routing.dna.yaml +278 -0
  131. package/dist/workflow/authoring-packet.d.ts +67 -0
  132. package/dist/workflow/authoring-packet.js +218 -0
  133. package/dist/workflow/draft.d.ts +159 -0
  134. package/dist/workflow/draft.js +800 -0
  135. package/dist/workflow/index.d.ts +3 -0
  136. package/dist/workflow/index.js +3 -0
  137. package/dist/workflow/suggestion-review.d.ts +65 -0
  138. package/dist/workflow/suggestion-review.js +245 -0
  139. package/package.json +1 -1
  140. package/spec/README.md +15 -48
  141. package/spec/codex-adapter-contract.md +176 -0
  142. package/spec/sync-target-plan.md +158 -0
  143. package/spec/workflow-capability-ir.md +153 -0
  144. package/spec/agent-dispatch-fix.md +0 -116
  145. package/spec/control-plane-convergence-handoff-2026-04-24.md +0 -432
  146. package/spec/flutter-rewrite-template-optimization.md +0 -301
  147. package/spec/foundation-hardening.md +0 -178
  148. package/spec/hooks-infra-harness-hardening.md +0 -741
  149. package/spec/multi-config.md +0 -172
  150. package/spec/parallel-isolation.md +0 -268
  151. package/spec/template-version-namespace-fix.md +0 -653
  152. package/spec/workflow-pipeline.md +0 -101
@@ -0,0 +1,391 @@
1
+ import { readFile, readdir } from "node:fs/promises";
2
+ import { isAbsolute, join } from "node:path";
3
+ import { findWorkflowAsset } from "./catalog.js";
4
+ import { getWorkflowAssetMetadata } from "./metadata.js";
5
+ function isRecord(value) {
6
+ return typeof value === "object" && value !== null && !Array.isArray(value);
7
+ }
8
+ function stringValue(value) {
9
+ return typeof value === "string" && value.length > 0 ? value : undefined;
10
+ }
11
+ function numberValue(value) {
12
+ return typeof value === "number" && Number.isFinite(value) ? value : 0;
13
+ }
14
+ function verdictValue(value) {
15
+ if (value === "PASS" || value === "CONTINUE" || value === "REQUEST_CHANGES" || value === "BLOCKED")
16
+ return value;
17
+ return "UNKNOWN";
18
+ }
19
+ function arrayOfStrings(value) {
20
+ return Array.isArray(value) ? value.filter((entry) => typeof entry === "string") : [];
21
+ }
22
+ function arrayOfRecords(value) {
23
+ return Array.isArray(value) ? value.filter((entry) => isRecord(entry)) : [];
24
+ }
25
+ function captureFactValue(value) {
26
+ if (value === "command" || value === "result" || value === "retry" || value === "manual_intervention" || value === "blocker" || value === "handoff")
27
+ return value;
28
+ return undefined;
29
+ }
30
+ function captureResultValue(value) {
31
+ if (value === "success" || value === "failure" || value === "blocked" || value === "skipped" || value === "unknown" || value === "unsupported")
32
+ return value;
33
+ return undefined;
34
+ }
35
+ async function readJson(path) {
36
+ try {
37
+ return JSON.parse(await readFile(path, "utf-8"));
38
+ }
39
+ catch {
40
+ return undefined;
41
+ }
42
+ }
43
+ function moduleFromFilename(file) {
44
+ return file.replace(/\.json$/, "");
45
+ }
46
+ function isCanonicalModuleProgressFile(file, record) {
47
+ const module = stringValue(record.module);
48
+ return module !== undefined && moduleFromFilename(file) === module;
49
+ }
50
+ function progressMarkdownPath(progressDir, module) {
51
+ return join(progressDir, `${module}.md`);
52
+ }
53
+ async function pathExists(path) {
54
+ try {
55
+ await readFile(path, "utf-8");
56
+ return true;
57
+ }
58
+ catch {
59
+ return false;
60
+ }
61
+ }
62
+ function moduleFromRecord(record, file, progressDir) {
63
+ const module = stringValue(record.module) ?? moduleFromFilename(file);
64
+ const markdownPath = progressMarkdownPath(progressDir, module);
65
+ return {
66
+ module,
67
+ verdict: verdictValue(record.verdict),
68
+ review: stringValue(record.review),
69
+ moduleComplete: record.module_complete === true,
70
+ round: typeof record.round === "number" ? record.round : undefined,
71
+ runId: stringValue(record.run_id),
72
+ gitHead: stringValue(record.git_head),
73
+ lastFixCommit: stringValue(record.last_fix_commit),
74
+ fixedCount: numberValue(record.fixed_count),
75
+ newRedCount: numberValue(record.new_red_count),
76
+ blockedCount: numberValue(record.blocked_count),
77
+ remainingCount: numberValue(record.remaining_count),
78
+ remainingUnimplementedSkippedCount: numberValue(record.remaining_unimplemented_skipped_count),
79
+ updatedAt: stringValue(record.updated_at),
80
+ progressJsonPath: join(progressDir, file),
81
+ progressMarkdownPath: markdownPath,
82
+ evidencePaths: arrayOfStrings(record.evidence_paths),
83
+ failureReason: stringValue(record.failure_reason),
84
+ nextRoundFocus: stringValue(record.next_round_focus),
85
+ };
86
+ }
87
+ function evidenceTotals(modules, runtimeArtifacts = [], captureFacts = []) {
88
+ return {
89
+ modules: modules.length,
90
+ pass: modules.filter((module) => module.verdict === "PASS").length,
91
+ continue: modules.filter((module) => module.verdict === "CONTINUE").length,
92
+ requestChanges: modules.filter((module) => module.verdict === "REQUEST_CHANGES").length,
93
+ blocked: modules.filter((module) => module.verdict === "BLOCKED").length,
94
+ unknown: modules.filter((module) => module.verdict === "UNKNOWN").length,
95
+ complete: modules.filter((module) => module.moduleComplete).length,
96
+ remaining: modules.reduce((sum, module) => sum + module.remainingCount, 0),
97
+ remainingUnimplementedSkipped: modules.reduce((sum, module) => sum + module.remainingUnimplementedSkippedCount, 0),
98
+ newRed: modules.reduce((sum, module) => sum + module.newRedCount, 0),
99
+ runtimeArtifacts: runtimeArtifacts.length,
100
+ agentPrompts: runtimeArtifacts.filter((artifact) => artifact.kind === "agent_prompt").length,
101
+ skillEntrypoints: runtimeArtifacts.filter((artifact) => artifact.kind === "skill_entrypoint").length,
102
+ captureFacts: captureFacts.length,
103
+ captureBlocked: captureFacts.filter((fact) => fact.fact === "blocker" || fact.result === "blocked").length,
104
+ captureFailures: captureFacts.filter((fact) => fact.result === "failure").length,
105
+ captureManualInterventions: captureFacts.filter((fact) => fact.fact === "manual_intervention").length,
106
+ captureRetries: captureFacts.filter((fact) => fact.fact === "retry").length,
107
+ };
108
+ }
109
+ function sortModules(modules) {
110
+ const verdictRank = {
111
+ BLOCKED: 0,
112
+ REQUEST_CHANGES: 1,
113
+ CONTINUE: 2,
114
+ UNKNOWN: 3,
115
+ PASS: 4,
116
+ };
117
+ return [...modules].sort((a, b) => {
118
+ const verdict = verdictRank[a.verdict] - verdictRank[b.verdict];
119
+ if (verdict !== 0)
120
+ return verdict;
121
+ if (b.remainingCount !== a.remainingCount)
122
+ return b.remainingCount - a.remainingCount;
123
+ return a.module.localeCompare(b.module);
124
+ });
125
+ }
126
+ function frontmatterValue(raw, key) {
127
+ const match = raw.match(new RegExp(`^${key}:\\s*(.+)$`, "m"));
128
+ if (!match)
129
+ return undefined;
130
+ return match[1]?.trim().replace(/^["']|["']$/g, "");
131
+ }
132
+ async function readOptional(path) {
133
+ try {
134
+ return await readFile(path, "utf-8");
135
+ }
136
+ catch {
137
+ return undefined;
138
+ }
139
+ }
140
+ async function listClaudeAgentArtifacts(projectPath, warnings) {
141
+ const agentsDir = join(projectPath, ".claude", "agents");
142
+ let files = [];
143
+ try {
144
+ files = await readdir(agentsDir);
145
+ }
146
+ catch {
147
+ warnings.push(`Claude Code agents directory is not readable: ${agentsDir}`);
148
+ return [];
149
+ }
150
+ const artifacts = [];
151
+ for (const file of files.filter((entry) => entry.endsWith(".md")).sort()) {
152
+ const path = join(agentsDir, file);
153
+ const raw = await readOptional(path);
154
+ artifacts.push({
155
+ target: "claude_code",
156
+ kind: "agent_prompt",
157
+ name: frontmatterValue(raw ?? "", "name") ?? file.replace(/\.md$/, ""),
158
+ path,
159
+ managed: raw?.includes("intentdna:managed") === true,
160
+ description: frontmatterValue(raw ?? "", "description"),
161
+ });
162
+ }
163
+ return artifacts;
164
+ }
165
+ async function listClaudeSkillArtifacts(projectPath, warnings) {
166
+ const skillsDir = join(projectPath, ".claude", "skills");
167
+ const skillMapPath = join(skillsDir, ".intentdna-skill-map.json");
168
+ const artifacts = [];
169
+ const rawMap = await readOptional(skillMapPath);
170
+ if (rawMap) {
171
+ let parsed;
172
+ try {
173
+ parsed = JSON.parse(rawMap);
174
+ }
175
+ catch {
176
+ warnings.push(`Claude Code skill map is not valid JSON: ${skillMapPath}`);
177
+ parsed = undefined;
178
+ }
179
+ artifacts.push({
180
+ target: "claude_code",
181
+ kind: "skill_map",
182
+ name: ".intentdna-skill-map",
183
+ path: skillMapPath,
184
+ managed: true,
185
+ });
186
+ const skills = isRecord(parsed) ? arrayOfRecords(parsed.skills) : [];
187
+ for (const skill of skills) {
188
+ const name = stringValue(skill.name) ?? stringValue(skill.dirName);
189
+ const dirName = stringValue(skill.dirName) ?? name;
190
+ if (!name || !dirName)
191
+ continue;
192
+ const skillPath = join(skillsDir, dirName, "SKILL.md");
193
+ const rawSkill = await readOptional(skillPath);
194
+ artifacts.push({
195
+ target: "claude_code",
196
+ kind: "skill_entrypoint",
197
+ name,
198
+ path: skillPath,
199
+ managed: rawSkill?.includes("intentdna:managed") === true,
200
+ source: stringValue(skill.source),
201
+ roles: arrayOfStrings(skill.roles),
202
+ consumes: arrayOfRecords(skill.consumes).length,
203
+ produces: arrayOfRecords(skill.produces).length,
204
+ bodyPath: stringValue(skill.bodyPath) ? join(skillsDir, stringValue(skill.bodyPath)) : undefined,
205
+ });
206
+ }
207
+ return artifacts;
208
+ }
209
+ let entries = [];
210
+ try {
211
+ entries = await readdir(skillsDir);
212
+ }
213
+ catch {
214
+ warnings.push(`Claude Code skills directory is not readable: ${skillsDir}`);
215
+ return artifacts;
216
+ }
217
+ for (const entry of entries.filter((name) => !name.startsWith(".")).sort()) {
218
+ const skillPath = join(skillsDir, entry, "SKILL.md");
219
+ const rawSkill = await readOptional(skillPath);
220
+ if (!rawSkill)
221
+ continue;
222
+ artifacts.push({
223
+ target: "claude_code",
224
+ kind: "skill_entrypoint",
225
+ name: frontmatterValue(rawSkill, "name") ?? entry,
226
+ path: skillPath,
227
+ managed: rawSkill.includes("intentdna:managed"),
228
+ description: frontmatterValue(rawSkill, "description"),
229
+ });
230
+ }
231
+ return artifacts;
232
+ }
233
+ async function listRuntimeArtifacts(projectPath, warnings) {
234
+ const artifacts = [
235
+ ...await listClaudeAgentArtifacts(projectPath, warnings),
236
+ ...await listClaudeSkillArtifacts(projectPath, warnings),
237
+ ];
238
+ return artifacts.sort((a, b) => a.target.localeCompare(b.target) ||
239
+ a.kind.localeCompare(b.kind) ||
240
+ a.name.localeCompare(b.name));
241
+ }
242
+ function envValue(name) {
243
+ const value = process.env[name]?.trim();
244
+ return value && value.length > 0 ? value : undefined;
245
+ }
246
+ function captureDir(projectDir) {
247
+ return join(projectDir, ".dna", "evidence", "capture");
248
+ }
249
+ function captureFromRecord(record, path) {
250
+ if (record.schema_version !== "intentdna.evidence_capture.v1")
251
+ return undefined;
252
+ const fact = captureFactValue(record.fact);
253
+ if (!fact)
254
+ return undefined;
255
+ const eventId = stringValue(record.event_id);
256
+ const capturedAt = stringValue(record.captured_at);
257
+ const summary = stringValue(record.summary);
258
+ if (!eventId || !capturedAt || !summary)
259
+ return undefined;
260
+ return {
261
+ eventId,
262
+ capturedAt,
263
+ source: stringValue(record.source) ?? "unknown",
264
+ workflowAsset: stringValue(record.workflow_asset) ?? "unknown",
265
+ workflowId: stringValue(record.workflow_id) ?? "unknown",
266
+ runId: stringValue(record.run_id) ?? "unknown",
267
+ stepId: stringValue(record.step_id) ?? "unknown",
268
+ fact,
269
+ summary,
270
+ command: stringValue(record.command),
271
+ result: captureResultValue(record.result),
272
+ evidenceRefs: arrayOfRecords(record.evidence_refs)
273
+ .map((ref) => ({ type: stringValue(ref.type) ?? "unknown", ref: stringValue(ref.ref) ?? "unknown" })),
274
+ path,
275
+ };
276
+ }
277
+ function captureMatchesAsset(capture, asset) {
278
+ if (!asset)
279
+ return false;
280
+ const names = new Set([
281
+ asset.name,
282
+ asset.id,
283
+ asset.dnaId,
284
+ ...asset.workflows.map((workflow) => workflow.id),
285
+ ...asset.workflows.map((workflow) => workflow.name),
286
+ ].filter((value) => typeof value === "string" && value.length > 0));
287
+ return names.has(capture.workflowAsset) || names.has(capture.workflowId);
288
+ }
289
+ async function readEvidenceCaptures(projectDir, asset, warnings) {
290
+ const dir = captureDir(projectDir);
291
+ let files = [];
292
+ try {
293
+ files = await readdir(dir);
294
+ }
295
+ catch {
296
+ return [];
297
+ }
298
+ const captures = [];
299
+ for (const file of files.filter((entry) => /^\d{4}-\d{2}-\d{2}\.jsonl$/.test(entry)).sort()) {
300
+ const path = join(dir, file);
301
+ let raw = "";
302
+ try {
303
+ raw = await readFile(path, "utf-8");
304
+ }
305
+ catch {
306
+ warnings.push(`C5 evidence capture file is not readable: ${path}`);
307
+ continue;
308
+ }
309
+ const lines = raw.split("\n");
310
+ for (let i = 0; i < lines.length; i += 1) {
311
+ const line = lines[i]?.trim();
312
+ if (!line)
313
+ continue;
314
+ try {
315
+ const parsed = JSON.parse(line);
316
+ const capture = isRecord(parsed) ? captureFromRecord(parsed, `${path}#L${i + 1}`) : undefined;
317
+ if (capture && captureMatchesAsset(capture, asset))
318
+ captures.push(capture);
319
+ }
320
+ catch {
321
+ warnings.push(`C5 evidence capture line is not valid JSON: ${path}#L${i + 1}`);
322
+ }
323
+ }
324
+ }
325
+ return captures.sort((a, b) => b.capturedAt.localeCompare(a.capturedAt));
326
+ }
327
+ function resolveDogfoodSource(dogfood, options) {
328
+ const projectPath = options?.dogfoodProjectPath ?? envValue("INTENTDNA_DOGFOOD_PROJECT_PATH") ?? dogfood.projectPath;
329
+ const progressDirValue = options?.dogfoodProgressDir ?? envValue("INTENTDNA_DOGFOOD_PROGRESS_DIR") ?? dogfood.progressDir ?? ".dna/fix-progress";
330
+ const progressDir = isAbsolute(progressDirValue) ? progressDirValue : join(projectPath, progressDirValue);
331
+ return { projectPath, progressDir };
332
+ }
333
+ export async function buildWorkflowAssetEvidenceIndex(name, options) {
334
+ const asset = await findWorkflowAsset(name, { projectDir: options?.projectDir });
335
+ if (!asset)
336
+ return undefined;
337
+ const projectDir = options?.projectDir ?? process.cwd();
338
+ const warnings = [];
339
+ const captureFacts = await readEvidenceCaptures(projectDir, asset, warnings);
340
+ const metadata = getWorkflowAssetMetadata(asset.name);
341
+ if (!metadata?.dogfood) {
342
+ return {
343
+ asset: asset.name,
344
+ projectPath: "",
345
+ progressDir: "",
346
+ sourceDescription: undefined,
347
+ totals: evidenceTotals([], [], captureFacts),
348
+ modules: [],
349
+ runtimeArtifacts: [],
350
+ captureFacts,
351
+ warnings: ["No dogfood progress source is registered for this asset.", ...warnings],
352
+ };
353
+ }
354
+ const source = resolveDogfoodSource(metadata.dogfood, options);
355
+ const modules = [];
356
+ let files = [];
357
+ try {
358
+ files = await readdir(source.progressDir);
359
+ }
360
+ catch {
361
+ warnings.push(`Dogfood progress directory is not readable: ${source.progressDir}`);
362
+ }
363
+ for (const file of files.filter((entry) => /^[A-Za-z0-9_-]+\.json$/.test(entry)).sort()) {
364
+ const parsed = await readJson(join(source.progressDir, file));
365
+ if (!isRecord(parsed) || typeof parsed.verdict !== "string")
366
+ continue;
367
+ if (!isCanonicalModuleProgressFile(file, parsed))
368
+ continue;
369
+ const module = moduleFromRecord(parsed, file, source.progressDir);
370
+ if (module.progressMarkdownPath && !await pathExists(module.progressMarkdownPath)) {
371
+ module.progressMarkdownPath = undefined;
372
+ }
373
+ modules.push(module);
374
+ }
375
+ if (modules.length === 0 && warnings.length === 0) {
376
+ warnings.push(`No module progress JSON files were found in ${source.progressDir}.`);
377
+ }
378
+ const runtimeArtifacts = await listRuntimeArtifacts(source.projectPath, warnings);
379
+ const sortedModules = sortModules(modules);
380
+ return {
381
+ asset: asset.name,
382
+ projectPath: source.projectPath,
383
+ progressDir: source.progressDir,
384
+ sourceDescription: metadata.dogfood.description,
385
+ totals: evidenceTotals(sortedModules, runtimeArtifacts, captureFacts),
386
+ modules: sortedModules,
387
+ runtimeArtifacts,
388
+ captureFacts,
389
+ warnings,
390
+ };
391
+ }
@@ -0,0 +1,4 @@
1
+ export { findWorkflowAsset, listWorkflowAssets, type WorkflowAssetControllerSummary, type WorkflowAssetCascadeSummary, type WorkflowAssetEvolutionSummary, type WorkflowAssetRoleSummary, type WorkflowAssetStepSummary, type WorkflowAssetSummary, type WorkflowAssetWorkflowSummary, } from "./catalog.js";
2
+ export { activeEvidenceFollowupRoute, activeEvidenceFollowupReviewRoute, activeEvidenceModules, buildWorkflowAssetCandidateBacklog, type ActiveEvidenceFollowupReviewRoute, type ActiveEvidenceFollowupRouteStatus, type AssetCandidateBacklog, type AssetCandidateReviewPacket, type AssetCandidateType, type AssetWorkflowCandidate, type WorkflowCandidateAction, type WorkflowCandidateActionPathStatus, type WorkflowCandidateActionPathStep, type WorkflowCandidateActionPathStepId, type WorkflowCandidateEditOperation, } from "./candidates.js";
3
+ export { buildWorkflowAssetEvidenceIndex, type WorkflowAssetEvidenceCapture, type WorkflowAssetEvidenceIndex, type WorkflowAssetEvidenceModule, type WorkflowAssetEvidenceVerdict, } from "./evidence.js";
4
+ export { getWorkflowAssetMetadata, WORKFLOW_ASSET_METADATA, type WorkflowAssetEvidenceLink, type WorkflowAssetMetadata, } from "./metadata.js";
@@ -0,0 +1,4 @@
1
+ export { findWorkflowAsset, listWorkflowAssets, } from "./catalog.js";
2
+ export { activeEvidenceFollowupRoute, activeEvidenceFollowupReviewRoute, activeEvidenceModules, buildWorkflowAssetCandidateBacklog, } from "./candidates.js";
3
+ export { buildWorkflowAssetEvidenceIndex, } from "./evidence.js";
4
+ export { getWorkflowAssetMetadata, WORKFLOW_ASSET_METADATA, } from "./metadata.js";
@@ -0,0 +1,19 @@
1
+ export interface WorkflowAssetEvidenceLink {
2
+ label: string;
3
+ path: string;
4
+ kind: "doc" | "dogfood" | "reference";
5
+ description?: string;
6
+ }
7
+ export interface WorkflowAssetDogfoodSource {
8
+ projectPath: string;
9
+ progressDir?: string;
10
+ description?: string;
11
+ }
12
+ export interface WorkflowAssetMetadata {
13
+ template: string;
14
+ positioning?: string;
15
+ dogfood?: WorkflowAssetDogfoodSource;
16
+ evidence?: readonly WorkflowAssetEvidenceLink[];
17
+ }
18
+ export declare const WORKFLOW_ASSET_METADATA: readonly WorkflowAssetMetadata[];
19
+ export declare function getWorkflowAssetMetadata(template: string): WorkflowAssetMetadata | undefined;
@@ -0,0 +1,227 @@
1
+ export const WORKFLOW_ASSET_METADATA = [
2
+ {
3
+ template: "flutter-rewrite",
4
+ positioning: "Dogfood-proven Flutter v1 to v2 behavior-preserving rewrite workflow.",
5
+ dogfood: {
6
+ projectPath: "/Users/samuel/lawark/lwk_flutter_v2-rewrite",
7
+ progressDir: ".dna/fix-progress",
8
+ description: "Real Claude Code dogfood project with module-level fix-loop progress JSON.",
9
+ },
10
+ evidence: [
11
+ {
12
+ label: "Flutter rewrite workflow asset",
13
+ path: "docs/archive/2026H1/references/flutter-rewrite-workflow-asset.md",
14
+ kind: "dogfood",
15
+ description: "IntentDNA-owned import of the dogfood workflow asset, excluding OMC logs.",
16
+ },
17
+ ],
18
+ },
19
+ {
20
+ template: "flutter-rewrite-new",
21
+ positioning: "Draft next-generation governed rewrite workflow shape.",
22
+ evidence: [
23
+ {
24
+ label: "Product spine route",
25
+ path: "docs/archive/2026H1/references/intentdna-product-spine.md",
26
+ kind: "reference",
27
+ description: "Route correction that frames governed workflow assets as the product spine.",
28
+ },
29
+ ],
30
+ },
31
+ {
32
+ template: "flutter-behavior-lock",
33
+ positioning: "Reusable behavior-lock workflow for capturing v1 module behavior as docs/tests before risky rewrite or refactor.",
34
+ evidence: [
35
+ {
36
+ label: "Flutter rewrite behavior docs",
37
+ path: "/Users/samuel/lawark/lwk_flutter_v2-rewrite/docs/behavior",
38
+ kind: "reference",
39
+ description: "Dogfood behavior documents created before repair work to lock source behavior at module/action level.",
40
+ },
41
+ {
42
+ label: "Flutter rewrite fix progress",
43
+ path: "/Users/samuel/lawark/lwk_flutter_v2-rewrite/.dna/fix-progress",
44
+ kind: "reference",
45
+ description: "Module progress evidence showing behavior lock as a repeated precondition for risky rewrite and fix loops.",
46
+ },
47
+ ],
48
+ },
49
+ {
50
+ template: "workflow-evidence-review",
51
+ positioning: "Reusable manager review gate for workflow evidence before adoption, evolution, rollout, or runtime sync.",
52
+ evidence: [
53
+ {
54
+ label: "Flutter rewrite dogfood progress",
55
+ path: "/Users/samuel/lawark/lwk_flutter_v2-rewrite/.dna/fix-progress",
56
+ kind: "reference",
57
+ description: "Module-level progress JSON, review verdicts, diagnosis specs, and test logs used to gate adoption/evolution/sync.",
58
+ },
59
+ {
60
+ label: "IntentDNA product spine",
61
+ path: "docs/archive/2026H1/references/intentdna-product-spine.md",
62
+ kind: "reference",
63
+ description: "Route alignment that defines evidence-backed workflow assets, manager review, and human-reviewed evolution.",
64
+ },
65
+ ],
66
+ },
67
+ {
68
+ template: "flutter-rewrite-diagnosis-review",
69
+ positioning: "Reusable diagnosis plus reviewer gate for risky rewrite work before any implementation edit.",
70
+ evidence: [
71
+ {
72
+ label: "Flutter rewrite diagnosis specs",
73
+ path: "/Users/samuel/lawark/lwk_flutter_v2-rewrite/.dna/specs",
74
+ kind: "reference",
75
+ description: "Dogfood diagnosis specs and review verdicts that gate implementation.",
76
+ },
77
+ {
78
+ label: "Flutter rewrite progress evidence",
79
+ path: "/Users/samuel/lawark/lwk_flutter_v2-rewrite/.dna/fix-progress",
80
+ kind: "reference",
81
+ description: "Module-level progress JSON and test logs showing diagnosis/review as a repeated workflow pattern.",
82
+ },
83
+ ],
84
+ },
85
+ {
86
+ template: "flutter-rewrite-fix-review-loop",
87
+ positioning: "Reusable diagnosis-backed fix, independent review, verification, and manager route loop for risky rewrite slices.",
88
+ evidence: [
89
+ {
90
+ label: "Flutter rewrite fix-loop progress",
91
+ path: "/Users/samuel/lawark/lwk_flutter_v2-rewrite/.dna/fix-progress",
92
+ kind: "reference",
93
+ description: "Module-level progress JSON and test logs showing the fix/review/verify loop across dogfood modules.",
94
+ },
95
+ {
96
+ label: "Flutter rewrite diagnosis specs",
97
+ path: "/Users/samuel/lawark/lwk_flutter_v2-rewrite/.dna/specs",
98
+ kind: "reference",
99
+ description: "Approved diagnosis and review artifacts consumed by the fix loop before implementation.",
100
+ },
101
+ ],
102
+ },
103
+ {
104
+ template: "workflow-blocked-scope-triage",
105
+ positioning: "Reusable triage gate for blocked, skipped, removed, infra, or intentionally deferred scope before manager review and rollout.",
106
+ evidence: [
107
+ {
108
+ label: "Flutter rewrite blocked scope evidence",
109
+ path: "/Users/samuel/lawark/lwk_flutter_v2-rewrite/.dna/fix-progress",
110
+ kind: "reference",
111
+ description: "Dogfood module progress where blocked or skipped work had to be separated from remaining implementation work.",
112
+ },
113
+ {
114
+ label: "Flutter rewrite workflow blocked item policy",
115
+ path: "src/templates/flutter-rewrite.dna.yaml",
116
+ kind: "reference",
117
+ description: "Existing full rewrite policy for remaining_unimplemented_skipped_count, blocked_count, and PASS/CONTINUE classification.",
118
+ },
119
+ ],
120
+ },
121
+ {
122
+ template: "workflow-cross-boundary-resource-approval",
123
+ positioning: "Reusable approval route for shared resource, localization, config, policy, or cross-module changes that exceed the current workflow scope.",
124
+ evidence: [
125
+ {
126
+ label: "Flutter rewrite Pay i18n blocker",
127
+ path: "/Users/samuel/lawark/lwk_flutter_v2-rewrite/.dna/fix-progress/Pay.json",
128
+ kind: "reference",
129
+ description: "Dogfood Pay progress where preserving payment_tips_prefix localization required shared lwk_i18n work outside feature_pay and needed human approval.",
130
+ },
131
+ {
132
+ label: "Flutter rewrite dogfood blocked evidence",
133
+ path: "/Users/samuel/lawark/lwk_flutter_v2-rewrite/.dna/fix-progress",
134
+ kind: "reference",
135
+ description: "Module-level dogfood evidence showing needs_human/outside_diagnosis work must route through approval before implementation, rollout, sync, or completion claims.",
136
+ },
137
+ ],
138
+ },
139
+ {
140
+ template: "workflow-completion-audit",
141
+ positioning: "Reusable completion gate for proving PASS/CONTINUE/BLOCKED from diagnosis, current verification, red classification, skipped comparison, and progress evidence.",
142
+ evidence: [
143
+ {
144
+ label: "Flutter rewrite module completion evidence",
145
+ path: "/Users/samuel/lawark/lwk_flutter_v2-rewrite/.dna/fix-progress",
146
+ kind: "reference",
147
+ description: "Dogfood module completion reports that compare diagnosis baselines, current summaries, red classifications, skipped tests, and progress JSON before PASS decisions.",
148
+ },
149
+ {
150
+ label: "Flutter rewrite diagnosis baselines",
151
+ path: "/Users/samuel/lawark/lwk_flutter_v2-rewrite/.dna/specs",
152
+ kind: "reference",
153
+ description: "Diagnosis baselines that define actionable UNIMPLEMENTED/BUG work versus TEST_BUG, INFRA, REMOVED, or approved blocked scope.",
154
+ },
155
+ ],
156
+ },
157
+ {
158
+ template: "workflow-verification-command-routing",
159
+ positioning: "Reusable verification route gate for choosing the authoritative command root/scope and capturing canonical machine evidence before completion, adoption, rollout, or sync.",
160
+ evidence: [
161
+ {
162
+ label: "Flutter rewrite ACTS verification route evidence",
163
+ path: "/Users/samuel/lawark/lwk_flutter_v2-rewrite/.dna/fix-progress/ACTS.md",
164
+ kind: "reference",
165
+ description: "Dogfood note showing wrong-root flutter test output was not valid behavior evidence; the accepted route ran from the v2 project root and produced machine summaries.",
166
+ },
167
+ {
168
+ label: "Flutter rewrite Gallery verification route evidence",
169
+ path: "/Users/samuel/lawark/lwk_flutter_v2-rewrite/.dna/fix-progress/Gallery.md",
170
+ kind: "reference",
171
+ description: "Dogfood note showing final Gallery verification required the feature_gallery package root rather than the standalone behavior-test directory.",
172
+ },
173
+ {
174
+ label: "Flutter rewrite AAC canonical verification evidence",
175
+ path: "/Users/samuel/lawark/lwk_flutter_v2-rewrite/.dna/fix-progress/AAC.md",
176
+ kind: "reference",
177
+ description: "Dogfood completion evidence requiring command status, machine log, parsed summary, red classification, and skipped-test checks before PASS.",
178
+ },
179
+ ],
180
+ },
181
+ {
182
+ template: "workflow-runtime-smoke-review",
183
+ positioning: "Reusable runtime smoke gate for proving a synced or distributed surface is actually usable before wider rollout.",
184
+ evidence: [
185
+ {
186
+ label: "Flutter rewrite ACTS e2e runtime evidence",
187
+ path: "/Users/samuel/lawark/lwk_flutter_v2-rewrite/.dna/fix-progress",
188
+ kind: "reference",
189
+ description: "Dogfood ACTS e2e artifacts including screenshots, UI XML, UI summaries, logcat captures, crash dialogs, route probes, and login/fullscreen blockers.",
190
+ },
191
+ {
192
+ label: "IntentDNA release deploy runbook",
193
+ path: "docs/archive/2026H1/workflows/release-runbook.md",
194
+ kind: "reference",
195
+ description: "Release gate that requires deployed URL verification when web/public surfaces changed.",
196
+ },
197
+ ],
198
+ },
199
+ {
200
+ template: "workflow-module-inventory",
201
+ positioning: "Reusable module/page/action inventory workflow for broad migrations before behavior locks, diagnosis, fixes, rollout, or sync.",
202
+ evidence: [
203
+ {
204
+ label: "Flutter rewrite Phase 0 global scan",
205
+ path: "/Users/samuel/lawark/lwk_flutter_v2-rewrite/docs/refactoring-workflow-v2.md",
206
+ kind: "reference",
207
+ description: "Dogfood workflow doctrine that starts with global module/page/action inventory before per-module behavior locks and fixes.",
208
+ },
209
+ {
210
+ label: "Flutter rewrite v1 feature inventory",
211
+ path: "/Users/samuel/lawark/lwk_flutter_v2-rewrite/docs/v1-feature-inventory.md",
212
+ kind: "reference",
213
+ description: "Real module inventory created to guide behavior docs, priorities, and per-module rewrite execution.",
214
+ },
215
+ {
216
+ label: "Flutter rewrite behavior document set",
217
+ path: "/Users/samuel/lawark/lwk_flutter_v2-rewrite/docs/behavior",
218
+ kind: "reference",
219
+ description: "Per-module behavior documents produced from inventory before diagnosis and fix loops.",
220
+ },
221
+ ],
222
+ },
223
+ ];
224
+ const WORKFLOW_ASSET_METADATA_BY_TEMPLATE = new Map(WORKFLOW_ASSET_METADATA.map((entry) => [entry.template, entry]));
225
+ export function getWorkflowAssetMetadata(template) {
226
+ return WORKFLOW_ASSET_METADATA_BY_TEMPLATE.get(template);
227
+ }