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
@@ -54,12 +54,11 @@ function validateControllerPolicy(policy, path, errors) {
54
54
  errors.push({ path: `${path}.progress_provenance_failure`, message: "must be a non-empty string" });
55
55
  }
56
56
  }
57
- function validateControllerWorkflowRoles(workflow, requiredRoleKeys, roleMap, path, errors) {
57
+ function validateControllerWorkflowRoles(workflow, roleEntries, path, errors) {
58
58
  if (!workflow)
59
59
  return;
60
60
  const workflowRoles = new Set(workflow.steps.map((step) => step.role));
61
- for (const roleKey of requiredRoleKeys) {
62
- const roleName = roleMap[roleKey];
61
+ for (const [roleKey, roleName] of roleEntries) {
63
62
  if (typeof roleName !== "string" || !roleName)
64
63
  continue;
65
64
  if (!workflowRoles.has(roleName)) {
@@ -91,32 +90,40 @@ export function validateController(controller, roleNames, workflows, path) {
91
90
  if (!Number.isInteger(controller.max_rounds) || controller.max_rounds < 1 || controller.max_rounds > 20) {
92
91
  errors.push({ path: `${path}.max_rounds`, message: "max_rounds must be an integer in 1..20" });
93
92
  }
94
- const requiredStringFields = [
95
- "progress_artifact_path",
96
- "diagnosis_workflow",
97
- "fix_workflow",
98
- "diagnosis_artifact_path",
99
- "diagnosis_review_artifact_path",
100
- "review_artifact_path",
101
- ];
93
+ const requiredStringFields = kindMetadata?.kind === "sequential"
94
+ ? ["progress_artifact_path", "workflow"]
95
+ : [
96
+ "progress_artifact_path",
97
+ "diagnosis_workflow",
98
+ "fix_workflow",
99
+ "diagnosis_artifact_path",
100
+ "diagnosis_review_artifact_path",
101
+ "review_artifact_path",
102
+ ];
102
103
  for (const field of requiredStringFields) {
103
104
  if (typeof controller[field] !== "string" || !controller[field]) {
104
105
  errors.push({ path: `${path}.${field}`, message: "must be a non-empty string" });
105
106
  }
106
107
  }
107
- const artifactPathFields = [
108
- "progress_artifact_path",
109
- "diagnosis_artifact_path",
110
- "diagnosis_review_artifact_path",
111
- "review_artifact_path",
112
- ];
108
+ const artifactPathFields = kindMetadata?.kind === "sequential"
109
+ ? ["progress_artifact_path"]
110
+ : [
111
+ "progress_artifact_path",
112
+ "diagnosis_artifact_path",
113
+ "diagnosis_review_artifact_path",
114
+ "review_artifact_path",
115
+ ];
113
116
  for (const field of artifactPathFields) {
114
117
  if (typeof controller[field] === "string" && !isSafeControllerArtifactPath(controller[field])) {
115
118
  errors.push({ path: `${path}.${field}`, message: "must be a relative .dna/ artifact template containing $ARGUMENTS without glob, brace, absolute, or parent traversal syntax" });
116
119
  }
117
120
  }
121
+ const workflow = controller.workflow ? workflows[controller.workflow] : undefined;
118
122
  const diagnosisWorkflow = controller.diagnosis_workflow ? workflows[controller.diagnosis_workflow] : undefined;
119
123
  const fixWorkflow = controller.fix_workflow ? workflows[controller.fix_workflow] : undefined;
124
+ if (controller.workflow && !workflow) {
125
+ errors.push({ path: `${path}.workflow`, message: `references unknown workflow '${controller.workflow}'` });
126
+ }
120
127
  if (controller.diagnosis_workflow && !diagnosisWorkflow) {
121
128
  errors.push({ path: `${path}.diagnosis_workflow`, message: `references unknown workflow '${controller.diagnosis_workflow}'` });
122
129
  }
@@ -128,8 +135,14 @@ export function validateController(controller, roleNames, workflows, path) {
128
135
  if (!roleMap || typeof roleMap !== "object") {
129
136
  errors.push({ path: `${path}.roles`, message: "controller requires roles" });
130
137
  }
138
+ else if (kindMetadata?.kind === "sequential" && Object.keys(roleMap).length === 0) {
139
+ errors.push({ path: `${path}.roles`, message: "sequential controller requires at least one workflow role" });
140
+ }
131
141
  else {
132
- for (const roleKey of requiredRoles) {
142
+ const roleKeysToValidate = kindMetadata?.kind === "sequential"
143
+ ? Object.keys(roleMap)
144
+ : requiredRoles;
145
+ for (const roleKey of roleKeysToValidate) {
133
146
  const roleName = roleMap[roleKey];
134
147
  if (typeof roleName !== "string" || !roleName) {
135
148
  errors.push({ path: `${path}.roles.${roleKey}`, message: "must be a non-empty role name" });
@@ -143,8 +156,13 @@ export function validateController(controller, roleNames, workflows, path) {
143
156
  }
144
157
  }
145
158
  if (roleMap && typeof roleMap === "object") {
146
- validateControllerWorkflowRoles(diagnosisWorkflow, kindMetadata?.diagnosisRoleKeys ?? ["analyzer", "analysis_reviewer"], roleMap, `${path}.diagnosis_workflow`, errors);
147
- validateControllerWorkflowRoles(fixWorkflow, kindMetadata?.fixRoleKeys ?? ["surgeon", "fix_reviewer", "test_runner"], roleMap, `${path}.fix_workflow`, errors);
159
+ if (kindMetadata?.kind === "sequential") {
160
+ validateControllerWorkflowRoles(workflow, Object.entries(roleMap), `${path}.workflow`, errors);
161
+ }
162
+ else {
163
+ validateControllerWorkflowRoles(diagnosisWorkflow, (kindMetadata?.diagnosisRoleKeys ?? ["analyzer", "analysis_reviewer"]).map((roleKey) => [roleKey, roleMap[roleKey]]), `${path}.diagnosis_workflow`, errors);
164
+ validateControllerWorkflowRoles(fixWorkflow, (kindMetadata?.fixRoleKeys ?? ["surgeon", "fix_reviewer", "test_runner"]).map((roleKey) => [roleKey, roleMap[roleKey]]), `${path}.fix_workflow`, errors);
165
+ }
148
166
  }
149
167
  if (controller.stop_format !== "configured_stop_report" && controller.stop_format !== "zh_three_part") {
150
168
  errors.push({ path: `${path}.stop_format`, message: "stop_format must be 'configured_stop_report' or legacy 'zh_three_part'" });
@@ -0,0 +1,29 @@
1
+ export interface AuthoringFieldConstraint {
2
+ name: string;
3
+ required: boolean;
4
+ type: string;
5
+ allowed_values?: readonly string[];
6
+ notes?: string;
7
+ }
8
+ export declare const WORKFLOW_AUTHORING_SCHEMA: {
9
+ readonly source: "src/schema/workflow-authoring-contract.ts; field maps are exhaustive against src/schema/types.ts";
10
+ readonly workflow: readonly AuthoringFieldConstraint[];
11
+ readonly step: readonly AuthoringFieldConstraint[];
12
+ readonly role: readonly AuthoringFieldConstraint[];
13
+ readonly tool_permissions: readonly AuthoringFieldConstraint[];
14
+ readonly scope: readonly AuthoringFieldConstraint[];
15
+ readonly handoff_artifact: {
16
+ readonly fields: readonly AuthoringFieldConstraint[];
17
+ readonly type_values: readonly ["file", "directory", "test_result", "git_commit", "summary", "state"];
18
+ readonly required_fields: string[];
19
+ readonly optional_fields: string[];
20
+ };
21
+ readonly checkpoint: {
22
+ readonly fields: readonly AuthoringFieldConstraint[];
23
+ readonly required_fields: string[];
24
+ readonly optional_fields: string[];
25
+ readonly action_values: readonly ["block", "warn"];
26
+ };
27
+ readonly transition: readonly AuthoringFieldConstraint[];
28
+ readonly retry_policy: readonly AuthoringFieldConstraint[];
29
+ };
@@ -0,0 +1,109 @@
1
+ import { CHECKPOINT_ACTION_VALUES, HANDOFF_TYPE_VALUES, RETRY_BACKOFF_VALUES, TRANSITION_CONDITION_VALUES, WORKFLOW_HANDOFF_EXHAUSTED_VALUES, WORKFLOW_ISOLATION_VALUES, WORKFLOW_MERGE_STRATEGY_VALUES, WORKFLOW_STEP_FAILURE_VALUES, } from "./types.js";
2
+ function fieldsFrom(definitions) {
3
+ return Object.entries(definitions).map(([name, definition]) => ({
4
+ name,
5
+ ...definition,
6
+ }));
7
+ }
8
+ const WORKFLOW_FIELDS = {
9
+ name: { required: true, type: "string", notes: "Human-readable workflow name." },
10
+ description: { required: false, type: "string" },
11
+ steps: { required: true, type: "WorkflowStepDef[]", notes: "At least one step; ids must be unique within the workflow." },
12
+ transitions: { required: false, type: "TransitionDef[]" },
13
+ retry_policy: { required: false, type: "RetryPolicy" },
14
+ max_rounds: { required: false, type: "number", notes: "Alias for retry rounds when retry_policy is omitted." },
15
+ produces: { required: false, type: "HandoffArtifact[]" },
16
+ consumes: { required: false, type: "HandoffArtifact[]" },
17
+ default_isolation: { required: false, type: "WorkflowIsolation", allowed_values: WORKFLOW_ISOLATION_VALUES },
18
+ merge_strategy: { required: false, type: "WorkflowMergeStrategy", allowed_values: WORKFLOW_MERGE_STRATEGY_VALUES },
19
+ };
20
+ const STEP_FIELDS = {
21
+ id: { required: true, type: "string", notes: "Stable safe identifier, unique within the workflow." },
22
+ role: { required: true, type: "string", notes: "Must reference a declared role in the same asset." },
23
+ description: { required: false, type: "string" },
24
+ depends_on: { required: false, type: "string[]" },
25
+ optional: { required: false, type: "boolean" },
26
+ run_if: { required: false, type: "string" },
27
+ prompt: { required: false, type: "string" },
28
+ completion: { required: false, type: "CompletionCheck[]" },
29
+ checkpoints: { required: false, type: "StepCheckpoint[]" },
30
+ handoff: { required: false, type: "StepHandoff" },
31
+ isolation: { required: false, type: "WorkflowIsolation", allowed_values: WORKFLOW_ISOLATION_VALUES },
32
+ enforce: { required: false, type: "step-level enforcement object" },
33
+ max_attempts: { required: false, type: "number" },
34
+ on_fail: { required: false, type: "WorkflowStepFailureAction", allowed_values: WORKFLOW_STEP_FAILURE_VALUES },
35
+ handoff_to: { required: false, type: "string" },
36
+ max_handoffs: { required: false, type: "number" },
37
+ on_handoff_exhausted: { required: false, type: "WorkflowHandoffExhaustedAction", allowed_values: WORKFLOW_HANDOFF_EXHAUSTED_VALUES },
38
+ blocked_items_path: { required: false, type: "string" },
39
+ };
40
+ const ROLE_FIELDS = {
41
+ description: { required: true, type: "string" },
42
+ tool_permissions: { required: false, type: "ToolPermissions" },
43
+ scope: { required: false, type: "ScopeDef" },
44
+ output_schema: { required: false, type: "string|OutputSchema" },
45
+ model: { required: false, type: "string", notes: "Harness hint only; use human for an explicit user-owned gate or interactive for a main-session external-agent step." },
46
+ activates_genes: { required: false, type: "string[]" },
47
+ suppresses_genes: { required: false, type: "string[]" },
48
+ post_checks: { required: false, type: "string[]" },
49
+ instructions: { required: false, type: "string[]" },
50
+ success_criteria: { required: false, type: "string[]" },
51
+ failure_modes: { required: false, type: "string[]" },
52
+ };
53
+ const TOOL_PERMISSION_FIELDS = {
54
+ allow: { required: false, type: "string[]" },
55
+ deny: { required: false, type: "string[]" },
56
+ };
57
+ const SCOPE_FIELDS = {
58
+ read: { required: false, type: "string[]" },
59
+ write: { required: false, type: "string[]" },
60
+ };
61
+ const HANDOFF_FIELDS = {
62
+ type: { required: true, type: "HandoffType", allowed_values: HANDOFF_TYPE_VALUES },
63
+ path: { required: false, type: "string" },
64
+ name: { required: false, type: "string" },
65
+ artifact_id: { required: false, type: "string" },
66
+ from: { required: false, type: "string" },
67
+ required: { required: false, type: "boolean", notes: "Defaults to true." },
68
+ description: { required: true, type: "string" },
69
+ };
70
+ const CHECKPOINT_FIELDS = {
71
+ assert: { required: true, type: "string" },
72
+ command: { required: false, type: "string", notes: "Required for custom assertions that are not built-ins." },
73
+ message: { required: true, type: "string" },
74
+ action: { required: false, type: "CheckpointAction", allowed_values: CHECKPOINT_ACTION_VALUES, notes: "Defaults to block." },
75
+ };
76
+ const TRANSITION_FIELDS = {
77
+ from: { required: true, type: "string" },
78
+ to: { required: true, type: "string" },
79
+ condition: { required: true, type: "TransitionCondition", allowed_values: TRANSITION_CONDITION_VALUES },
80
+ };
81
+ const RETRY_POLICY_FIELDS = {
82
+ max_retries: { required: true, type: "number", notes: "Must be zero or greater." },
83
+ retry_from: { required: false, type: "string", notes: "Must reference an existing step when present." },
84
+ backoff: { required: false, type: "RetryBackoff", allowed_values: RETRY_BACKOFF_VALUES },
85
+ };
86
+ const handoffFields = fieldsFrom(HANDOFF_FIELDS);
87
+ const checkpointFields = fieldsFrom(CHECKPOINT_FIELDS);
88
+ export const WORKFLOW_AUTHORING_SCHEMA = {
89
+ source: "src/schema/workflow-authoring-contract.ts; field maps are exhaustive against src/schema/types.ts",
90
+ workflow: fieldsFrom(WORKFLOW_FIELDS),
91
+ step: fieldsFrom(STEP_FIELDS),
92
+ role: fieldsFrom(ROLE_FIELDS),
93
+ tool_permissions: fieldsFrom(TOOL_PERMISSION_FIELDS),
94
+ scope: fieldsFrom(SCOPE_FIELDS),
95
+ handoff_artifact: {
96
+ fields: handoffFields,
97
+ type_values: HANDOFF_TYPE_VALUES,
98
+ required_fields: handoffFields.filter((field) => field.required).map((field) => field.name),
99
+ optional_fields: handoffFields.filter((field) => !field.required).map((field) => field.name),
100
+ },
101
+ checkpoint: {
102
+ fields: checkpointFields,
103
+ required_fields: checkpointFields.filter((field) => field.required).map((field) => field.name),
104
+ optional_fields: checkpointFields.filter((field) => !field.required).map((field) => field.name),
105
+ action_values: CHECKPOINT_ACTION_VALUES,
106
+ },
107
+ transition: fieldsFrom(TRANSITION_FIELDS),
108
+ retry_policy: fieldsFrom(RETRY_POLICY_FIELDS),
109
+ };
@@ -224,6 +224,24 @@ function parseScalar(s) {
224
224
  // Inline empty object: {}
225
225
  if (s === "{}")
226
226
  return {};
227
+ // Inline object: { key: value, other: "quoted" }
228
+ if (s.startsWith("{") && s.endsWith("}")) {
229
+ const inner = s.slice(1, -1).trim();
230
+ if (inner === "")
231
+ return {};
232
+ const result = {};
233
+ for (const entry of splitInlineArray(inner)) {
234
+ const colonIdx = findKeyColon(entry);
235
+ if (colonIdx <= 0)
236
+ return s;
237
+ const key = entry.slice(0, colonIdx).trim().replace(/^["']|["']$/g, "");
238
+ const value = entry.slice(colonIdx + 1).trim();
239
+ if (!key)
240
+ return s;
241
+ result[key] = parseScalar(value);
242
+ }
243
+ return result;
244
+ }
227
245
  // Quoted string
228
246
  if ((s.startsWith('"') && s.endsWith('"')) || (s.startsWith("'") && s.endsWith("'"))) {
229
247
  return s.slice(1, -1).replace(/\\"/g, '"').replace(/\\'/g, "'").replace(/\\\\/g, "\\");
@@ -5,6 +5,25 @@
5
5
  version: "0.1.0"
6
6
  id: template_api_backend
7
7
  name: API Backend Standards
8
+ purpose: Provide a backend API baseline for security, quality, database safety, and reviewable implementation.
9
+ maturity: draft
10
+ fit:
11
+ - Node.js, Python, or service API projects that need a local governance baseline.
12
+ - Teams starting from API standards before authoring a richer workflow asset.
13
+ not_for:
14
+ - Replacing endpoint-specific design, tests, or threat modeling.
15
+ - Online execution, cloud deployment, or database mutation by the template itself.
16
+ inputs:
17
+ - API task scope
18
+ - endpoint and data model context
19
+ - security and database constraints
20
+ outputs:
21
+ - backend development guardrails
22
+ - API quality review notes
23
+ - database safety reminders
24
+ lineage:
25
+ source: built-in backend standards template
26
+ reference: src/templates/api-backend.dna.yaml
8
27
  type: project
9
28
  namespace: be
10
29
 
@@ -6,6 +6,25 @@
6
6
  version: "0.1.0"
7
7
  id: template_brainstorming_first
8
8
  name: Brainstorming First
9
+ purpose: Force design, Socratic refinement, and task decomposition before implementation starts.
10
+ maturity: draft
11
+ fit:
12
+ - Early-stage tasks where requirements, tradeoffs, or implementation chunks are unclear.
13
+ - Planning work that should produce small verifiable steps before coding.
14
+ not_for:
15
+ - Already approved implementation slices with clear acceptance criteria.
16
+ - Letting brainstorming replace tests, review, or delivery evidence.
17
+ inputs:
18
+ - raw idea or task request
19
+ - known constraints and open questions
20
+ - desired outcome or decision point
21
+ outputs:
22
+ - refined requirements
23
+ - decomposed task plan
24
+ - implementation readiness notes
25
+ lineage:
26
+ source: brainstorming and writing-plans workflow shape
27
+ reference: src/templates/brainstorming-first.dna.yaml
9
28
  type: project
10
29
  namespace: bs
11
30
 
@@ -1,6 +1,25 @@
1
1
  version: "0.1.0"
2
2
  id: template_code_cleanup
3
3
  name: Code Cleanup (Regression-Safe)
4
+ purpose: Clean code in small behavior-preserving passes with tests between each smell-focused edit.
5
+ maturity: reviewed
6
+ fit:
7
+ - Refactors or cleanup where existing behavior must stay stable.
8
+ - Reducing dead code, duplication, naming issues, or local complexity under test coverage.
9
+ not_for:
10
+ - Mixing feature work into cleanup.
11
+ - Large unverified rewrites or cleanup without regression checks.
12
+ inputs:
13
+ - cleanup scope
14
+ - current tests or behavior evidence
15
+ - identified smell category
16
+ outputs:
17
+ - scoped cleanup diff
18
+ - regression verification evidence
19
+ - remaining cleanup risk notes
20
+ lineage:
21
+ source: built-in regression-safe cleanup workflow
22
+ reference: docs/archive/fix-notes/refactoring-workflow-principles.md
4
23
  type: project
5
24
  namespace: cc
6
25
 
@@ -5,6 +5,24 @@
5
5
  version: "0.1.0"
6
6
  id: template_code_review_pipeline
7
7
  name: Code Review Pipeline
8
+ purpose: Run structured implementation review with actionable findings, tests, and follow-up fixes before merge or adoption.
9
+ maturity: reviewed
10
+ fit:
11
+ - Pull request or patch review that needs explicit PASS/FAIL evidence.
12
+ - Separating reviewer feedback from implementation fixes.
13
+ not_for:
14
+ - Rubber-stamp approval.
15
+ - Replacing targeted tests or security checks with prose.
16
+ inputs:
17
+ - changed files
18
+ - task specification
19
+ - test results
20
+ outputs:
21
+ - review findings with code references
22
+ - required fixes
23
+ - re-review verdict
24
+ lineage:
25
+ source: requesting-code-review and receiving-code-review workflow shape
8
26
  type: project
9
27
  namespace: crp
10
28
 
@@ -5,6 +5,25 @@
5
5
  version: "0.1.0"
6
6
  id: template_documentation_writer
7
7
  name: Documentation Writer
8
+ purpose: Write technical documentation from code evidence with audience-aware structure and explicit accuracy constraints.
9
+ maturity: draft
10
+ fit:
11
+ - API docs, user guides, internal technical docs, or migration notes grounded in code.
12
+ - Documentation tasks where accuracy and scannable structure matter.
13
+ not_for:
14
+ - Inventing behavior not present in code or verified references.
15
+ - Publishing docs without human or maintainer review.
16
+ inputs:
17
+ - documentation request
18
+ - source code or API references
19
+ - target audience and format
20
+ outputs:
21
+ - structured documentation draft
22
+ - code-grounded accuracy notes
23
+ - review-ready doc artifact
24
+ lineage:
25
+ source: built-in technical documentation writer template
26
+ reference: src/templates/documentation-writer.dna.yaml
8
27
  type: project
9
28
  namespace: doc
10
29
 
@@ -6,6 +6,25 @@
6
6
  version: "0.1.0"
7
7
  id: template_flutter_behavior_lock
8
8
  name: Flutter Behavior Lock
9
+ purpose: Capture source behavior as docs and tests before risky Flutter rewrite, refactor, diagnosis, or fix work starts.
10
+ maturity: reviewed
11
+ fit:
12
+ - Flutter module rewrites where v1 behavior must be preserved before implementation.
13
+ - Migration work that needs source-backed behavior documents and baseline tests per module.
14
+ not_for:
15
+ - Editing app source during discovery.
16
+ - Feature redesigns or behavior changes mixed into migration evidence.
17
+ inputs:
18
+ - v1 source module path
19
+ - v2 test and behavior-document destination
20
+ - target module name or route
21
+ outputs:
22
+ - behavior document
23
+ - baseline unit or integration tests
24
+ - optional device smoke evidence
25
+ lineage:
26
+ source: Flutter rewrite dogfood behavior-lock workflow
27
+ reference: /Users/samuel/lawark/lwk_flutter_v2-rewrite/docs/behavior
9
28
  type: project
10
29
  namespace: fbl
11
30
 
@@ -6,6 +6,25 @@
6
6
  version: "0.1.0"
7
7
  id: template_flutter_refactoring_rescue
8
8
  name: Flutter Refactoring Rescue
9
+ purpose: Rescue an already migrated Flutter project by repairing one broken feature chain at a time using v1 as oracle.
10
+ maturity: reviewed
11
+ fit:
12
+ - Flutter migrations where framework movement is done but user-visible chains are broken.
13
+ - Small verified fixes that must preserve existing behavior.
14
+ not_for:
15
+ - First-pass migration planning.
16
+ - Broad redesign or multi-feature cleanup work.
17
+ inputs:
18
+ - broken feature chain
19
+ - v1 oracle behavior
20
+ - device or test verification output
21
+ outputs:
22
+ - scoped fix plan
23
+ - reviewable change evidence
24
+ - runtime verification summary
25
+ lineage:
26
+ source: dogfood extraction
27
+ reference: safe-refactoring plus verification-loop workflow shape
9
28
  type: project
10
29
  namespace: frr
11
30
 
@@ -0,0 +1,210 @@
1
+ # flutter-rewrite-diagnosis-review: reusable diagnosis + reviewer gate extracted from Flutter rewrite dogfood
2
+ # Source: flutter-rewrite diagnosis workflow and module-level progress evidence
3
+ # Purpose: make "classify before editing" a smaller workflow asset users can adopt without the full rewrite loop
4
+
5
+ version: "0.1.0"
6
+ id: template_flutter_rewrite_diagnosis_review
7
+ name: Flutter Rewrite Diagnosis Review
8
+ purpose: Classify risky Flutter rewrite failures from evidence and require independent diagnosis review before implementation starts.
9
+ maturity: reviewed
10
+ fit:
11
+ - Rewrite or migration slices where failures must be classified before editing.
12
+ - Teams that need evidence-only diagnosis and a reviewer verdict before handoff to fixing.
13
+ not_for:
14
+ - Writing implementation plans inside the diagnosis artifact.
15
+ - Self-approving diagnosis or skipping evidence review before code changes.
16
+ inputs:
17
+ - behavior documents
18
+ - failing tests or runtime evidence
19
+ - v1 and v2 implementation references
20
+ outputs:
21
+ - evidence-only diagnosis artifact
22
+ - independent review verdict
23
+ - manager-readable implementation route
24
+ lineage:
25
+ source: Flutter rewrite dogfood diagnosis workflow
26
+ reference: /Users/samuel/lawark/lwk_flutter_v2-rewrite/.dna/specs
27
+ type: project
28
+ namespace: frdr
29
+
30
+ cascade:
31
+ inherits: ["species:default"]
32
+ priority: 100
33
+
34
+ variables:
35
+ behavior_docs:
36
+ description: "Behavior evidence directory"
37
+ default: "docs/behavior"
38
+ diagnosis_path:
39
+ description: "Diagnosis artifact path"
40
+ default: ".dna/specs/diagnosis-$ARGUMENTS.md"
41
+ diagnosis_review_path:
42
+ description: "Diagnosis review verdict path"
43
+ default: ".dna/specs/diagnosis-$ARGUMENTS.review.json"
44
+
45
+ evidence:
46
+ - label: Flutter rewrite diagnosis workflow
47
+ kind: reference
48
+ path: /Users/samuel/lawark/lwk_flutter_v2-rewrite/.dna/specs
49
+ description: Dogfood diagnosis specs and review verdicts that gate implementation.
50
+ - label: Flutter rewrite progress evidence
51
+ kind: reference
52
+ path: /Users/samuel/lawark/lwk_flutter_v2-rewrite/.dna/fix-progress
53
+ description: Module-level progress JSON and test logs showing diagnosis/review as a repeated work pattern.
54
+
55
+ genes:
56
+ diagnosis_before_edit:
57
+ description: Risky rewrite work must classify failures and missing behavior before any implementation edit
58
+ codons:
59
+ - type: attract
60
+ target: evidence_first_diagnosis
61
+ - type: repel
62
+ target: edit_before_classification
63
+ - type: threshold
64
+ condition: "diagnosis_review_verdict == APPROVE"
65
+ action: block
66
+
67
+ evidence_only_diagnosis:
68
+ description: Diagnosis artifacts describe facts and classifications, not implementation orders or hidden fix plans
69
+ codons:
70
+ - type: attract
71
+ target: v1_reference
72
+ - type: attract
73
+ target: failing_test_reference
74
+ - type: repel
75
+ target: fix_prescription_in_diagnosis
76
+ - type: sense
77
+ signal: missing_evidence_path
78
+ response: request_reanalysis
79
+
80
+ reviewer_gate:
81
+ description: A separate reviewer must approve diagnosis quality before the workflow can hand off to fixing
82
+ codons:
83
+ - type: attract
84
+ target: independent_reviewer_verdict
85
+ - type: repel
86
+ target: self_approved_diagnosis
87
+ - type: threshold
88
+ condition: "diagnosis_review_written == true"
89
+ action: block
90
+
91
+ contexts: {}
92
+
93
+ roles:
94
+ diagnostician:
95
+ description: Reads behavior evidence, tests, v1/v2 code, and writes an evidence-only diagnosis artifact.
96
+ tool_permissions:
97
+ allow: [Read, Grep, Glob, Write]
98
+ deny: [Edit, Bash, NotebookEdit]
99
+ scope:
100
+ read: ["**/*", ".dna/**", "docs/**"]
101
+ write: [".dna/specs/**"]
102
+ instructions:
103
+ - Read the behavior document, failing tests, v1 implementation, and v2 current state before writing diagnosis.
104
+ - Classify each issue as BUG, UNIMPLEMENTED, INFRA, REMOVED, or TEST_BUG.
105
+ - Include concrete evidence paths and v1/v2 references for every classification.
106
+ - Do not include fix prescriptions, implementation order, call-site instructions, or notes for the implementer.
107
+ - Write only the diagnosis artifact; do not edit app code, tests, org profiles, templates, or runtime artifacts.
108
+
109
+ diagnosis_reviewer:
110
+ description: Reviews diagnosis quality and writes the durable approval or reanalysis verdict.
111
+ tool_permissions:
112
+ allow: [Read, Grep, Glob, Write]
113
+ deny: [Edit, Bash, NotebookEdit]
114
+ scope:
115
+ read: ["**/*", ".dna/**", "docs/**"]
116
+ write: [".dna/specs/*.review.json"]
117
+ instructions:
118
+ - Verify every failing, skipped, or hung test from the baseline is covered.
119
+ - Verify v1 references and evidence paths exist and support the classifications.
120
+ - Reject diagnosis that contains implementation instructions or unsupported claims.
121
+ - Write verdict JSON with verdict, artifact_reviewed, sections_to_fix, evidence_paths, confidence, summary, and updated_at.
122
+ - APPROVE permits later fixing; REQUEST_REANALYSIS blocks implementation and routes back to diagnosis.
123
+
124
+ manager_reviewer:
125
+ description: Turns the diagnosis/review state into a manager-readable next-action packet.
126
+ tool_permissions:
127
+ allow: [Read, Grep, Glob]
128
+ deny: [Edit, Write, Bash, NotebookEdit]
129
+ scope:
130
+ read: ["**/*", ".dna/**", "docs/**"]
131
+ write: []
132
+ instructions:
133
+ - Summarize whether implementation is allowed, blocked, or needs reanalysis.
134
+ - Name the exact diagnosis and review artifacts used as evidence.
135
+ - If review is missing or REQUEST_REANALYSIS, block fixing and provide the next command.
136
+ - Keep Obsidian/wiki as internal memory only; use machine artifacts as workflow evidence.
137
+
138
+ workflows:
139
+ diagnosis-review:
140
+ name: Diagnosis Review
141
+ description: Analyze module failures and require an independent diagnosis review before implementation starts.
142
+ steps:
143
+ - id: diagnose
144
+ role: diagnostician
145
+ description: Produce evidence-only diagnosis for the target module or risky rewrite slice.
146
+ prompt: |
147
+ Diagnose $ARGUMENTS before any implementation edit.
148
+ Read {{behavior_docs}}/$ARGUMENTS.md, failing test evidence, v1 implementation, and v2 current state.
149
+ Write {{diagnosis_path}} with classifications, evidence paths, v1/v2 references, and uncertainty.
150
+ Do not include fix prescriptions, implementation order, call-site instructions, or notes for the implementer.
151
+ handoff:
152
+ produces:
153
+ - type: file
154
+ path: "{{diagnosis_path}}"
155
+ description: Evidence-only diagnosis artifact.
156
+ - id: review-diagnosis
157
+ role: diagnosis_reviewer
158
+ depends_on: [diagnose]
159
+ description: Review diagnosis quality and write an approval or reanalysis verdict.
160
+ prompt: |
161
+ Review {{diagnosis_path}} for $ARGUMENTS.
162
+ Verify coverage, evidence paths, classification quality, and absence of fix prescriptions.
163
+ Write {{diagnosis_review_path}} with verdict APPROVE or REQUEST_REANALYSIS.
164
+ checkpoints:
165
+ - assert: diagnosis_review_verdict_present
166
+ command: "test -s \"{{diagnosis_review_path}}\""
167
+ message: "Diagnosis review verdict must exist before any implementation handoff."
168
+ action: block
169
+ handoff:
170
+ consumes:
171
+ - type: file
172
+ path: "{{diagnosis_path}}"
173
+ from: diagnose
174
+ description: Diagnosis artifact.
175
+ produces:
176
+ - type: file
177
+ path: "{{diagnosis_review_path}}"
178
+ description: Diagnosis review verdict.
179
+ - id: manager-route
180
+ role: manager_reviewer
181
+ depends_on: [review-diagnosis]
182
+ description: Produce manager-readable next action for implementation, reanalysis, or blocked scope.
183
+ prompt: |
184
+ Read {{diagnosis_path}} and {{diagnosis_review_path}}.
185
+ State whether fixing is allowed, blocked, or requires reanalysis.
186
+ Include evidence paths, confidence, and the next command.
187
+ handoff:
188
+ consumes:
189
+ - type: file
190
+ path: "{{diagnosis_review_path}}"
191
+ from: review-diagnosis
192
+ description: Diagnosis review verdict.
193
+ produces:
194
+ - type: summary
195
+ name: diagnosis_route
196
+ description: Manager-readable route to fix, reanalysis, or blocked state.
197
+
198
+ controllers:
199
+ diagnosis-review-gate:
200
+ name: Diagnosis Review Gate
201
+ description: "Run diagnosis, independent diagnosis review, and manager route before implementation starts."
202
+ kind: sequential
203
+ workflow: diagnosis-review
204
+ max_rounds: 1
205
+ progress_artifact_path: ".dna/diagnosis-review/$ARGUMENTS.json"
206
+ roles:
207
+ diagnostician: diagnostician
208
+ diagnosis_reviewer: diagnosis_reviewer
209
+ manager_reviewer: manager_reviewer
210
+ stop_format: configured_stop_report