ultra-builder-pro-cli 0.14.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 (154) 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 +44 -1
  8. package/README.md +34 -19
  9. package/adapters/_shared/codex-assets.cjs +6 -2
  10. package/adapters/_shared/file-ops.cjs +6 -2
  11. package/adapters/claude.js +3 -2
  12. package/adapters/codex.js +1 -0
  13. package/adapters/kimi.js +3 -2
  14. package/adapters/opencode.js +3 -2
  15. package/agents/review-coordinator.md +9 -6
  16. package/docs/AGENT-CONTEXT.md +15 -8
  17. package/docs/ARCHITECTURE.md +33 -12
  18. package/docs/PLAN.zh-CN.md +3 -2
  19. package/docs/ROADMAP.md +8 -4
  20. package/docs/RUNTIME-COMPAT-MATRIX.md +4 -4
  21. package/docs/STATE-DB-ACCESS-POLICY.md +27 -25
  22. package/docs/WORKFLOW-LIFECYCLE.md +266 -0
  23. package/hooks/README.md +6 -1
  24. package/hooks/health_check.py +12 -3
  25. package/hooks/subagent_tracker.py +52 -77
  26. package/mcp-server/hook-event.cjs +34 -0
  27. package/mcp-server/lib/archive-journal.cjs +17 -5
  28. package/mcp-server/lib/baseline-workflow.cjs +158 -18
  29. package/mcp-server/lib/change-workflow.cjs +550 -85
  30. package/mcp-server/lib/context-spine.cjs +242 -24
  31. package/mcp-server/lib/doctor.cjs +33 -3
  32. package/mcp-server/lib/init-project.cjs +210 -16
  33. package/mcp-server/lib/plan-store.cjs +4 -1
  34. package/mcp-server/lib/pricing.cjs +7 -10
  35. package/mcp-server/lib/project-breadcrumb.cjs +6 -0
  36. package/mcp-server/lib/projector.cjs +57 -3
  37. package/mcp-server/lib/spec-learning.cjs +79 -2
  38. package/mcp-server/lib/state-db.cjs +145 -8
  39. package/mcp-server/lib/state-ops.cjs +160 -9
  40. package/mcp-server/lib/workflow-state.cjs +2292 -0
  41. package/mcp-server/server.cjs +161 -15
  42. package/orchestrator/daemon.cjs +1 -2
  43. package/orchestrator/dispatch-rules.cjs +5 -31
  44. package/orchestrator/planner/plan-builder.cjs +21 -12
  45. package/package.json +13 -3
  46. package/skills/ultra-change/SKILL.md +53 -68
  47. package/skills/ultra-change/references/change-contract.md +36 -0
  48. package/skills/ultra-deliver/SKILL.md +69 -79
  49. package/skills/ultra-deliver/references/baseline-reconciliation.md +20 -0
  50. package/skills/ultra-dev/SKILL.md +54 -59
  51. package/skills/ultra-doctor/SKILL.md +40 -71
  52. package/skills/ultra-init/SKILL.md +96 -103
  53. package/skills/ultra-init/references/brownfield-adoption.md +2 -2
  54. package/skills/ultra-plan/SKILL.md +79 -85
  55. package/skills/ultra-plan/references/semantic-preflight.md +18 -0
  56. package/skills/ultra-research/SKILL.md +87 -60
  57. package/skills/ultra-research/references/00-problem-validation.md +36 -0
  58. package/skills/ultra-research/references/01-opportunity-discovery.md +33 -0
  59. package/skills/ultra-research/references/02-market-assessment.md +30 -0
  60. package/skills/ultra-research/references/03-competitive-landscape.md +31 -0
  61. package/skills/ultra-research/references/04-product-strategy.md +32 -0
  62. package/skills/ultra-research/references/05-assumptions-validation.md +31 -0
  63. package/skills/ultra-research/references/10-user-personas.md +29 -0
  64. package/skills/ultra-research/references/11-user-scenarios.md +28 -0
  65. package/skills/ultra-research/references/20-user-stories.md +30 -0
  66. package/skills/ultra-research/references/21-features-scope.md +29 -0
  67. package/skills/ultra-research/references/22-success-metrics.md +28 -0
  68. package/skills/ultra-research/references/30-architecture-context.md +30 -0
  69. package/skills/ultra-research/references/31-solution-strategy.md +28 -0
  70. package/skills/ultra-research/references/32-building-blocks.md +28 -0
  71. package/skills/ultra-research/references/40-deployment.md +29 -0
  72. package/skills/ultra-research/references/41-quality-risks.md +28 -0
  73. package/skills/ultra-research/references/99-synthesis.md +35 -0
  74. package/skills/ultra-review/SKILL.md +57 -73
  75. package/skills/ultra-review/references/review-modes.md +27 -0
  76. package/skills/ultra-review/references/unified-schema.md +25 -0
  77. package/skills/ultra-review/scripts/review_wait.py +40 -3
  78. package/skills/ultra-status/SKILL.md +41 -45
  79. package/skills/ultra-test/SKILL.md +48 -55
  80. package/skills/ultra-verify/SKILL.md +1 -1
  81. package/skills/ultra-verify/references/{confidence-system.md → evidence-status.md} +3 -3
  82. package/spec/cli-protocol.md +7 -2
  83. package/spec/mcp-tools.yaml +384 -63
  84. package/spec/schemas/baseline-reconciliation.v1.schema.json +73 -0
  85. package/spec/schemas/delivery-report.v1.schema.json +111 -0
  86. package/spec/schemas/mcp-tools.schema.json +1 -1
  87. package/spec/schemas/state-db.sql +82 -1
  88. package/spec/schemas/tasks.v4.5.schema.json +8 -1
  89. package/spec/schemas/test-report.v1.schema.json +194 -0
  90. package/ultra-tools/cli.cjs +1 -1
  91. package/ultra-tools/commands/migrate.cjs +3 -3
  92. package/ultra-tools/commands/status.cjs +213 -12
  93. package/.ultra-template/delivery-report.json +0 -9
  94. package/.ultra-template/test-report.json +0 -8
  95. package/adapters/_shared/tests/file-ops.test.cjs +0 -54
  96. package/adapters/_shared/tests/frontmatter.test.cjs +0 -47
  97. package/adapters/_shared/tests/handbook.test.cjs +0 -101
  98. package/adapters/_shared/tests/path-rewrite.test.cjs +0 -60
  99. package/adapters/_shared/tests/provenance.test.cjs +0 -133
  100. package/adapters/_shared/tests/resolve-target.test.cjs +0 -75
  101. package/adapters/_shared/tests/runtime-assets.test.cjs +0 -149
  102. package/adapters/_shared/tests/settings-merge.test.cjs +0 -85
  103. package/adapters/_shared/tests/validate.test.cjs +0 -30
  104. package/adapters/tests/claude.test.cjs +0 -138
  105. package/adapters/tests/codex-hook.test.cjs +0 -142
  106. package/adapters/tests/codex.test.cjs +0 -430
  107. package/adapters/tests/kimi-hook.test.cjs +0 -149
  108. package/adapters/tests/kimi.test.cjs +0 -259
  109. package/adapters/tests/opencode.test.cjs +0 -357
  110. package/mcp-server/lib/archive-journal.test.cjs +0 -35
  111. package/mcp-server/lib/baseline-workflow.test.cjs +0 -477
  112. package/mcp-server/lib/change-workflow.test.cjs +0 -971
  113. package/mcp-server/lib/context-spine.test.cjs +0 -93
  114. package/mcp-server/lib/doctor.test.cjs +0 -148
  115. package/mcp-server/lib/plan-store.test.cjs +0 -132
  116. package/mcp-server/lib/prd-parser.test.cjs +0 -82
  117. package/mcp-server/lib/project-breadcrumb.test.cjs +0 -112
  118. package/mcp-server/lib/runtime-state.test.cjs +0 -92
  119. package/mcp-server/lib/spec-learning.test.cjs +0 -67
  120. package/mcp-server/lib/state-db.test.cjs +0 -314
  121. package/mcp-server/lib/task-expander.test.cjs +0 -169
  122. package/mcp-server/lib/topo.test.cjs +0 -158
  123. package/mcp-server/tests/circuit-breaker.test.cjs +0 -125
  124. package/mcp-server/tests/commit-hash-flow.test.cjs +0 -117
  125. package/mcp-server/tests/concurrency-update.test.cjs +0 -96
  126. package/mcp-server/tests/concurrency.test.cjs +0 -112
  127. package/mcp-server/tests/db-ops.test.cjs +0 -121
  128. package/mcp-server/tests/init-project.test.cjs +0 -393
  129. package/mcp-server/tests/migrate.test.cjs +0 -232
  130. package/mcp-server/tests/projector.test.cjs +0 -162
  131. package/mcp-server/tests/server-contract.test.cjs +0 -1467
  132. package/mcp-server/tests/staleness.test.cjs +0 -190
  133. package/mcp-server/tests/state-db.test.cjs +0 -106
  134. package/mcp-server/tests/state-ops.test.cjs +0 -449
  135. package/mcp-server/tests/tagged-tasks.test.cjs +0 -163
  136. package/mcp-server/tests/telemetry.test.cjs +0 -219
  137. package/orchestrator/planner/plan-builder.test.cjs +0 -165
  138. package/orchestrator/tests/auto-merge.test.cjs +0 -216
  139. package/orchestrator/tests/daemon.test.cjs +0 -311
  140. package/orchestrator/tests/dispatch-rules.test.cjs +0 -124
  141. package/orchestrator/tests/parallel-orchestrator.test.cjs +0 -233
  142. package/orchestrator/tests/phase-8b-gate.test.cjs +0 -183
  143. package/orchestrator/tests/recovery.test.cjs +0 -190
  144. package/orchestrator/tests/session-runner.test.cjs +0 -314
  145. package/orchestrator/tests/skill-miner.test.cjs +0 -147
  146. package/orchestrator/tests/worktree-manager.test.cjs +0 -148
  147. package/skills/ultra-research/references/architecture.md +0 -38
  148. package/skills/ultra-research/references/problem-product.md +0 -39
  149. package/skills/ultra-research/references/quality-delivery.md +0 -34
  150. package/skills/ultra-research/references/synthesis.md +0 -38
  151. package/skills/ultra-research/references/users-scope.md +0 -40
  152. package/ultra-tools/legacy-memory.test.cjs +0 -80
  153. package/ultra-tools/status-command.test.cjs +0 -181
  154. 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
@@ -401,6 +458,7 @@ tools:
401
458
  errors:
402
459
  - { code: PARSE_FAILED, description: 'the host-derived PRD task graph is invalid' }
403
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' }
404
462
  - { code: CHANGE_NOT_FOUND, description: 'assigned change does not exist' }
405
463
  - { code: CHANGE_NOT_MUTABLE, description: 'assigned change no longer accepts tasks' }
406
464
  - { code: BASELINE_NOT_READY, description: 'persisting parsed tasks requires a ready baseline or an already-authorized active change' }
@@ -416,8 +474,12 @@ tools:
416
474
  input_schema:
417
475
  type: object
418
476
  additionalProperties: false
477
+ oneOf:
478
+ - required: [task_ids]
479
+ - required: [change_id]
419
480
  properties:
420
- 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_\-]+$' }
421
483
  output_schema:
422
484
  type: object
423
485
  required: [waves]
@@ -427,13 +489,15 @@ tools:
427
489
  cycles: { type: array, items: { type: array, items: { type: string } } }
428
490
  errors:
429
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' }
430
494
  cli_subcommand: task topo
431
495
  emits_events: []
432
496
  trace_to: '§7.3, D34'
433
497
 
434
498
  - name: task.append_event
435
499
  family: task
436
- 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.
437
501
  phase: '2'
438
502
  writer_role: any
439
503
  input_schema:
@@ -448,35 +512,12 @@ tools:
448
512
  type:
449
513
  type: string
450
514
  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
515
  - context_updated
465
- - plan_approved
466
516
  - commit_pushed
467
- - review_verdict
468
517
  - merge_conflict
469
- - auto_merged
470
518
  - cost_alert
471
519
  - token_alert
472
520
  - 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
521
  payload: { type: object }
481
522
  output_schema:
482
523
  type: object
@@ -958,13 +999,71 @@ tools:
958
999
  writer_role: mcp
959
1000
  input_schema:
960
1001
  type: object
961
- required: [id, title, kind, intent]
1002
+ required: [id, title, kind, intent, contract, classification, research_disposition]
962
1003
  additionalProperties: false
963
1004
  properties:
964
1005
  id: { type: string, pattern: '^[a-zA-Z0-9_\-]+$' }
965
1006
  title: { type: string, minLength: 3 }
966
1007
  kind: { type: string, enum: [quick, standard, major, incident] }
967
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 }
968
1067
  base_commit: { type: string, pattern: '^[0-9a-f]{7,40}$' }
969
1068
  baseline_bypass:
970
1069
  type: object
@@ -1009,20 +1108,25 @@ tools:
1009
1108
  status: { type: string, enum: [available, unavailable, fresh, stale, unknown] }
1010
1109
  output_schema:
1011
1110
  type: object
1012
- required: [change, intent_path, context_manifest_path]
1111
+ required: [change, intent_path, context_manifest_path, workflow]
1013
1112
  additionalProperties: false
1014
1113
  properties:
1015
1114
  change: { type: object }
1016
1115
  intent_path: { type: string }
1017
1116
  context_manifest_path: { type: string }
1117
+ workflow: { type: object }
1018
1118
  errors:
1019
1119
  - { code: DUPLICATE_CHANGE_ID, description: 'change id already exists' }
1020
1120
  - { code: PROVIDER_CONTENT_FORBIDDEN, description: 'provider payload content must remain external' }
1021
1121
  - { code: VALIDATION_ERROR, description: 'change input failed validation' }
1022
1122
  - { code: BASELINE_NOT_READY, description: 'ordinary work is blocked until the project baseline is healthy' }
1023
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' }
1024
1128
  cli_subcommand: change create
1025
- emits_events: [change_created, context_updated]
1129
+ emits_events: [change_created, context_updated, workflow_started, workflow_step_updated]
1026
1130
 
1027
1131
  - name: change.update
1028
1132
  family: change
@@ -1075,6 +1179,9 @@ tools:
1075
1179
  revision: { type: string }
1076
1180
  indexed_head: { type: string }
1077
1181
  status: { type: string, enum: [available, unavailable, fresh, stale, unknown] }
1182
+ contract: *change_contract
1183
+ classification: *change_classification
1184
+ research_disposition: *change_research_disposition
1078
1185
  output_schema:
1079
1186
  type: object
1080
1187
  required: [ok, change]
@@ -1138,7 +1245,7 @@ tools:
1138
1245
 
1139
1246
  - name: change.context
1140
1247
  family: change
1141
- 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.
1142
1249
  phase: '10'
1143
1250
  writer_role: mcp
1144
1251
  input_schema:
@@ -1150,7 +1257,6 @@ tools:
1150
1257
  task_id: { type: string }
1151
1258
  role: { type: string, enum: [plan, implement, check, review] }
1152
1259
  gate: { type: string, enum: [alignment, planning, implementation, verification, review, convergence, recovery] }
1153
- next_action: { type: string, minLength: 3 }
1154
1260
  spec_refs: { type: array, items: { type: object } }
1155
1261
  context_refs:
1156
1262
  type: array
@@ -1175,11 +1281,7 @@ tools:
1175
1281
  type: object
1176
1282
  additionalProperties: false
1177
1283
  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
1284
  context_budget_percent: { type: integer, minimum: 1, maximum: 100, default: 40 }
1182
- allowed_paths: { type: array, items: { type: string } }
1183
1285
  provider_refs:
1184
1286
  type: object
1185
1287
  additionalProperties: false
@@ -1219,6 +1321,9 @@ tools:
1219
1321
  - { code: CHANGE_NOT_FOUND, description: 'change id does not exist' }
1220
1322
  - { code: CHANGE_TERMINAL, description: 'terminal change cannot compile a new context' }
1221
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' }
1222
1327
  - { code: PROVIDER_CONTENT_FORBIDDEN, description: 'provider payload content must remain external' }
1223
1328
  cli_subcommand: change context
1224
1329
  emits_events: [context_updated]
@@ -1291,6 +1396,10 @@ tools:
1291
1396
  candidate_id: { type: string, pattern: '^[a-zA-Z0-9_\-]+$' }
1292
1397
  decision: { type: string, enum: [approve, reject, apply] }
1293
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 } }
1294
1403
  output_schema:
1295
1404
  type: object
1296
1405
  required: [candidate]
@@ -1302,6 +1411,8 @@ tools:
1302
1411
  - { code: CHANGE_NOT_FOUND, description: 'change id does not exist' }
1303
1412
  - { code: LEARNING_NOT_FOUND, description: 'candidate id does not exist for the change' }
1304
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' }
1305
1416
  cli_subcommand: change learning-resolve
1306
1417
  emits_events: [spec_learning_resolved]
1307
1418
 
@@ -1312,34 +1423,10 @@ tools:
1312
1423
  writer_role: mcp
1313
1424
  input_schema:
1314
1425
  type: object
1315
- required: [id, evidence]
1426
+ required: [id]
1316
1427
  additionalProperties: false
1317
1428
  properties:
1318
1429
  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
1430
  output_schema:
1344
1431
  type: object
1345
1432
  required: [ready, status, blockers]
@@ -1352,6 +1439,7 @@ tools:
1352
1439
  errors:
1353
1440
  - { code: CHANGE_NOT_FOUND, description: 'change id does not exist' }
1354
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' }
1355
1443
  cli_subcommand: change converge
1356
1444
  emits_events: [change_blocked, change_converged]
1357
1445
 
@@ -1362,13 +1450,14 @@ tools:
1362
1450
  writer_role: mcp
1363
1451
  input_schema:
1364
1452
  type: object
1365
- required: [id, summary]
1453
+ required: [id, summary, reconciliation_path]
1366
1454
  additionalProperties: false
1367
1455
  properties:
1368
1456
  id: { type: string }
1369
1457
  summary: { type: string, minLength: 3 }
1370
1458
  baseline_updates: { type: array, items: { type: string } }
1371
1459
  no_baseline_change_reason: { type: string, minLength: 3 }
1460
+ reconciliation_path: { type: string, minLength: 3 }
1372
1461
  output_schema:
1373
1462
  type: object
1374
1463
  required: [change, archive_path]
@@ -1381,10 +1470,236 @@ tools:
1381
1470
  - { code: BASELINE_RECONCILIATION_REQUIRED, description: 'baseline update or explicit no-change reason required' }
1382
1471
  - { code: BASELINE_FILE_MISSING, description: 'a declared baseline update does not exist' }
1383
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' }
1384
1475
  - { code: ARCHIVE_EXISTS, description: 'archive target already exists' }
1385
1476
  cli_subcommand: change archive
1386
1477
  emits_events: [change_archived]
1387
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
+
1388
1703
  # ────────────────────────── system family ──────────────────────────────
1389
1704
  - name: system.doctor
1390
1705
  family: system
@@ -1420,10 +1735,11 @@ tools:
1420
1735
  writer_role: mcp
1421
1736
  input_schema:
1422
1737
  type: object
1423
- required: [out_path]
1738
+ required: [change_id, out_path]
1424
1739
  additionalProperties: false
1425
1740
  properties:
1426
1741
  format: { type: string, enum: [json, md], default: json }
1742
+ change_id: { type: string, pattern: '^[a-zA-Z0-9_\-]+$' }
1427
1743
  out_path: { type: string }
1428
1744
  tag: { type: string }
1429
1745
  output_schema:
@@ -1435,9 +1751,11 @@ tools:
1435
1751
  wave_count: { type: integer, minimum: 0 }
1436
1752
  errors:
1437
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' }
1438
1756
  - { code: WRITE_FAILED, description: 'cannot write plan file' }
1439
1757
  cli_subcommand: plan export
1440
- emits_events: [plan_approved]
1758
+ emits_events: [plan_exported]
1441
1759
  trace_to: '§7.3, D34'
1442
1760
 
1443
1761
  - name: plan.get
@@ -1447,8 +1765,10 @@ tools:
1447
1765
  readonly: true
1448
1766
  input_schema:
1449
1767
  type: object
1768
+ required: [change_id]
1450
1769
  additionalProperties: false
1451
1770
  properties:
1771
+ change_id: { type: string, pattern: '^[a-zA-Z0-9_\-]+$' }
1452
1772
  section: { type: string, enum: [tasks, topo, conflicts, all], default: all }
1453
1773
  output_schema:
1454
1774
  type: object
@@ -1458,6 +1778,7 @@ tools:
1458
1778
  plan: { type: object }
1459
1779
  errors:
1460
1780
  - { code: NO_PLAN, description: 'no plan has been computed yet' }
1781
+ - { code: PLAN_CHANGE_MISMATCH, description: 'current plan artifact belongs to another change' }
1461
1782
  cli_subcommand: plan get
1462
1783
  emits_events: []
1463
1784
  trace_to: '§7.3, D34'