ultra-builder-pro-cli 0.11.0 → 0.12.1
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/specs/architecture.md +54 -223
- package/.ultra-template/specs/discovery.md +34 -231
- package/.ultra-template/specs/product.md +44 -200
- package/.ultra-template/tasks/contexts/TEMPLATE.md +36 -0
- package/.ultra-template/tasks/tasks.json +6 -0
- package/CHANGELOG.md +42 -1
- package/README.md +21 -9
- package/adapters/_shared/codex-assets.cjs +1 -1
- package/adapters/_shared/handbook.cjs +4 -3
- package/adapters/_shared/tests/handbook.test.cjs +4 -0
- package/adapters/opencode.js +8 -2
- package/adapters/tests/codex.test.cjs +2 -2
- package/adapters/tests/kimi-hook.test.cjs +1 -1
- package/adapters/tests/opencode.test.cjs +36 -1
- package/commands/ultra-init.md +3 -3
- package/docs/AGENT-CONTEXT.md +16 -8
- package/docs/ARCHITECTURE.md +32 -5
- package/docs/PLAN.zh-CN.md +7 -5
- package/docs/ROADMAP.md +4 -2
- package/docs/RUNTIME-COMPAT-MATRIX.md +8 -5
- package/docs/STATE-DB-ACCESS-POLICY.md +17 -11
- package/docs/USER-HANDBOOK-CONTRACT.md +8 -5
- package/hooks/README.md +4 -3
- package/hooks/adapters/codex.py +1 -1
- package/hooks/adapters/kimi.py +1 -1
- package/hooks/context_spine.py +120 -16
- package/hooks/health_check.py +11 -0
- package/hooks/pre_stop_check.py +6 -5
- package/mcp-server/lib/baseline-workflow.cjs +415 -0
- package/mcp-server/lib/baseline-workflow.test.cjs +225 -0
- package/mcp-server/lib/change-workflow.cjs +24 -27
- package/mcp-server/lib/change-workflow.test.cjs +202 -6
- package/mcp-server/lib/context-spine.cjs +74 -9
- package/mcp-server/lib/context-spine.test.cjs +15 -0
- package/mcp-server/lib/doctor.cjs +14 -0
- package/mcp-server/lib/doctor.test.cjs +25 -1
- package/mcp-server/lib/init-project.cjs +49 -14
- package/mcp-server/lib/provider-refs.cjs +42 -0
- package/mcp-server/lib/spec-learning.test.cjs +5 -0
- package/mcp-server/lib/state-db.cjs +63 -4
- package/mcp-server/lib/state-db.test.cjs +8 -3
- package/mcp-server/server.cjs +48 -3
- package/mcp-server/tests/init-project.test.cjs +54 -8
- package/mcp-server/tests/server-contract.test.cjs +99 -2
- package/mcp-server/tests/state-db.test.cjs +11 -2
- package/package.json +1 -1
- package/skills/ultra-change/SKILL.md +24 -13
- package/skills/ultra-deliver/SKILL.md +15 -5
- package/skills/ultra-dev/SKILL.md +4 -0
- package/skills/ultra-doctor/SKILL.md +8 -2
- package/skills/ultra-init/SKILL.md +46 -50
- package/skills/ultra-init/references/brownfield-adoption.md +65 -0
- package/skills/ultra-plan/SKILL.md +9 -2
- package/skills/ultra-research/SKILL.md +10 -5
- package/skills/ultra-status/SKILL.md +13 -6
- package/spec/cli-protocol.md +4 -0
- package/spec/mcp-tools.yaml +223 -4
- package/spec/schemas/mcp-tools.schema.json +1 -1
- package/spec/schemas/state-db.sql +33 -2
- package/ultra-tools/commands/status.cjs +20 -2
- package/ultra-tools/commands/task.cjs +4 -1
- package/ultra-tools/status-command.test.cjs +20 -0
- package/ultra-tools/system-command.test.cjs +5 -0
|
@@ -1,223 +1,67 @@
|
|
|
1
1
|
# Product Specification
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
> Technical HOW belongs in `architecture.md`.
|
|
3
|
+
This document defines accepted product behavior and scope. It is a durable contract,
|
|
4
|
+
not a research transcript or a task list.
|
|
6
5
|
|
|
7
|
-
|
|
6
|
+
## Scope
|
|
8
7
|
|
|
9
|
-
|
|
8
|
+
- Product or repository boundary:
|
|
9
|
+
- Intended outcome:
|
|
10
|
+
- Explicit non-goals:
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
[NEEDS CLARIFICATION] — One paragraph describing the problem, grounded in discovery.md §0
|
|
12
|
+
## Observed
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
Record confirmed current behavior and externally visible constraints. For an existing
|
|
15
|
+
project, cite source, test, runtime, or maintained documentation evidence.
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
- **Opportunity cost**: [NEEDS CLARIFICATION] — What they can't do because of this problem
|
|
17
|
+
| Behavior or constraint | Evidence reference | Status |
|
|
18
|
+
|---|---|---|
|
|
19
|
+
| | | |
|
|
21
20
|
|
|
22
|
-
|
|
21
|
+
## Decisions
|
|
23
22
|
|
|
24
|
-
|
|
23
|
+
Record accepted product decisions and the evidence or owner decision behind them.
|
|
25
24
|
|
|
26
|
-
|
|
25
|
+
| Decision | Rationale | Acceptance impact | Owner |
|
|
26
|
+
|---|---|---|---|
|
|
27
|
+
| | | | |
|
|
27
28
|
|
|
28
|
-
|
|
29
|
-
**Context**: Where they work, team dynamics, industry
|
|
29
|
+
## Unknowns
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
3. Tertiary goal (nice to have)
|
|
31
|
+
| Unknown | Blocking | Owner | Resolution evidence |
|
|
32
|
+
|---|---|---|---|
|
|
33
|
+
| | | | |
|
|
35
34
|
|
|
36
|
-
|
|
37
|
-
1. [NEEDS CLARIFICATION] — Connects to Opportunity O# from discovery.md §1
|
|
38
|
-
2. Connects to Opportunity O#
|
|
39
|
-
3. Source: URL or user quote
|
|
35
|
+
## Actors and Entry Points
|
|
40
36
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
> Tools used: List of current tools/processes
|
|
44
|
-
> Time spent: X hours/week
|
|
37
|
+
Include actors only when they are supported by evidence. Describe the public entry
|
|
38
|
+
point through which each actor reaches the behavior.
|
|
45
39
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
40
|
+
| Actor or system | Need | Entry point | Evidence |
|
|
41
|
+
|---|---|---|---|
|
|
42
|
+
| | | | |
|
|
49
43
|
|
|
50
|
-
|
|
44
|
+
## Behavior Contracts
|
|
51
45
|
|
|
52
|
-
|
|
53
|
-
|
|
46
|
+
Give each required behavior a stable identifier. State preconditions, observable
|
|
47
|
+
result, failure behavior, and recovery where relevant.
|
|
54
48
|
|
|
55
|
-
|
|
56
|
-
1. [NEEDS CLARIFICATION]
|
|
49
|
+
### Behavior: pending
|
|
57
50
|
|
|
58
|
-
|
|
59
|
-
|
|
51
|
+
- Trigger:
|
|
52
|
+
- Preconditions:
|
|
53
|
+
- Observable result:
|
|
54
|
+
- Failure behavior:
|
|
55
|
+
- Recovery:
|
|
56
|
+
- Evidence or decision:
|
|
60
57
|
|
|
61
|
-
|
|
62
|
-
> [NEEDS CLARIFICATION]
|
|
58
|
+
## Acceptance
|
|
63
59
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
60
|
+
| Behavior | Acceptance evidence | Public seam | Verification |
|
|
61
|
+
|---|---|---|---|
|
|
62
|
+
| | | | |
|
|
67
63
|
|
|
68
|
-
|
|
64
|
+
## Documentation Impact
|
|
69
65
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
| P1 | [NEEDS CLARIFICATION] | | | **Primary** |
|
|
73
|
-
| P2 | | | | **Secondary** |
|
|
74
|
-
|
|
75
|
-
---
|
|
76
|
-
|
|
77
|
-
## §3 User Scenarios
|
|
78
|
-
|
|
79
|
-
### Scenario Overview
|
|
80
|
-
|
|
81
|
-
| # | Scenario | Persona | Frequency | Pain | Value | Score |
|
|
82
|
-
|---|----------|---------|-----------|------|-------|-------|
|
|
83
|
-
| S1 | [NEEDS CLARIFICATION] | P1 | /5 | /5 | /5 | |
|
|
84
|
-
| S2 | | | | | | |
|
|
85
|
-
| S3 | | | | | | |
|
|
86
|
-
|
|
87
|
-
> Priority Score = Frequency × Pain × Value
|
|
88
|
-
|
|
89
|
-
### Scenario 1: [NEEDS CLARIFICATION] — Primary
|
|
90
|
-
|
|
91
|
-
**Persona**: [NEEDS CLARIFICATION]
|
|
92
|
-
**Frequency**: Daily / Weekly / Monthly
|
|
93
|
-
|
|
94
|
-
**Trigger**: What event causes this scenario
|
|
95
|
-
**Context**: Where, when, device, time pressure
|
|
96
|
-
|
|
97
|
-
**Current Flow** (painful):
|
|
98
|
-
1. [NEEDS CLARIFICATION] — What they do today
|
|
99
|
-
2. Where friction occurs
|
|
100
|
-
3. Workaround they use
|
|
101
|
-
4. Outcome and time wasted
|
|
102
|
-
|
|
103
|
-
**Desired Flow** (with our product):
|
|
104
|
-
1. [NEEDS CLARIFICATION] — Trigger detected
|
|
105
|
-
2. Streamlined action
|
|
106
|
-
3. Fast resolution
|
|
107
|
-
4. Outcome achieved in less time
|
|
108
|
-
|
|
109
|
-
**Success Outcome**: [NEEDS CLARIFICATION] — Specific and measurable
|
|
110
|
-
**Failure Outcome**: [NEEDS CLARIFICATION] — Consequences
|
|
111
|
-
**Emotional Arc**: Frustration → Discovery → Relief
|
|
112
|
-
|
|
113
|
-
### Scenario 2: [NEEDS CLARIFICATION]
|
|
114
|
-
|
|
115
|
-
[Same structure as Scenario 1]
|
|
116
|
-
|
|
117
|
-
### Scenario 3: [NEEDS CLARIFICATION]
|
|
118
|
-
|
|
119
|
-
[Same structure as Scenario 1]
|
|
120
|
-
|
|
121
|
-
---
|
|
122
|
-
|
|
123
|
-
## §4 User Stories & Features
|
|
124
|
-
|
|
125
|
-
### Story Map Overview
|
|
126
|
-
|
|
127
|
-
| ID | Story | Persona | Scenario | Priority | Complexity |
|
|
128
|
-
|----|-------|---------|----------|----------|-----------|
|
|
129
|
-
| US-01 | [NEEDS CLARIFICATION] | P1 | S1 | Must | S/M/L |
|
|
130
|
-
| US-02 | | | | | |
|
|
131
|
-
| US-03 | | | | | |
|
|
132
|
-
|
|
133
|
-
### Must-Have Stories
|
|
134
|
-
|
|
135
|
-
#### US-01: [NEEDS CLARIFICATION]
|
|
136
|
-
**As a** [Persona], **I want** [action], **so that** [benefit].
|
|
137
|
-
|
|
138
|
-
**Acceptance Criteria**:
|
|
139
|
-
- [ ] Given [context], when [action], then [result]
|
|
140
|
-
- [ ] Given [context], when [edge case], then [result]
|
|
141
|
-
|
|
142
|
-
**Traces to**: Scenario S#, Opportunity O#
|
|
143
|
-
**Complexity**: S/M/L
|
|
144
|
-
|
|
145
|
-
### Should-Have Stories
|
|
146
|
-
|
|
147
|
-
#### US-04: [NEEDS CLARIFICATION]
|
|
148
|
-
[Same structure]
|
|
149
|
-
|
|
150
|
-
### Could-Have Stories
|
|
151
|
-
|
|
152
|
-
#### US-07: [NEEDS CLARIFICATION]
|
|
153
|
-
[Same structure]
|
|
154
|
-
|
|
155
|
-
---
|
|
156
|
-
|
|
157
|
-
## §5 Feature Scope
|
|
158
|
-
|
|
159
|
-
### Features In (MVP)
|
|
160
|
-
|
|
161
|
-
#### Feature 1: [NEEDS CLARIFICATION]
|
|
162
|
-
- **Description**: What this feature does
|
|
163
|
-
- **Stories**: US-01, US-02
|
|
164
|
-
- **User value**: What user can do with this
|
|
165
|
-
- **Priority**: Must-Have
|
|
166
|
-
- **Complexity**: S/M/L
|
|
167
|
-
|
|
168
|
-
### Features In (v2 — Planned)
|
|
169
|
-
|
|
170
|
-
#### Feature 4: [NEEDS CLARIFICATION]
|
|
171
|
-
- **Description**: What this feature does
|
|
172
|
-
- **Stories**: US-07, US-08
|
|
173
|
-
- **Rationale for deferral**: Why not MVP
|
|
174
|
-
- **Trigger to build**: When to reconsider
|
|
175
|
-
|
|
176
|
-
### Features Out (Explicitly Excluded)
|
|
177
|
-
|
|
178
|
-
| Feature | Rationale | Reconsider When | Alternative |
|
|
179
|
-
|---------|-----------|----------------|-------------|
|
|
180
|
-
| [NEEDS CLARIFICATION] | Why excluded (ref strategy §4) | Condition | What users do instead |
|
|
181
|
-
|
|
182
|
-
### Scope Summary
|
|
183
|
-
- **MVP features**: [NEEDS CLARIFICATION] features, stories
|
|
184
|
-
- **v2 features**: features, stories
|
|
185
|
-
- **Excluded features**: features
|
|
186
|
-
|
|
187
|
-
---
|
|
188
|
-
|
|
189
|
-
## §6 Success Metrics
|
|
190
|
-
|
|
191
|
-
### North Star Metric
|
|
192
|
-
- **Metric**: [NEEDS CLARIFICATION]
|
|
193
|
-
- **Definition**: Exactly what is measured
|
|
194
|
-
- **Current baseline**: Current state or industry benchmark
|
|
195
|
-
- **Target**: Specific number
|
|
196
|
-
- **Timeline**: When to achieve
|
|
197
|
-
- **Measurement method**: How to collect this data
|
|
198
|
-
|
|
199
|
-
### Business Metrics
|
|
200
|
-
|
|
201
|
-
| Metric | Baseline | Target (M3) | Target (M6) | Target (M12) | How Measured |
|
|
202
|
-
|--------|----------|-------------|-------------|--------------|-------------|
|
|
203
|
-
| [NEEDS CLARIFICATION] | | | | | |
|
|
204
|
-
|
|
205
|
-
### User Metrics
|
|
206
|
-
|
|
207
|
-
| Metric | Baseline | Target | How Measured |
|
|
208
|
-
|--------|----------|--------|-------------|
|
|
209
|
-
| Task completion rate | [NEEDS CLARIFICATION] | | |
|
|
210
|
-
| Time on task | | | |
|
|
211
|
-
| User satisfaction (NPS) | | | |
|
|
212
|
-
| Feature adoption | | | |
|
|
213
|
-
|
|
214
|
-
### Anti-Metrics (What NOT to Optimize)
|
|
215
|
-
|
|
216
|
-
| Anti-Metric | Why Not | What It Could Sacrifice |
|
|
217
|
-
|------------|---------|------------------------|
|
|
218
|
-
| [NEEDS CLARIFICATION] | | |
|
|
219
|
-
|
|
220
|
-
---
|
|
221
|
-
|
|
222
|
-
**Document Status**: Draft
|
|
223
|
-
**Last Updated**: [Date]
|
|
66
|
+
List maintained documents that must stay consistent with this contract, or record a
|
|
67
|
+
specific reason why no documentation change is required.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<!-- Body template only. The projector owns authoritative YAML frontmatter. -->
|
|
2
|
+
|
|
3
|
+
# Task {id}: {title}
|
|
4
|
+
|
|
5
|
+
## Outcome
|
|
6
|
+
|
|
7
|
+
[Describe the observable result this task must produce.]
|
|
8
|
+
|
|
9
|
+
## Required context
|
|
10
|
+
|
|
11
|
+
- `[project-relative reference]` — [why it is required]
|
|
12
|
+
|
|
13
|
+
## Execution contract
|
|
14
|
+
|
|
15
|
+
- Public seam: [reachable entry point or observable boundary]
|
|
16
|
+
- Verification command: `[exact deterministic command]`
|
|
17
|
+
- Documentation impact: [required paths or a specific no-change rationale]
|
|
18
|
+
|
|
19
|
+
## Constraints
|
|
20
|
+
|
|
21
|
+
- [Confirmed constraint with its evidence source]
|
|
22
|
+
|
|
23
|
+
## Acceptance evidence
|
|
24
|
+
|
|
25
|
+
- [Expected behavior and the evidence that will verify it]
|
|
26
|
+
|
|
27
|
+
## Traceability
|
|
28
|
+
|
|
29
|
+
- Change: [change id or initial baseline]
|
|
30
|
+
- Specification: [project-relative section reference]
|
|
31
|
+
|
|
32
|
+
## Completion evidence
|
|
33
|
+
|
|
34
|
+
- Commit: [verified commit when applicable]
|
|
35
|
+
- Tests: [command and result]
|
|
36
|
+
- Summary: [delivered behavior]
|
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,45 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.12.1] — 2026-07-18
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- Fixed the published project scaffold so its task projection and neutral context
|
|
15
|
+
template are tracked on fresh checkouts instead of being hidden by a broad ignore
|
|
16
|
+
rule; the seed projection now uses the authoritative v4.5 state contract.
|
|
17
|
+
|
|
18
|
+
## [0.12.0] — 2026-07-18
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
|
|
22
|
+
- Added schema 11.0 project baselines and four `baseline.*` MCP contracts for
|
|
23
|
+
greenfield initialization, brownfield adoption, evidence recording, explicit
|
|
24
|
+
approval, re-adoption history, and archive reconciliation.
|
|
25
|
+
- Added automatic new/existing repository detection, neutral baseline templates,
|
|
26
|
+
metadata-only provider references, and cross-host baseline status/doctor output.
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- Reclassified file count, token estimate, and context-share limits as advisory
|
|
31
|
+
attention warnings. Necessary incident context and active work are no longer
|
|
32
|
+
rejected or repaired by arbitrarily raising a threshold.
|
|
33
|
+
- Made incomplete or stale baseline state advisory during an active bounded change,
|
|
34
|
+
requiring approved adoption at `change.converge` and complete revision/spec
|
|
35
|
+
reconciliation in the atomic archive transaction.
|
|
36
|
+
- Changed the Stop hook from a workflow-completion denial into a lifecycle advisory;
|
|
37
|
+
direct writes to the authoritative task projection remain blocked.
|
|
38
|
+
|
|
39
|
+
### Fixed
|
|
40
|
+
|
|
41
|
+
- Prevented old projects from being initialized as empty greenfield products or
|
|
42
|
+
using generated `tasks.json` as project metadata authority.
|
|
43
|
+
- Updated Claude Code, Codex, OpenCode, and Kimi presentation so hooks expose
|
|
44
|
+
warnings without turning them into edit, stop, or workflow refusal gates.
|
|
45
|
+
- Removed the convergence deadlock where normal HEAD or tracked-spec changes made by
|
|
46
|
+
the active change were rejected before archive could reconcile them; incomplete
|
|
47
|
+
archive declarations now fail with full state and artifact rollback.
|
|
48
|
+
|
|
10
49
|
## [0.11.0] — 2026-07-18
|
|
11
50
|
|
|
12
51
|
### Added
|
|
@@ -451,7 +490,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
451
490
|
skill manifest, CLI protocol + mapping table; 5 spec validators.
|
|
452
491
|
- **Phase 0 — skeleton**: multi-runtime installer scaffolding.
|
|
453
492
|
|
|
454
|
-
[Unreleased]: https://github.com/rocky2431/ultra-builder-pro-cli/compare/v0.
|
|
493
|
+
[Unreleased]: https://github.com/rocky2431/ultra-builder-pro-cli/compare/v0.12.1...HEAD
|
|
494
|
+
[0.12.1]: https://github.com/rocky2431/ultra-builder-pro-cli/compare/v0.12.0...v0.12.1
|
|
495
|
+
[0.12.0]: https://github.com/rocky2431/ultra-builder-pro-cli/compare/v0.11.0...v0.12.0
|
|
455
496
|
[0.11.0]: https://github.com/rocky2431/ultra-builder-pro-cli/compare/v0.10.0...v0.11.0
|
|
456
497
|
[0.10.0]: https://github.com/rocky2431/ultra-builder-pro-cli/compare/v0.9.0...v0.10.0
|
|
457
498
|
[0.9.0]: https://github.com/rocky2431/ultra-builder-pro-cli/compare/v0.8.1...v0.9.0
|
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ authoritative `.ultra/state.db`.
|
|
|
8
8
|
|
|
9
9
|
<div align="center">
|
|
10
10
|
|
|
11
|
-
[](./CHANGELOG.md)
|
|
12
12
|
[](#verification)
|
|
13
13
|
[](./LICENSE)
|
|
14
14
|
[](./package.json)
|
|
@@ -27,7 +27,7 @@ authoritative `.ultra/state.db`.
|
|
|
27
27
|
Install and uninstall are symmetric on every supported host; `ubp --doctor`
|
|
28
28
|
verifies the installed asset hashes and host entry points without mutation.
|
|
29
29
|
- **Shares state across runtimes.** `.ultra/state.db` (SQLite + WAL) is the
|
|
30
|
-
authoritative source for changes, tasks, sessions, events, incidents,
|
|
30
|
+
authoritative source for baselines, changes, tasks, sessions, events, incidents,
|
|
31
31
|
projection jobs, and telemetry. `tasks.json` and context markdown are
|
|
32
32
|
generated projections, not handwritten.
|
|
33
33
|
- **Keeps memory ownership explicit.** Ultra Builder Pro does not collect
|
|
@@ -37,12 +37,16 @@ authoritative `.ultra/state.db`.
|
|
|
37
37
|
`.ultra/execution-plan.json` → parallel worktree sessions → auto-merge back.
|
|
38
38
|
- **Keeps daily work convergent.** `/ultra-change` creates a bounded delta and
|
|
39
39
|
Context Manifest v2; the Context Spine assigns a role/gate, verifies required
|
|
40
|
-
references
|
|
40
|
+
references, reports fresh-context budget pressure as advisory warnings, exposes one DB-derived breadcrumb, and
|
|
41
41
|
routes a single next action. `/ultra-deliver` requires applied specification
|
|
42
42
|
learning plus docs/test/two-axis review evidence before archive. `/ultra-doctor` reports incidents,
|
|
43
43
|
projection lag, orphan sessions, and backup-first mechanical recovery.
|
|
44
44
|
Incident changes additionally require a five-section `diagnosis.md` covering
|
|
45
45
|
reproduction, hypotheses, root cause, regression test, and recovery.
|
|
46
|
+
- **Adopts existing repositories without pretending they are new.** `ultra-init`
|
|
47
|
+
auto-detects greenfield versus brownfield work. Brownfield adoption records
|
|
48
|
+
current specifications, repository/runtime evidence, known-red verification,
|
|
49
|
+
unknowns, and explicit approval without rewriting application code.
|
|
46
50
|
- **Keeps external context external.** Memory and code-graph providers retain
|
|
47
51
|
their own content; Ultra stores only provider/project/revision/status metadata
|
|
48
52
|
references in a compiled change context.
|
|
@@ -82,6 +86,14 @@ install or update.
|
|
|
82
86
|
See [`docs/RUNTIME-COMPAT-MATRIX.md`](./docs/RUNTIME-COMPAT-MATRIX.md)
|
|
83
87
|
for per-runtime capabilities.
|
|
84
88
|
|
|
89
|
+
Start with `ultra-init` in both new and existing projects. An empty project opens
|
|
90
|
+
a `draft` greenfield baseline. An existing codebase opens an `adopting`
|
|
91
|
+
brownfield baseline; inspect current behavior, call `baseline.record`, then
|
|
92
|
+
approve it through `baseline.converge` before normal planning or delivery. An
|
|
93
|
+
urgent active fix may continue while adoption or context-size warnings are
|
|
94
|
+
visible. `change.converge` requires approved adoption, while normal HEAD/spec drift
|
|
95
|
+
from that change is declared and health-checked atomically by `change.archive`.
|
|
96
|
+
|
|
85
97
|
## Three-layer architecture
|
|
86
98
|
|
|
87
99
|
| Layer | Purpose | When it's used |
|
|
@@ -93,7 +105,7 @@ for per-runtime capabilities.
|
|
|
93
105
|
The layers share one `.ultra/state.db`, but the CLI is not a mirror of every MCP
|
|
94
106
|
tool: continuous change mutations are MCP-only and fail closed. See
|
|
95
107
|
[`docs/ARCHITECTURE.md`](./docs/ARCHITECTURE.md) for the full contract and
|
|
96
|
-
[`spec/cli-protocol.md`](./spec/cli-protocol.md) for the
|
|
108
|
+
[`spec/cli-protocol.md`](./spec/cli-protocol.md) for the 36 live contracts.
|
|
97
109
|
Review, impact discovery, skill resolution, and user interaction stay on each
|
|
98
110
|
Host's native surfaces; the generated Codex capability map documents those
|
|
99
111
|
replacements without advertising non-existent MCP tools.
|
|
@@ -121,11 +133,11 @@ Full details in [`docs/RUNTIME-COMPAT-MATRIX.md`](./docs/RUNTIME-COMPAT-MATRIX.m
|
|
|
121
133
|
## Typical workflow
|
|
122
134
|
|
|
123
135
|
```bash
|
|
124
|
-
# 1. Initialize a project
|
|
125
|
-
ultra-tools task init-project --name myapp
|
|
136
|
+
# 1. Initialize a new project or adopt an existing repository automatically
|
|
137
|
+
ultra-tools task init-project --project-name myapp --mode auto
|
|
126
138
|
|
|
127
|
-
# 2.
|
|
128
|
-
#
|
|
139
|
+
# 2. Record and converge the greenfield/brownfield baseline, then turn accepted
|
|
140
|
+
# behavior into a task graph (normally driven by ultra-init/research/plan)
|
|
129
141
|
|
|
130
142
|
# 3. Run the plan — parallel sessions, auto-merge back to main on success
|
|
131
143
|
ubp-orchestrator run
|
|
@@ -138,7 +150,7 @@ ultra-tools system doctor
|
|
|
138
150
|
```
|
|
139
151
|
|
|
140
152
|
Or let the skills drive it. In Codex, invoke
|
|
141
|
-
`$ultra-builder-pro:ultra-plan` → `$ultra-builder-pro:ultra-dev` →
|
|
153
|
+
`$ultra-builder-pro:ultra-init` → `$ultra-builder-pro:ultra-plan` → `$ultra-builder-pro:ultra-dev` →
|
|
142
154
|
`$ultra-builder-pro:ultra-test` → `$ultra-builder-pro:ultra-review` →
|
|
143
155
|
`$ultra-builder-pro:ultra-deliver`; after the baseline is delivered, daily work
|
|
144
156
|
starts with `$ultra-builder-pro:ultra-change`, while
|
|
@@ -400,7 +400,7 @@ function buildHooksManifest() {
|
|
|
400
400
|
{ hooks: [commandHook('workflow_resume.py', 10, 'Restoring Ultra workflow checkpoint')] },
|
|
401
401
|
],
|
|
402
402
|
Stop: [
|
|
403
|
-
{ hooks: [commandHook('pre_stop_check.py', 5, '
|
|
403
|
+
{ hooks: [commandHook('pre_stop_check.py', 5, 'Reporting Ultra workflow position')] },
|
|
404
404
|
],
|
|
405
405
|
SubagentStart: [
|
|
406
406
|
{ hooks: [commandHook('subagent_tracker.py', 5, 'Tracking Ultra subagent', 'start')] },
|
|
@@ -59,11 +59,12 @@ function renderHandbook(runtime) {
|
|
|
59
59
|
`- Workflow entry points: ${value.invocation}.`,
|
|
60
60
|
`- Collaboration boundary: ${value.collaboration}. The current host remains primary and owns final verification.`,
|
|
61
61
|
`- Coordination boundary: ${value.coordination}.`,
|
|
62
|
-
'- Authority: `.ultra/state.db` is the only durable Ultra authority for changes, tasks, sessions, events, incidents, projection state, telemetry, and review evidence. Generated JSON and Markdown are projections or workflow artifacts.',
|
|
63
|
-
'-
|
|
62
|
+
'- Authority: `.ultra/state.db` is the only durable Ultra authority for baselines, changes, tasks, sessions, events, incidents, projection state, telemetry, and review evidence. Generated JSON and Markdown are projections or workflow artifacts.',
|
|
63
|
+
'- Baseline boundary: `task.init_project` detects greenfield or brownfield work; `baseline.start`, `baseline.record`, and `baseline.converge` adopt the project without rewriting application code. An incomplete baseline is advisory during active work but blocks change convergence; normal HEAD or tracked-spec drift from that change is reconciled and health-checked atomically at archive.',
|
|
64
|
+
'- Context Spine boundary: `change.context` compiles role/gate readiness, required references, a fresh-context budget, public seam, verification command, and one next action. File, token, and context-share budgets are advisory attention signals, not refusal gates. Hooks inject only the DB-derived `change.breadcrumb`; missing required evidence or stale execution context must be recompiled.',
|
|
64
65
|
'- Specification learning boundary: stable implementation discoveries use approval-gated propose/approve-or-reject/apply transitions. Unresolved learning blocks convergence; review requires independent specification-fidelity and engineering-standards evidence.',
|
|
65
66
|
'- Memory and graph boundary: Ultra Builder Pro does not capture prompts, transcripts, observations, summaries, cross-session memory, or code-graph content. Separately installed providers own that data; Ultra may store only their metadata references in a change context manifest.',
|
|
66
|
-
'- Hook boundary: Ultra hooks observe workflow/change lifecycle only. Health/context may run when `.ultra/state.db` exists;
|
|
67
|
+
'- Hook boundary: Ultra hooks observe workflow/change lifecycle only. Health/context may run when `.ultra/state.db` exists; advisory warnings never reject work, and an incomplete workflow never traps session stop. Direct projection protection remains authoritative; compact and subagent recovery stays active-workflow scoped. Generic command blocking and post-edit policy stay in user or repository governance.',
|
|
67
68
|
'- Installation boundary: `ubp --doctor` is the read-only authority for installed asset provenance, content hashes, and host entry-point wiring; `system.doctor` remains scoped to project state and workflow recovery.',
|
|
68
69
|
'- Agent boundary: the bundled review and debugging agents are bounded workers. They use the current checkout and parent-supplied context, do not own private persistent state, and never replace the primary agent.',
|
|
69
70
|
'- Package boundary: only the twelve Ultra workflows, four internal review-rule skills, host-specific collaboration companions, and the minimal host bootstrap belong to this plugin. General browser, deployment, discovery, and framework skills must be installed from their owners.',
|
|
@@ -34,6 +34,10 @@ test('renders one common contract with host-native invocation syntax', () => {
|
|
|
34
34
|
assert.match(rendered, /ultra-doctor/);
|
|
35
35
|
assert.match(rendered, /metadata references/);
|
|
36
36
|
assert.match(rendered, /Context Spine boundary/);
|
|
37
|
+
assert.match(rendered, /budgets are advisory attention signals/);
|
|
38
|
+
assert.match(rendered, /blocks change convergence/);
|
|
39
|
+
assert.match(rendered, /health-checked atomically at archive/);
|
|
40
|
+
assert.match(rendered, /never traps session stop/);
|
|
37
41
|
assert.match(rendered, /change\.breadcrumb/);
|
|
38
42
|
assert.match(rendered, /Specification learning boundary/);
|
|
39
43
|
assert.doesNotMatch(rendered, /\.ultra\/memory|memory\.retain|memory\.recall/);
|
package/adapters/opencode.js
CHANGED
|
@@ -345,11 +345,14 @@ function findUltraContext(directory) {
|
|
|
345
345
|
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
|
|
346
346
|
if (manifest?.change) {
|
|
347
347
|
const compiledHead = manifest.git?.head ?? null;
|
|
348
|
-
const legacyContext = manifest.schema_version !== "2.0";
|
|
348
|
+
const legacyContext = manifest.schema_version !== "2.0" || !manifest.baseline;
|
|
349
349
|
const headStale = Boolean(compiledHead && currentHead && compiledHead !== currentHead);
|
|
350
350
|
const blockers = Array.isArray(manifest.readiness?.blockers)
|
|
351
351
|
? [...manifest.readiness.blockers]
|
|
352
352
|
: [];
|
|
353
|
+
const warnings = Array.isArray(manifest.readiness?.warnings)
|
|
354
|
+
? [...manifest.readiness.warnings]
|
|
355
|
+
: [];
|
|
353
356
|
if (headStale && !blockers.includes("CONTEXT_HEAD_STALE")) blockers.push("CONTEXT_HEAD_STALE");
|
|
354
357
|
if (legacyContext && !blockers.includes("CONTEXT_SNAPSHOT_UPGRADE_REQUIRED")) {
|
|
355
358
|
blockers.unshift("CONTEXT_SNAPSHOT_UPGRADE_REQUIRED");
|
|
@@ -367,6 +370,8 @@ function findUltraContext(directory) {
|
|
|
367
370
|
: (manifest.next_action ?? "Inspect Ultra status."),
|
|
368
371
|
readiness: legacyContext || headStale ? "blocked" : (manifest.readiness?.status ?? "ready"),
|
|
369
372
|
blockers,
|
|
373
|
+
warnings,
|
|
374
|
+
baseline: manifest.baseline ?? null,
|
|
370
375
|
taskId: manifest.selected_task?.id ?? manifest.resume?.task_id ?? null,
|
|
371
376
|
taskStatus: manifest.selected_task?.status ?? manifest.resume?.task_status ?? null,
|
|
372
377
|
tokenEstimate: manifest.context?.token_estimate ?? 0,
|
|
@@ -411,6 +416,7 @@ function contextText(active) {
|
|
|
411
416
|
\`Gate: \${change.gate}\`,
|
|
412
417
|
\`Readiness: \${change.readiness}\`,
|
|
413
418
|
...(change.blockers.length > 0 ? [\`Blockers: \${change.blockers.join(", ")}\`] : []),
|
|
419
|
+
...(change.warnings.length > 0 ? [\`Warnings: \${change.warnings.join(", ")}\`] : []),
|
|
414
420
|
\`Next: \${change.nextAction}\`,
|
|
415
421
|
\`Context manifest: \${change.manifestPath}\`,
|
|
416
422
|
);
|
|
@@ -422,7 +428,7 @@ function contextText(active) {
|
|
|
422
428
|
lines.push(
|
|
423
429
|
"[Ultra baseline]",
|
|
424
430
|
\`Project: \${active.root}\`,
|
|
425
|
-
"No active continuous change.
|
|
431
|
+
"No active continuous change. Run ultra-status; resume ultra-init when the baseline is missing, incomplete, or stale, otherwise start ultra-change.",
|
|
426
432
|
);
|
|
427
433
|
}
|
|
428
434
|
lines.push("Authority: .ultra/state.db; JSON/Markdown remain projections or evidence artifacts.");
|
|
@@ -245,8 +245,8 @@ test('plugin declares current Codex hooks and a project-local Ultra MCP server',
|
|
|
245
245
|
const liveSpec = yaml.load(fs.readFileSync(path.join(layout.pluginRoot, 'spec', 'mcp-tools.yaml'), 'utf8'));
|
|
246
246
|
const upstreamSpec = yaml.load(fs.readFileSync(path.join(layout.pluginRoot, 'spec', 'upstream-mcp-tools.yaml'), 'utf8'));
|
|
247
247
|
const capabilityMap = JSON.parse(fs.readFileSync(path.join(layout.pluginRoot, 'spec', 'codex-capability-map.json'), 'utf8'));
|
|
248
|
-
assert.equal(liveSpec.tools.length,
|
|
249
|
-
assert.equal(upstreamSpec.tools.length,
|
|
248
|
+
assert.equal(liveSpec.tools.length, 36);
|
|
249
|
+
assert.equal(upstreamSpec.tools.length, 36);
|
|
250
250
|
assert.deepEqual(upstreamSpec.tools.map((tool) => tool.name).sort(), liveSpec.tools.map((tool) => tool.name).sort());
|
|
251
251
|
assert.deepEqual(capabilityMap.live_mcp_tools.sort(), liveSpec.tools.map((tool) => tool.name).sort());
|
|
252
252
|
assert.equal(Object.keys(capabilityMap.codex_native_replacements).length, 9);
|
|
@@ -97,7 +97,7 @@ test('Kimi subagent fields are normalized for the existing lifecycle tracker', (
|
|
|
97
97
|
});
|
|
98
98
|
});
|
|
99
99
|
|
|
100
|
-
test('Kimi
|
|
100
|
+
test('Kimi adapter preserves an explicit Stop deny and recovery context schema', () => {
|
|
101
101
|
const script = [
|
|
102
102
|
'import importlib.util, json, pathlib',
|
|
103
103
|
`p = pathlib.Path(${JSON.stringify(ADAPTER)})`,
|
|
@@ -206,11 +206,14 @@ test('OpenCode context covers active changes and projection writes are blocked f
|
|
|
206
206
|
fs.mkdirSync(changeRoot, { recursive: true });
|
|
207
207
|
fs.writeFileSync(path.join(changeRoot, 'context-manifest.json'), JSON.stringify({
|
|
208
208
|
schema_version: '2.0',
|
|
209
|
+
baseline: { id: 'project-baseline', mode: 'brownfield', status: 'ready', repository_revision: compiledHead },
|
|
209
210
|
change: { id: 'daily-fix', title: 'Daily fix', kind: 'quick', status: 'active', intent: 'Fix drift' },
|
|
210
211
|
role: 'implement',
|
|
211
212
|
gate: 'implementation',
|
|
212
213
|
next_action: 'Run the exact regression test.',
|
|
213
|
-
readiness: {
|
|
214
|
+
readiness: {
|
|
215
|
+
status: 'ready', blockers: [], warnings: ['CONTEXT_FILE_BUDGET_EXCEEDED'],
|
|
216
|
+
},
|
|
214
217
|
git: { head: compiledHead },
|
|
215
218
|
selected_task: { id: 'daily-task', status: 'in_progress' },
|
|
216
219
|
context: { token_estimate: 1200, budget: { max_tokens: 8000, max_files: 8 } },
|
|
@@ -225,6 +228,7 @@ test('OpenCode context covers active changes and projection writes are blocked f
|
|
|
225
228
|
assert.match(output.system.join('\n'), /Role: implement/);
|
|
226
229
|
assert.match(output.system.join('\n'), /Gate: implementation/);
|
|
227
230
|
assert.match(output.system.join('\n'), /Readiness: ready/);
|
|
231
|
+
assert.match(output.system.join('\n'), /Warnings: CONTEXT_FILE_BUDGET_EXCEEDED/);
|
|
228
232
|
assert.match(output.system.join('\n'), /Run the exact regression test/);
|
|
229
233
|
assert.doesNotMatch(output.system.join('\n'), /Fix drift|cloud-mem/);
|
|
230
234
|
|
|
@@ -238,6 +242,16 @@ test('OpenCode context covers active changes and projection writes are blocked f
|
|
|
238
242
|
legacyManifest.schema_version = '2.0';
|
|
239
243
|
fs.writeFileSync(manifestFile, JSON.stringify(legacyManifest));
|
|
240
244
|
|
|
245
|
+
delete legacyManifest.baseline;
|
|
246
|
+
fs.writeFileSync(manifestFile, JSON.stringify(legacyManifest));
|
|
247
|
+
const missingBaselineOutput = { system: [] };
|
|
248
|
+
await plugin['experimental.chat.system.transform']({}, missingBaselineOutput);
|
|
249
|
+
assert.match(missingBaselineOutput.system.join('\n'), /CONTEXT_SNAPSHOT_UPGRADE_REQUIRED/);
|
|
250
|
+
legacyManifest.baseline = {
|
|
251
|
+
id: 'project-baseline', mode: 'brownfield', status: 'ready', repository_revision: compiledHead,
|
|
252
|
+
};
|
|
253
|
+
fs.writeFileSync(manifestFile, JSON.stringify(legacyManifest));
|
|
254
|
+
|
|
241
255
|
fs.writeFileSync(path.join(project, 'app.txt'), 'changed\n');
|
|
242
256
|
execFileSync('git', ['add', 'app.txt'], { cwd: project, stdio: 'ignore' });
|
|
243
257
|
execFileSync('git', ['-c', 'user.name=Ultra Tests', '-c', 'user.email=ultra@example.invalid', 'commit', '-m', 'change'], {
|
|
@@ -262,6 +276,27 @@ test('OpenCode context covers active changes and projection writes are blocked f
|
|
|
262
276
|
}
|
|
263
277
|
});
|
|
264
278
|
|
|
279
|
+
test('OpenCode does not assume a project baseline is ready when no active change manifest exists', async () => {
|
|
280
|
+
const target = mkTarget();
|
|
281
|
+
const project = mkTarget();
|
|
282
|
+
try {
|
|
283
|
+
opencode.install({ configDir: target, repoRoot: REPO_ROOT });
|
|
284
|
+
fs.mkdirSync(path.join(project, '.ultra'), { recursive: true });
|
|
285
|
+
fs.writeFileSync(path.join(project, '.ultra', 'state.db'), 'owned-by-ultra');
|
|
286
|
+
const module = await import(`${pathToFileURL(path.join(target, 'plugins', 'ultra-builder-pro.js')).href}?baseline`);
|
|
287
|
+
const plugin = await module.UltraBuilderProPlugin({ directory: project });
|
|
288
|
+
const output = { system: [] };
|
|
289
|
+
await plugin['experimental.chat.system.transform']({}, output);
|
|
290
|
+
const text = output.system.join('\n');
|
|
291
|
+
assert.match(text, /ultra-status/);
|
|
292
|
+
assert.match(text, /ultra-init/);
|
|
293
|
+
assert.doesNotMatch(text, /Start daily work with the ultra-change workflow/);
|
|
294
|
+
} finally {
|
|
295
|
+
fs.rmSync(target, { recursive: true, force: true });
|
|
296
|
+
fs.rmSync(project, { recursive: true, force: true });
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
|
|
265
300
|
test('install preserves user mcp entries; uninstall removes only owned Ultra assets', () => {
|
|
266
301
|
const target = mkTarget();
|
|
267
302
|
const configFile = path.join(target, 'opencode.json');
|
package/commands/ultra-init.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Initialize
|
|
3
|
-
argument-hint: "[name] [type] [stack] [
|
|
2
|
+
description: Initialize a new project or adopt an existing repository into authoritative Ultra baseline state
|
|
3
|
+
argument-hint: "[name] [type] [stack] [auto|greenfield|brownfield]"
|
|
4
4
|
workflow-ref: "@skills/ultra-init/SKILL.md"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
# Initialize an Ultra project
|
|
7
|
+
# Initialize or adopt an Ultra project
|
|
8
8
|
|
|
9
9
|
Read and follow `@skills/ultra-init/SKILL.md`, using `$ARGUMENTS` as optional project metadata.
|
|
10
10
|
Treat the referenced skill as the only workflow definition.
|