ultra-builder-pro-cli 0.20.0 → 0.22.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 (109) hide show
  1. package/.ultra-template/docs/research/README.md +26 -5
  2. package/.ultra-template/specs/discovery.md +1 -1
  3. package/.ultra-template/tasks/tasks.json +10 -3
  4. package/.ultra-template/templates/task-context.md +19 -0
  5. package/CHANGELOG.md +106 -0
  6. package/README.md +215 -41
  7. package/adapters/_shared/codex-assets.cjs +69 -11
  8. package/adapters/_shared/interaction-contract.cjs +36 -3
  9. package/adapters/_shared/runtime-assets.cjs +41 -1
  10. package/adapters/claude.js +7 -5
  11. package/adapters/codex.js +1 -1
  12. package/adapters/kimi.js +2 -8
  13. package/adapters/opencode.js +43 -30
  14. package/bin/orchestrator.js +64 -24
  15. package/docs/AGENT-CONTEXT.md +89 -49
  16. package/docs/ARCHITECTURE.md +112 -45
  17. package/docs/ARTIFACT-AUTHORITY.md +274 -0
  18. package/docs/COMMIT-HASH-BACKFILL.md +33 -90
  19. package/docs/DECISIONS.md +14 -6
  20. package/docs/LEGACY-CLI-CROSSWALK.md +16 -6
  21. package/docs/PLUGIN-ISOLATION-CONTRACT.md +6 -4
  22. package/docs/ROADMAP.md +20 -6
  23. package/docs/RUNTIME-COMPAT-MATRIX.md +29 -16
  24. package/docs/STATE-DB-ACCESS-POLICY.md +43 -13
  25. package/docs/WORKFLOW-LIFECYCLE.md +105 -50
  26. package/hooks/README.md +10 -8
  27. package/hooks/active_task_context.py +105 -18
  28. package/hooks/context_spine.py +16 -4
  29. package/hooks/health_check.py +5 -4
  30. package/hooks/pre_stop_check.py +5 -2
  31. package/hooks/runtime_paths.py +396 -0
  32. package/hooks/subagent_tracker.py +5 -2
  33. package/hooks/workflow_checkpoint.py +16 -3
  34. package/hooks/workflow_context.py +11 -3
  35. package/hooks/workflow_resume.py +7 -4
  36. package/mcp-server/breadcrumb.cjs +20 -2
  37. package/mcp-server/lib/archive-journal.cjs +1026 -111
  38. package/mcp-server/lib/archive-mutation-worker.py +365 -0
  39. package/mcp-server/lib/artifact-registry.cjs +1127 -0
  40. package/mcp-server/lib/baseline-workflow.cjs +69 -28
  41. package/mcp-server/lib/change-packet.cjs +818 -0
  42. package/mcp-server/lib/change-workflow.cjs +932 -176
  43. package/mcp-server/lib/context-paths.cjs +142 -0
  44. package/mcp-server/lib/context-spine.cjs +511 -45
  45. package/mcp-server/lib/decision-dialogue.cjs +345 -3
  46. package/mcp-server/lib/delivery-transaction.cjs +471 -0
  47. package/mcp-server/lib/doctor-backup-worker.cjs +328 -0
  48. package/mcp-server/lib/doctor.cjs +401 -11
  49. package/mcp-server/lib/git-bootstrap.cjs +458 -47
  50. package/mcp-server/lib/init-project.cjs +240 -95
  51. package/mcp-server/lib/plan-publication-worker.cjs +830 -0
  52. package/mcp-server/lib/plan-store.cjs +700 -5
  53. package/mcp-server/lib/project-breadcrumb.cjs +23 -4
  54. package/mcp-server/lib/projector.cjs +211 -42
  55. package/mcp-server/lib/runtime-paths.cjs +1687 -0
  56. package/mcp-server/lib/safe-project-file.cjs +385 -0
  57. package/mcp-server/lib/spec-learning.cjs +28 -12
  58. package/mcp-server/lib/state-authority.cjs +19 -3
  59. package/mcp-server/lib/state-db.cjs +263 -9
  60. package/mcp-server/lib/state-ops.cjs +254 -50
  61. package/mcp-server/lib/task-ledger.cjs +1342 -0
  62. package/mcp-server/lib/telemetry.cjs +12 -3
  63. package/mcp-server/lib/workflow-state.cjs +610 -58
  64. package/mcp-server/server.cjs +423 -42
  65. package/orchestrator/daemon.cjs +2 -10
  66. package/orchestrator/parallel-orchestrator.cjs +314 -50
  67. package/orchestrator/planner/plan-builder.cjs +1 -1
  68. package/orchestrator/recovery.cjs +125 -7
  69. package/orchestrator/session-close-journal-worker.cjs +5 -0
  70. package/orchestrator/session-close-journal.cjs +1014 -0
  71. package/orchestrator/session-runner.cjs +679 -69
  72. package/orchestrator/worktree-manager.cjs +186 -35
  73. package/package.json +2 -3
  74. package/skills/cc-collab/SKILL.md +4 -1
  75. package/skills/codex-collab/SKILL.md +5 -2
  76. package/skills/ultra-change/SKILL.md +34 -8
  77. package/skills/ultra-deliver/SKILL.md +26 -11
  78. package/skills/ultra-dev/SKILL.md +52 -10
  79. package/skills/ultra-doctor/SKILL.md +16 -3
  80. package/skills/ultra-init/SKILL.md +22 -11
  81. package/skills/ultra-plan/SKILL.md +58 -18
  82. package/skills/ultra-research/SKILL.md +37 -35
  83. package/skills/ultra-review/SKILL.md +14 -8
  84. package/skills/ultra-status/SKILL.md +18 -9
  85. package/skills/ultra-test/SKILL.md +11 -5
  86. package/skills/ultra-think/SKILL.md +6 -2
  87. package/skills/ultra-think/references/decision-dialogue.md +17 -6
  88. package/skills/ultra-verify/SKILL.md +4 -1
  89. package/spec/cli-protocol.md +21 -7
  90. package/spec/mcp-tools.yaml +629 -44
  91. package/spec/schemas/change-delta.v1.schema.json +153 -0
  92. package/spec/schemas/context-file.v4.5.schema.json +1 -1
  93. package/spec/schemas/documentation-reconciliation.v1.schema.json +106 -0
  94. package/spec/schemas/mcp-tools.schema.json +1 -1
  95. package/spec/schemas/state-db.sql +51 -14
  96. package/spec/schemas/task-ledger.v1.schema.json +217 -0
  97. package/spec/schemas/tasks.v4.5.schema.json +1 -1
  98. package/ultra-tools/cli.cjs +3 -2
  99. package/ultra-tools/commands/db.cjs +76 -25
  100. package/ultra-tools/commands/migrate.cjs +1000 -82
  101. package/ultra-tools/commands/session.cjs +34 -8
  102. package/ultra-tools/commands/status.cjs +32 -6
  103. package/ultra-tools/commands/system.cjs +129 -22
  104. package/.ultra-template/tasks/contexts/TEMPLATE.md +0 -19
  105. package/commands/learn.md +0 -10
  106. package/orchestrator/skill-miner.cjs +0 -133
  107. package/output-styles/coding-vibes.md +0 -67
  108. package/output-styles/structural-thinking.md +0 -61
  109. package/skills/learn/SKILL.md +0 -58
@@ -0,0 +1,153 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://ultra-builder-pro.dev/schemas/change-delta.v1.schema.json",
4
+ "title": "Ultra Change delta v1",
5
+ "type": "object",
6
+ "required": [
7
+ "$schema",
8
+ "change_id",
9
+ "baseline_anchor",
10
+ "decisions",
11
+ "non_goals",
12
+ "acceptance",
13
+ "documentation_impact",
14
+ "unknowns",
15
+ "mutations"
16
+ ],
17
+ "additionalProperties": false,
18
+ "properties": {
19
+ "$schema": { "const": "ultra-change-delta-v1" },
20
+ "change_id": { "type": "string", "minLength": 1 },
21
+ "baseline_anchor": {
22
+ "type": "object",
23
+ "required": ["baseline_id", "repository_revision", "specs"],
24
+ "additionalProperties": false,
25
+ "properties": {
26
+ "baseline_id": { "type": "string", "minLength": 1 },
27
+ "repository_revision": { "type": ["string", "null"] },
28
+ "specs": {
29
+ "type": "array",
30
+ "uniqueItems": true,
31
+ "items": {
32
+ "type": "object",
33
+ "required": ["path", "digest"],
34
+ "additionalProperties": false,
35
+ "properties": {
36
+ "path": { "type": "string", "minLength": 1 },
37
+ "digest": { "type": "string", "pattern": "^[0-9a-f]{64}$" }
38
+ }
39
+ }
40
+ }
41
+ }
42
+ },
43
+ "decisions": {
44
+ "type": "array",
45
+ "items": {
46
+ "type": "object",
47
+ "required": ["id", "summary"],
48
+ "additionalProperties": false,
49
+ "properties": {
50
+ "id": { "type": "string", "pattern": "^[a-zA-Z0-9_\\-]+$" },
51
+ "summary": { "type": "string", "minLength": 1 },
52
+ "rationale": { "type": "string", "minLength": 1 }
53
+ }
54
+ }
55
+ },
56
+ "non_goals": {
57
+ "type": "array",
58
+ "uniqueItems": true,
59
+ "items": { "type": "string", "minLength": 1 }
60
+ },
61
+ "acceptance": {
62
+ "type": "array",
63
+ "minItems": 1,
64
+ "items": {
65
+ "type": "object",
66
+ "required": ["id", "criterion", "verification"],
67
+ "additionalProperties": false,
68
+ "properties": {
69
+ "id": { "type": "string", "pattern": "^[a-zA-Z0-9_\\-]+$" },
70
+ "criterion": { "type": "string", "minLength": 1 },
71
+ "verification": { "type": "string", "minLength": 1 }
72
+ }
73
+ }
74
+ },
75
+ "documentation_impact": {
76
+ "type": "object",
77
+ "required": ["status", "files", "rationale"],
78
+ "additionalProperties": false,
79
+ "properties": {
80
+ "status": { "enum": ["none", "required"] },
81
+ "files": {
82
+ "type": "array",
83
+ "uniqueItems": true,
84
+ "items": { "type": "string", "minLength": 1 }
85
+ },
86
+ "rationale": { "type": "string", "minLength": 3 }
87
+ }
88
+ },
89
+ "unknowns": {
90
+ "type": "array",
91
+ "items": {
92
+ "type": "object",
93
+ "required": ["id", "summary", "blocking"],
94
+ "additionalProperties": false,
95
+ "properties": {
96
+ "id": { "type": "string", "pattern": "^[a-zA-Z0-9_\\-]+$" },
97
+ "summary": { "type": "string", "minLength": 1 },
98
+ "blocking": { "type": "boolean" }
99
+ }
100
+ }
101
+ },
102
+ "no_semantic_change_reason": { "type": "string", "minLength": 3 },
103
+ "mutations": {
104
+ "type": "array",
105
+ "items": {
106
+ "type": "object",
107
+ "required": [
108
+ "id",
109
+ "action",
110
+ "target_path",
111
+ "overlay_path",
112
+ "before_digest",
113
+ "after_digest",
114
+ "acceptance_refs",
115
+ "documentation_refs"
116
+ ],
117
+ "additionalProperties": false,
118
+ "properties": {
119
+ "id": { "type": "string", "pattern": "^[a-zA-Z0-9_\\-]+$" },
120
+ "action": { "enum": ["add", "update"] },
121
+ "target_path": { "type": "string", "minLength": 1 },
122
+ "overlay_path": { "type": "string", "minLength": 1 },
123
+ "before_digest": {
124
+ "type": ["string", "null"],
125
+ "pattern": "^[0-9a-f]{64}$"
126
+ },
127
+ "after_digest": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
128
+ "acceptance_refs": {
129
+ "type": "array",
130
+ "minItems": 1,
131
+ "uniqueItems": true,
132
+ "items": { "type": "string", "minLength": 1 }
133
+ },
134
+ "documentation_refs": {
135
+ "type": "array",
136
+ "uniqueItems": true,
137
+ "items": { "type": "string", "minLength": 1 }
138
+ }
139
+ }
140
+ }
141
+ }
142
+ },
143
+ "allOf": [
144
+ {
145
+ "if": {
146
+ "properties": {
147
+ "mutations": { "maxItems": 0 }
148
+ }
149
+ },
150
+ "then": { "required": ["no_semantic_change_reason"] }
151
+ }
152
+ ]
153
+ }
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://ultra-builder-pro.dev/spec/context-file.v4.5.schema.json",
4
4
  "title": "context-file projection (v4.5)",
5
- "description": "Schema for the parsed representation of .ultra/tasks/contexts/task-*.md. The header is regenerated by the projector from state.db. Body sections are author-owned; status MUST NOT appear in body. Authority boundary: docs/DECISIONS.md.",
5
+ "description": "Schema for the parsed representation of .ultra/.runtime/projections/contexts/task-*.md. The file is regenerated by the projector from state.db and remains checkout-local. Authority boundary: docs/ARTIFACT-AUTHORITY.md.",
6
6
  "type": "object",
7
7
  "required": ["header", "body"],
8
8
  "additionalProperties": false,
@@ -0,0 +1,106 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://ultra-builder-pro.dev/schemas/documentation-reconciliation.v1.schema.json",
4
+ "title": "Ultra documentation reconciliation v1",
5
+ "type": "object",
6
+ "required": [
7
+ "$schema",
8
+ "change_id",
9
+ "delta_artifact_id",
10
+ "delta_digest",
11
+ "documents"
12
+ ],
13
+ "additionalProperties": false,
14
+ "properties": {
15
+ "$schema": { "const": "ultra-documentation-reconciliation-v1" },
16
+ "change_id": { "type": "string", "minLength": 1 },
17
+ "delta_artifact_id": { "type": "string", "minLength": 1 },
18
+ "delta_digest": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
19
+ "no_change_reason": { "type": "string", "minLength": 3 },
20
+ "documents": {
21
+ "type": "array",
22
+ "items": {
23
+ "type": "object",
24
+ "required": [
25
+ "path",
26
+ "action",
27
+ "overlay_path",
28
+ "before_digest",
29
+ "after_digest",
30
+ "delta_refs",
31
+ "acceptance_refs",
32
+ "verification",
33
+ "consumers"
34
+ ],
35
+ "additionalProperties": false,
36
+ "properties": {
37
+ "path": { "type": "string", "minLength": 1 },
38
+ "action": { "enum": ["add", "update"] },
39
+ "overlay_path": { "type": "string", "minLength": 1 },
40
+ "before_digest": {
41
+ "type": ["string", "null"],
42
+ "pattern": "^[0-9a-f]{64}$"
43
+ },
44
+ "after_digest": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
45
+ "delta_refs": {
46
+ "type": "array",
47
+ "minItems": 1,
48
+ "uniqueItems": true,
49
+ "items": { "type": "string", "minLength": 1 }
50
+ },
51
+ "acceptance_refs": {
52
+ "type": "array",
53
+ "minItems": 1,
54
+ "uniqueItems": true,
55
+ "items": { "type": "string", "minLength": 1 }
56
+ },
57
+ "verification": {
58
+ "type": "array",
59
+ "minItems": 1,
60
+ "items": {
61
+ "type": "object",
62
+ "required": ["command", "status", "evidence_refs"],
63
+ "additionalProperties": false,
64
+ "properties": {
65
+ "command": { "type": "string", "minLength": 1 },
66
+ "status": { "const": "pass" },
67
+ "evidence_refs": {
68
+ "type": "array",
69
+ "minItems": 1,
70
+ "uniqueItems": true,
71
+ "items": { "type": "string", "minLength": 1 }
72
+ }
73
+ }
74
+ }
75
+ },
76
+ "consumers": {
77
+ "type": "array",
78
+ "items": {
79
+ "type": "object",
80
+ "required": ["type", "id", "relation"],
81
+ "additionalProperties": false,
82
+ "properties": {
83
+ "type": {
84
+ "enum": ["artifact", "project", "baseline", "change", "task", "workflow", "external"]
85
+ },
86
+ "id": { "type": "string", "minLength": 1 },
87
+ "relation": { "type": "string", "minLength": 1 }
88
+ }
89
+ }
90
+ },
91
+ "no_consumer_reason": { "type": "string", "minLength": 3 }
92
+ }
93
+ }
94
+ }
95
+ },
96
+ "allOf": [
97
+ {
98
+ "if": {
99
+ "properties": {
100
+ "documents": { "maxItems": 0 }
101
+ }
102
+ },
103
+ "then": { "required": ["no_change_reason"] }
104
+ }
105
+ ]
106
+ }
@@ -60,7 +60,7 @@
60
60
  },
61
61
  "family": {
62
62
  "type": "string",
63
- "enum": ["task", "memory", "review", "impact", "skill", "session", "ask", "plan", "baseline", "change", "decision", "workflow", "system"]
63
+ "enum": ["task", "memory", "review", "impact", "skill", "session", "ask", "plan", "baseline", "change", "decision", "workflow", "artifact", "system"]
64
64
  },
65
65
  "description": { "type": "string", "minLength": 10 },
66
66
  "phase": {
@@ -1,5 +1,5 @@
1
1
  -- Ultra Builder Pro — authoritative state schema
2
- -- This file builds .ultra/state.db, the source of truth for all
2
+ -- This file builds .ultra/.runtime/state.db, the source of truth for all
3
3
  -- baseline / change / task / session / event / telemetry data. tasks.json and context md status
4
4
  -- headers are projections.
5
5
  --
@@ -15,7 +15,7 @@
15
15
  -- ──────────────────────────── project baseline ─────────────────────────────
16
16
  -- The baseline is the approved, repository-scoped snapshot that every change
17
17
  -- is measured against. It stores digests and evidence references, never source,
18
- -- prompt, transcript, memory, or code-graph payloads.
18
+ -- prompt, transcript, general memory-provider, or code-graph payloads.
19
19
  CREATE TABLE IF NOT EXISTS baselines (
20
20
  id TEXT PRIMARY KEY,
21
21
  project_name TEXT NOT NULL,
@@ -105,7 +105,7 @@ CREATE TABLE IF NOT EXISTS tasks (
105
105
  docs_impact_json TEXT NOT NULL DEFAULT '{"status":"unknown","files":[],"rationale":null}',
106
106
  ownership_json TEXT NOT NULL DEFAULT '{}',
107
107
  context_file TEXT, -- projection target path
108
- completion_commit TEXT, -- backfilled hash (Phase 2.8)
108
+ completion_commit TEXT, -- checkout-local integrated commit evidence
109
109
  change_id TEXT REFERENCES changes(id) ON DELETE SET NULL,
110
110
  parent_id TEXT REFERENCES tasks(id) ON DELETE SET NULL, -- Phase 8A.1: task.expand subtask→parent
111
111
  created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
@@ -159,6 +159,8 @@ CREATE TABLE IF NOT EXISTS sessions (
159
159
 
160
160
  CREATE INDEX IF NOT EXISTS sessions_active ON sessions(status, task_id);
161
161
  CREATE INDEX IF NOT EXISTS sessions_lease ON sessions(lease_expires_at) WHERE status = 'running';
162
+ CREATE UNIQUE INDEX IF NOT EXISTS sessions_one_active_task
163
+ ON sessions(task_id) WHERE status = 'running';
162
164
 
163
165
  -- ──────────────────────────── schema_version ──────────────────────────────
164
166
  -- Cross-version misread guard (D30, R27). Single row per applied version.
@@ -225,20 +227,51 @@ CREATE INDEX IF NOT EXISTS circuit_breaker_tripped ON circuit_breaker(tripped_at
225
227
 
226
228
  -- ──────────────────────────── change artifacts ────────────────────────────
227
229
  CREATE TABLE IF NOT EXISTS artifacts (
228
- id TEXT PRIMARY KEY,
229
- change_id TEXT NOT NULL REFERENCES changes(id) ON DELETE CASCADE,
230
- task_id TEXT REFERENCES tasks(id) ON DELETE SET NULL,
231
- kind TEXT NOT NULL,
232
- path TEXT NOT NULL,
233
- content_hash TEXT,
234
- metadata_json TEXT,
235
- status TEXT NOT NULL DEFAULT 'current' CHECK (status IN ('current', 'archived')),
236
- created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
237
- updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
238
- UNIQUE(change_id, kind, path)
230
+ id TEXT PRIMARY KEY,
231
+ owner_type TEXT NOT NULL
232
+ CHECK (owner_type IN ('project', 'baseline', 'change', 'task', 'workflow')),
233
+ owner_id TEXT NOT NULL,
234
+ change_id TEXT REFERENCES changes(id) ON DELETE SET NULL,
235
+ task_id TEXT REFERENCES tasks(id) ON DELETE SET NULL,
236
+ kind TEXT NOT NULL,
237
+ path TEXT NOT NULL,
238
+ digest TEXT,
239
+ content_hash TEXT,
240
+ before_digest TEXT,
241
+ after_digest TEXT,
242
+ provenance_json TEXT NOT NULL DEFAULT '{}',
243
+ metadata_json TEXT,
244
+ managed INTEGER NOT NULL DEFAULT 0 CHECK (managed IN (0, 1)),
245
+ status TEXT NOT NULL DEFAULT 'current'
246
+ CHECK (status IN ('current', 'stale', 'terminal', 'archived')),
247
+ created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
248
+ updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
249
+ UNIQUE(owner_type, owner_id, kind, path)
239
250
  );
240
251
 
241
252
  CREATE INDEX IF NOT EXISTS artifacts_change ON artifacts(change_id, kind);
253
+ CREATE INDEX IF NOT EXISTS artifacts_owner ON artifacts(owner_type, owner_id, status);
254
+ CREATE INDEX IF NOT EXISTS artifacts_path ON artifacts(path, status);
255
+ CREATE UNIQUE INDEX IF NOT EXISTS artifacts_one_active_path
256
+ ON artifacts(path) WHERE status <> 'archived';
257
+
258
+ CREATE TABLE IF NOT EXISTS artifact_edges (
259
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
260
+ source_type TEXT NOT NULL
261
+ CHECK (source_type IN ('artifact', 'project', 'baseline', 'change', 'task', 'workflow', 'external')),
262
+ source_id TEXT NOT NULL,
263
+ target_type TEXT NOT NULL
264
+ CHECK (target_type IN ('artifact', 'project', 'baseline', 'change', 'task', 'workflow', 'external')),
265
+ target_id TEXT NOT NULL,
266
+ relation TEXT NOT NULL,
267
+ created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
268
+ UNIQUE(source_type, source_id, target_type, target_id, relation)
269
+ );
270
+
271
+ CREATE INDEX IF NOT EXISTS artifact_edges_source
272
+ ON artifact_edges(source_type, source_id);
273
+ CREATE INDEX IF NOT EXISTS artifact_edges_target
274
+ ON artifact_edges(target_type, target_id);
242
275
 
243
276
  CREATE TABLE IF NOT EXISTS context_snapshots (
244
277
  id TEXT PRIMARY KEY,
@@ -265,6 +298,8 @@ CREATE TABLE IF NOT EXISTS context_snapshots (
265
298
  );
266
299
 
267
300
  CREATE INDEX IF NOT EXISTS context_snapshots_change ON context_snapshots(change_id, created_at);
301
+ CREATE INDEX IF NOT EXISTS context_snapshots_binding
302
+ ON context_snapshots(change_id, task_id, role, gate, created_at);
268
303
 
269
304
  CREATE TABLE IF NOT EXISTS spec_learning_candidates (
270
305
  id TEXT PRIMARY KEY,
@@ -495,3 +530,5 @@ INSERT OR IGNORE INTO schema_version (version, description)
495
530
  VALUES ('18.0', 'Adaptive capability transitions, independent initialization, and recoverable workflow migration');
496
531
  INSERT OR IGNORE INTO schema_version (version, description)
497
532
  VALUES ('19.0', 'Non-ceremonial decision completion and host-neutral intent persistence');
533
+ INSERT OR IGNORE INTO schema_version (version, description)
534
+ VALUES ('20.0', 'Typed artifact registry, normalized dependency edges, and orphan diagnostics');
@@ -0,0 +1,217 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://ultra-builder-pro.dev/spec/task-ledger.v1.schema.json",
4
+ "title": "Ultra team task ledger v1",
5
+ "description": "Git-facing checkpoint ledger for durable task contracts and statuses. Live sessions, leases, worktrees, and in-progress ownership remain in .ultra/.runtime/state.db.",
6
+ "type": "object",
7
+ "required": [
8
+ "kind",
9
+ "schema_version",
10
+ "generation",
11
+ "parent_digest",
12
+ "ancestors",
13
+ "state_digest",
14
+ "published_at",
15
+ "reason",
16
+ "baseline",
17
+ "changes",
18
+ "tasks"
19
+ ],
20
+ "additionalProperties": false,
21
+ "properties": {
22
+ "kind": { "const": "ultra-team-task-ledger" },
23
+ "schema_version": { "const": "1.0" },
24
+ "generation": { "type": "integer", "minimum": 0 },
25
+ "parent_digest": {
26
+ "type": ["string", "null"],
27
+ "pattern": "^[0-9a-f]{64}$"
28
+ },
29
+ "ancestors": {
30
+ "type": "array",
31
+ "maxItems": 64,
32
+ "items": { "type": "string", "pattern": "^[0-9a-f]{64}$" }
33
+ },
34
+ "state_digest": {
35
+ "type": "string",
36
+ "pattern": "^[0-9a-f]{64}$"
37
+ },
38
+ "published_at": {
39
+ "type": ["string", "null"],
40
+ "format": "date-time"
41
+ },
42
+ "reason": { "type": "string", "minLength": 1 },
43
+ "baseline": {
44
+ "oneOf": [
45
+ { "type": "null" },
46
+ { "$ref": "#/$defs/baseline" }
47
+ ]
48
+ },
49
+ "changes": {
50
+ "type": "array",
51
+ "items": {
52
+ "type": "object",
53
+ "required": [
54
+ "id",
55
+ "title",
56
+ "kind",
57
+ "status",
58
+ "intent",
59
+ "artifact_root",
60
+ "revision",
61
+ "parent_digest",
62
+ "digest"
63
+ ],
64
+ "additionalProperties": false,
65
+ "properties": {
66
+ "id": { "type": "string" },
67
+ "title": { "type": "string", "minLength": 1 },
68
+ "kind": { "type": "string", "enum": ["quick", "standard", "major", "incident"] },
69
+ "status": { "type": "string", "enum": ["active", "blocked", "ready", "archived", "cancelled"] },
70
+ "intent": { "type": "string", "minLength": 1 },
71
+ "docs_impact": { "type": "object" },
72
+ "provider_refs": { "type": "object" },
73
+ "baseline_bypass": { "type": "object" },
74
+ "contract": { "type": "object" },
75
+ "classification": { "type": "object" },
76
+ "research_disposition": { "type": "object" },
77
+ "base_commit": { "type": "string" },
78
+ "artifact_root": { "type": "string", "minLength": 1 },
79
+ "closed_at": { "type": "string" },
80
+ "revision": { "type": "integer", "minimum": 1 },
81
+ "parent_digest": {
82
+ "type": ["string", "null"],
83
+ "pattern": "^[0-9a-f]{64}$"
84
+ },
85
+ "digest": { "type": "string", "pattern": "^[0-9a-f]{64}$" }
86
+ }
87
+ }
88
+ },
89
+ "tasks": {
90
+ "type": "array",
91
+ "items": { "$ref": "#/$defs/task" }
92
+ }
93
+ },
94
+ "$defs": {
95
+ "baseline": {
96
+ "type": "object",
97
+ "required": [
98
+ "id",
99
+ "project_name",
100
+ "mode",
101
+ "status",
102
+ "scope",
103
+ "worktree_accepted",
104
+ "known_red_accepted",
105
+ "spec_refs",
106
+ "evidence",
107
+ "verification",
108
+ "unknowns",
109
+ "gaps",
110
+ "classification",
111
+ "provider_refs",
112
+ "revision",
113
+ "parent_digest",
114
+ "digest"
115
+ ],
116
+ "additionalProperties": false,
117
+ "properties": {
118
+ "id": { "type": "string", "minLength": 1 },
119
+ "project_name": { "type": "string", "minLength": 1 },
120
+ "project_type": { "type": "string" },
121
+ "stack": { "type": "string" },
122
+ "mode": {
123
+ "type": "string",
124
+ "enum": ["greenfield", "brownfield", "migrated"]
125
+ },
126
+ "status": {
127
+ "type": "string",
128
+ "enum": ["draft", "adopting", "blocked", "ready"]
129
+ },
130
+ "scope": {
131
+ "type": "array",
132
+ "minItems": 1,
133
+ "items": { "type": "string", "minLength": 1 }
134
+ },
135
+ "repository_revision": { "type": "string" },
136
+ "repository_branch": { "type": "string" },
137
+ "worktree_state": { "type": "string" },
138
+ "worktree_digest": { "type": "string" },
139
+ "worktree_accepted": { "type": "boolean" },
140
+ "known_red_accepted": { "type": "boolean" },
141
+ "spec_refs": { "type": "array" },
142
+ "evidence": { "type": "array" },
143
+ "verification": { "type": "array" },
144
+ "unknowns": { "type": "array" },
145
+ "gaps": { "type": "array" },
146
+ "classification": { "type": "object" },
147
+ "provider_refs": { "type": "object" },
148
+ "research_run_id": { "type": "string" },
149
+ "approved_by": { "type": "string" },
150
+ "approval_note": { "type": "string" },
151
+ "converged_at": { "type": "string" },
152
+ "revision": { "type": "integer", "minimum": 1 },
153
+ "parent_digest": {
154
+ "type": ["string", "null"],
155
+ "pattern": "^[0-9a-f]{64}$"
156
+ },
157
+ "digest": { "type": "string", "pattern": "^[0-9a-f]{64}$" }
158
+ }
159
+ },
160
+ "task": {
161
+ "type": "object",
162
+ "required": [
163
+ "id",
164
+ "title",
165
+ "type",
166
+ "priority",
167
+ "status",
168
+ "deps",
169
+ "files_modified",
170
+ "stale",
171
+ "acceptance",
172
+ "context_refs",
173
+ "docs_impact",
174
+ "ownership",
175
+ "revision",
176
+ "parent_digest",
177
+ "digest"
178
+ ],
179
+ "additionalProperties": false,
180
+ "properties": {
181
+ "id": { "type": "string", "pattern": "^[a-zA-Z0-9_\\-]+$" },
182
+ "title": { "type": "string", "minLength": 3 },
183
+ "type": { "type": "string", "enum": ["architecture", "feature", "bugfix"] },
184
+ "priority": { "type": "string", "enum": ["P0", "P1", "P2", "P3"] },
185
+ "complexity": { "type": "integer", "minimum": 1, "maximum": 10 },
186
+ "estimated_days": { "type": "number", "exclusiveMinimum": 0 },
187
+ "status": {
188
+ "type": "string",
189
+ "enum": ["pending", "completed", "blocked", "expanded"]
190
+ },
191
+ "deps": { "type": "array", "items": { "type": "string" } },
192
+ "files_modified": { "type": "array", "items": { "type": "string" } },
193
+ "stale": { "type": "boolean" },
194
+ "trace_to": { "type": "string" },
195
+ "outcome": { "type": "string" },
196
+ "slice_kind": {
197
+ "type": "string",
198
+ "enum": ["tracer_bullet", "expand_contract", "integration_checkpoint"]
199
+ },
200
+ "public_seam": { "type": "string" },
201
+ "verification_command": { "type": "string" },
202
+ "acceptance": { "type": "array", "items": { "type": "object" } },
203
+ "context_refs": { "type": "array", "items": { "type": "object" } },
204
+ "docs_impact": { "type": "object" },
205
+ "ownership": { "type": "object" },
206
+ "change_id": { "type": "string" },
207
+ "parent_id": { "type": "string" },
208
+ "revision": { "type": "integer", "minimum": 1 },
209
+ "parent_digest": {
210
+ "type": ["string", "null"],
211
+ "pattern": "^[0-9a-f]{64}$"
212
+ },
213
+ "digest": { "type": "string", "pattern": "^[0-9a-f]{64}$" }
214
+ }
215
+ }
216
+ }
217
+ }
@@ -9,7 +9,7 @@
9
9
  "properties": {
10
10
  "schema_version": { "const": "4.5" },
11
11
  "generated_at": { "type": "string", "format": "date-time" },
12
- "source": { "const": ".ultra/state.db", "description": "authoritative source (D32)" },
12
+ "source": { "const": ".ultra/.runtime/state.db", "description": "authoritative source (D32)" },
13
13
  "tasks": {
14
14
  "type": "array",
15
15
  "items": { "$ref": "#/$defs/task" }
@@ -17,6 +17,7 @@
17
17
 
18
18
  const fs = require('node:fs');
19
19
  const path = require('node:path');
20
+ const runtimePaths = require('../mcp-server/lib/runtime-paths.cjs');
20
21
 
21
22
  const VERSION = (() => {
22
23
  try {
@@ -38,7 +39,7 @@ SUBCOMMANDS:
38
39
  system doctor [--repair] | restore | rebaseline
39
40
  status [--cost] [--since <duration>] [--json]
40
41
  db init | checkpoint | vacuum | integrity | backup (Phase 2)
41
- migrate --from=<4.4|4.5> --to=<4.5|19.0> [--dry|--rollback]
42
+ migrate --from=<4.4|4.5> --to=<4.5|20.0> [--dry|--rollback]
42
43
  legacy-memory inspect | archive | prune --confirm DELETE_ULTRA_LEGACY_MEMORY
43
44
 
44
45
  --help / -h show this message
@@ -75,7 +76,7 @@ const TELEMETRY_SUBCOMMANDS = new Set(['session']);
75
76
 
76
77
  function emitCliTelemetry(sub, rest) {
77
78
  try {
78
- const dbPath = path.resolve('.ultra', 'state.db');
79
+ const dbPath = runtimePaths.locateStateDb(process.cwd());
79
80
  if (!fs.existsSync(dbPath)) return;
80
81
  const Database = require('better-sqlite3');
81
82
  const db = new Database(dbPath);