ultra-builder-pro-cli 0.14.0 → 0.16.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 (163) 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 +77 -1
  8. package/README.md +46 -24
  9. package/adapters/_shared/codex-assets.cjs +6 -2
  10. package/adapters/_shared/file-ops.cjs +6 -2
  11. package/adapters/_shared/handbook.cjs +2 -1
  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 +3 -2
  16. package/agents/review-coordinator.md +9 -6
  17. package/commands/ultra-change.md +1 -1
  18. package/commands/ultra-plan.md +1 -1
  19. package/commands/ultra-research.md +1 -1
  20. package/commands/ultra-think.md +2 -2
  21. package/docs/AGENT-CONTEXT.md +43 -19
  22. package/docs/ARCHITECTURE.md +54 -13
  23. package/docs/PLAN.zh-CN.md +4 -2
  24. package/docs/ROADMAP.md +10 -4
  25. package/docs/RUNTIME-COMPAT-MATRIX.md +4 -4
  26. package/docs/STATE-DB-ACCESS-POLICY.md +33 -29
  27. package/docs/USER-HANDBOOK-CONTRACT.md +8 -2
  28. package/docs/WORKFLOW-LIFECYCLE.md +342 -0
  29. package/hooks/README.md +6 -1
  30. package/hooks/health_check.py +12 -3
  31. package/hooks/subagent_tracker.py +52 -77
  32. package/mcp-server/hook-event.cjs +34 -0
  33. package/mcp-server/lib/archive-journal.cjs +17 -5
  34. package/mcp-server/lib/baseline-workflow.cjs +158 -18
  35. package/mcp-server/lib/change-workflow.cjs +598 -85
  36. package/mcp-server/lib/context-spine.cjs +305 -25
  37. package/mcp-server/lib/decision-dialogue.cjs +713 -0
  38. package/mcp-server/lib/doctor.cjs +42 -3
  39. package/mcp-server/lib/init-project.cjs +210 -16
  40. package/mcp-server/lib/plan-store.cjs +4 -1
  41. package/mcp-server/lib/pricing.cjs +7 -10
  42. package/mcp-server/lib/project-breadcrumb.cjs +15 -0
  43. package/mcp-server/lib/projector.cjs +57 -3
  44. package/mcp-server/lib/spec-learning.cjs +79 -2
  45. package/mcp-server/lib/state-db.cjs +168 -8
  46. package/mcp-server/lib/state-ops.cjs +160 -9
  47. package/mcp-server/lib/workflow-state.cjs +2305 -0
  48. package/mcp-server/server.cjs +215 -15
  49. package/orchestrator/daemon.cjs +1 -2
  50. package/orchestrator/dispatch-rules.cjs +5 -31
  51. package/orchestrator/planner/plan-builder.cjs +21 -12
  52. package/package.json +13 -3
  53. package/skills/ultra-change/SKILL.md +94 -80
  54. package/skills/ultra-change/references/change-contract.md +36 -0
  55. package/skills/ultra-deliver/SKILL.md +76 -79
  56. package/skills/ultra-deliver/references/baseline-reconciliation.md +20 -0
  57. package/skills/ultra-dev/SKILL.md +62 -59
  58. package/skills/ultra-doctor/SKILL.md +61 -82
  59. package/skills/ultra-init/SKILL.md +101 -103
  60. package/skills/ultra-init/references/brownfield-adoption.md +2 -2
  61. package/skills/ultra-plan/SKILL.md +99 -85
  62. package/skills/ultra-plan/references/semantic-preflight.md +18 -0
  63. package/skills/ultra-research/SKILL.md +102 -60
  64. package/skills/ultra-research/references/00-problem-validation.md +36 -0
  65. package/skills/ultra-research/references/01-opportunity-discovery.md +33 -0
  66. package/skills/ultra-research/references/02-market-assessment.md +30 -0
  67. package/skills/ultra-research/references/03-competitive-landscape.md +31 -0
  68. package/skills/ultra-research/references/04-product-strategy.md +32 -0
  69. package/skills/ultra-research/references/05-assumptions-validation.md +31 -0
  70. package/skills/ultra-research/references/10-user-personas.md +29 -0
  71. package/skills/ultra-research/references/11-user-scenarios.md +28 -0
  72. package/skills/ultra-research/references/20-user-stories.md +30 -0
  73. package/skills/ultra-research/references/21-features-scope.md +29 -0
  74. package/skills/ultra-research/references/22-success-metrics.md +28 -0
  75. package/skills/ultra-research/references/30-architecture-context.md +30 -0
  76. package/skills/ultra-research/references/31-solution-strategy.md +28 -0
  77. package/skills/ultra-research/references/32-building-blocks.md +28 -0
  78. package/skills/ultra-research/references/40-deployment.md +29 -0
  79. package/skills/ultra-research/references/41-quality-risks.md +28 -0
  80. package/skills/ultra-research/references/99-synthesis.md +35 -0
  81. package/skills/ultra-review/SKILL.md +63 -73
  82. package/skills/ultra-review/references/review-modes.md +27 -0
  83. package/skills/ultra-review/references/unified-schema.md +25 -0
  84. package/skills/ultra-review/scripts/review_wait.py +40 -3
  85. package/skills/ultra-status/SKILL.md +41 -41
  86. package/skills/ultra-test/SKILL.md +54 -55
  87. package/skills/ultra-think/SKILL.md +26 -12
  88. package/skills/ultra-think/references/decision-dialogue.md +130 -0
  89. package/skills/ultra-verify/SKILL.md +1 -1
  90. package/skills/ultra-verify/references/{confidence-system.md → evidence-status.md} +3 -3
  91. package/spec/cli-protocol.md +17 -3
  92. package/spec/mcp-tools.yaml +683 -64
  93. package/spec/schemas/baseline-reconciliation.v1.schema.json +73 -0
  94. package/spec/schemas/delivery-report.v1.schema.json +111 -0
  95. package/spec/schemas/mcp-tools.schema.json +1 -1
  96. package/spec/schemas/state-db.sql +140 -1
  97. package/spec/schemas/tasks.v4.5.schema.json +8 -1
  98. package/spec/schemas/test-report.v1.schema.json +194 -0
  99. package/ultra-tools/cli.cjs +1 -1
  100. package/ultra-tools/commands/migrate.cjs +3 -3
  101. package/ultra-tools/commands/status.cjs +228 -12
  102. package/.ultra-template/delivery-report.json +0 -9
  103. package/.ultra-template/test-report.json +0 -8
  104. package/adapters/_shared/tests/file-ops.test.cjs +0 -54
  105. package/adapters/_shared/tests/frontmatter.test.cjs +0 -47
  106. package/adapters/_shared/tests/handbook.test.cjs +0 -101
  107. package/adapters/_shared/tests/path-rewrite.test.cjs +0 -60
  108. package/adapters/_shared/tests/provenance.test.cjs +0 -133
  109. package/adapters/_shared/tests/resolve-target.test.cjs +0 -75
  110. package/adapters/_shared/tests/runtime-assets.test.cjs +0 -149
  111. package/adapters/_shared/tests/settings-merge.test.cjs +0 -85
  112. package/adapters/_shared/tests/validate.test.cjs +0 -30
  113. package/adapters/tests/claude.test.cjs +0 -138
  114. package/adapters/tests/codex-hook.test.cjs +0 -142
  115. package/adapters/tests/codex.test.cjs +0 -430
  116. package/adapters/tests/kimi-hook.test.cjs +0 -149
  117. package/adapters/tests/kimi.test.cjs +0 -259
  118. package/adapters/tests/opencode.test.cjs +0 -357
  119. package/mcp-server/lib/archive-journal.test.cjs +0 -35
  120. package/mcp-server/lib/baseline-workflow.test.cjs +0 -477
  121. package/mcp-server/lib/change-workflow.test.cjs +0 -971
  122. package/mcp-server/lib/context-spine.test.cjs +0 -93
  123. package/mcp-server/lib/doctor.test.cjs +0 -148
  124. package/mcp-server/lib/plan-store.test.cjs +0 -132
  125. package/mcp-server/lib/prd-parser.test.cjs +0 -82
  126. package/mcp-server/lib/project-breadcrumb.test.cjs +0 -112
  127. package/mcp-server/lib/runtime-state.test.cjs +0 -92
  128. package/mcp-server/lib/spec-learning.test.cjs +0 -67
  129. package/mcp-server/lib/state-db.test.cjs +0 -314
  130. package/mcp-server/lib/task-expander.test.cjs +0 -169
  131. package/mcp-server/lib/topo.test.cjs +0 -158
  132. package/mcp-server/tests/circuit-breaker.test.cjs +0 -125
  133. package/mcp-server/tests/commit-hash-flow.test.cjs +0 -117
  134. package/mcp-server/tests/concurrency-update.test.cjs +0 -96
  135. package/mcp-server/tests/concurrency.test.cjs +0 -112
  136. package/mcp-server/tests/db-ops.test.cjs +0 -121
  137. package/mcp-server/tests/init-project.test.cjs +0 -393
  138. package/mcp-server/tests/migrate.test.cjs +0 -232
  139. package/mcp-server/tests/projector.test.cjs +0 -162
  140. package/mcp-server/tests/server-contract.test.cjs +0 -1467
  141. package/mcp-server/tests/staleness.test.cjs +0 -190
  142. package/mcp-server/tests/state-db.test.cjs +0 -106
  143. package/mcp-server/tests/state-ops.test.cjs +0 -449
  144. package/mcp-server/tests/tagged-tasks.test.cjs +0 -163
  145. package/mcp-server/tests/telemetry.test.cjs +0 -219
  146. package/orchestrator/planner/plan-builder.test.cjs +0 -165
  147. package/orchestrator/tests/auto-merge.test.cjs +0 -216
  148. package/orchestrator/tests/daemon.test.cjs +0 -311
  149. package/orchestrator/tests/dispatch-rules.test.cjs +0 -124
  150. package/orchestrator/tests/parallel-orchestrator.test.cjs +0 -233
  151. package/orchestrator/tests/phase-8b-gate.test.cjs +0 -183
  152. package/orchestrator/tests/recovery.test.cjs +0 -190
  153. package/orchestrator/tests/session-runner.test.cjs +0 -314
  154. package/orchestrator/tests/skill-miner.test.cjs +0 -147
  155. package/orchestrator/tests/worktree-manager.test.cjs +0 -148
  156. package/skills/ultra-research/references/architecture.md +0 -38
  157. package/skills/ultra-research/references/problem-product.md +0 -39
  158. package/skills/ultra-research/references/quality-delivery.md +0 -34
  159. package/skills/ultra-research/references/synthesis.md +0 -38
  160. package/skills/ultra-research/references/users-scope.md +0 -40
  161. package/ultra-tools/legacy-memory.test.cjs +0 -80
  162. package/ultra-tools/status-command.test.cjs +0 -181
  163. package/ultra-tools/system-command.test.cjs +0 -309
@@ -3,7 +3,7 @@
3
3
  # Validated by spec/schemas/mcp-tools.schema.json (run `npm run test:spec`).
4
4
  # Trace: PLAN §7.3, decisions D12 / D29 / D31-D34.
5
5
 
6
- version: '1.2'
6
+ version: '1.3'
7
7
 
8
8
  info:
9
9
  title: Ultra Builder Pro MCP tool contracts
@@ -25,6 +25,8 @@ 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: decision, description: 'durable owner-agent alignment, one-question presentation, and approved checkpoints', phase: '16' }
29
+ - { name: workflow, description: 'durable cross-stage run position, evidence, outputs, blockers, and recovery', phase: '13' }
28
30
  - { name: system, description: 'read-only diagnostics and explicit backup-first repair', phase: '9' }
29
31
 
30
32
  tools:
@@ -51,6 +53,48 @@ tools:
51
53
  parent_id: { type: string, description: 'Phase 8A.3 parent reference; the child inherits this task change ownership' }
52
54
  tag: { type: string, description: 'git branch tag (Phase 7.2)' }
53
55
  trace_to: { type: string, description: 'spec anchor (e.g. spec/mcp-tools.yaml#task.create)' }
56
+ outcome: { type: string, minLength: 1, description: 'observable result owned by this task' }
57
+ slice_kind: { type: string, enum: [tracer_bullet, expand_contract, integration_checkpoint] }
58
+ public_seam: { type: string, minLength: 1, description: 'public or integration seam exercised by the slice' }
59
+ verification_command: { type: string, minLength: 1, description: 'exact task-level verification command' }
60
+ acceptance:
61
+ type: array
62
+ minItems: 1
63
+ items:
64
+ type: object
65
+ required: [id, criterion, verification]
66
+ additionalProperties: false
67
+ properties:
68
+ id: { type: string, minLength: 1 }
69
+ criterion: { type: string, minLength: 1 }
70
+ verification: { type: string, minLength: 1 }
71
+ context_refs:
72
+ type: array
73
+ minItems: 1
74
+ items:
75
+ type: object
76
+ required: [ref, reason]
77
+ additionalProperties: false
78
+ properties:
79
+ ref: { type: string, minLength: 1 }
80
+ reason: { type: string, minLength: 1 }
81
+ kind: { type: string, enum: [spec, source, test, docs, external], default: source }
82
+ required: { type: boolean, default: true }
83
+ docs_impact:
84
+ type: object
85
+ required: [status, files, rationale]
86
+ additionalProperties: false
87
+ properties:
88
+ status: { type: string, enum: [unknown, required, none] }
89
+ files: { type: array, items: { type: string, minLength: 1 } }
90
+ rationale: { type: ['string', 'null'] }
91
+ ownership:
92
+ type: object
93
+ required: [owner]
94
+ additionalProperties: false
95
+ properties:
96
+ owner: { type: string, minLength: 1 }
97
+ reviewers: { type: array, items: { type: string, minLength: 1 }, default: [] }
54
98
  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
99
  output_schema:
56
100
  type: object
@@ -98,6 +142,15 @@ tools:
98
142
  session_id: { type: string }
99
143
  stale: { type: boolean }
100
144
  tag: { type: string }
145
+ trace_to: { type: string }
146
+ outcome: { type: string, minLength: 1 }
147
+ slice_kind: { type: string, enum: [tracer_bullet, expand_contract, integration_checkpoint] }
148
+ public_seam: { type: string, minLength: 1 }
149
+ verification_command: { type: string, minLength: 1 }
150
+ acceptance: { type: array, items: { type: object } }
151
+ context_refs: { type: array, items: { type: object } }
152
+ docs_impact: { type: object }
153
+ ownership: { type: object }
101
154
  completion_commit: { type: string, pattern: '^[0-9a-f]{7,40}$' }
102
155
  change_id: { type: ['string', 'null'], pattern: '^[a-zA-Z0-9_\-]+$' }
103
156
  output_schema:
@@ -114,6 +167,7 @@ tools:
114
167
  - { code: CHANGE_NOT_FOUND, description: 'assigned change does not exist' }
115
168
  - { code: CHANGE_NOT_MUTABLE, description: 'assigned change no longer accepts task updates' }
116
169
  - { code: TASK_CHANGE_OWNERSHIP_MISMATCH, description: 'task ownership conflicts with its parent or children' }
170
+ - { 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
171
  - { code: LEGACY_STATE_MIGRATION_REQUIRED, description: 'non-empty v4.4 projection must be migrated before state-backed tools can run' }
118
172
  cli_subcommand: task update
119
173
  emits_events: [task_started, task_completed, task_blocked, task_stale_marked]
@@ -131,6 +185,7 @@ tools:
131
185
  properties:
132
186
  status: { type: string, enum: [pending, in_progress, completed, blocked, expanded, any] }
133
187
  tag: { type: string }
188
+ change_id: { type: string, pattern: '^[a-zA-Z0-9_\-]+$' }
134
189
  since: { type: string, format: date-time }
135
190
  limit: { type: integer, minimum: 1, maximum: 1000 }
136
191
  output_schema:
@@ -274,7 +329,7 @@ tools:
274
329
  description: override path to the template root (defaults to bundled templates/.ultra/)
275
330
  output_schema:
276
331
  type: object
277
- required: [created_path, state_db_path, status, mode, baseline, copied_files, repository_profile]
332
+ required: [created_path, state_db_path, status, mode, baseline, copied_files, repository_profile, workflow]
278
333
  additionalProperties: false
279
334
  properties:
280
335
  created_path:
@@ -300,6 +355,9 @@ tools:
300
355
  repository_profile:
301
356
  type: object
302
357
  description: bounded classification evidence used to route greenfield or brownfield adoption
358
+ workflow:
359
+ type: object
360
+ description: durable initialization and research run ids, states, mode, and exact next route
303
361
  backup_path:
304
362
  type: string
305
363
  description: set only when status=overwritten
@@ -401,6 +459,7 @@ tools:
401
459
  errors:
402
460
  - { code: PARSE_FAILED, description: 'the host-derived PRD task graph is invalid' }
403
461
  - { code: CYCLE_DETECTED, description: 'the proposed task graph contains a dependency cycle' }
462
+ - { code: CHANGE_REQUIRED, description: 'persisting a parsed task graph requires an owning change_id' }
404
463
  - { code: CHANGE_NOT_FOUND, description: 'assigned change does not exist' }
405
464
  - { code: CHANGE_NOT_MUTABLE, description: 'assigned change no longer accepts tasks' }
406
465
  - { code: BASELINE_NOT_READY, description: 'persisting parsed tasks requires a ready baseline or an already-authorized active change' }
@@ -416,8 +475,12 @@ tools:
416
475
  input_schema:
417
476
  type: object
418
477
  additionalProperties: false
478
+ oneOf:
479
+ - required: [task_ids]
480
+ - required: [change_id]
419
481
  properties:
420
- task_ids: { type: array, items: { type: string } }
482
+ task_ids: { type: array, minItems: 1, uniqueItems: true, items: { type: string } }
483
+ change_id: { type: string, pattern: '^[a-zA-Z0-9_\-]+$' }
421
484
  output_schema:
422
485
  type: object
423
486
  required: [waves]
@@ -427,13 +490,15 @@ tools:
427
490
  cycles: { type: array, items: { type: array, items: { type: string } } }
428
491
  errors:
429
492
  - { code: CYCLE_DETECTED, description: 'dependency graph has cycles' }
493
+ - { code: TASK_NOT_FOUND, description: 'an explicitly requested task does not exist' }
494
+ - { code: CHANGE_NOT_FOUND, description: 'the requested owning change does not exist' }
430
495
  cli_subcommand: task topo
431
496
  emits_events: []
432
497
  trace_to: '§7.3, D34'
433
498
 
434
499
  - name: task.append_event
435
500
  family: task
436
- description: Append a row to events table. Returns assigned id (subscribe cursor).
501
+ 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.
437
502
  phase: '2'
438
503
  writer_role: any
439
504
  input_schema:
@@ -448,35 +513,12 @@ tools:
448
513
  type:
449
514
  type: string
450
515
  enum:
451
- - task_created
452
- - task_started
453
- - task_completed
454
- - task_failed
455
- - task_blocked
456
- - task_expanded
457
- - task_stale_marked
458
- - session_spawned
459
- - session_closed
460
- - session_crashed
461
- - session_orphaned
462
- - session_heartbeat_lost
463
- - spec_changed
464
516
  - context_updated
465
- - plan_approved
466
517
  - commit_pushed
467
- - review_verdict
468
518
  - merge_conflict
469
- - auto_merged
470
519
  - cost_alert
471
520
  - token_alert
472
521
  - circuit_open
473
- - change_created
474
- - change_updated
475
- - change_blocked
476
- - change_converged
477
- - change_archived
478
- - spec_learning_proposed
479
- - spec_learning_resolved
480
522
  payload: { type: object }
481
523
  output_schema:
482
524
  type: object
@@ -958,13 +1000,72 @@ tools:
958
1000
  writer_role: mcp
959
1001
  input_schema:
960
1002
  type: object
961
- required: [id, title, kind, intent]
1003
+ required: [id, title, kind, intent, contract, classification, research_disposition]
962
1004
  additionalProperties: false
963
1005
  properties:
964
1006
  id: { type: string, pattern: '^[a-zA-Z0-9_\-]+$' }
965
1007
  title: { type: string, minLength: 3 }
966
1008
  kind: { type: string, enum: [quick, standard, major, incident] }
967
1009
  intent: { type: string, minLength: 3 }
1010
+ contract: &change_contract
1011
+ type: object
1012
+ required: [outcome, acceptance, non_goals, public_seams, recovery, unresolved_decisions]
1013
+ additionalProperties: false
1014
+ properties:
1015
+ outcome: { type: string, minLength: 1 }
1016
+ acceptance:
1017
+ type: array
1018
+ minItems: 1
1019
+ items:
1020
+ type: object
1021
+ required: [id, criterion, verification]
1022
+ additionalProperties: false
1023
+ properties:
1024
+ id: { type: string, pattern: '^[a-zA-Z0-9_\-]+$' }
1025
+ criterion: { type: string, minLength: 1 }
1026
+ verification: { type: string, minLength: 1 }
1027
+ non_goals: { type: array, minItems: 1, items: { type: string, minLength: 1 } }
1028
+ public_seams: { type: array, minItems: 1, items: { type: string, minLength: 1 } }
1029
+ recovery:
1030
+ type: object
1031
+ required: [strategy, verification]
1032
+ additionalProperties: false
1033
+ properties:
1034
+ strategy: { type: string, minLength: 1 }
1035
+ verification: { type: string, minLength: 1 }
1036
+ unresolved_decisions:
1037
+ type: array
1038
+ items:
1039
+ type: object
1040
+ required: [id, summary, blocking]
1041
+ additionalProperties: false
1042
+ properties:
1043
+ id: { type: string, minLength: 1 }
1044
+ summary: { type: string, minLength: 1 }
1045
+ blocking: { type: boolean }
1046
+ owner: { type: ['string', 'null'] }
1047
+ classification: &change_classification
1048
+ type: object
1049
+ required: [rationale, risk_flags]
1050
+ additionalProperties: false
1051
+ properties:
1052
+ rationale: { type: string, minLength: 1 }
1053
+ risk_flags:
1054
+ type: array
1055
+ uniqueItems: true
1056
+ items:
1057
+ type: string
1058
+ enum: [public_contract, schema_migration, data_migration, authorization, security, multi_module, external_integration, release_semantics]
1059
+ research_disposition: &change_research_disposition
1060
+ type: object
1061
+ required: [status, mode, selected_steps, rationale]
1062
+ additionalProperties: false
1063
+ properties:
1064
+ status: { type: string, enum: [none, bounded, required] }
1065
+ mode: { type: ['string', 'null'], enum: [product, feature, architecture, custom, null] }
1066
+ selected_steps: { type: array, uniqueItems: true, items: { type: string, minLength: 1 } }
1067
+ rationale: { type: string, minLength: 1 }
1068
+ alignment_thread_id: { type: string, description: 'confirmed decision checkpoint that produced this change contract' }
968
1069
  base_commit: { type: string, pattern: '^[0-9a-f]{7,40}$' }
969
1070
  baseline_bypass:
970
1071
  type: object
@@ -1009,20 +1110,26 @@ tools:
1009
1110
  status: { type: string, enum: [available, unavailable, fresh, stale, unknown] }
1010
1111
  output_schema:
1011
1112
  type: object
1012
- required: [change, intent_path, context_manifest_path]
1113
+ required: [change, intent_path, context_manifest_path, workflow]
1013
1114
  additionalProperties: false
1014
1115
  properties:
1015
1116
  change: { type: object }
1016
1117
  intent_path: { type: string }
1017
1118
  context_manifest_path: { type: string }
1119
+ workflow: { type: object }
1018
1120
  errors:
1019
1121
  - { code: DUPLICATE_CHANGE_ID, description: 'change id already exists' }
1020
1122
  - { code: PROVIDER_CONTENT_FORBIDDEN, description: 'provider payload content must remain external' }
1021
1123
  - { code: VALIDATION_ERROR, description: 'change input failed validation' }
1022
1124
  - { code: BASELINE_NOT_READY, description: 'ordinary work is blocked until the project baseline is healthy' }
1023
1125
  - { code: BASELINE_BYPASS_REQUIRED, description: 'an incident on an unhealthy baseline requires explicit break-glass approval' }
1126
+ - { code: CHANGE_CONTRACT_REQUIRED, description: 'outcome, acceptance, seams, recovery, or decisions are incomplete' }
1127
+ - { code: CHANGE_CLASSIFICATION_REQUIRED, description: 'classification rationale or risk flags are incomplete' }
1128
+ - { code: CHANGE_RESEARCH_DISPOSITION_REQUIRED, description: 'research routing is incomplete or inconsistent' }
1129
+ - { code: CHANGE_PROFILE_ESCALATION_REQUIRED, description: 'quick profile conflicts with material risk or research' }
1130
+ - { code: CHANGE_ALIGNMENT_REQUIRED, description: 'declared alignment thread is missing, unconfirmed, stale, not artifact-bound, bound to another authority, or not scoped to the current baseline' }
1024
1131
  cli_subcommand: change create
1025
- emits_events: [change_created, context_updated]
1132
+ emits_events: [change_created, context_updated, workflow_started, workflow_step_updated]
1026
1133
 
1027
1134
  - name: change.update
1028
1135
  family: change
@@ -1075,6 +1182,9 @@ tools:
1075
1182
  revision: { type: string }
1076
1183
  indexed_head: { type: string }
1077
1184
  status: { type: string, enum: [available, unavailable, fresh, stale, unknown] }
1185
+ contract: *change_contract
1186
+ classification: *change_classification
1187
+ research_disposition: *change_research_disposition
1078
1188
  output_schema:
1079
1189
  type: object
1080
1190
  required: [ok, change]
@@ -1138,7 +1248,7 @@ tools:
1138
1248
 
1139
1249
  - name: change.context
1140
1250
  family: change
1141
- description: Compile a role-scoped Context Spine manifest with readiness, budget, execution seam, and next-action evidence.
1251
+ description: Compile an immutable role-scoped Context Spine snapshot whose execution seam and next action are derived from authoritative task and workflow state.
1142
1252
  phase: '10'
1143
1253
  writer_role: mcp
1144
1254
  input_schema:
@@ -1150,7 +1260,6 @@ tools:
1150
1260
  task_id: { type: string }
1151
1261
  role: { type: string, enum: [plan, implement, check, review] }
1152
1262
  gate: { type: string, enum: [alignment, planning, implementation, verification, review, convergence, recovery] }
1153
- next_action: { type: string, minLength: 3 }
1154
1263
  spec_refs: { type: array, items: { type: object } }
1155
1264
  context_refs:
1156
1265
  type: array
@@ -1175,11 +1284,7 @@ tools:
1175
1284
  type: object
1176
1285
  additionalProperties: false
1177
1286
  properties:
1178
- slice_kind: { type: string, enum: [tracer_bullet, expand_contract, integration_checkpoint], default: tracer_bullet }
1179
- public_seam: { type: string }
1180
- verification_command: { type: string }
1181
1287
  context_budget_percent: { type: integer, minimum: 1, maximum: 100, default: 40 }
1182
- allowed_paths: { type: array, items: { type: string } }
1183
1288
  provider_refs:
1184
1289
  type: object
1185
1290
  additionalProperties: false
@@ -1219,6 +1324,9 @@ tools:
1219
1324
  - { code: CHANGE_NOT_FOUND, description: 'change id does not exist' }
1220
1325
  - { code: CHANGE_TERMINAL, description: 'terminal change cannot compile a new context' }
1221
1326
  - { code: TASK_NOT_FOUND, description: 'task id is not linked to the change' }
1327
+ - { code: EXECUTION_CONTRACT_CONFLICT, description: 'Prompt input attempted to override the DB-backed task seam or verification command' }
1328
+ - { code: EXECUTION_CONTEXT_REFS_CONFLICT, description: 'Prompt input attempted to override DB-backed task context references' }
1329
+ - { code: CONTEXT_NEXT_ACTION_AUTHORITY_VIOLATION, description: 'next action is derived from workflow and task state and cannot be supplied by Prompt input' }
1222
1330
  - { code: PROVIDER_CONTENT_FORBIDDEN, description: 'provider payload content must remain external' }
1223
1331
  cli_subcommand: change context
1224
1332
  emits_events: [context_updated]
@@ -1291,6 +1399,10 @@ tools:
1291
1399
  candidate_id: { type: string, pattern: '^[a-zA-Z0-9_\-]+$' }
1292
1400
  decision: { type: string, enum: [approve, reject, apply] }
1293
1401
  resolution: { type: string }
1402
+ applied_ref: { type: string, minLength: 3 }
1403
+ before_digest: { type: string, pattern: '^[0-9a-f]{64}$' }
1404
+ after_digest: { type: string, pattern: '^[0-9a-f]{64}$' }
1405
+ apply_evidence: { type: array, minItems: 1, uniqueItems: true, items: { type: string, minLength: 3 } }
1294
1406
  output_schema:
1295
1407
  type: object
1296
1408
  required: [candidate]
@@ -1302,6 +1414,8 @@ tools:
1302
1414
  - { code: CHANGE_NOT_FOUND, description: 'change id does not exist' }
1303
1415
  - { code: LEARNING_NOT_FOUND, description: 'candidate id does not exist for the change' }
1304
1416
  - { code: ILLEGAL_LEARNING_TRANSITION, description: 'candidate state transition is not permitted' }
1417
+ - { code: LEARNING_APPLY_EVIDENCE_REQUIRED, description: 'apply requires exact target, before and after digests, and evidence' }
1418
+ - { code: LEARNING_APPLY_EVIDENCE_MISMATCH, description: 'apply evidence does not match the current target artifact' }
1305
1419
  cli_subcommand: change learning-resolve
1306
1420
  emits_events: [spec_learning_resolved]
1307
1421
 
@@ -1312,34 +1426,10 @@ tools:
1312
1426
  writer_role: mcp
1313
1427
  input_schema:
1314
1428
  type: object
1315
- required: [id, evidence]
1429
+ required: [id]
1316
1430
  additionalProperties: false
1317
1431
  properties:
1318
1432
  id: { type: string }
1319
- evidence:
1320
- type: array
1321
- minItems: 1
1322
- items:
1323
- type: object
1324
- required: [category, status, evidence]
1325
- additionalProperties: false
1326
- properties:
1327
- category: { type: string, enum: [diagnosis, diff, tests, spec, docs, review] }
1328
- status: { type: string, enum: [pass, fail, not_applicable] }
1329
- evidence: { type: string, minLength: 3 }
1330
- axis: { type: string, enum: [spec_fidelity, engineering_standards] }
1331
- seam: { type: string, minLength: 3 }
1332
- signal:
1333
- type: object
1334
- additionalProperties: false
1335
- required: [command, expected_red, observed_red, observed_green, deterministic]
1336
- properties:
1337
- command: { type: string, minLength: 3 }
1338
- expected_red: { type: string, minLength: 3 }
1339
- observed_red: { type: boolean }
1340
- observed_green: { type: boolean }
1341
- deterministic: { type: boolean }
1342
- duration_ms: { type: number, minimum: 0 }
1343
1433
  output_schema:
1344
1434
  type: object
1345
1435
  required: [ready, status, blockers]
@@ -1352,6 +1442,7 @@ tools:
1352
1442
  errors:
1353
1443
  - { code: CHANGE_NOT_FOUND, description: 'change id does not exist' }
1354
1444
  - { code: CHANGE_NOT_CONVERGEABLE, description: 'change lifecycle does not allow convergence' }
1445
+ - { code: CONVERGENCE_EVIDENCE_AUTHORITY_VIOLATION, description: 'Prompt-supplied gate verdicts cannot replace DB-backed workflow evidence' }
1355
1446
  cli_subcommand: change converge
1356
1447
  emits_events: [change_blocked, change_converged]
1357
1448
 
@@ -1362,13 +1453,14 @@ tools:
1362
1453
  writer_role: mcp
1363
1454
  input_schema:
1364
1455
  type: object
1365
- required: [id, summary]
1456
+ required: [id, summary, reconciliation_path]
1366
1457
  additionalProperties: false
1367
1458
  properties:
1368
1459
  id: { type: string }
1369
1460
  summary: { type: string, minLength: 3 }
1370
1461
  baseline_updates: { type: array, items: { type: string } }
1371
1462
  no_baseline_change_reason: { type: string, minLength: 3 }
1463
+ reconciliation_path: { type: string, minLength: 3 }
1372
1464
  output_schema:
1373
1465
  type: object
1374
1466
  required: [change, archive_path]
@@ -1381,10 +1473,531 @@ tools:
1381
1473
  - { code: BASELINE_RECONCILIATION_REQUIRED, description: 'baseline update or explicit no-change reason required' }
1382
1474
  - { code: BASELINE_FILE_MISSING, description: 'a declared baseline update does not exist' }
1383
1475
  - { code: BASELINE_RECONCILIATION_INCOMPLETE, description: 'repository revision or tracked specification digests remain stale after reconciliation' }
1476
+ - { code: BASELINE_RECONCILIATION_MANIFEST_REQUIRED, description: 'a change-bound reconciliation manifest is required' }
1477
+ - { code: BASELINE_RECONCILIATION_MANIFEST_INVALID, description: 'semantic changes, digests, resolutions, or verification are invalid' }
1384
1478
  - { code: ARCHIVE_EXISTS, description: 'archive target already exists' }
1385
1479
  cli_subcommand: change archive
1386
1480
  emits_events: [change_archived]
1387
1481
 
1482
+ # ────────────────────────── decision family ────────────────────────────
1483
+ - name: decision.thread_start
1484
+ family: decision
1485
+ description: Start one durable owner-agent alignment thread bound to baseline, change, or workflow authority.
1486
+ phase: '16'
1487
+ writer_role: mcp
1488
+ input_schema:
1489
+ type: object
1490
+ required: [id, purpose]
1491
+ additionalProperties: false
1492
+ properties:
1493
+ id: { type: string, pattern: '^[a-zA-Z0-9_\-]+$' }
1494
+ purpose: { type: string, minLength: 3 }
1495
+ mode: { type: string, enum: [guided, fast, autonomous, diagnostic], default: guided }
1496
+ baseline_id: { type: string }
1497
+ change_id: { type: string }
1498
+ workflow_run_id: { type: string }
1499
+ output_schema:
1500
+ type: object
1501
+ required: [thread]
1502
+ additionalProperties: false
1503
+ properties:
1504
+ thread: { type: object }
1505
+ errors:
1506
+ - { code: DECISION_AUTHORITY_REQUIRED, description: 'thread has no baseline, change, or workflow authority' }
1507
+ - { code: DECISION_AUTHORITY_MISMATCH, description: 'thread authority differs from its workflow binding' }
1508
+ - { code: DECISION_THREAD_IN_PROGRESS, description: 'the same authority and purpose already has an active thread' }
1509
+ - { code: DUPLICATE_DECISION_THREAD, description: 'decision thread id already exists' }
1510
+ - { code: VALIDATION_ERROR, description: 'thread input is incomplete or invalid' }
1511
+ cli_subcommand: decision thread-start
1512
+ emits_events: [decision_thread_started]
1513
+
1514
+ - name: decision.get
1515
+ family: decision
1516
+ description: Read one decision thread with its current question, normalized decisions, and checkpoint authority.
1517
+ phase: '16'
1518
+ readonly: true
1519
+ input_schema:
1520
+ type: object
1521
+ required: [id]
1522
+ additionalProperties: false
1523
+ properties:
1524
+ id: { type: string }
1525
+ output_schema:
1526
+ type: object
1527
+ required: [thread]
1528
+ additionalProperties: false
1529
+ properties:
1530
+ thread: { type: object }
1531
+ errors:
1532
+ - { code: DECISION_THREAD_NOT_FOUND, description: 'decision thread id does not exist' }
1533
+ cli_subcommand: decision get
1534
+ emits_events: []
1535
+
1536
+ - name: decision.list
1537
+ family: decision
1538
+ description: List durable decision threads by authority, mode, or lifecycle state for recovery and status reporting.
1539
+ phase: '16'
1540
+ readonly: true
1541
+ input_schema:
1542
+ type: object
1543
+ additionalProperties: false
1544
+ properties:
1545
+ status: { type: string, enum: [active, checkpoint_ready, confirmed, cancelled] }
1546
+ mode: { type: string, enum: [guided, fast, autonomous, diagnostic] }
1547
+ baseline_id: { type: string }
1548
+ change_id: { type: string }
1549
+ workflow_run_id: { type: string }
1550
+ limit: { type: integer, minimum: 1, maximum: 500, default: 100 }
1551
+ output_schema:
1552
+ type: object
1553
+ required: [threads, count]
1554
+ additionalProperties: false
1555
+ properties:
1556
+ threads: { type: array, items: { type: object } }
1557
+ count: { type: integer, minimum: 0 }
1558
+ errors:
1559
+ - { code: STATE_DB_ERROR, description: 'decision thread state could not be read' }
1560
+ cli_subcommand: decision list
1561
+ emits_events: []
1562
+
1563
+ - name: decision.open
1564
+ family: decision
1565
+ description: Open the sole user-facing decision in a thread with evidence, recommendation, credible alternatives, and durable effects.
1566
+ phase: '16'
1567
+ writer_role: mcp
1568
+ input_schema:
1569
+ type: object
1570
+ required: [id, thread_id, phase, question, why_now, recommendation, effects]
1571
+ additionalProperties: false
1572
+ properties:
1573
+ id: { type: string, pattern: '^[a-zA-Z0-9_\-]+$' }
1574
+ thread_id: { type: string }
1575
+ phase: { type: string, minLength: 1 }
1576
+ question: { type: string, minLength: 1 }
1577
+ why_now: { type: string, minLength: 1 }
1578
+ recommendation: { type: string, minLength: 1 }
1579
+ options:
1580
+ type: array
1581
+ maxItems: 3
1582
+ items: &decision_option
1583
+ type: object
1584
+ required: [id, label, tradeoff]
1585
+ additionalProperties: false
1586
+ properties:
1587
+ id: { type: string, pattern: '^[a-zA-Z0-9_\-]+$' }
1588
+ label: { type: string, minLength: 1 }
1589
+ tradeoff: { type: string, minLength: 1 }
1590
+ evidence_refs: { type: array, uniqueItems: true, items: { type: string, minLength: 1 } }
1591
+ dependency_ids: { type: array, uniqueItems: true, items: { type: string, minLength: 1 } }
1592
+ effects: { type: object, minProperties: 1 }
1593
+ blocking: { type: boolean, default: true }
1594
+ output_schema:
1595
+ type: object
1596
+ required: [thread]
1597
+ additionalProperties: false
1598
+ properties:
1599
+ thread: { type: object }
1600
+ errors:
1601
+ - { code: DECISION_THREAD_NOT_FOUND, description: 'decision thread id does not exist' }
1602
+ - { code: DECISION_ALREADY_OPEN, description: 'another decision is already awaiting an answer' }
1603
+ - { code: DECISION_CHECKPOINT_PENDING, description: 'the prepared checkpoint must be confirmed or revised first' }
1604
+ - { code: DECISION_DEPENDENCY_UNRESOLVED, description: 'a declared decision dependency is unresolved' }
1605
+ - { code: DUPLICATE_DECISION_ID, description: 'decision item id already exists' }
1606
+ - { code: VALIDATION_ERROR, description: 'question, recommendation, options, evidence, or effects are invalid' }
1607
+ cli_subcommand: decision open
1608
+ emits_events: [decision_opened]
1609
+
1610
+ - name: decision.resolve
1611
+ family: decision
1612
+ description: Resolve the current question as an explicit normalized owner decision without storing the conversation transcript.
1613
+ phase: '16'
1614
+ writer_role: mcp
1615
+ input_schema:
1616
+ type: object
1617
+ required: [id, decision, rationale, decided_by]
1618
+ additionalProperties: false
1619
+ properties:
1620
+ id: { type: string }
1621
+ decision: { type: string, minLength: 1 }
1622
+ rationale: { type: string, minLength: 1 }
1623
+ decided_by: { type: string, minLength: 1 }
1624
+ output_schema:
1625
+ type: object
1626
+ required: [thread]
1627
+ additionalProperties: false
1628
+ properties:
1629
+ thread: { type: object }
1630
+ errors:
1631
+ - { code: DECISION_NOT_FOUND, description: 'decision item id does not exist' }
1632
+ - { code: DECISION_NOT_OPEN, description: 'decision item is no longer awaiting an answer' }
1633
+ - { code: VALIDATION_ERROR, description: 'normalized owner decision is incomplete' }
1634
+ cli_subcommand: decision resolve
1635
+ emits_events: [decision_resolved]
1636
+
1637
+ - name: decision.delegate
1638
+ family: decision
1639
+ description: Record explicit owner delegation for a reversible decision, including the selected result and non-negotiable guardrails.
1640
+ phase: '16'
1641
+ writer_role: mcp
1642
+ input_schema:
1643
+ type: object
1644
+ required: [id, delegated_to, decision, rationale, guardrails]
1645
+ additionalProperties: false
1646
+ properties:
1647
+ id: { type: string }
1648
+ delegated_to: { type: string, minLength: 1 }
1649
+ decision: { type: string, minLength: 1 }
1650
+ rationale: { type: string, minLength: 1 }
1651
+ guardrails: { type: array, minItems: 1, uniqueItems: true, items: { type: string, minLength: 1 } }
1652
+ output_schema:
1653
+ type: object
1654
+ required: [thread]
1655
+ additionalProperties: false
1656
+ properties:
1657
+ thread: { type: object }
1658
+ errors:
1659
+ - { code: DECISION_NOT_FOUND, description: 'decision item id does not exist' }
1660
+ - { code: DECISION_NOT_OPEN, description: 'decision item is no longer awaiting an answer' }
1661
+ - { code: VALIDATION_ERROR, description: 'delegation result or guardrails are incomplete' }
1662
+ cli_subcommand: decision delegate
1663
+ emits_events: [decision_resolved]
1664
+
1665
+ - name: decision.defer
1666
+ family: decision
1667
+ description: Defer the current decision with explicit consequences and a deterministic condition for revisiting it.
1668
+ phase: '16'
1669
+ writer_role: mcp
1670
+ input_schema:
1671
+ type: object
1672
+ required: [id, reason, consequences, revisit_condition]
1673
+ additionalProperties: false
1674
+ properties:
1675
+ id: { type: string }
1676
+ reason: { type: string, minLength: 1 }
1677
+ consequences: { type: string, minLength: 1 }
1678
+ revisit_condition: { type: string, minLength: 1 }
1679
+ output_schema:
1680
+ type: object
1681
+ required: [thread]
1682
+ additionalProperties: false
1683
+ properties:
1684
+ thread: { type: object }
1685
+ errors:
1686
+ - { code: DECISION_NOT_FOUND, description: 'decision item id does not exist' }
1687
+ - { code: DECISION_NOT_OPEN, description: 'decision item is no longer awaiting an answer' }
1688
+ - { code: VALIDATION_ERROR, description: 'deferral consequence or revisit condition is incomplete' }
1689
+ cli_subcommand: decision defer
1690
+ emits_events: [decision_resolved]
1691
+
1692
+ - name: decision.supersede
1693
+ family: decision
1694
+ description: Preserve a prior resolved decision and reopen alignment with one replacement question when evidence or owner intent changes.
1695
+ phase: '16'
1696
+ writer_role: mcp
1697
+ input_schema:
1698
+ type: object
1699
+ required: [id, reason, replacement]
1700
+ additionalProperties: false
1701
+ properties:
1702
+ id: { type: string }
1703
+ reason: { type: string, minLength: 1 }
1704
+ replacement:
1705
+ type: object
1706
+ required: [id, phase, question, why_now, recommendation, effects]
1707
+ additionalProperties: false
1708
+ properties:
1709
+ id: { type: string, pattern: '^[a-zA-Z0-9_\-]+$' }
1710
+ phase: { type: string, minLength: 1 }
1711
+ question: { type: string, minLength: 1 }
1712
+ why_now: { type: string, minLength: 1 }
1713
+ recommendation: { type: string, minLength: 1 }
1714
+ options: { type: array, maxItems: 3, items: *decision_option }
1715
+ evidence_refs: { type: array, uniqueItems: true, items: { type: string, minLength: 1 } }
1716
+ dependency_ids: { type: array, uniqueItems: true, items: { type: string, minLength: 1 } }
1717
+ effects: { type: object, minProperties: 1 }
1718
+ blocking: { type: boolean, default: true }
1719
+ output_schema:
1720
+ type: object
1721
+ required: [thread]
1722
+ additionalProperties: false
1723
+ properties:
1724
+ thread: { type: object }
1725
+ errors:
1726
+ - { code: DECISION_NOT_FOUND, description: 'decision item id does not exist' }
1727
+ - { code: DECISION_NOT_SUPERSEDEABLE, description: 'decision item cannot be revised from its current state' }
1728
+ - { code: DECISION_ALREADY_OPEN, description: 'another decision is already awaiting an answer' }
1729
+ - { code: VALIDATION_ERROR, description: 'replacement question or revision reason is invalid' }
1730
+ cli_subcommand: decision supersede
1731
+ emits_events: [decision_opened]
1732
+
1733
+ - name: decision.checkpoint
1734
+ family: decision
1735
+ description: Prepare or confirm a decision checkpoint, including renewal of unchanged decisions against current artifacts; change- and workflow-bound threads require an artifact, while a standalone baseline thread may record an explicit no-artifact reason.
1736
+ phase: '16'
1737
+ writer_role: mcp
1738
+ input_schema:
1739
+ type: object
1740
+ required: [id, action]
1741
+ additionalProperties: false
1742
+ properties:
1743
+ id: { type: string }
1744
+ action: { type: string, enum: [prepare, confirm] }
1745
+ summary: { type: string, minLength: 1 }
1746
+ approved_by: { type: string, minLength: 1 }
1747
+ approval_note: { type: string, minLength: 3 }
1748
+ artifacts:
1749
+ type: array
1750
+ items:
1751
+ type: object
1752
+ required: [path, kind]
1753
+ additionalProperties: false
1754
+ properties:
1755
+ path: { type: string, minLength: 1 }
1756
+ kind: { type: string, minLength: 1 }
1757
+ no_artifact_reason: { type: string, minLength: 3 }
1758
+ output_schema:
1759
+ type: object
1760
+ required: [thread]
1761
+ additionalProperties: false
1762
+ properties:
1763
+ thread: { type: object }
1764
+ errors:
1765
+ - { code: DECISION_THREAD_NOT_FOUND, description: 'decision thread id does not exist' }
1766
+ - { code: DECISION_THREAD_NOT_MUTABLE, description: 'cancelled decision thread cannot be checkpointed' }
1767
+ - { code: DECISION_ALIGNMENT_BLOCKING, description: 'an open or deferred blocking decision prevents checkpointing' }
1768
+ - { code: DECISION_CHECKPOINT_STALE, description: 'prepared decision digest no longer matches current authority' }
1769
+ - { code: DECISION_ARTIFACT_REQUIRED, description: 'confirmation lacks required artifact bindings; no-artifact reasons are allowed only for standalone baseline thinking' }
1770
+ - { code: DECISION_ARTIFACT_MISSING, description: 'a declared checkpoint artifact does not exist' }
1771
+ - { code: VALIDATION_ERROR, description: 'checkpoint action, approval, or artifact input is invalid' }
1772
+ cli_subcommand: decision checkpoint
1773
+ emits_events: [decision_checkpoint_prepared, decision_checkpoint_confirmed]
1774
+
1775
+ # ────────────────────────── workflow family ────────────────────────────
1776
+ - name: workflow.start
1777
+ family: workflow
1778
+ 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.
1779
+ phase: '13'
1780
+ writer_role: mcp
1781
+ input_schema:
1782
+ type: object
1783
+ required: [kind, subject]
1784
+ additionalProperties: false
1785
+ properties:
1786
+ id: { type: string, pattern: '^[a-zA-Z0-9_\-]+$' }
1787
+ kind: { type: string, enum: [init, research, plan, change, dev, test, review, deliver] }
1788
+ subject: { type: string, minLength: 3 }
1789
+ mode: { type: string, enum: [full, adoption, product, feature, architecture, custom] }
1790
+ selected_steps: { type: array, uniqueItems: true, items: { type: string } }
1791
+ baseline_id: { type: string }
1792
+ change_id: { type: string }
1793
+ task_id: { type: string }
1794
+ metadata: { type: object }
1795
+ output_schema:
1796
+ type: object
1797
+ required: [workflow]
1798
+ additionalProperties: false
1799
+ properties:
1800
+ workflow: { type: object }
1801
+ errors:
1802
+ - { code: VALIDATION_ERROR, description: 'definition, mode, selection, or linked authority is invalid' }
1803
+ - { code: DUPLICATE_WORKFLOW_ID, description: 'workflow id already exists' }
1804
+ - { code: WORKFLOW_IN_PROGRESS, description: 'the same authority already has an active workflow of this kind' }
1805
+ - { code: WORKFLOW_CHANGE_NOT_FOUND, description: 'the requested change authority does not exist' }
1806
+ - { code: WORKFLOW_CHANGE_RUN_REQUIRED, description: 'change-bound stages require the owning durable change workflow; legacy gaps route through doctor repair' }
1807
+ - { code: WORKFLOW_BASELINE_MISMATCH, description: 'a supplied stage baseline differs from the baseline bound by the owning change workflow' }
1808
+ - { code: WORKFLOW_BASELINE_REQUIRED, description: 'a baseline-free plan is valid only for an approved incident break-glass change' }
1809
+ - { code: WORKFLOW_CHANGE_NOT_MUTABLE, description: 'the owning change does not accept a new workflow of this stage' }
1810
+ - { code: TASK_EXECUTION_CONTRACT_INCOMPLETE, description: 'dev cannot start until the linked task contract is executable' }
1811
+ - { code: TASK_CHANGE_OWNERSHIP_MISMATCH, description: 'linked task and change authority disagree' }
1812
+ cli_subcommand: workflow start
1813
+ emits_events: [workflow_started]
1814
+
1815
+ - name: workflow.get
1816
+ family: workflow
1817
+ description: Read one workflow run with every step, current recovery position, blockers, and output freshness.
1818
+ phase: '13'
1819
+ readonly: true
1820
+ input_schema:
1821
+ type: object
1822
+ required: [id]
1823
+ additionalProperties: false
1824
+ properties:
1825
+ id: { type: string }
1826
+ output_schema:
1827
+ type: object
1828
+ required: [workflow]
1829
+ additionalProperties: false
1830
+ properties:
1831
+ workflow: { type: object }
1832
+ errors:
1833
+ - { code: WORKFLOW_NOT_FOUND, description: 'workflow id does not exist' }
1834
+ cli_subcommand: workflow get
1835
+ emits_events: []
1836
+
1837
+ - name: workflow.list
1838
+ family: workflow
1839
+ description: List workflow runs by phase, state, baseline, change, or task authority.
1840
+ phase: '13'
1841
+ readonly: true
1842
+ input_schema:
1843
+ type: object
1844
+ additionalProperties: false
1845
+ properties:
1846
+ kind: { type: string, enum: [init, research, plan, change, dev, test, review, deliver] }
1847
+ status: { type: string, enum: [active, blocked, ready, completed, cancelled] }
1848
+ baseline_id: { type: string }
1849
+ change_id: { type: string }
1850
+ task_id: { type: string }
1851
+ limit: { type: integer, minimum: 1, maximum: 500, default: 100 }
1852
+ output_schema:
1853
+ type: object
1854
+ required: [workflows, count]
1855
+ additionalProperties: false
1856
+ properties:
1857
+ workflows: { type: array, items: { type: object } }
1858
+ count: { type: integer, minimum: 0 }
1859
+ errors:
1860
+ - { code: STATE_DB_ERROR, description: 'workflow state could not be read' }
1861
+ cli_subcommand: workflow list
1862
+ emits_events: []
1863
+
1864
+ - name: workflow.step
1865
+ family: workflow
1866
+ description: Record one canonical workflow-step transition with bounded evidence, durable output digests, decisions, or blockers.
1867
+ phase: '13'
1868
+ writer_role: mcp
1869
+ input_schema:
1870
+ type: object
1871
+ required: [id, step_id, status]
1872
+ additionalProperties: false
1873
+ properties:
1874
+ id: { type: string }
1875
+ step_id: { type: string }
1876
+ status: { type: string, enum: [in_progress, completed, skipped, blocked] }
1877
+ evidence:
1878
+ type: array
1879
+ items:
1880
+ type: object
1881
+ required: [kind, ref, summary]
1882
+ additionalProperties: false
1883
+ properties:
1884
+ kind: { type: string, minLength: 1 }
1885
+ ref: { type: string, minLength: 1 }
1886
+ summary: { type: string, minLength: 1 }
1887
+ outputs:
1888
+ type: array
1889
+ items:
1890
+ type: object
1891
+ required: [path, kind]
1892
+ additionalProperties: false
1893
+ properties:
1894
+ path: { type: string, minLength: 1 }
1895
+ kind: { type: string, minLength: 1 }
1896
+ decisions: { type: array, items: { type: object } }
1897
+ semantic_records:
1898
+ type: array
1899
+ items:
1900
+ type: object
1901
+ required: [id, kind, status, summary, source_ref, evidence_refs, attributes, links]
1902
+ additionalProperties: false
1903
+ properties:
1904
+ id: { type: string, pattern: '^[a-zA-Z0-9_\-]+$' }
1905
+ kind: { type: string, minLength: 1 }
1906
+ status: { type: string, enum: [observed, verified, decided, accepted, unknown, not_applicable] }
1907
+ summary: { type: string, minLength: 1 }
1908
+ source_ref: { type: string, minLength: 3 }
1909
+ evidence_refs: { type: array, minItems: 1, items: { type: string, minLength: 1 } }
1910
+ attributes: { type: object }
1911
+ links:
1912
+ type: array
1913
+ items:
1914
+ type: object
1915
+ required: [relation, target]
1916
+ additionalProperties: false
1917
+ properties:
1918
+ relation: { type: string, minLength: 1 }
1919
+ target: { type: string, minLength: 1 }
1920
+ blockers: { type: array, uniqueItems: true, items: { type: string, minLength: 1 } }
1921
+ output_schema:
1922
+ type: object
1923
+ required: [workflow]
1924
+ additionalProperties: false
1925
+ properties:
1926
+ workflow: { type: object }
1927
+ errors:
1928
+ - { code: WORKFLOW_NOT_FOUND, description: 'workflow id does not exist' }
1929
+ - { code: WORKFLOW_STEP_NOT_FOUND, description: 'step is not part of the canonical workflow' }
1930
+ - { code: WORKFLOW_STEP_OUT_OF_ORDER, description: 'an earlier selected step remains incomplete' }
1931
+ - { code: WORKFLOW_EVIDENCE_REQUIRED, description: 'the step cannot complete without evidence' }
1932
+ - { code: WORKFLOW_OUTPUT_REQUIRED, description: 'the step cannot complete without a durable output' }
1933
+ - { code: WORKFLOW_OUTPUT_MISSING, description: 'a declared output file is missing' }
1934
+ - { code: WORKFLOW_RESEARCH_REPORT_REQUIRED, description: 'a research step requires its immutable workflow-and-step-bound report path' }
1935
+ - { code: WORKFLOW_RESEARCH_REPORT_INVALID, description: 'the research report is missing its required evidence structure' }
1936
+ - { code: WORKFLOW_RESEARCH_SYNTHESIS_INCOMPLETE, description: 'full or adoption synthesis did not bind all baseline specifications and the distillate' }
1937
+ - { code: WORKFLOW_SEMANTIC_RECORDS_REQUIRED, description: 'a research step did not persist typed semantic results' }
1938
+ - { code: WORKFLOW_SEMANTIC_RECORD_INVALID, description: 'a semantic record does not satisfy its step contract' }
1939
+ - { code: WORKFLOW_SYNTHESIS_TRACE_INVALID, description: 'synthesis references missing research semantic records' }
1940
+ - { code: WORKFLOW_BLOCKER_REQUIRED, description: 'blocked state requires a specific blocker code' }
1941
+ - { code: WORKFLOW_CONTEXT_OUTPUT_REQUIRED, description: 'the stage requires its immutable Context Manifest v2 output' }
1942
+ - { code: WORKFLOW_CONTEXT_MISMATCH, description: 'the context role, gate, change, task, or readiness does not match the stage' }
1943
+ - { code: WORKFLOW_CONTEXT_AUTHORITY_MISMATCH, description: 'the context artifact does not match its DB snapshot row' }
1944
+ - { code: WORKFLOW_CONTEXT_STALE, description: 'the context artifact no longer matches the current checkout' }
1945
+ - { code: WORKFLOW_RELEASE_AUTHORIZATION_INVALID, description: 'release-if-authorized requires one complete durable owner decision' }
1946
+ - { code: DECISION_ALIGNMENT_BLOCKING, description: 'matching owner decisions or artifact checkpoints are not current' }
1947
+ cli_subcommand: workflow step
1948
+ emits_events: [workflow_step_updated, workflow_blocked]
1949
+
1950
+ - name: workflow.complete
1951
+ family: workflow
1952
+ description: Complete a ready workflow only when every selected step is complete and every recorded output digest remains current.
1953
+ phase: '13'
1954
+ writer_role: mcp
1955
+ input_schema:
1956
+ type: object
1957
+ required: [id]
1958
+ additionalProperties: false
1959
+ properties:
1960
+ id: { type: string }
1961
+ approval:
1962
+ type: object
1963
+ required: [approved_by, approval_note]
1964
+ additionalProperties: false
1965
+ properties:
1966
+ approved_by: { type: string, minLength: 1 }
1967
+ approval_note: { type: string, minLength: 3 }
1968
+ approved_at: { type: string, format: date-time }
1969
+ output_schema:
1970
+ type: object
1971
+ required: [workflow]
1972
+ additionalProperties: false
1973
+ properties:
1974
+ workflow: { type: object }
1975
+ errors:
1976
+ - { code: WORKFLOW_NOT_FOUND, description: 'workflow id does not exist' }
1977
+ - { code: WORKFLOW_NOT_READY, description: 'selected steps or blockers remain incomplete' }
1978
+ - { code: WORKFLOW_OUTPUT_STALE, description: 'a recorded output changed or disappeared' }
1979
+ - { code: WORKFLOW_TASKS_REQUIRED, description: 'plan completion requires a non-empty authoritative task set' }
1980
+ - { code: TASK_EXECUTION_CONTRACT_INCOMPLETE, description: 'one or more planned tasks lack an executable contract' }
1981
+ - { code: TASK_DEPENDENCY_MISSING, description: 'a planned dependency does not exist' }
1982
+ - { code: TASK_DEPENDENCY_CYCLE, description: 'the planned task graph contains a cycle' }
1983
+ - { code: WORKFLOW_TASK_NOT_COMPLETED, description: 'dev convergence requires its task to be completed' }
1984
+ - { code: WORKFLOW_APPROVAL_REQUIRED, description: 'plan convergence requires explicit approved_by and approval_note fields' }
1985
+ - { code: WORKFLOW_SUMMARY_AUTHORITY_VIOLATION, description: 'Prompt summary fields are not allowed to replace DB-derived gate evidence or the complete change task set' }
1986
+ - { code: WORKFLOW_APPROVAL_AUTHORITY_VIOLATION, description: 'only the plan workflow accepts completion approval' }
1987
+ - { code: WORKFLOW_GATE_MISSING, description: 'a required completed dev, test, or review gate is missing' }
1988
+ - { code: WORKFLOW_GATE_STALE, description: 'a required gate no longer matches its task contract or commit ancestry' }
1989
+ - { code: WORKFLOW_REPORT_INVALID, description: 'a required report is malformed or incomplete' }
1990
+ - { code: WORKFLOW_REPORT_CONTEXT_MISMATCH, description: 'a report is not bound to the recorded stage context digest' }
1991
+ - { code: WORKFLOW_REPORT_REVISION_STALE, description: 'a report does not match the current full Git HEAD' }
1992
+ - { code: WORKFLOW_REPORT_WORKTREE_STALE, description: 'a report does not match the current worktree digest' }
1993
+ - { code: WORKFLOW_REVIEW_NOT_APPROVED, description: 'both independent review axes must pass' }
1994
+ - { code: WORKFLOW_TEST_NOT_PASSED, description: 'the current change-level test gate did not pass' }
1995
+ - { code: WORKFLOW_CHANGE_NOT_ARCHIVED, description: 'delivery completion requires an archived change' }
1996
+ - { code: WORKFLOW_RELEASE_AUTHORITY_MISMATCH, description: 'delivery release claims differ from the durable owner authorization decision' }
1997
+ - { code: DECISION_ALIGNMENT_BLOCKING, description: 'matching owner decisions or artifact checkpoints are not current' }
1998
+ cli_subcommand: workflow complete
1999
+ emits_events: [workflow_completed, plan_approved]
2000
+
1388
2001
  # ────────────────────────── system family ──────────────────────────────
1389
2002
  - name: system.doctor
1390
2003
  family: system
@@ -1420,10 +2033,11 @@ tools:
1420
2033
  writer_role: mcp
1421
2034
  input_schema:
1422
2035
  type: object
1423
- required: [out_path]
2036
+ required: [change_id, out_path]
1424
2037
  additionalProperties: false
1425
2038
  properties:
1426
2039
  format: { type: string, enum: [json, md], default: json }
2040
+ change_id: { type: string, pattern: '^[a-zA-Z0-9_\-]+$' }
1427
2041
  out_path: { type: string }
1428
2042
  tag: { type: string }
1429
2043
  output_schema:
@@ -1435,9 +2049,11 @@ tools:
1435
2049
  wave_count: { type: integer, minimum: 0 }
1436
2050
  errors:
1437
2051
  - { code: NO_TASKS, description: 'no tasks to plan' }
2052
+ - { code: CHANGE_NOT_FOUND, description: 'owning change does not exist' }
2053
+ - { code: CHANGE_NOT_MUTABLE, description: 'owning change no longer accepts planning output' }
1438
2054
  - { code: WRITE_FAILED, description: 'cannot write plan file' }
1439
2055
  cli_subcommand: plan export
1440
- emits_events: [plan_approved]
2056
+ emits_events: [plan_exported]
1441
2057
  trace_to: '§7.3, D34'
1442
2058
 
1443
2059
  - name: plan.get
@@ -1447,8 +2063,10 @@ tools:
1447
2063
  readonly: true
1448
2064
  input_schema:
1449
2065
  type: object
2066
+ required: [change_id]
1450
2067
  additionalProperties: false
1451
2068
  properties:
2069
+ change_id: { type: string, pattern: '^[a-zA-Z0-9_\-]+$' }
1452
2070
  section: { type: string, enum: [tasks, topo, conflicts, all], default: all }
1453
2071
  output_schema:
1454
2072
  type: object
@@ -1458,6 +2076,7 @@ tools:
1458
2076
  plan: { type: object }
1459
2077
  errors:
1460
2078
  - { code: NO_PLAN, description: 'no plan has been computed yet' }
2079
+ - { code: PLAN_CHANGE_MISMATCH, description: 'current plan artifact belongs to another change' }
1461
2080
  cli_subcommand: plan get
1462
2081
  emits_events: []
1463
2082
  trace_to: '§7.3, D34'