ultra-builder-pro-cli 0.12.1 → 0.14.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.
- package/.ultra-template/docs/research/README.md +21 -44
- package/.ultra-template/specs/discovery.md +10 -0
- package/CHANGELOG.md +95 -1
- package/README.md +31 -16
- package/adapters/_shared/codex-assets.cjs +23 -163
- package/adapters/_shared/handbook.cjs +2 -2
- package/adapters/_shared/runtime-assets.cjs +1 -0
- package/adapters/_shared/tests/runtime-assets.test.cjs +18 -0
- package/adapters/opencode.js +30 -120
- package/adapters/tests/claude.test.cjs +3 -2
- package/adapters/tests/codex-hook.test.cjs +34 -7
- package/adapters/tests/codex.test.cjs +21 -6
- package/adapters/tests/kimi-hook.test.cjs +34 -7
- package/adapters/tests/opencode.test.cjs +70 -84
- package/commands/ultra-init.md +1 -1
- package/docs/AGENT-CONTEXT.md +10 -6
- package/docs/ARCHITECTURE.md +40 -17
- package/docs/PLAN.zh-CN.md +5 -4
- package/docs/ROADMAP.md +2 -2
- package/docs/RUNTIME-COMPAT-MATRIX.md +4 -4
- package/docs/STATE-DB-ACCESS-POLICY.md +3 -3
- package/docs/USER-HANDBOOK-CONTRACT.md +5 -4
- package/hooks/active_task_context.py +22 -50
- package/hooks/context_spine.py +61 -299
- package/hooks/health_check.py +19 -17
- package/hooks/pre_stop_check.py +28 -33
- package/hooks/subagent_tracker.py +13 -19
- package/hooks/workflow_checkpoint.py +39 -47
- package/hooks/workflow_context.py +4 -9
- package/hooks/workflow_resume.py +48 -128
- package/mcp-server/breadcrumb.cjs +22 -0
- package/mcp-server/lib/archive-journal.cjs +192 -0
- package/mcp-server/lib/archive-journal.test.cjs +35 -0
- package/mcp-server/lib/baseline-workflow.cjs +404 -38
- package/mcp-server/lib/baseline-workflow.test.cjs +252 -0
- package/mcp-server/lib/change-workflow.cjs +249 -75
- package/mcp-server/lib/change-workflow.test.cjs +235 -1
- package/mcp-server/lib/context-spine.test.cjs +5 -0
- package/mcp-server/lib/doctor.cjs +14 -1
- package/mcp-server/lib/doctor.test.cjs +42 -4
- package/mcp-server/lib/init-project.cjs +292 -9
- package/mcp-server/lib/prd-parser.cjs +14 -41
- package/mcp-server/lib/prd-parser.test.cjs +49 -138
- package/mcp-server/lib/project-breadcrumb.cjs +139 -0
- package/mcp-server/lib/project-breadcrumb.test.cjs +112 -0
- package/mcp-server/lib/spec-learning.test.cjs +1 -1
- package/mcp-server/lib/state-authority.cjs +9 -3
- package/mcp-server/lib/state-db.cjs +154 -32
- package/mcp-server/lib/state-db.test.cjs +136 -4
- package/mcp-server/lib/state-ops.cjs +68 -6
- package/mcp-server/lib/task-expander.cjs +14 -37
- package/mcp-server/lib/task-expander.test.cjs +80 -164
- package/mcp-server/server.cjs +34 -37
- package/mcp-server/tests/init-project.test.cjs +162 -1
- package/mcp-server/tests/migrate.test.cjs +33 -0
- package/mcp-server/tests/server-contract.test.cjs +391 -17
- package/mcp-server/tests/state-db.test.cjs +14 -2
- package/mcp-server/tests/state-ops.test.cjs +108 -0
- package/package.json +2 -4
- package/skills/cc-collab/SKILL.md +2 -2
- package/skills/codex-collab/SKILL.md +2 -3
- package/skills/ultra-change/SKILL.md +18 -10
- package/skills/ultra-deliver/SKILL.md +13 -9
- package/skills/ultra-dev/SKILL.md +6 -4
- package/skills/ultra-doctor/SKILL.md +22 -7
- package/skills/ultra-init/SKILL.md +104 -59
- package/skills/ultra-init/references/brownfield-adoption.md +65 -37
- package/skills/ultra-plan/SKILL.md +20 -7
- package/skills/ultra-research/SKILL.md +12 -5
- package/skills/ultra-status/SKILL.md +6 -4
- package/skills/ultra-verify/SKILL.md +21 -30
- package/skills/ultra-verify/scripts/verify_wait.py +54 -54
- package/spec/cli-protocol.md +11 -1
- package/spec/mcp-tools.yaml +133 -19
- package/spec/schemas/state-db.sql +11 -0
- package/ultra-tools/cli.cjs +9 -5
- package/ultra-tools/commands/migrate.cjs +62 -36
- package/ultra-tools/commands/status.cjs +18 -9
- package/ultra-tools/commands/system.cjs +340 -6
- package/ultra-tools/commands/task.cjs +7 -1
- package/ultra-tools/status-command.test.cjs +29 -0
- package/ultra-tools/system-command.test.cjs +252 -1
- package/mcp-server/lib/llm-client.cjs +0 -157
- package/mcp-server/lib/llm-client.test.cjs +0 -156
- package/orchestrator/planner/expand-prompt.cjs +0 -62
- package/orchestrator/planner/expand-prompt.test.cjs +0 -52
- package/orchestrator/planner/prd-prompt.cjs +0 -44
- package/orchestrator/planner/prd-prompt.test.cjs +0 -30
package/docs/AGENT-CONTEXT.md
CHANGED
|
@@ -78,9 +78,10 @@ necessary context when they do not.
|
|
|
78
78
|
role, gate, readiness, blockers, and one next action. They must not inject intent
|
|
79
79
|
bodies, transcripts, external memory, or graph payloads. Missing references,
|
|
80
80
|
digest drift, HEAD drift, or a missing execution seam blocks readiness. Context
|
|
81
|
-
size and
|
|
82
|
-
|
|
83
|
-
|
|
81
|
+
size and baseline drift are advisory for a change that is already active. New ordinary
|
|
82
|
+
work requires a healthy baseline. Only an explicitly approved incident break-glass may
|
|
83
|
+
start without it; incident archive records a blocking reconciliation gap. Revision and
|
|
84
|
+
tracked-spec integrity are reconciled and rechecked atomically for ordinary archive.
|
|
84
85
|
|
|
85
86
|
Stable discoveries use `change.learning_propose`; they reach the baseline only
|
|
86
87
|
through approve/reject/apply transitions in `change.learning_resolve`. Unresolved
|
|
@@ -112,8 +113,10 @@ the shared read-only `context_spine.py` breadcrumb helper:
|
|
|
112
113
|
- `pre_stop_check.py` reports unfinished workflow position at stop without denial;
|
|
113
114
|
- `subagent_tracker.py` for bounded worker lifecycle evidence.
|
|
114
115
|
|
|
115
|
-
`workflow_context.py`, `active_task_context.py`,
|
|
116
|
-
|
|
116
|
+
`workflow_context.py`, `active_task_context.py`, `workflow_resume.py`, and the
|
|
117
|
+
OpenCode plugin invoke the same bundled JavaScript `change.breadcrumb` reader
|
|
118
|
+
through the thin `context_spine.py` bridge. No hook reimplements the state query.
|
|
119
|
+
`health_check.py` and
|
|
117
120
|
`workflow_context.py` may inspect any initialized project;
|
|
118
121
|
`active_task_context.py` always protects the task projection but limits ordinary
|
|
119
122
|
edit guidance to an active workflow. Compact/stop/subagent hooks remain
|
|
@@ -148,7 +151,8 @@ Archive before prune; the confirmation token is intentionally required.
|
|
|
148
151
|
```text
|
|
149
152
|
.ultra/
|
|
150
153
|
├── state.db # authoritative SQLite store
|
|
151
|
-
├──
|
|
154
|
+
├── runtime/
|
|
155
|
+
│ └── checkpoint.json # advisory breadcrumb recovery projection
|
|
152
156
|
├── changes/
|
|
153
157
|
│ ├── active/<id>/ # intent, delta, plan, context v2, learning, verification
|
|
154
158
|
│ └── archive/ # converged packets after baseline reconciliation
|
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -74,7 +74,7 @@ covers seventeen tables:
|
|
|
74
74
|
|
|
75
75
|
| Table | Holds | Phase |
|
|
76
76
|
|--------------------|---------------------------------------------------|-------|
|
|
77
|
-
| `baselines` | greenfield/brownfield adoption, specs, verification,
|
|
77
|
+
| `baselines` | repository classification, greenfield/brownfield adoption, worktree snapshot, specs, evidence, verification, gap ledger, and approval | 12 |
|
|
78
78
|
| `tasks` | task rows — id, status, deps, files_modified, … | 2 |
|
|
79
79
|
| `events` | append-only event stream; `id` is subscription cursor (D31) | 2 |
|
|
80
80
|
| `sessions` | execution sessions, **including lease + heartbeat fields** (D32) | 4.5 |
|
|
@@ -83,7 +83,7 @@ covers seventeen tables:
|
|
|
83
83
|
| `telemetry` | per-session token / cost / tool-call counters | 6 |
|
|
84
84
|
| `specs_refs` | spec change tracking → staleness propagation | 5 |
|
|
85
85
|
| `circuit_breaker` | bounded retry and halt state for failed tasks | 5 |
|
|
86
|
-
| `changes` | continuous feature/fix/incident lifecycle
|
|
86
|
+
| `changes` | continuous feature/fix/incident lifecycle and incident baseline bypass | 12 |
|
|
87
87
|
| `artifacts` | intent/context/verification artifact registry | 8C |
|
|
88
88
|
| `context_snapshots`| role/gate context, readiness, budget, execution seam, hashes, git head, provider refs | 10 |
|
|
89
89
|
| `spec_learning_candidates` | approval-gated implementation discoveries for baseline convergence | 10 |
|
|
@@ -128,23 +128,34 @@ archive/prune command for data created by older releases.
|
|
|
128
128
|
|
|
129
129
|
### Project baseline adoption
|
|
130
130
|
|
|
131
|
-
`task.init_project`
|
|
132
|
-
|
|
133
|
-
|
|
131
|
+
`task.init_project` classifies source, tests, deployment, persistence, package
|
|
132
|
+
scripts, and monorepo markers. It detects `greenfield` or `brownfield`, records
|
|
133
|
+
bounded classification evidence and selected repository scope, and creates the
|
|
134
|
+
same authoritative state shape without rewriting application code.
|
|
135
|
+
|
|
136
|
+
Projection-only v4.4 and v4.5 projects use `ultra-tools migrate` to preserve the
|
|
137
|
+
entire `.ultra` tree, import tasks and events, and create a `migrated/adopting`
|
|
138
|
+
compatibility row. Schema upgrades use `ultra-tools system doctor --repair` and
|
|
139
|
+
produce a pre-migration backup. Compatibility state never grants baseline approval;
|
|
140
|
+
`baseline.start` with `replace_migrated: true` opens the actual brownfield adoption.
|
|
134
141
|
|
|
135
142
|
`baseline.start` opens adoption, `baseline.record` captures server-hashed spec
|
|
136
143
|
references, bounded repository/runtime evidence, actual verification results,
|
|
137
|
-
known unknowns, and
|
|
144
|
+
known unknowns, repository branch and worktree snapshot, the categorized gap ledger,
|
|
145
|
+
and metadata-only external provider references, and
|
|
138
146
|
`baseline.converge` records explicit owner approval. A ready baseline is replaced
|
|
139
147
|
only by an explicit re-adoption, preserving the superseded row for recovery.
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
+
For a selected monorepo scope, the worktree digest and dirty-file list include only
|
|
149
|
+
that scope; out-of-scope changes remain visible repository context but cannot be
|
|
150
|
+
accepted implicitly by `accept_dirty_worktree`.
|
|
151
|
+
|
|
152
|
+
New ordinary changes require a healthy `ready` baseline. A change that was already
|
|
153
|
+
active may continue with baseline drift surfaced as a warning. A new incident can
|
|
154
|
+
start on an unhealthy baseline only with an explicit reason and approver stored in
|
|
155
|
+
`baseline_bypass_json`. Ordinary convergence and archive reconcile HEAD, worktree,
|
|
156
|
+
and tracked-spec drift atomically. Break-glass incident archive creates an open
|
|
157
|
+
blocking reconciliation gap, so incident recovery can finish without falsely marking
|
|
158
|
+
the project baseline healthy.
|
|
148
159
|
|
|
149
160
|
## 4. Continuous changes — the daily unit of convergence
|
|
150
161
|
|
|
@@ -179,10 +190,17 @@ checking, review, convergence, and recovery. Each snapshot records:
|
|
|
179
190
|
- one deterministic next action.
|
|
180
191
|
|
|
181
192
|
`change.breadcrumb` derives the compact current position from state.db. Session,
|
|
182
|
-
edit,
|
|
193
|
+
edit, resume, and OpenCode lifecycle hooks invoke one bundled read-only reader
|
|
194
|
+
and inject only this breadcrumb, never the intent body,
|
|
183
195
|
provider content, or a conversation summary. A changed git HEAD marks the
|
|
184
196
|
snapshot stale and routes back to `change.context`.
|
|
185
197
|
|
|
198
|
+
PRD decomposition and complex-task subdivision use the active host model. The
|
|
199
|
+
MCP accepts the resulting structured tasks, validates schema, topology,
|
|
200
|
+
baseline/change ownership, and transaction boundaries, then persists them. It
|
|
201
|
+
does not call Anthropic, OpenAI, or another model provider and needs no separate
|
|
202
|
+
model API credential.
|
|
203
|
+
|
|
186
204
|
File count, token estimate, and context-share overflow produce warnings, never a
|
|
187
205
|
refusal. The agent may narrow reads, load files lazily, or split a slice when that
|
|
188
206
|
preserves correctness; it must not raise a threshold merely to clear a gate or
|
|
@@ -204,8 +222,13 @@ evidence, and final convergence decision.
|
|
|
204
222
|
|
|
205
223
|
Mutating MCP calls enqueue durable `projection_jobs`. Success is exposed in MCP
|
|
206
224
|
response metadata; failure becomes a retryable structured incident instead of a
|
|
207
|
-
swallowed warning. `system.doctor` is read-only by default
|
|
208
|
-
backup-first
|
|
225
|
+
swallowed warning. `system.doctor` is read-only by default. Explicit repair performs
|
|
226
|
+
backup-first schema upgrade, archive-journal recovery, session and projection
|
|
227
|
+
recovery, and regenerated projections. It cannot approve a baseline or replace a
|
|
228
|
+
corrupt SQLite file silently. `system restore` accepts only a verified SQLite backup
|
|
229
|
+
inside `.ultra/backups`, quarantines the corrupt authority, and rolls back on failure.
|
|
230
|
+
When no valid backup exists, confirmed `system rebaseline` preserves both corrupt
|
|
231
|
+
authority and the legacy task projection before creating a new brownfield adoption.
|
|
209
232
|
|
|
210
233
|
## 5. Sessions — the execution unit
|
|
211
234
|
|
package/docs/PLAN.zh-CN.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# ultra-builder-pro-cli — 历史执行计划与决策日志
|
|
2
2
|
|
|
3
|
-
> **2026-07-18 当前生效边界(D50-
|
|
3
|
+
> **2026-07-18 当前生效边界(D50-D55,覆盖下文旧 Phase 6/7 的内置图谱、memory 与 runtime 设计)**:
|
|
4
4
|
> Ultra Builder Pro 不再拥有 `memory.*`、recall、prompt/transcript/observation/summary
|
|
5
5
|
> 收集 hook 或私有 agent memory。跨会话记忆全部交给独立安装的 cloud-mem/claude-mem。
|
|
6
6
|
> 插件只保留 12 个 Ultra 公共 workflow(新增 daily `ultra-change` 与诊断
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
> Kimi Code 采用各自 native plugin 呈现,其他旧 runtime adapter 已退役。下文所有与此冲突的
|
|
11
11
|
> memory/hindsight 章节仅作为历史实施记录,不再是当前需求或运行时契约。
|
|
12
12
|
|
|
13
|
-
**当前状态**:v0.
|
|
14
|
-
schema
|
|
13
|
+
**当前状态**:v0.13.0;四宿主 native plugin、36 个 live MCP tool、
|
|
14
|
+
schema 12.0(17 表)、portable Skill authoring contract、双轴 review、
|
|
15
15
|
Context Spine v2 / breadcrumb / spec-learning、持续 change/context/convergence/doctor、incident debug lane、
|
|
16
16
|
checkpoint 恢复消费与跨宿主安装 provenance/doctor 已落地;npm 发布由
|
|
17
17
|
`v*.*.*` tag 触发。以下 Phase 0-9 正文保留为 2026-04 的实施历史,不再作为
|
|
@@ -29,7 +29,7 @@ checkpoint 恢复消费与跨宿主安装 provenance/doctor 已落地;npm 发
|
|
|
29
29
|
- **Phase 4.6 拆 a/b**(R6 + D35):v0.1 只跑 smoke flow,full conformance 推 v0.2
|
|
30
30
|
- **Codex 第二轮结论**:"小改后开工"(tl;dr);本版已完成小改
|
|
31
31
|
|
|
32
|
-
**总决策数**:D1-
|
|
32
|
+
**总决策数**:D1-D55(当前边界以 D50-D55 为准)
|
|
33
33
|
**总风险数**:R1-R32(v0.3.1 新增 R25-R32 共 8 条)
|
|
34
34
|
|
|
35
35
|
---
|
|
@@ -1643,6 +1643,7 @@ Week 18 buffer(ship 中任何 Phase 的 25% 滑动吃掉)
|
|
|
1643
1643
|
| **D52** | **2026-07-17** | **初始交付后进入持续变更闭环**:新增 `ultra-change` / `ultra-doctor`、change/context/artifact/trace/incident/projection/consumer 状态、delta-first spec、确定性 convergence 与 baseline reconciliation;删除内置 code-graph watcher 和通用命令代理,Memory/图谱只保留外部 provider 元数据引用 | 用户确认采用最佳组合落地;解决日常小改导致 spec/context 漂移、投影失败静默和异常无恢复证据的问题 |
|
|
1644
1644
|
| **D53** | **2026-07-17** | **Harness 缺口一次性闭环**:`incident` 成为带五段 `diagnosis.md` 结构门禁的 canonical debug lane;compact checkpoint 由 resume 消费、校验、择新并原子恢复;三宿主安装写 normalized provenance,`ubp --doctor` 只读校验 asset hash 与 plugin/hook/MCP/runtime contract | 将 GSD 的 debug/fresh context、GStack 的 checkpoint/readiness 与 ECC 的 doctor/provenance 思路收敛为 Ultra 自有契约;Memory 与图谱继续由外部 provider 所有,且不恢复任何已退役 surface |
|
|
1645
1645
|
| **D54** | **2026-07-18** | **老项目接入与非阻断门禁闭环**:schema 11.0 新增 greenfield/brownfield baseline authority 与 `baseline.start/record/get/converge`;`task.init_project` 自动识别新旧仓库;上下文文件数、token 和占比改为 advisory warning,active change 的 baseline 问题同样只告警,`change.converge` / delivery 恢复硬门禁 | 避免 Ultra 把既有项目当新产品,也避免必要的 IM incident 因四个大文件超预算而无法施工;限制只在损坏权威、缺少执行契约、证据陈旧和最终收敛边界阻断 |
|
|
1646
|
+
| **D55** | **2026-07-18** | **新项目、老项目与旧版 Ultra 接入完成统一闭环**:schema 12.0 增加 repository branch/worktree digest、classification、gap ledger 与 incident bypass authority;`ultra-init` 自动分类、resume 只补缺失 scaffold、projection-only state 走支持的备份式 import、旧 DB 备份后升级、migrated baseline 必须显式 brownfield replacement;普通新 change 要求 ready baseline,已开工 change 保持可执行,紧急 incident 只允许有审批记录的 break-glass 并在 archive 写阻断 reconciliation gap | 老项目不再被重置或伪装成 greenfield/ready;历史任务、事件与文档可恢复迁移;健康项目可直接进入日常 change,损坏权威停在明确的 restore-or-rebaseline 决策边界 |
|
|
1646
1647
|
|
|
1647
1648
|
---
|
|
1648
1649
|
|
package/docs/ROADMAP.md
CHANGED
|
@@ -70,7 +70,7 @@ ultra-tools/ ← CLI fallback, migration, and diagnostics
|
|
|
70
70
|
├── cli.cjs
|
|
71
71
|
└── commands/
|
|
72
72
|
├── db.cjs (init/checkpoint/vacuum/integrity/backup)
|
|
73
|
-
├── migrate.cjs (v4.4 → v4.5
|
|
73
|
+
├── migrate.cjs (v4.4 projection → v4.5 authority; v4.5 projection → schema 12; dry/rollback)
|
|
74
74
|
└── legacy-memory.cjs (explicit inspect/archive/confirmed prune)
|
|
75
75
|
|
|
76
76
|
bin/install.js ← multi-runtime installer
|
|
@@ -101,5 +101,5 @@ npm audit
|
|
|
101
101
|
## Out of scope for v1.0 (deferred)
|
|
102
102
|
|
|
103
103
|
PLAN §13 lists Copilot / Cursor / Windsurf / 7 more runtimes, web
|
|
104
|
-
dashboard / TUI,
|
|
104
|
+
dashboard / TUI, team-collab server, plugin
|
|
105
105
|
marketplace.
|
|
@@ -46,7 +46,7 @@ not presented as nonexistent custom agents.
|
|
|
46
46
|
|
|
47
47
|
| Lifecycle | Claude Code | OpenCode | Codex | Kimi Code 0.26+ |
|
|
48
48
|
|---|---|---|---|---|
|
|
49
|
-
| Session context/health | FULL, DB-derived Context Spine breadcrumb on native `SessionStart` |
|
|
49
|
+
| Session context/health | FULL, DB-derived Context Spine breadcrumb on native `SessionStart` | FULL, the native JS plugin invokes the same bundled DB breadcrumb reader; health via `system.doctor` | FULL, DB-derived breadcrumb on native `SessionStart` | FULL, DB-derived breadcrumb via session-start skill + hooks |
|
|
50
50
|
| Active edit boundary | FULL, `PreToolUse Edit|Write` | FULL, `tool.execute.before` rejects projection writes | FULL, `PreToolUse Edit|Write|apply_patch` | FULL, native `PreToolUse Edit|Write` deny contract |
|
|
51
51
|
| Pre-compact checkpoint | FULL | FULL | FULL | FULL, native `PreCompact` |
|
|
52
52
|
| Post-compact context injection | FULL | FULL, native compacting context | FULL, native `PostCompact` restore | DEGRADED; checkpoint restoration runs, but Kimi 0.26/0.27 does not reinject fire-and-forget hook text |
|
|
@@ -73,7 +73,7 @@ they do not deny edits or stop active incident work.
|
|
|
73
73
|
| stdio MCP registration | plugin `.mcp.json` | `opencode.json` local MCP entry | plugin `.mcp.json` | plugin `mcpServers` entry |
|
|
74
74
|
| Live/declared contracts | 36 | 36 | 36 | 36 |
|
|
75
75
|
| Greenfield/brownfield baseline adoption | FULL | FULL | FULL | FULL |
|
|
76
|
-
| Context Spine v2 / breadcrumb | FULL | FULL,
|
|
76
|
+
| Context Spine v2 / breadcrumb | FULL | FULL, same bundled read-only DB reader as every hook | FULL | FULL |
|
|
77
77
|
| Approval-gated spec learning | FULL | FULL | FULL | FULL |
|
|
78
78
|
| Host-native review/discovery/ask | native | native | documented in `codex-capability-map.json` | native Kimi tools and workers |
|
|
79
79
|
| Durable authority | project `.ultra/state.db` | project `.ultra/state.db` | project `.ultra/state.db` | project `.ultra/state.db` |
|
|
@@ -126,9 +126,9 @@ records. Uninstall refuses an unmanaged or conflicting root.
|
|
|
126
126
|
|
|
127
127
|
| Capability | Contract |
|
|
128
128
|
|---|---|
|
|
129
|
-
| Current state schema | `
|
|
129
|
+
| Current state schema | `12.0` |
|
|
130
130
|
| Runtime values | `claude`, `opencode`, `codex`, `kimi` |
|
|
131
|
-
| Upgrade from earlier schema | preserves runtime rows, adds Context Spine state through 10.0,
|
|
131
|
+
| Upgrade from earlier schema | preserves runtime rows, adds Context Spine state through 10.0, authoritative baseline adoption in 11.0, then runtime constraint compatibility in 12.0 |
|
|
132
132
|
| Preservation gate | rows, IDs, indexes, foreign keys, telemetry, incidents, and migration history remain intact |
|
|
133
133
|
| Failure behavior | rollback; no partially upgraded authority database |
|
|
134
134
|
|
|
@@ -70,7 +70,7 @@ Detection happens at boot: `statvfs` of `.ultra/state.db`'s mount;
|
|
|
70
70
|
|
|
71
71
|
| Table | Writer of record |
|
|
72
72
|
|--------------------|--------------------------------------------------------|
|
|
73
|
-
| `baselines` | MCP server (`baseline.start` / `baseline.record` / `baseline.converge`); initialization
|
|
73
|
+
| `baselines` | MCP server (`baseline.start` / `baseline.record` / `baseline.converge`); initialization and legacy-projection migration may create only the first draft or compatibility row |
|
|
74
74
|
| `tasks` | MCP server (`task.create` / `task.update` / `task.delete`) |
|
|
75
75
|
| `changes` | MCP server (`change.create` / `change.update` / `change.converge` / `change.archive`) |
|
|
76
76
|
| `artifacts`, `context_snapshots`, `spec_learning_candidates`, `trace_links` | MCP server through change lifecycle tools |
|
|
@@ -79,8 +79,8 @@ Detection happens at boot: `statvfs` of `.ultra/state.db`'s mount;
|
|
|
79
79
|
| `sessions` | MCP server (`session.spawn` / `session.close` / `session.heartbeat`); orchestrator may write status transitions |
|
|
80
80
|
| `telemetry` | MCP server (collected from tool-call wrappers); orchestrator may dump bulk samples |
|
|
81
81
|
| `specs_refs` | MCP server (rebuilt on `spec_changed` event); orchestrator may rebuild |
|
|
82
|
-
| `migration_history`| `ultra-tools migrate`
|
|
83
|
-
| `schema_version` | `ultra-tools db init
|
|
82
|
+
| `migration_history`| schema initializer and `ultra-tools migrate` or doctor repair |
|
|
83
|
+
| `schema_version` | schema initializer, `ultra-tools db init`, migration, and doctor repair |
|
|
84
84
|
|
|
85
85
|
## 5. Forbidden patterns
|
|
86
86
|
|
|
@@ -22,10 +22,11 @@ host receives only its native invocation and collaboration names.
|
|
|
22
22
|
|
|
23
23
|
The managed block deliberately stays short. It says that `.ultra/state.db` is
|
|
24
24
|
authoritative; `change.context` compiles role/gate readiness, bounded references,
|
|
25
|
-
fresh-context budget, public seam, and exact verification; size budgets
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
fresh-context budget, public seam, and exact verification; size budgets are advisory,
|
|
26
|
+
new ordinary work requires a healthy baseline, existing active work may continue with
|
|
27
|
+
warnings, and only an approved incident break-glass may start without baseline
|
|
28
|
+
readiness; ordinary archive restores baseline health while break-glass archive records
|
|
29
|
+
a blocking reconciliation gap; hooks inject only the DB-derived
|
|
29
30
|
`change.breadcrumb`; and unresolved specification learning or either failed review
|
|
30
31
|
axis blocks convergence. Detailed procedures remain in the plugin skills so user
|
|
31
32
|
handbooks do not accumulate duplicated prompt sediment.
|
|
@@ -2,13 +2,11 @@
|
|
|
2
2
|
"""Protect Ultra projections and restate an active task boundary before edits."""
|
|
3
3
|
|
|
4
4
|
import json
|
|
5
|
-
import sqlite3
|
|
6
5
|
import sys
|
|
7
6
|
from pathlib import Path
|
|
8
7
|
|
|
9
|
-
from context_spine import read_breadcrumb, render_breadcrumb
|
|
8
|
+
from context_spine import ContextSpineError, find_root, read_breadcrumb, render_breadcrumb
|
|
10
9
|
|
|
11
|
-
TERMINAL = {"committed", "completed", "done", "cancelled"}
|
|
12
10
|
TASKS_PROJECTION = Path(".ultra/tasks/tasks.json")
|
|
13
11
|
|
|
14
12
|
|
|
@@ -34,58 +32,32 @@ def main() -> None:
|
|
|
34
32
|
except json.JSONDecodeError as exc:
|
|
35
33
|
print(f"[active_task_context] invalid hook input: {exc}", file=sys.stderr)
|
|
36
34
|
data = {}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
(ultra / "state.db").is_file()
|
|
43
|
-
or state_file.is_file()
|
|
44
|
-
or (ultra / "changes" / "active").is_dir()
|
|
45
|
-
)
|
|
46
|
-
if not initialized:
|
|
47
|
-
continue
|
|
48
|
-
if targets_tasks_projection(data, root):
|
|
49
|
-
print(json.dumps({"hookSpecificOutput": {
|
|
50
|
-
"hookEventName": "PreToolUse",
|
|
51
|
-
"permissionDecision": "deny",
|
|
52
|
-
"permissionDecisionReason": (
|
|
53
|
-
"Refusing a direct write to the .ultra/tasks/tasks.json projection. "
|
|
54
|
-
".ultra/state.db is authoritative; use the Ultra MCP task tools and "
|
|
55
|
-
"run ultra-doctor when state or projection health is degraded."
|
|
56
|
-
),
|
|
57
|
-
}}))
|
|
58
|
-
return
|
|
59
|
-
try:
|
|
60
|
-
breadcrumb = read_breadcrumb(root)
|
|
61
|
-
except (sqlite3.Error, OSError) as exc:
|
|
62
|
-
print(f"[active_task_context] cannot inspect Context Spine: {exc}", file=sys.stderr)
|
|
63
|
-
breadcrumb = None
|
|
64
|
-
if breadcrumb and breadcrumb.get("task_id"):
|
|
65
|
-
print(json.dumps({"hookSpecificOutput": {
|
|
66
|
-
"hookEventName": "PreToolUse",
|
|
67
|
-
"additionalContext": render_breadcrumb(root, breadcrumb),
|
|
68
|
-
}}))
|
|
69
|
-
return
|
|
70
|
-
if not state_file.is_file():
|
|
71
|
-
break
|
|
72
|
-
try:
|
|
73
|
-
state = json.loads(state_file.read_text(encoding="utf-8"))
|
|
74
|
-
except (OSError, json.JSONDecodeError) as exc:
|
|
75
|
-
print(f"[active_task_context] cannot read {state_file}: {exc}", file=sys.stderr)
|
|
76
|
-
break
|
|
77
|
-
if not isinstance(state, dict) or state.get("status") in TERMINAL:
|
|
78
|
-
break
|
|
79
|
-
task = state.get("task_id", state.get("task", "unknown"))
|
|
80
|
-
step = state.get("step", "unknown")
|
|
35
|
+
root = find_root(Path(data.get("cwd") or Path.cwd()).resolve())
|
|
36
|
+
if root is None:
|
|
37
|
+
print(json.dumps({}))
|
|
38
|
+
return
|
|
39
|
+
if targets_tasks_projection(data, root):
|
|
81
40
|
print(json.dumps({"hookSpecificOutput": {
|
|
82
41
|
"hookEventName": "PreToolUse",
|
|
83
|
-
"
|
|
84
|
-
|
|
85
|
-
"
|
|
42
|
+
"permissionDecision": "deny",
|
|
43
|
+
"permissionDecisionReason": (
|
|
44
|
+
"Refusing a direct write to the .ultra/tasks/tasks.json projection. "
|
|
45
|
+
".ultra/state.db is authoritative; use the Ultra MCP task tools and "
|
|
46
|
+
"run ultra-doctor when state or projection health is degraded."
|
|
86
47
|
),
|
|
87
48
|
}}))
|
|
88
49
|
return
|
|
50
|
+
try:
|
|
51
|
+
breadcrumb = read_breadcrumb(root)
|
|
52
|
+
except ContextSpineError as exc:
|
|
53
|
+
print(f"[active_task_context] cannot inspect Context Spine: {exc}", file=sys.stderr)
|
|
54
|
+
breadcrumb = None
|
|
55
|
+
if breadcrumb and breadcrumb.get("change_id"):
|
|
56
|
+
print(json.dumps({"hookSpecificOutput": {
|
|
57
|
+
"hookEventName": "PreToolUse",
|
|
58
|
+
"additionalContext": render_breadcrumb(root, breadcrumb),
|
|
59
|
+
}}))
|
|
60
|
+
return
|
|
89
61
|
print(json.dumps({}))
|
|
90
62
|
|
|
91
63
|
|