ultra-builder-pro-cli 0.13.0 → 0.15.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 (172) hide show
  1. package/.ultra-template/docs/research/README.md +11 -7
  2. package/.ultra-template/specs/architecture.md +36 -36
  3. package/.ultra-template/specs/discovery.md +46 -33
  4. package/.ultra-template/specs/product.md +38 -29
  5. package/.ultra-template/specs/research-distillate.md +48 -0
  6. package/.ultra-template/tasks/contexts/TEMPLATE.md +11 -28
  7. package/CHANGELOG.md +86 -1
  8. package/README.md +40 -26
  9. package/adapters/_shared/codex-assets.cjs +29 -165
  10. package/adapters/_shared/file-ops.cjs +6 -2
  11. package/adapters/_shared/runtime-assets.cjs +1 -0
  12. package/adapters/claude.js +3 -2
  13. package/adapters/codex.js +1 -0
  14. package/adapters/kimi.js +3 -2
  15. package/adapters/opencode.js +33 -122
  16. package/agents/review-coordinator.md +9 -6
  17. package/docs/AGENT-CONTEXT.md +21 -11
  18. package/docs/ARCHITECTURE.md +41 -13
  19. package/docs/PLAN.zh-CN.md +3 -2
  20. package/docs/ROADMAP.md +9 -5
  21. package/docs/RUNTIME-COMPAT-MATRIX.md +6 -6
  22. package/docs/STATE-DB-ACCESS-POLICY.md +27 -25
  23. package/docs/WORKFLOW-LIFECYCLE.md +266 -0
  24. package/hooks/README.md +6 -1
  25. package/hooks/active_task_context.py +22 -50
  26. package/hooks/context_spine.py +61 -332
  27. package/hooks/health_check.py +29 -18
  28. package/hooks/pre_stop_check.py +28 -33
  29. package/hooks/subagent_tracker.py +54 -85
  30. package/hooks/workflow_checkpoint.py +39 -47
  31. package/hooks/workflow_context.py +4 -9
  32. package/hooks/workflow_resume.py +48 -128
  33. package/mcp-server/breadcrumb.cjs +22 -0
  34. package/mcp-server/hook-event.cjs +34 -0
  35. package/mcp-server/lib/archive-journal.cjs +17 -5
  36. package/mcp-server/lib/baseline-workflow.cjs +158 -18
  37. package/mcp-server/lib/change-workflow.cjs +550 -85
  38. package/mcp-server/lib/context-spine.cjs +242 -24
  39. package/mcp-server/lib/doctor.cjs +33 -3
  40. package/mcp-server/lib/init-project.cjs +210 -16
  41. package/mcp-server/lib/plan-store.cjs +4 -1
  42. package/mcp-server/lib/prd-parser.cjs +14 -41
  43. package/mcp-server/lib/pricing.cjs +7 -10
  44. package/mcp-server/lib/project-breadcrumb.cjs +145 -0
  45. package/mcp-server/lib/projector.cjs +57 -3
  46. package/mcp-server/lib/spec-learning.cjs +79 -2
  47. package/mcp-server/lib/state-db.cjs +145 -8
  48. package/mcp-server/lib/state-ops.cjs +160 -9
  49. package/mcp-server/lib/task-expander.cjs +9 -38
  50. package/mcp-server/lib/workflow-state.cjs +2292 -0
  51. package/mcp-server/server.cjs +182 -50
  52. package/orchestrator/daemon.cjs +1 -2
  53. package/orchestrator/dispatch-rules.cjs +5 -31
  54. package/orchestrator/planner/plan-builder.cjs +21 -12
  55. package/package.json +14 -6
  56. package/skills/cc-collab/SKILL.md +2 -2
  57. package/skills/codex-collab/SKILL.md +2 -3
  58. package/skills/ultra-change/SKILL.md +53 -68
  59. package/skills/ultra-change/references/change-contract.md +36 -0
  60. package/skills/ultra-deliver/SKILL.md +69 -79
  61. package/skills/ultra-deliver/references/baseline-reconciliation.md +20 -0
  62. package/skills/ultra-dev/SKILL.md +54 -59
  63. package/skills/ultra-doctor/SKILL.md +40 -71
  64. package/skills/ultra-init/SKILL.md +96 -103
  65. package/skills/ultra-init/references/brownfield-adoption.md +2 -2
  66. package/skills/ultra-plan/SKILL.md +79 -75
  67. package/skills/ultra-plan/references/semantic-preflight.md +18 -0
  68. package/skills/ultra-research/SKILL.md +87 -60
  69. package/skills/ultra-research/references/00-problem-validation.md +36 -0
  70. package/skills/ultra-research/references/01-opportunity-discovery.md +33 -0
  71. package/skills/ultra-research/references/02-market-assessment.md +30 -0
  72. package/skills/ultra-research/references/03-competitive-landscape.md +31 -0
  73. package/skills/ultra-research/references/04-product-strategy.md +32 -0
  74. package/skills/ultra-research/references/05-assumptions-validation.md +31 -0
  75. package/skills/ultra-research/references/10-user-personas.md +29 -0
  76. package/skills/ultra-research/references/11-user-scenarios.md +28 -0
  77. package/skills/ultra-research/references/20-user-stories.md +30 -0
  78. package/skills/ultra-research/references/21-features-scope.md +29 -0
  79. package/skills/ultra-research/references/22-success-metrics.md +28 -0
  80. package/skills/ultra-research/references/30-architecture-context.md +30 -0
  81. package/skills/ultra-research/references/31-solution-strategy.md +28 -0
  82. package/skills/ultra-research/references/32-building-blocks.md +28 -0
  83. package/skills/ultra-research/references/40-deployment.md +29 -0
  84. package/skills/ultra-research/references/41-quality-risks.md +28 -0
  85. package/skills/ultra-research/references/99-synthesis.md +35 -0
  86. package/skills/ultra-review/SKILL.md +57 -73
  87. package/skills/ultra-review/references/review-modes.md +27 -0
  88. package/skills/ultra-review/references/unified-schema.md +25 -0
  89. package/skills/ultra-review/scripts/review_wait.py +40 -3
  90. package/skills/ultra-status/SKILL.md +41 -45
  91. package/skills/ultra-test/SKILL.md +48 -55
  92. package/skills/ultra-verify/SKILL.md +22 -31
  93. package/skills/ultra-verify/references/{confidence-system.md → evidence-status.md} +3 -3
  94. package/skills/ultra-verify/scripts/verify_wait.py +54 -54
  95. package/spec/cli-protocol.md +7 -2
  96. package/spec/mcp-tools.yaml +422 -73
  97. package/spec/schemas/baseline-reconciliation.v1.schema.json +73 -0
  98. package/spec/schemas/delivery-report.v1.schema.json +111 -0
  99. package/spec/schemas/mcp-tools.schema.json +1 -1
  100. package/spec/schemas/state-db.sql +82 -1
  101. package/spec/schemas/tasks.v4.5.schema.json +8 -1
  102. package/spec/schemas/test-report.v1.schema.json +194 -0
  103. package/ultra-tools/cli.cjs +1 -1
  104. package/ultra-tools/commands/migrate.cjs +3 -3
  105. package/ultra-tools/commands/status.cjs +213 -12
  106. package/.ultra-template/delivery-report.json +0 -9
  107. package/.ultra-template/test-report.json +0 -8
  108. package/adapters/_shared/tests/file-ops.test.cjs +0 -54
  109. package/adapters/_shared/tests/frontmatter.test.cjs +0 -47
  110. package/adapters/_shared/tests/handbook.test.cjs +0 -101
  111. package/adapters/_shared/tests/path-rewrite.test.cjs +0 -60
  112. package/adapters/_shared/tests/provenance.test.cjs +0 -133
  113. package/adapters/_shared/tests/resolve-target.test.cjs +0 -75
  114. package/adapters/_shared/tests/runtime-assets.test.cjs +0 -131
  115. package/adapters/_shared/tests/settings-merge.test.cjs +0 -85
  116. package/adapters/_shared/tests/validate.test.cjs +0 -30
  117. package/adapters/tests/claude.test.cjs +0 -137
  118. package/adapters/tests/codex-hook.test.cjs +0 -115
  119. package/adapters/tests/codex.test.cjs +0 -423
  120. package/adapters/tests/kimi-hook.test.cjs +0 -122
  121. package/adapters/tests/kimi.test.cjs +0 -259
  122. package/adapters/tests/opencode.test.cjs +0 -371
  123. package/mcp-server/lib/archive-journal.test.cjs +0 -35
  124. package/mcp-server/lib/baseline-workflow.test.cjs +0 -477
  125. package/mcp-server/lib/change-workflow.test.cjs +0 -971
  126. package/mcp-server/lib/context-spine.test.cjs +0 -93
  127. package/mcp-server/lib/doctor.test.cjs +0 -148
  128. package/mcp-server/lib/llm-client.cjs +0 -157
  129. package/mcp-server/lib/llm-client.test.cjs +0 -156
  130. package/mcp-server/lib/plan-store.test.cjs +0 -132
  131. package/mcp-server/lib/prd-parser.test.cjs +0 -171
  132. package/mcp-server/lib/runtime-state.test.cjs +0 -92
  133. package/mcp-server/lib/spec-learning.test.cjs +0 -67
  134. package/mcp-server/lib/state-db.test.cjs +0 -314
  135. package/mcp-server/lib/task-expander.test.cjs +0 -324
  136. package/mcp-server/lib/topo.test.cjs +0 -158
  137. package/mcp-server/tests/circuit-breaker.test.cjs +0 -125
  138. package/mcp-server/tests/commit-hash-flow.test.cjs +0 -117
  139. package/mcp-server/tests/concurrency-update.test.cjs +0 -96
  140. package/mcp-server/tests/concurrency.test.cjs +0 -112
  141. package/mcp-server/tests/db-ops.test.cjs +0 -121
  142. package/mcp-server/tests/init-project.test.cjs +0 -393
  143. package/mcp-server/tests/migrate.test.cjs +0 -232
  144. package/mcp-server/tests/projector.test.cjs +0 -162
  145. package/mcp-server/tests/server-contract.test.cjs +0 -1471
  146. package/mcp-server/tests/staleness.test.cjs +0 -190
  147. package/mcp-server/tests/state-db.test.cjs +0 -106
  148. package/mcp-server/tests/state-ops.test.cjs +0 -449
  149. package/mcp-server/tests/tagged-tasks.test.cjs +0 -163
  150. package/mcp-server/tests/telemetry.test.cjs +0 -219
  151. package/orchestrator/planner/expand-prompt.cjs +0 -62
  152. package/orchestrator/planner/expand-prompt.test.cjs +0 -52
  153. package/orchestrator/planner/plan-builder.test.cjs +0 -165
  154. package/orchestrator/planner/prd-prompt.cjs +0 -44
  155. package/orchestrator/planner/prd-prompt.test.cjs +0 -30
  156. package/orchestrator/tests/auto-merge.test.cjs +0 -216
  157. package/orchestrator/tests/daemon.test.cjs +0 -311
  158. package/orchestrator/tests/dispatch-rules.test.cjs +0 -124
  159. package/orchestrator/tests/parallel-orchestrator.test.cjs +0 -233
  160. package/orchestrator/tests/phase-8b-gate.test.cjs +0 -183
  161. package/orchestrator/tests/recovery.test.cjs +0 -190
  162. package/orchestrator/tests/session-runner.test.cjs +0 -314
  163. package/orchestrator/tests/skill-miner.test.cjs +0 -147
  164. package/orchestrator/tests/worktree-manager.test.cjs +0 -148
  165. package/skills/ultra-research/references/architecture.md +0 -38
  166. package/skills/ultra-research/references/problem-product.md +0 -39
  167. package/skills/ultra-research/references/quality-delivery.md +0 -34
  168. package/skills/ultra-research/references/synthesis.md +0 -38
  169. package/skills/ultra-research/references/users-scope.md +0 -40
  170. package/ultra-tools/legacy-memory.test.cjs +0 -80
  171. package/ultra-tools/status-command.test.cjs +0 -181
  172. package/ultra-tools/system-command.test.cjs +0 -309
@@ -25,6 +25,7 @@ families:
25
25
  - { name: plan, description: 'execution-plan artifact export and query (D34)', phase: '8a' }
26
26
  - { name: baseline, description: 'project adoption, baseline evidence, convergence, and drift authority', phase: '11' }
27
27
  - { name: change, description: 'continuous post-delivery change lifecycle and convergence', phase: '9' }
28
+ - { name: workflow, description: 'durable cross-stage run position, evidence, outputs, blockers, and recovery', phase: '13' }
28
29
  - { name: system, description: 'read-only diagnostics and explicit backup-first repair', phase: '9' }
29
30
 
30
31
  tools:
@@ -51,6 +52,48 @@ tools:
51
52
  parent_id: { type: string, description: 'Phase 8A.3 parent reference; the child inherits this task change ownership' }
52
53
  tag: { type: string, description: 'git branch tag (Phase 7.2)' }
53
54
  trace_to: { type: string, description: 'spec anchor (e.g. spec/mcp-tools.yaml#task.create)' }
55
+ outcome: { type: string, minLength: 1, description: 'observable result owned by this task' }
56
+ slice_kind: { type: string, enum: [tracer_bullet, expand_contract, integration_checkpoint] }
57
+ public_seam: { type: string, minLength: 1, description: 'public or integration seam exercised by the slice' }
58
+ verification_command: { type: string, minLength: 1, description: 'exact task-level verification command' }
59
+ acceptance:
60
+ type: array
61
+ minItems: 1
62
+ items:
63
+ type: object
64
+ required: [id, criterion, verification]
65
+ additionalProperties: false
66
+ properties:
67
+ id: { type: string, minLength: 1 }
68
+ criterion: { type: string, minLength: 1 }
69
+ verification: { type: string, minLength: 1 }
70
+ context_refs:
71
+ type: array
72
+ minItems: 1
73
+ items:
74
+ type: object
75
+ required: [ref, reason]
76
+ additionalProperties: false
77
+ properties:
78
+ ref: { type: string, minLength: 1 }
79
+ reason: { type: string, minLength: 1 }
80
+ kind: { type: string, enum: [spec, source, test, docs, external], default: source }
81
+ required: { type: boolean, default: true }
82
+ docs_impact:
83
+ type: object
84
+ required: [status, files, rationale]
85
+ additionalProperties: false
86
+ properties:
87
+ status: { type: string, enum: [unknown, required, none] }
88
+ files: { type: array, items: { type: string, minLength: 1 } }
89
+ rationale: { type: ['string', 'null'] }
90
+ ownership:
91
+ type: object
92
+ required: [owner]
93
+ additionalProperties: false
94
+ properties:
95
+ owner: { type: string, minLength: 1 }
96
+ reviewers: { type: array, items: { type: string, minLength: 1 }, default: [] }
54
97
  change_id: { type: string, pattern: '^[a-zA-Z0-9_\-]+$', description: 'active or blocked continuous change unit owning this task; inherited from parent_id when omitted' }
55
98
  output_schema:
56
99
  type: object
@@ -98,6 +141,15 @@ tools:
98
141
  session_id: { type: string }
99
142
  stale: { type: boolean }
100
143
  tag: { type: string }
144
+ trace_to: { type: string }
145
+ outcome: { type: string, minLength: 1 }
146
+ slice_kind: { type: string, enum: [tracer_bullet, expand_contract, integration_checkpoint] }
147
+ public_seam: { type: string, minLength: 1 }
148
+ verification_command: { type: string, minLength: 1 }
149
+ acceptance: { type: array, items: { type: object } }
150
+ context_refs: { type: array, items: { type: object } }
151
+ docs_impact: { type: object }
152
+ ownership: { type: object }
101
153
  completion_commit: { type: string, pattern: '^[0-9a-f]{7,40}$' }
102
154
  change_id: { type: ['string', 'null'], pattern: '^[a-zA-Z0-9_\-]+$' }
103
155
  output_schema:
@@ -114,6 +166,7 @@ tools:
114
166
  - { code: CHANGE_NOT_FOUND, description: 'assigned change does not exist' }
115
167
  - { code: CHANGE_NOT_MUTABLE, description: 'assigned change no longer accepts task updates' }
116
168
  - { code: TASK_CHANGE_OWNERSHIP_MISMATCH, description: 'task ownership conflicts with its parent or children' }
169
+ - { code: TASK_EXECUTION_CONTRACT_INCOMPLETE, description: 'task is not executable until its outcome, seam, checks, evidence context, docs impact, ownership, and traceability are complete' }
117
170
  - { code: LEGACY_STATE_MIGRATION_REQUIRED, description: 'non-empty v4.4 projection must be migrated before state-backed tools can run' }
118
171
  cli_subcommand: task update
119
172
  emits_events: [task_started, task_completed, task_blocked, task_stale_marked]
@@ -131,6 +184,7 @@ tools:
131
184
  properties:
132
185
  status: { type: string, enum: [pending, in_progress, completed, blocked, expanded, any] }
133
186
  tag: { type: string }
187
+ change_id: { type: string, pattern: '^[a-zA-Z0-9_\-]+$' }
134
188
  since: { type: string, format: date-time }
135
189
  limit: { type: integer, minimum: 1, maximum: 1000 }
136
190
  output_schema:
@@ -274,7 +328,7 @@ tools:
274
328
  description: override path to the template root (defaults to bundled templates/.ultra/)
275
329
  output_schema:
276
330
  type: object
277
- required: [created_path, state_db_path, status, mode, baseline, copied_files, repository_profile]
331
+ required: [created_path, state_db_path, status, mode, baseline, copied_files, repository_profile, workflow]
278
332
  additionalProperties: false
279
333
  properties:
280
334
  created_path:
@@ -300,6 +354,9 @@ tools:
300
354
  repository_profile:
301
355
  type: object
302
356
  description: bounded classification evidence used to route greenfield or brownfield adoption
357
+ workflow:
358
+ type: object
359
+ description: durable initialization and research run ids, states, mode, and exact next route
303
360
  backup_path:
304
361
  type: string
305
362
  description: set only when status=overwritten
@@ -321,17 +378,30 @@ tools:
321
378
 
322
379
  - name: task.expand
323
380
  family: task
324
- description: Expand a parent task into N child sub-tasks (Phase 8A).
381
+ description: Validate and atomically persist child tasks derived by the current host from one parent task.
325
382
  phase: '8a'
326
383
  writer_role: mcp
327
384
  input_schema:
328
385
  type: object
329
- required: [id]
386
+ required: [id, children]
330
387
  additionalProperties: false
331
388
  properties:
332
- id: { type: string }
333
- sub_count: { type: integer, minimum: 1, maximum: 16 }
334
- strategy: { type: string, enum: [llm], default: llm }
389
+ id: { type: string }
390
+ children:
391
+ type: array
392
+ minItems: 1
393
+ items:
394
+ type: object
395
+ required: [id, title, type, priority]
396
+ additionalProperties: false
397
+ properties:
398
+ id: { type: string, pattern: '^[a-zA-Z0-9_\-]+$' }
399
+ title: { type: string, minLength: 3, maxLength: 200 }
400
+ type: { type: string, enum: [architecture, feature, bugfix] }
401
+ priority: { type: string, enum: [P0, P1, P2, P3] }
402
+ complexity: { type: integer, minimum: 1, maximum: 10 }
403
+ deps: { type: array, items: { type: string } }
404
+ files_modified: { type: array, items: { type: string } }
335
405
  output_schema:
336
406
  type: object
337
407
  required: [parent_id, children]
@@ -345,21 +415,36 @@ tools:
345
415
  - { code: CHANGE_NOT_FOUND, description: 'the parent task change does not exist' }
346
416
  - { code: CHANGE_NOT_MUTABLE, description: 'the parent task change no longer accepts children' }
347
417
  - { code: BASELINE_NOT_READY, description: 'child creation requires a ready baseline or the parent task to belong to an already-authorized active change' }
418
+ - { code: INVALID_OUTPUT, description: 'the host-derived child task graph is invalid' }
348
419
  cli_subcommand: task expand
349
420
  emits_events: [task_expanded]
350
421
  trace_to: '§7.3, D34'
351
422
 
352
423
  - name: task.parse_prd
353
424
  family: task
354
- description: Parse a PRD document into a task graph (Phase 8A). When dry_run=true the tasks are returned without writing to state.db (supports ultra-plan human gate workflow).
425
+ description: Validate a host-derived PRD task graph and optionally persist it after the Ultra planning approval gate.
355
426
  phase: '8a'
356
427
  writer_role: mcp
357
428
  input_schema:
358
429
  type: object
430
+ required: [tasks]
359
431
  additionalProperties: false
360
432
  properties:
361
- prd_path: { type: string }
362
- prd_text: { type: string }
433
+ tasks:
434
+ type: array
435
+ minItems: 1
436
+ items:
437
+ type: object
438
+ required: [id, title, type, priority]
439
+ additionalProperties: false
440
+ properties:
441
+ id: { type: string, pattern: '^[a-zA-Z0-9_\-]+$' }
442
+ title: { type: string, minLength: 3, maxLength: 200 }
443
+ type: { type: string, enum: [architecture, feature, bugfix] }
444
+ priority: { type: string, enum: [P0, P1, P2, P3] }
445
+ complexity: { type: integer, minimum: 1, maximum: 10 }
446
+ deps: { type: array, items: { type: string } }
447
+ files_modified: { type: array, items: { type: string } }
363
448
  tag: { type: string }
364
449
  change_id: { type: string, pattern: '^[a-zA-Z0-9_\-]+$', description: 'continuous change unit that will own every persisted parsed task' }
365
450
  dry_run: { type: boolean, default: false, description: 'when true, do not persist to state.db — used by ultra-plan gate to preview before approve' }
@@ -371,8 +456,9 @@ tools:
371
456
  tasks: { type: array, items: { type: object } }
372
457
  topo: { type: array, items: { type: array, items: { type: string } } }
373
458
  errors:
374
- - { code: NO_INPUT, description: 'one of prd_path or prd_text required' }
375
- - { code: PARSE_FAILED, description: 'PRD could not be parsed into tasks' }
459
+ - { code: PARSE_FAILED, description: 'the host-derived PRD task graph is invalid' }
460
+ - { code: CYCLE_DETECTED, description: 'the proposed task graph contains a dependency cycle' }
461
+ - { code: CHANGE_REQUIRED, description: 'persisting a parsed task graph requires an owning change_id' }
376
462
  - { code: CHANGE_NOT_FOUND, description: 'assigned change does not exist' }
377
463
  - { code: CHANGE_NOT_MUTABLE, description: 'assigned change no longer accepts tasks' }
378
464
  - { code: BASELINE_NOT_READY, description: 'persisting parsed tasks requires a ready baseline or an already-authorized active change' }
@@ -388,8 +474,12 @@ tools:
388
474
  input_schema:
389
475
  type: object
390
476
  additionalProperties: false
477
+ oneOf:
478
+ - required: [task_ids]
479
+ - required: [change_id]
391
480
  properties:
392
- task_ids: { type: array, items: { type: string } }
481
+ task_ids: { type: array, minItems: 1, uniqueItems: true, items: { type: string } }
482
+ change_id: { type: string, pattern: '^[a-zA-Z0-9_\-]+$' }
393
483
  output_schema:
394
484
  type: object
395
485
  required: [waves]
@@ -399,13 +489,15 @@ tools:
399
489
  cycles: { type: array, items: { type: array, items: { type: string } } }
400
490
  errors:
401
491
  - { code: CYCLE_DETECTED, description: 'dependency graph has cycles' }
492
+ - { code: TASK_NOT_FOUND, description: 'an explicitly requested task does not exist' }
493
+ - { code: CHANGE_NOT_FOUND, description: 'the requested owning change does not exist' }
402
494
  cli_subcommand: task topo
403
495
  emits_events: []
404
496
  trace_to: '§7.3, D34'
405
497
 
406
498
  - name: task.append_event
407
499
  family: task
408
- description: Append a row to events table. Returns assigned id (subscribe cursor).
500
+ description: Append a non-authoritative observation to the event timeline. Lifecycle events are emitted only by their owning mutation tools. Returns the assigned subscribe cursor.
409
501
  phase: '2'
410
502
  writer_role: any
411
503
  input_schema:
@@ -420,35 +512,12 @@ tools:
420
512
  type:
421
513
  type: string
422
514
  enum:
423
- - task_created
424
- - task_started
425
- - task_completed
426
- - task_failed
427
- - task_blocked
428
- - task_expanded
429
- - task_stale_marked
430
- - session_spawned
431
- - session_closed
432
- - session_crashed
433
- - session_orphaned
434
- - session_heartbeat_lost
435
- - spec_changed
436
515
  - context_updated
437
- - plan_approved
438
516
  - commit_pushed
439
- - review_verdict
440
517
  - merge_conflict
441
- - auto_merged
442
518
  - cost_alert
443
519
  - token_alert
444
520
  - circuit_open
445
- - change_created
446
- - change_updated
447
- - change_blocked
448
- - change_converged
449
- - change_archived
450
- - spec_learning_proposed
451
- - spec_learning_resolved
452
521
  payload: { type: object }
453
522
  output_schema:
454
523
  type: object
@@ -930,13 +999,71 @@ tools:
930
999
  writer_role: mcp
931
1000
  input_schema:
932
1001
  type: object
933
- required: [id, title, kind, intent]
1002
+ required: [id, title, kind, intent, contract, classification, research_disposition]
934
1003
  additionalProperties: false
935
1004
  properties:
936
1005
  id: { type: string, pattern: '^[a-zA-Z0-9_\-]+$' }
937
1006
  title: { type: string, minLength: 3 }
938
1007
  kind: { type: string, enum: [quick, standard, major, incident] }
939
1008
  intent: { type: string, minLength: 3 }
1009
+ contract: &change_contract
1010
+ type: object
1011
+ required: [outcome, acceptance, non_goals, public_seams, recovery, unresolved_decisions]
1012
+ additionalProperties: false
1013
+ properties:
1014
+ outcome: { type: string, minLength: 1 }
1015
+ acceptance:
1016
+ type: array
1017
+ minItems: 1
1018
+ items:
1019
+ type: object
1020
+ required: [id, criterion, verification]
1021
+ additionalProperties: false
1022
+ properties:
1023
+ id: { type: string, pattern: '^[a-zA-Z0-9_\-]+$' }
1024
+ criterion: { type: string, minLength: 1 }
1025
+ verification: { type: string, minLength: 1 }
1026
+ non_goals: { type: array, minItems: 1, items: { type: string, minLength: 1 } }
1027
+ public_seams: { type: array, minItems: 1, items: { type: string, minLength: 1 } }
1028
+ recovery:
1029
+ type: object
1030
+ required: [strategy, verification]
1031
+ additionalProperties: false
1032
+ properties:
1033
+ strategy: { type: string, minLength: 1 }
1034
+ verification: { type: string, minLength: 1 }
1035
+ unresolved_decisions:
1036
+ type: array
1037
+ items:
1038
+ type: object
1039
+ required: [id, summary, blocking]
1040
+ additionalProperties: false
1041
+ properties:
1042
+ id: { type: string, minLength: 1 }
1043
+ summary: { type: string, minLength: 1 }
1044
+ blocking: { type: boolean }
1045
+ owner: { type: ['string', 'null'] }
1046
+ classification: &change_classification
1047
+ type: object
1048
+ required: [rationale, risk_flags]
1049
+ additionalProperties: false
1050
+ properties:
1051
+ rationale: { type: string, minLength: 1 }
1052
+ risk_flags:
1053
+ type: array
1054
+ uniqueItems: true
1055
+ items:
1056
+ type: string
1057
+ enum: [public_contract, schema_migration, data_migration, authorization, security, multi_module, external_integration, release_semantics]
1058
+ research_disposition: &change_research_disposition
1059
+ type: object
1060
+ required: [status, mode, selected_steps, rationale]
1061
+ additionalProperties: false
1062
+ properties:
1063
+ status: { type: string, enum: [none, bounded, required] }
1064
+ mode: { type: ['string', 'null'], enum: [product, feature, architecture, custom, null] }
1065
+ selected_steps: { type: array, uniqueItems: true, items: { type: string, minLength: 1 } }
1066
+ rationale: { type: string, minLength: 1 }
940
1067
  base_commit: { type: string, pattern: '^[0-9a-f]{7,40}$' }
941
1068
  baseline_bypass:
942
1069
  type: object
@@ -981,20 +1108,25 @@ tools:
981
1108
  status: { type: string, enum: [available, unavailable, fresh, stale, unknown] }
982
1109
  output_schema:
983
1110
  type: object
984
- required: [change, intent_path, context_manifest_path]
1111
+ required: [change, intent_path, context_manifest_path, workflow]
985
1112
  additionalProperties: false
986
1113
  properties:
987
1114
  change: { type: object }
988
1115
  intent_path: { type: string }
989
1116
  context_manifest_path: { type: string }
1117
+ workflow: { type: object }
990
1118
  errors:
991
1119
  - { code: DUPLICATE_CHANGE_ID, description: 'change id already exists' }
992
1120
  - { code: PROVIDER_CONTENT_FORBIDDEN, description: 'provider payload content must remain external' }
993
1121
  - { code: VALIDATION_ERROR, description: 'change input failed validation' }
994
1122
  - { code: BASELINE_NOT_READY, description: 'ordinary work is blocked until the project baseline is healthy' }
995
1123
  - { code: BASELINE_BYPASS_REQUIRED, description: 'an incident on an unhealthy baseline requires explicit break-glass approval' }
1124
+ - { code: CHANGE_CONTRACT_REQUIRED, description: 'outcome, acceptance, seams, recovery, or decisions are incomplete' }
1125
+ - { code: CHANGE_CLASSIFICATION_REQUIRED, description: 'classification rationale or risk flags are incomplete' }
1126
+ - { code: CHANGE_RESEARCH_DISPOSITION_REQUIRED, description: 'research routing is incomplete or inconsistent' }
1127
+ - { code: CHANGE_PROFILE_ESCALATION_REQUIRED, description: 'quick profile conflicts with material risk or research' }
996
1128
  cli_subcommand: change create
997
- emits_events: [change_created, context_updated]
1129
+ emits_events: [change_created, context_updated, workflow_started, workflow_step_updated]
998
1130
 
999
1131
  - name: change.update
1000
1132
  family: change
@@ -1047,6 +1179,9 @@ tools:
1047
1179
  revision: { type: string }
1048
1180
  indexed_head: { type: string }
1049
1181
  status: { type: string, enum: [available, unavailable, fresh, stale, unknown] }
1182
+ contract: *change_contract
1183
+ classification: *change_classification
1184
+ research_disposition: *change_research_disposition
1050
1185
  output_schema:
1051
1186
  type: object
1052
1187
  required: [ok, change]
@@ -1110,7 +1245,7 @@ tools:
1110
1245
 
1111
1246
  - name: change.context
1112
1247
  family: change
1113
- description: Compile a role-scoped Context Spine manifest with readiness, budget, execution seam, and next-action evidence.
1248
+ description: Compile an immutable role-scoped Context Spine snapshot whose execution seam and next action are derived from authoritative task and workflow state.
1114
1249
  phase: '10'
1115
1250
  writer_role: mcp
1116
1251
  input_schema:
@@ -1122,7 +1257,6 @@ tools:
1122
1257
  task_id: { type: string }
1123
1258
  role: { type: string, enum: [plan, implement, check, review] }
1124
1259
  gate: { type: string, enum: [alignment, planning, implementation, verification, review, convergence, recovery] }
1125
- next_action: { type: string, minLength: 3 }
1126
1260
  spec_refs: { type: array, items: { type: object } }
1127
1261
  context_refs:
1128
1262
  type: array
@@ -1147,11 +1281,7 @@ tools:
1147
1281
  type: object
1148
1282
  additionalProperties: false
1149
1283
  properties:
1150
- slice_kind: { type: string, enum: [tracer_bullet, expand_contract, integration_checkpoint], default: tracer_bullet }
1151
- public_seam: { type: string }
1152
- verification_command: { type: string }
1153
1284
  context_budget_percent: { type: integer, minimum: 1, maximum: 100, default: 40 }
1154
- allowed_paths: { type: array, items: { type: string } }
1155
1285
  provider_refs:
1156
1286
  type: object
1157
1287
  additionalProperties: false
@@ -1191,6 +1321,9 @@ tools:
1191
1321
  - { code: CHANGE_NOT_FOUND, description: 'change id does not exist' }
1192
1322
  - { code: CHANGE_TERMINAL, description: 'terminal change cannot compile a new context' }
1193
1323
  - { code: TASK_NOT_FOUND, description: 'task id is not linked to the change' }
1324
+ - { code: EXECUTION_CONTRACT_CONFLICT, description: 'Prompt input attempted to override the DB-backed task seam or verification command' }
1325
+ - { code: EXECUTION_CONTEXT_REFS_CONFLICT, description: 'Prompt input attempted to override DB-backed task context references' }
1326
+ - { code: CONTEXT_NEXT_ACTION_AUTHORITY_VIOLATION, description: 'next action is derived from workflow and task state and cannot be supplied by Prompt input' }
1194
1327
  - { code: PROVIDER_CONTENT_FORBIDDEN, description: 'provider payload content must remain external' }
1195
1328
  cli_subcommand: change context
1196
1329
  emits_events: [context_updated]
@@ -1263,6 +1396,10 @@ tools:
1263
1396
  candidate_id: { type: string, pattern: '^[a-zA-Z0-9_\-]+$' }
1264
1397
  decision: { type: string, enum: [approve, reject, apply] }
1265
1398
  resolution: { type: string }
1399
+ applied_ref: { type: string, minLength: 3 }
1400
+ before_digest: { type: string, pattern: '^[0-9a-f]{64}$' }
1401
+ after_digest: { type: string, pattern: '^[0-9a-f]{64}$' }
1402
+ apply_evidence: { type: array, minItems: 1, uniqueItems: true, items: { type: string, minLength: 3 } }
1266
1403
  output_schema:
1267
1404
  type: object
1268
1405
  required: [candidate]
@@ -1274,6 +1411,8 @@ tools:
1274
1411
  - { code: CHANGE_NOT_FOUND, description: 'change id does not exist' }
1275
1412
  - { code: LEARNING_NOT_FOUND, description: 'candidate id does not exist for the change' }
1276
1413
  - { code: ILLEGAL_LEARNING_TRANSITION, description: 'candidate state transition is not permitted' }
1414
+ - { code: LEARNING_APPLY_EVIDENCE_REQUIRED, description: 'apply requires exact target, before and after digests, and evidence' }
1415
+ - { code: LEARNING_APPLY_EVIDENCE_MISMATCH, description: 'apply evidence does not match the current target artifact' }
1277
1416
  cli_subcommand: change learning-resolve
1278
1417
  emits_events: [spec_learning_resolved]
1279
1418
 
@@ -1284,34 +1423,10 @@ tools:
1284
1423
  writer_role: mcp
1285
1424
  input_schema:
1286
1425
  type: object
1287
- required: [id, evidence]
1426
+ required: [id]
1288
1427
  additionalProperties: false
1289
1428
  properties:
1290
1429
  id: { type: string }
1291
- evidence:
1292
- type: array
1293
- minItems: 1
1294
- items:
1295
- type: object
1296
- required: [category, status, evidence]
1297
- additionalProperties: false
1298
- properties:
1299
- category: { type: string, enum: [diagnosis, diff, tests, spec, docs, review] }
1300
- status: { type: string, enum: [pass, fail, not_applicable] }
1301
- evidence: { type: string, minLength: 3 }
1302
- axis: { type: string, enum: [spec_fidelity, engineering_standards] }
1303
- seam: { type: string, minLength: 3 }
1304
- signal:
1305
- type: object
1306
- additionalProperties: false
1307
- required: [command, expected_red, observed_red, observed_green, deterministic]
1308
- properties:
1309
- command: { type: string, minLength: 3 }
1310
- expected_red: { type: string, minLength: 3 }
1311
- observed_red: { type: boolean }
1312
- observed_green: { type: boolean }
1313
- deterministic: { type: boolean }
1314
- duration_ms: { type: number, minimum: 0 }
1315
1430
  output_schema:
1316
1431
  type: object
1317
1432
  required: [ready, status, blockers]
@@ -1324,6 +1439,7 @@ tools:
1324
1439
  errors:
1325
1440
  - { code: CHANGE_NOT_FOUND, description: 'change id does not exist' }
1326
1441
  - { code: CHANGE_NOT_CONVERGEABLE, description: 'change lifecycle does not allow convergence' }
1442
+ - { code: CONVERGENCE_EVIDENCE_AUTHORITY_VIOLATION, description: 'Prompt-supplied gate verdicts cannot replace DB-backed workflow evidence' }
1327
1443
  cli_subcommand: change converge
1328
1444
  emits_events: [change_blocked, change_converged]
1329
1445
 
@@ -1334,13 +1450,14 @@ tools:
1334
1450
  writer_role: mcp
1335
1451
  input_schema:
1336
1452
  type: object
1337
- required: [id, summary]
1453
+ required: [id, summary, reconciliation_path]
1338
1454
  additionalProperties: false
1339
1455
  properties:
1340
1456
  id: { type: string }
1341
1457
  summary: { type: string, minLength: 3 }
1342
1458
  baseline_updates: { type: array, items: { type: string } }
1343
1459
  no_baseline_change_reason: { type: string, minLength: 3 }
1460
+ reconciliation_path: { type: string, minLength: 3 }
1344
1461
  output_schema:
1345
1462
  type: object
1346
1463
  required: [change, archive_path]
@@ -1353,10 +1470,236 @@ tools:
1353
1470
  - { code: BASELINE_RECONCILIATION_REQUIRED, description: 'baseline update or explicit no-change reason required' }
1354
1471
  - { code: BASELINE_FILE_MISSING, description: 'a declared baseline update does not exist' }
1355
1472
  - { code: BASELINE_RECONCILIATION_INCOMPLETE, description: 'repository revision or tracked specification digests remain stale after reconciliation' }
1473
+ - { code: BASELINE_RECONCILIATION_MANIFEST_REQUIRED, description: 'a change-bound reconciliation manifest is required' }
1474
+ - { code: BASELINE_RECONCILIATION_MANIFEST_INVALID, description: 'semantic changes, digests, resolutions, or verification are invalid' }
1356
1475
  - { code: ARCHIVE_EXISTS, description: 'archive target already exists' }
1357
1476
  cli_subcommand: change archive
1358
1477
  emits_events: [change_archived]
1359
1478
 
1479
+ # ────────────────────────── workflow family ────────────────────────────
1480
+ - name: workflow.start
1481
+ family: workflow
1482
+ description: Start one durable Ultra workflow run from its canonical step definition. Research defaults to the complete seventeen-step flow and never infers a reduced product posture.
1483
+ phase: '13'
1484
+ writer_role: mcp
1485
+ input_schema:
1486
+ type: object
1487
+ required: [kind, subject]
1488
+ additionalProperties: false
1489
+ properties:
1490
+ id: { type: string, pattern: '^[a-zA-Z0-9_\-]+$' }
1491
+ kind: { type: string, enum: [init, research, plan, change, dev, test, review, deliver] }
1492
+ subject: { type: string, minLength: 3 }
1493
+ mode: { type: string, enum: [full, adoption, product, feature, architecture, custom] }
1494
+ selected_steps: { type: array, uniqueItems: true, items: { type: string } }
1495
+ baseline_id: { type: string }
1496
+ change_id: { type: string }
1497
+ task_id: { type: string }
1498
+ metadata: { type: object }
1499
+ output_schema:
1500
+ type: object
1501
+ required: [workflow]
1502
+ additionalProperties: false
1503
+ properties:
1504
+ workflow: { type: object }
1505
+ errors:
1506
+ - { code: VALIDATION_ERROR, description: 'definition, mode, selection, or linked authority is invalid' }
1507
+ - { code: DUPLICATE_WORKFLOW_ID, description: 'workflow id already exists' }
1508
+ - { code: WORKFLOW_IN_PROGRESS, description: 'the same authority already has an active workflow of this kind' }
1509
+ - { code: WORKFLOW_CHANGE_NOT_FOUND, description: 'the requested change authority does not exist' }
1510
+ - { code: WORKFLOW_CHANGE_RUN_REQUIRED, description: 'change-bound stages require the owning durable change workflow; legacy gaps route through doctor repair' }
1511
+ - { code: WORKFLOW_BASELINE_MISMATCH, description: 'a supplied stage baseline differs from the baseline bound by the owning change workflow' }
1512
+ - { code: WORKFLOW_BASELINE_REQUIRED, description: 'a baseline-free plan is valid only for an approved incident break-glass change' }
1513
+ - { code: WORKFLOW_CHANGE_NOT_MUTABLE, description: 'the owning change does not accept a new workflow of this stage' }
1514
+ - { code: TASK_EXECUTION_CONTRACT_INCOMPLETE, description: 'dev cannot start until the linked task contract is executable' }
1515
+ - { code: TASK_CHANGE_OWNERSHIP_MISMATCH, description: 'linked task and change authority disagree' }
1516
+ cli_subcommand: workflow start
1517
+ emits_events: [workflow_started]
1518
+
1519
+ - name: workflow.get
1520
+ family: workflow
1521
+ description: Read one workflow run with every step, current recovery position, blockers, and output freshness.
1522
+ phase: '13'
1523
+ readonly: true
1524
+ input_schema:
1525
+ type: object
1526
+ required: [id]
1527
+ additionalProperties: false
1528
+ properties:
1529
+ id: { type: string }
1530
+ output_schema:
1531
+ type: object
1532
+ required: [workflow]
1533
+ additionalProperties: false
1534
+ properties:
1535
+ workflow: { type: object }
1536
+ errors:
1537
+ - { code: WORKFLOW_NOT_FOUND, description: 'workflow id does not exist' }
1538
+ cli_subcommand: workflow get
1539
+ emits_events: []
1540
+
1541
+ - name: workflow.list
1542
+ family: workflow
1543
+ description: List workflow runs by phase, state, baseline, change, or task authority.
1544
+ phase: '13'
1545
+ readonly: true
1546
+ input_schema:
1547
+ type: object
1548
+ additionalProperties: false
1549
+ properties:
1550
+ kind: { type: string, enum: [init, research, plan, change, dev, test, review, deliver] }
1551
+ status: { type: string, enum: [active, blocked, ready, completed, cancelled] }
1552
+ baseline_id: { type: string }
1553
+ change_id: { type: string }
1554
+ task_id: { type: string }
1555
+ limit: { type: integer, minimum: 1, maximum: 500, default: 100 }
1556
+ output_schema:
1557
+ type: object
1558
+ required: [workflows, count]
1559
+ additionalProperties: false
1560
+ properties:
1561
+ workflows: { type: array, items: { type: object } }
1562
+ count: { type: integer, minimum: 0 }
1563
+ errors:
1564
+ - { code: STATE_DB_ERROR, description: 'workflow state could not be read' }
1565
+ cli_subcommand: workflow list
1566
+ emits_events: []
1567
+
1568
+ - name: workflow.step
1569
+ family: workflow
1570
+ description: Record one canonical workflow-step transition with bounded evidence, durable output digests, decisions, or blockers.
1571
+ phase: '13'
1572
+ writer_role: mcp
1573
+ input_schema:
1574
+ type: object
1575
+ required: [id, step_id, status]
1576
+ additionalProperties: false
1577
+ properties:
1578
+ id: { type: string }
1579
+ step_id: { type: string }
1580
+ status: { type: string, enum: [in_progress, completed, skipped, blocked] }
1581
+ evidence:
1582
+ type: array
1583
+ items:
1584
+ type: object
1585
+ required: [kind, ref, summary]
1586
+ additionalProperties: false
1587
+ properties:
1588
+ kind: { type: string, minLength: 1 }
1589
+ ref: { type: string, minLength: 1 }
1590
+ summary: { type: string, minLength: 1 }
1591
+ outputs:
1592
+ type: array
1593
+ items:
1594
+ type: object
1595
+ required: [path, kind]
1596
+ additionalProperties: false
1597
+ properties:
1598
+ path: { type: string, minLength: 1 }
1599
+ kind: { type: string, minLength: 1 }
1600
+ decisions: { type: array, items: { type: object } }
1601
+ semantic_records:
1602
+ type: array
1603
+ items:
1604
+ type: object
1605
+ required: [id, kind, status, summary, source_ref, evidence_refs, attributes, links]
1606
+ additionalProperties: false
1607
+ properties:
1608
+ id: { type: string, pattern: '^[a-zA-Z0-9_\-]+$' }
1609
+ kind: { type: string, minLength: 1 }
1610
+ status: { type: string, enum: [observed, verified, decided, accepted, unknown, not_applicable] }
1611
+ summary: { type: string, minLength: 1 }
1612
+ source_ref: { type: string, minLength: 3 }
1613
+ evidence_refs: { type: array, minItems: 1, items: { type: string, minLength: 1 } }
1614
+ attributes: { type: object }
1615
+ links:
1616
+ type: array
1617
+ items:
1618
+ type: object
1619
+ required: [relation, target]
1620
+ additionalProperties: false
1621
+ properties:
1622
+ relation: { type: string, minLength: 1 }
1623
+ target: { type: string, minLength: 1 }
1624
+ blockers: { type: array, uniqueItems: true, items: { type: string, minLength: 1 } }
1625
+ output_schema:
1626
+ type: object
1627
+ required: [workflow]
1628
+ additionalProperties: false
1629
+ properties:
1630
+ workflow: { type: object }
1631
+ errors:
1632
+ - { code: WORKFLOW_NOT_FOUND, description: 'workflow id does not exist' }
1633
+ - { code: WORKFLOW_STEP_NOT_FOUND, description: 'step is not part of the canonical workflow' }
1634
+ - { code: WORKFLOW_STEP_OUT_OF_ORDER, description: 'an earlier selected step remains incomplete' }
1635
+ - { code: WORKFLOW_EVIDENCE_REQUIRED, description: 'the step cannot complete without evidence' }
1636
+ - { code: WORKFLOW_OUTPUT_REQUIRED, description: 'the step cannot complete without a durable output' }
1637
+ - { code: WORKFLOW_OUTPUT_MISSING, description: 'a declared output file is missing' }
1638
+ - { code: WORKFLOW_RESEARCH_REPORT_REQUIRED, description: 'a research step requires its immutable workflow-and-step-bound report path' }
1639
+ - { code: WORKFLOW_RESEARCH_REPORT_INVALID, description: 'the research report is missing its required evidence structure' }
1640
+ - { code: WORKFLOW_RESEARCH_SYNTHESIS_INCOMPLETE, description: 'full or adoption synthesis did not bind all baseline specifications and the distillate' }
1641
+ - { code: WORKFLOW_SEMANTIC_RECORDS_REQUIRED, description: 'a research step did not persist typed semantic results' }
1642
+ - { code: WORKFLOW_SEMANTIC_RECORD_INVALID, description: 'a semantic record does not satisfy its step contract' }
1643
+ - { code: WORKFLOW_SYNTHESIS_TRACE_INVALID, description: 'synthesis references missing research semantic records' }
1644
+ - { code: WORKFLOW_BLOCKER_REQUIRED, description: 'blocked state requires a specific blocker code' }
1645
+ - { code: WORKFLOW_CONTEXT_OUTPUT_REQUIRED, description: 'the stage requires its immutable Context Manifest v2 output' }
1646
+ - { code: WORKFLOW_CONTEXT_MISMATCH, description: 'the context role, gate, change, task, or readiness does not match the stage' }
1647
+ - { code: WORKFLOW_CONTEXT_AUTHORITY_MISMATCH, description: 'the context artifact does not match its DB snapshot row' }
1648
+ - { code: WORKFLOW_CONTEXT_STALE, description: 'the context artifact no longer matches the current checkout' }
1649
+ - { code: WORKFLOW_RELEASE_AUTHORIZATION_INVALID, description: 'release-if-authorized requires one complete durable owner decision' }
1650
+ cli_subcommand: workflow step
1651
+ emits_events: [workflow_step_updated, workflow_blocked]
1652
+
1653
+ - name: workflow.complete
1654
+ family: workflow
1655
+ description: Complete a ready workflow only when every selected step is complete and every recorded output digest remains current.
1656
+ phase: '13'
1657
+ writer_role: mcp
1658
+ input_schema:
1659
+ type: object
1660
+ required: [id]
1661
+ additionalProperties: false
1662
+ properties:
1663
+ id: { type: string }
1664
+ approval:
1665
+ type: object
1666
+ required: [approved_by, approval_note]
1667
+ additionalProperties: false
1668
+ properties:
1669
+ approved_by: { type: string, minLength: 1 }
1670
+ approval_note: { type: string, minLength: 3 }
1671
+ approved_at: { type: string, format: date-time }
1672
+ output_schema:
1673
+ type: object
1674
+ required: [workflow]
1675
+ additionalProperties: false
1676
+ properties:
1677
+ workflow: { type: object }
1678
+ errors:
1679
+ - { code: WORKFLOW_NOT_FOUND, description: 'workflow id does not exist' }
1680
+ - { code: WORKFLOW_NOT_READY, description: 'selected steps or blockers remain incomplete' }
1681
+ - { code: WORKFLOW_OUTPUT_STALE, description: 'a recorded output changed or disappeared' }
1682
+ - { code: WORKFLOW_TASKS_REQUIRED, description: 'plan completion requires a non-empty authoritative task set' }
1683
+ - { code: TASK_EXECUTION_CONTRACT_INCOMPLETE, description: 'one or more planned tasks lack an executable contract' }
1684
+ - { code: TASK_DEPENDENCY_MISSING, description: 'a planned dependency does not exist' }
1685
+ - { code: TASK_DEPENDENCY_CYCLE, description: 'the planned task graph contains a cycle' }
1686
+ - { code: WORKFLOW_TASK_NOT_COMPLETED, description: 'dev convergence requires its task to be completed' }
1687
+ - { code: WORKFLOW_APPROVAL_REQUIRED, description: 'plan convergence requires explicit approved_by and approval_note fields' }
1688
+ - { code: WORKFLOW_SUMMARY_AUTHORITY_VIOLATION, description: 'Prompt summary fields are not allowed to replace DB-derived gate evidence or the complete change task set' }
1689
+ - { code: WORKFLOW_APPROVAL_AUTHORITY_VIOLATION, description: 'only the plan workflow accepts completion approval' }
1690
+ - { code: WORKFLOW_GATE_MISSING, description: 'a required completed dev, test, or review gate is missing' }
1691
+ - { code: WORKFLOW_GATE_STALE, description: 'a required gate no longer matches its task contract or commit ancestry' }
1692
+ - { code: WORKFLOW_REPORT_INVALID, description: 'a required report is malformed or incomplete' }
1693
+ - { code: WORKFLOW_REPORT_CONTEXT_MISMATCH, description: 'a report is not bound to the recorded stage context digest' }
1694
+ - { code: WORKFLOW_REPORT_REVISION_STALE, description: 'a report does not match the current full Git HEAD' }
1695
+ - { code: WORKFLOW_REPORT_WORKTREE_STALE, description: 'a report does not match the current worktree digest' }
1696
+ - { code: WORKFLOW_REVIEW_NOT_APPROVED, description: 'both independent review axes must pass' }
1697
+ - { code: WORKFLOW_TEST_NOT_PASSED, description: 'the current change-level test gate did not pass' }
1698
+ - { code: WORKFLOW_CHANGE_NOT_ARCHIVED, description: 'delivery completion requires an archived change' }
1699
+ - { code: WORKFLOW_RELEASE_AUTHORITY_MISMATCH, description: 'delivery release claims differ from the durable owner authorization decision' }
1700
+ cli_subcommand: workflow complete
1701
+ emits_events: [workflow_completed, plan_approved]
1702
+
1360
1703
  # ────────────────────────── system family ──────────────────────────────
1361
1704
  - name: system.doctor
1362
1705
  family: system
@@ -1392,10 +1735,11 @@ tools:
1392
1735
  writer_role: mcp
1393
1736
  input_schema:
1394
1737
  type: object
1395
- required: [out_path]
1738
+ required: [change_id, out_path]
1396
1739
  additionalProperties: false
1397
1740
  properties:
1398
1741
  format: { type: string, enum: [json, md], default: json }
1742
+ change_id: { type: string, pattern: '^[a-zA-Z0-9_\-]+$' }
1399
1743
  out_path: { type: string }
1400
1744
  tag: { type: string }
1401
1745
  output_schema:
@@ -1407,9 +1751,11 @@ tools:
1407
1751
  wave_count: { type: integer, minimum: 0 }
1408
1752
  errors:
1409
1753
  - { code: NO_TASKS, description: 'no tasks to plan' }
1754
+ - { code: CHANGE_NOT_FOUND, description: 'owning change does not exist' }
1755
+ - { code: CHANGE_NOT_MUTABLE, description: 'owning change no longer accepts planning output' }
1410
1756
  - { code: WRITE_FAILED, description: 'cannot write plan file' }
1411
1757
  cli_subcommand: plan export
1412
- emits_events: [plan_approved]
1758
+ emits_events: [plan_exported]
1413
1759
  trace_to: '§7.3, D34'
1414
1760
 
1415
1761
  - name: plan.get
@@ -1419,8 +1765,10 @@ tools:
1419
1765
  readonly: true
1420
1766
  input_schema:
1421
1767
  type: object
1768
+ required: [change_id]
1422
1769
  additionalProperties: false
1423
1770
  properties:
1771
+ change_id: { type: string, pattern: '^[a-zA-Z0-9_\-]+$' }
1424
1772
  section: { type: string, enum: [tasks, topo, conflicts, all], default: all }
1425
1773
  output_schema:
1426
1774
  type: object
@@ -1430,6 +1778,7 @@ tools:
1430
1778
  plan: { type: object }
1431
1779
  errors:
1432
1780
  - { code: NO_PLAN, description: 'no plan has been computed yet' }
1781
+ - { code: PLAN_CHANGE_MISMATCH, description: 'current plan artifact belongs to another change' }
1433
1782
  cli_subcommand: plan get
1434
1783
  emits_events: []
1435
1784
  trace_to: '§7.3, D34'