ultra-builder-pro-cli 5.0.1 → 6.0.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/CHANGELOG.md +103 -3
- package/README.md +67 -478
- package/README.zh-CN.md +49 -422
- package/adapters/_shared/frontmatter.cjs +1 -18
- package/adapters/_shared/plugin-core.cjs +17 -83
- package/adapters/_shared/runtime-assets.cjs +6 -120
- package/adapters/claude.js +8 -24
- package/adapters/codex.js +13 -32
- package/bin/install.js +35 -57
- package/docs/PLUGIN-ISOLATION-CONTRACT.md +13 -101
- package/docs/examples/drive/claude-reviewer.sh +53 -0
- package/docs/examples/drive/claude-writer.sh +43 -0
- package/engine/FORMATS.md +1051 -0
- package/engine/checks.cjs +139 -0
- package/engine/cli.cjs +148 -0
- package/engine/completion.cjs +48 -0
- package/engine/context.cjs +94 -0
- package/engine/drive.cjs +220 -0
- package/engine/expect-worker.cjs +5 -0
- package/engine/expect.cjs +33 -0
- package/engine/formats.cjs +189 -0
- package/engine/git-state.cjs +112 -0
- package/engine/ledger.cjs +205 -0
- package/engine/loading.cjs +28 -0
- package/engine/merge.cjs +273 -0
- package/engine/milestone.cjs +89 -0
- package/engine/plan.cjs +232 -0
- package/engine/project.cjs +5 -0
- package/engine/signals.cjs +3 -0
- package/engine/states.cjs +175 -0
- package/hooks/session-start.cjs +54 -0
- package/package.json +17 -52
- package/skills/ultra/SKILL.md +395 -0
- package/.ultra-template/changes/abandoned/.gitkeep +0 -0
- package/.ultra-template/changes/active/.gitkeep +0 -1
- package/.ultra-template/changes/archive/.gitkeep +0 -1
- package/.ultra-template/contexts/TEMPLATE.md +0 -135
- package/.ultra-template/decisions/.gitkeep +0 -1
- package/.ultra-template/evidence/.gitkeep +0 -1
- package/.ultra-template/north-star.md +0 -52
- package/.ultra-template/project-brief.md +0 -28
- package/.ultra-template/research/.gitkeep +0 -1
- package/.ultra-template/specs/architecture.md +0 -81
- package/.ultra-template/specs/discovery.md +0 -74
- package/.ultra-template/specs/product.md +0 -80
- package/.ultra-template/specs/research-distillate.md +0 -57
- package/.ultra-template/tasks.json +0 -4
- package/.ultra-template/test-report.json +0 -44
- package/adapters/_shared/host-profile.cjs +0 -5
- package/adapters/grok.js +0 -242
- package/adapters/kimi.js +0 -232
- package/adapters/opencode.js +0 -408
- package/adapters/zcode.js +0 -375
- package/bin/delegate-worker.cjs +0 -5
- package/bin/delegate.cjs +0 -5
- package/docs/ARCHITECTURE.md +0 -274
- package/docs/ARTIFACT-AUTHORITY.md +0 -305
- package/docs/DECISIONS.md +0 -229
- package/docs/PHILOSOPHY.md +0 -261
- package/docs/RUNTIME-COMPAT-MATRIX.md +0 -316
- package/docs/SKILL-AUTHORING.md +0 -113
- package/docs/WORKFLOW-LIFECYCLE.md +0 -350
- package/docs/evals/adversarial-review-2026-08-14.md +0 -84
- package/docs/evals/ultra-5-0-journey-results.md +0 -62
- package/docs/evals/ultra-5-0-live-acp-conformance.md +0 -93
- package/docs/evals/ultra-5-0-route-journeys.md +0 -145
- package/docs/evals/zcode-automation-2026-08-14.md +0 -103
- package/hooks/README.md +0 -52
- package/hooks/_common.py +0 -1779
- package/hooks/adapters/codex.py +0 -295
- package/hooks/adapters/grok.py +0 -134
- package/hooks/adapters/kimi.py +0 -156
- package/hooks/adapters/zcode.py +0 -227
- package/hooks/block_dangerous_commands.py +0 -201
- package/hooks/compact_context.py +0 -224
- package/hooks/mid_workflow_recall.py +0 -47
- package/hooks/post_edit_guard.py +0 -215
- package/hooks/session_context.py +0 -741
- package/skills/ultra-change/SKILL.md +0 -165
- package/skills/ultra-change/references/change-contract.md +0 -199
- package/skills/ultra-change/references/execution-grant.md +0 -109
- package/skills/ultra-change/references/primary-transfer.md +0 -273
- package/skills/ultra-change/scripts/validate_primary_transfer.cjs +0 -1928
- package/skills/ultra-delegate/SKILL.md +0 -195
- package/skills/ultra-delegate/patches/zcode-acp-0.1.0-zcode-0.16.5.patch +0 -184
- package/skills/ultra-delegate/references/delegation-contract.md +0 -138
- package/skills/ultra-delegate/scripts/acp-conformance.cjs +0 -287
- package/skills/ultra-delegate/scripts/acp-driver.cjs +0 -762
- package/skills/ultra-delegate/scripts/agent-execution-driver.cjs +0 -320
- package/skills/ultra-delegate/scripts/cli-driver.cjs +0 -61
- package/skills/ultra-delegate/scripts/delegate-profiles/kimi-read-only.md +0 -15
- package/skills/ultra-delegate/scripts/delegate-profiles/kimi-write.md +0 -17
- package/skills/ultra-delegate/scripts/delegate-worker.cjs +0 -328
- package/skills/ultra-delegate/scripts/delegate.cjs +0 -690
- package/skills/ultra-delegate/scripts/delegate_wait.py +0 -86
- package/skills/ultra-delegate/scripts/host-profile.cjs +0 -267
- package/skills/ultra-deliver/SKILL.md +0 -194
- package/skills/ultra-deliver/references/baseline-reconciliation.md +0 -41
- package/skills/ultra-dev/SKILL.md +0 -265
- package/skills/ultra-dev/references/debugging.md +0 -22
- package/skills/ultra-domain-modeling/SKILL.md +0 -79
- package/skills/ultra-grilling/SKILL.md +0 -121
- package/skills/ultra-grilling/references/reframing.md +0 -76
- package/skills/ultra-init/SKILL.md +0 -143
- package/skills/ultra-init/references/brownfield-adoption.md +0 -32
- package/skills/ultra-init/scripts/init_project.cjs +0 -1031
- package/skills/ultra-plan/SKILL.md +0 -160
- package/skills/ultra-plan/references/task-evidence-v2.md +0 -300
- package/skills/ultra-plan/scripts/validate_task_evidence.cjs +0 -859
- package/skills/ultra-research/SKILL.md +0 -167
- package/skills/ultra-research/references/00-problem-validation.md +0 -36
- package/skills/ultra-research/references/01-opportunity-discovery.md +0 -33
- package/skills/ultra-research/references/02-market-assessment.md +0 -31
- package/skills/ultra-research/references/03-alternatives.md +0 -31
- package/skills/ultra-research/references/04-product-strategy.md +0 -41
- package/skills/ultra-research/references/05-assumptions-validation.md +0 -31
- package/skills/ultra-research/references/10-user-personas.md +0 -30
- package/skills/ultra-research/references/11-user-scenarios.md +0 -28
- package/skills/ultra-research/references/20-user-stories.md +0 -31
- package/skills/ultra-research/references/21-features-scope.md +0 -38
- package/skills/ultra-research/references/22-success-metrics.md +0 -33
- package/skills/ultra-research/references/30-architecture-context.md +0 -30
- package/skills/ultra-research/references/31-solution-strategy.md +0 -28
- package/skills/ultra-research/references/32-building-blocks.md +0 -28
- package/skills/ultra-research/references/40-deployment.md +0 -29
- package/skills/ultra-research/references/41-quality-risks.md +0 -28
- package/skills/ultra-research/references/99-synthesis.md +0 -59
- package/skills/ultra-research/references/north-star-v2.md +0 -168
- package/skills/ultra-research/references/wayfinding.md +0 -50
- package/skills/ultra-research/scripts/validate_north_star.cjs +0 -1174
- package/skills/ultra-review/SKILL.md +0 -275
- package/skills/ultra-review/references/adversarial-evaluation.md +0 -31
- package/skills/ultra-review/references/code.md +0 -17
- package/skills/ultra-review/references/comments.md +0 -12
- package/skills/ultra-review/references/design.md +0 -12
- package/skills/ultra-review/references/errors.md +0 -13
- package/skills/ultra-review/references/review-modes.md +0 -29
- package/skills/ultra-review/references/spec.md +0 -18
- package/skills/ultra-review/references/tests.md +0 -12
- package/skills/ultra-review/references/unified-schema.md +0 -284
- package/skills/ultra-review/references/worker-packet.md +0 -183
- package/skills/ultra-review/scripts/review_wait.py +0 -2943
- package/skills/ultra-status/SKILL.md +0 -209
- package/skills/ultra-status/references/route-contract.md +0 -100
- package/skills/ultra-tdd/SKILL.md +0 -91
- package/skills/ultra-tdd/references/templates/README.md +0 -20
- package/skills/ultra-tdd/references/templates/feature-flag-default-audit.sh +0 -79
- package/skills/ultra-tdd/references/templates/persistence-real.ts +0 -78
- package/skills/ultra-tdd/references/templates/testcontainer-postgres.py +0 -78
- package/skills/ultra-tdd/references/templates/testcontainer-postgres.ts +0 -73
- package/skills/ultra-tdd/references/templates/vertical-slice.ts +0 -66
- package/skills/ultra-tdd/references/test-execution.md +0 -23
- package/skills/ultra-test/SKILL.md +0 -244
- package/skills/ultra-test/references/export-syntax.md +0 -18
- package/skills/ultra-test/scripts/validate_review_transport.cjs +0 -549
- package/skills/ultra-test/scripts/worktree_digest.cjs +0 -576
- package/skills/ultra-think/SKILL.md +0 -56
- package/skills/ultra-think/references/autonomy-boundary.md +0 -48
- package/skills/ultra-think/references/interaction-boundary.md +0 -42
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""Wait for one delegated result to become non-empty and stable."""
|
|
3
|
-
|
|
4
|
-
from __future__ import annotations
|
|
5
|
-
|
|
6
|
-
import argparse
|
|
7
|
-
import json
|
|
8
|
-
import re
|
|
9
|
-
import time
|
|
10
|
-
from pathlib import Path
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
RESULT_SCHEMA = "ultra-delegation-result-v1"
|
|
14
|
-
STATUSES = {"finished", "blocked", "failed"}
|
|
15
|
-
CHECK_STATUSES = {"passed", "failed", "not_run"}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
def nonempty(value) -> bool:
|
|
19
|
-
return isinstance(value, str) and bool(value.strip())
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
def validate_result(payload: dict) -> None:
|
|
23
|
-
if not isinstance(payload, dict):
|
|
24
|
-
raise ValueError("result must be a JSON object")
|
|
25
|
-
if payload.get("$schema") != RESULT_SCHEMA:
|
|
26
|
-
raise ValueError(f"result $schema must be {RESULT_SCHEMA}")
|
|
27
|
-
if payload.get("status") not in STATUSES:
|
|
28
|
-
raise ValueError("result status must be finished, blocked, or failed")
|
|
29
|
-
if not nonempty(payload.get("summary")):
|
|
30
|
-
raise ValueError("result summary must be non-empty")
|
|
31
|
-
for field in ("changed_files", "checks", "evidence", "questions", "residual_risks"):
|
|
32
|
-
if not isinstance(payload.get(field), list):
|
|
33
|
-
raise ValueError(f"result {field} must be an array")
|
|
34
|
-
for field in ("changed_files", "evidence", "questions", "residual_risks"):
|
|
35
|
-
if not all(nonempty(item) for item in payload[field]):
|
|
36
|
-
raise ValueError(f"result {field} must contain non-empty strings")
|
|
37
|
-
for check in payload["checks"]:
|
|
38
|
-
if not isinstance(check, dict) or not nonempty(check.get("command")):
|
|
39
|
-
raise ValueError("result checks require a command")
|
|
40
|
-
if check.get("status") not in CHECK_STATUSES:
|
|
41
|
-
raise ValueError("result check status is invalid")
|
|
42
|
-
if payload["status"] == "blocked" and not payload["questions"]:
|
|
43
|
-
raise ValueError("blocked result requires a question")
|
|
44
|
-
for field in ("delegation_id", "host", "base_head", "final_head", "started_at", "finished_at"):
|
|
45
|
-
if not nonempty(payload.get(field)):
|
|
46
|
-
raise ValueError(f"result {field} must be non-empty")
|
|
47
|
-
for field in ("instruction_digest", "permission_digest", "output_schema_digest"):
|
|
48
|
-
if not isinstance(payload.get(field), str) or not re.fullmatch(r"[0-9a-f]{64}", payload[field]):
|
|
49
|
-
raise ValueError(f"result {field} must be a SHA-256 digest")
|
|
50
|
-
if not isinstance(payload.get("read_only"), bool):
|
|
51
|
-
raise ValueError("result read_only must be a boolean")
|
|
52
|
-
if payload.get("exit_code") is not None and not isinstance(payload["exit_code"], int):
|
|
53
|
-
raise ValueError("result exit_code must be an integer or null")
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
def wait_for_result(path: Path, interval: float, timeout: float) -> dict:
|
|
57
|
-
deadline = time.monotonic() + timeout
|
|
58
|
-
previous_size = -1
|
|
59
|
-
stable_reads = 0
|
|
60
|
-
while time.monotonic() < deadline:
|
|
61
|
-
size = path.stat().st_size if path.exists() else 0
|
|
62
|
-
if size > 0 and size == previous_size:
|
|
63
|
-
stable_reads += 1
|
|
64
|
-
if stable_reads >= 1:
|
|
65
|
-
payload = json.loads(path.read_text(encoding="utf-8"))
|
|
66
|
-
validate_result(payload)
|
|
67
|
-
return payload
|
|
68
|
-
else:
|
|
69
|
-
stable_reads = 0
|
|
70
|
-
previous_size = size
|
|
71
|
-
time.sleep(interval)
|
|
72
|
-
raise TimeoutError(f"result did not stabilize within {timeout:g}s: {path}")
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
def main() -> int:
|
|
76
|
-
parser = argparse.ArgumentParser()
|
|
77
|
-
parser.add_argument("result", type=Path)
|
|
78
|
-
parser.add_argument("--interval", type=float, default=1.0)
|
|
79
|
-
parser.add_argument("--timeout", type=float, default=1800.0)
|
|
80
|
-
args = parser.parse_args()
|
|
81
|
-
print(json.dumps(wait_for_result(args.result, args.interval, args.timeout)))
|
|
82
|
-
return 0
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
if __name__ == "__main__":
|
|
86
|
-
raise SystemExit(main())
|
|
@@ -1,267 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const fs = require('node:fs');
|
|
4
|
-
const path = require('node:path');
|
|
5
|
-
|
|
6
|
-
const KIMI_PROFILE_ROOT = path.join(__dirname, 'delegate-profiles');
|
|
7
|
-
const ZCODE_BUNDLED_CLI = '/Applications/ZCode.app/Contents/Resources/glm/zcode.cjs';
|
|
8
|
-
const CLAUDE_ACP_PACKAGE = '@agentclientprotocol/claude-agent-acp@0.70.0';
|
|
9
|
-
const CODEX_ACP_PACKAGE = '@agentclientprotocol/codex-acp@1.6.2';
|
|
10
|
-
const ZCODE_ACP_SOURCE = Object.freeze({
|
|
11
|
-
repository: 'https://github.com/jpalmae/zcode-acp',
|
|
12
|
-
version: '0.1.0',
|
|
13
|
-
commit: '42fe149d4b501469343c01f23ba3801832306d53',
|
|
14
|
-
buildMarker: 'zcode-acp 0.1.0+ultra.zcode.0.16.5',
|
|
15
|
-
runtimeVersion: '0.16.5',
|
|
16
|
-
patch: Object.freeze({
|
|
17
|
-
path: 'skills/ultra-delegate/patches/zcode-acp-0.1.0-zcode-0.16.5.patch',
|
|
18
|
-
sha256: '174dfd0feafe84320556a84b5ae08b10e44c5515fea4992fd1d58af54cee4e3d',
|
|
19
|
-
compatibility: 'ZCode CLI 0.16.5 runtime-preferences handshake',
|
|
20
|
-
}),
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
// The ZCode app-bundled CLI is a verified-local surface, not a provider
|
|
24
|
-
// stability promise: official documentation plus a full recovery drill must
|
|
25
|
-
// both hold before any transport may claim 'supported'.
|
|
26
|
-
const TRANSPORT_MATURITY = Object.freeze({
|
|
27
|
-
claude: 'documented+verified',
|
|
28
|
-
codex: 'documented+verified',
|
|
29
|
-
opencode: 'documented+verified',
|
|
30
|
-
kimi: 'documented+verified',
|
|
31
|
-
grok: 'documented+verified',
|
|
32
|
-
zcode: 'experimental',
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
const ACP_CONFORMANCE = Object.freeze({
|
|
36
|
-
claude: Object.freeze({
|
|
37
|
-
status: 'passed',
|
|
38
|
-
evidence: 'docs/evals/ultra-5-0-live-acp-conformance.md#claude-code',
|
|
39
|
-
receiptSha256: '9b1d88cbd5e5b66a56e0cf19f34e7f2107f9e4b8fde9d80b9eadcdfc8f4a25e3',
|
|
40
|
-
}),
|
|
41
|
-
codex: Object.freeze({
|
|
42
|
-
status: 'passed',
|
|
43
|
-
evidence: 'docs/evals/ultra-5-0-live-acp-conformance.md#codex',
|
|
44
|
-
receiptSha256: 'e82287609397807fb6968dff104d7f6569499b53c77be6a186aa33939a4c629e',
|
|
45
|
-
}),
|
|
46
|
-
opencode: Object.freeze({
|
|
47
|
-
status: 'passed',
|
|
48
|
-
evidence: 'docs/evals/ultra-5-0-live-acp-conformance.md#opencode',
|
|
49
|
-
receiptSha256: '3575b148f6feb8c9f1472add705390e6d47b87be080403ec7006b66a29f7873b',
|
|
50
|
-
}),
|
|
51
|
-
kimi: Object.freeze({
|
|
52
|
-
status: 'passed',
|
|
53
|
-
evidence: 'docs/evals/ultra-5-0-live-acp-conformance.md#kimi-code',
|
|
54
|
-
receiptSha256: '30d8adec2877f80fadf0b20c3cb7fa6b732dea3598d7484c143f9835770301fe',
|
|
55
|
-
}),
|
|
56
|
-
grok: Object.freeze({
|
|
57
|
-
status: 'passed',
|
|
58
|
-
evidence: 'docs/evals/ultra-5-0-live-acp-conformance.md#grok-build',
|
|
59
|
-
receiptSha256: '370eeae12d63443188d519825ed8040fd8bba9b27fddb82e499d9cb590f4a33d',
|
|
60
|
-
}),
|
|
61
|
-
zcode: Object.freeze({
|
|
62
|
-
status: 'passed',
|
|
63
|
-
evidence: 'docs/evals/ultra-5-0-live-acp-conformance.md#zcode',
|
|
64
|
-
receiptSha256: '156080f88ed84a013fb26d93e5138230732d2ef0e2b5b10a7c3deb501d3548e9',
|
|
65
|
-
}),
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
function zcodeBinary({ platform = process.platform, exists = fs.existsSync } = {}) {
|
|
69
|
-
return platform === 'darwin' && exists(ZCODE_BUNDLED_CLI)
|
|
70
|
-
? ZCODE_BUNDLED_CLI
|
|
71
|
-
: 'zcode';
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function opencodePermission(writableRoots) {
|
|
75
|
-
const edit = { '*': 'deny' };
|
|
76
|
-
for (const root of writableRoots) {
|
|
77
|
-
if (root === '.') edit['*'] = 'allow';
|
|
78
|
-
else edit[`${root}/**`] = 'allow';
|
|
79
|
-
}
|
|
80
|
-
return JSON.stringify({
|
|
81
|
-
share: 'disabled',
|
|
82
|
-
permission: {
|
|
83
|
-
'*': 'deny',
|
|
84
|
-
read: 'allow',
|
|
85
|
-
glob: 'allow',
|
|
86
|
-
grep: 'allow',
|
|
87
|
-
list: 'allow',
|
|
88
|
-
lsp: 'allow',
|
|
89
|
-
edit,
|
|
90
|
-
external_directory: 'deny',
|
|
91
|
-
bash: 'deny',
|
|
92
|
-
task: 'deny',
|
|
93
|
-
webfetch: 'deny',
|
|
94
|
-
websearch: 'deny',
|
|
95
|
-
question: 'deny',
|
|
96
|
-
skill: 'deny',
|
|
97
|
-
},
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
const PROFILES = Object.freeze({
|
|
102
|
-
claude: Object.freeze({
|
|
103
|
-
binary: 'claude',
|
|
104
|
-
acp: Object.freeze({
|
|
105
|
-
surface: `official ${CLAUDE_ACP_PACKAGE} stdio adapter`,
|
|
106
|
-
transport: 'stdio',
|
|
107
|
-
protocolVersions: [1],
|
|
108
|
-
conformance: ACP_CONFORMANCE.claude,
|
|
109
|
-
command: () => 'npx',
|
|
110
|
-
argv: () => ['--yes', CLAUDE_ACP_PACKAGE],
|
|
111
|
-
}),
|
|
112
|
-
delegateArgv: (prompt, _cwd, options) => [
|
|
113
|
-
'-p', prompt,
|
|
114
|
-
'--permission-mode', options.readOnly ? 'plan' : 'acceptEdits',
|
|
115
|
-
'--no-session-persistence',
|
|
116
|
-
'--output-format', 'json',
|
|
117
|
-
'--tools', options.readOnly ? 'Read,Grep,Glob' : 'Read,Write,Edit,Grep,Glob',
|
|
118
|
-
],
|
|
119
|
-
}),
|
|
120
|
-
codex: Object.freeze({
|
|
121
|
-
binary: 'codex',
|
|
122
|
-
acp: Object.freeze({
|
|
123
|
-
surface: `official ${CODEX_ACP_PACKAGE} stdio adapter`,
|
|
124
|
-
transport: 'stdio',
|
|
125
|
-
protocolVersions: [1],
|
|
126
|
-
conformance: ACP_CONFORMANCE.codex,
|
|
127
|
-
command: () => 'npx',
|
|
128
|
-
argv: () => ['--yes', CODEX_ACP_PACKAGE],
|
|
129
|
-
}),
|
|
130
|
-
delegateArgv: (prompt, cwd, options) => [
|
|
131
|
-
'exec', '--ephemeral', '--ignore-user-config',
|
|
132
|
-
'--sandbox', options.readOnly ? 'read-only' : 'workspace-write',
|
|
133
|
-
'--cd', cwd,
|
|
134
|
-
'--config', 'sandbox_workspace_write.network_access=false',
|
|
135
|
-
'--output-schema', options.schemaFile,
|
|
136
|
-
'--output-last-message', options.hostOutput,
|
|
137
|
-
'--json', prompt,
|
|
138
|
-
],
|
|
139
|
-
}),
|
|
140
|
-
opencode: Object.freeze({
|
|
141
|
-
binary: 'opencode',
|
|
142
|
-
acp: Object.freeze({
|
|
143
|
-
surface: 'native OpenCode ACP stdio server',
|
|
144
|
-
transport: 'stdio',
|
|
145
|
-
protocolVersions: [1],
|
|
146
|
-
conformance: ACP_CONFORMANCE.opencode,
|
|
147
|
-
command: ({ cliCommand }) => cliCommand,
|
|
148
|
-
argv: () => ['acp'],
|
|
149
|
-
}),
|
|
150
|
-
delegateArgv: (prompt, cwd) => [
|
|
151
|
-
'run', '--dir', cwd, '--format', 'json', '--auto', prompt,
|
|
152
|
-
],
|
|
153
|
-
delegateEnv: (options) => ({
|
|
154
|
-
OPENCODE_CONFIG_CONTENT: opencodePermission(options.writableRoots),
|
|
155
|
-
}),
|
|
156
|
-
}),
|
|
157
|
-
kimi: Object.freeze({
|
|
158
|
-
binary: 'kimi',
|
|
159
|
-
supportsModelSelection: true,
|
|
160
|
-
acp: Object.freeze({
|
|
161
|
-
surface: 'Kimi Code ACP stdio server',
|
|
162
|
-
transport: 'stdio',
|
|
163
|
-
protocolVersions: [1],
|
|
164
|
-
conformance: ACP_CONFORMANCE.kimi,
|
|
165
|
-
command: ({ cliCommand }) => cliCommand,
|
|
166
|
-
argv: () => ['acp'],
|
|
167
|
-
}),
|
|
168
|
-
delegateArgv: (prompt, _cwd, options) => {
|
|
169
|
-
const args = ['-p', prompt, '--output-format', 'stream-json'];
|
|
170
|
-
if (options.model) args.push('--model', options.model);
|
|
171
|
-
args.push(
|
|
172
|
-
'--agent-file',
|
|
173
|
-
path.join(
|
|
174
|
-
KIMI_PROFILE_ROOT,
|
|
175
|
-
options.readOnly ? 'kimi-read-only.md' : 'kimi-write.md',
|
|
176
|
-
),
|
|
177
|
-
);
|
|
178
|
-
return args;
|
|
179
|
-
},
|
|
180
|
-
}),
|
|
181
|
-
grok: Object.freeze({
|
|
182
|
-
binary: 'grok',
|
|
183
|
-
acp: Object.freeze({
|
|
184
|
-
surface: 'Grok agent stdio candidate',
|
|
185
|
-
transport: 'stdio',
|
|
186
|
-
protocolVersions: [1],
|
|
187
|
-
conformance: ACP_CONFORMANCE.grok,
|
|
188
|
-
command: ({ cliCommand }) => cliCommand,
|
|
189
|
-
argv: () => ['agent', 'stdio'],
|
|
190
|
-
}),
|
|
191
|
-
delegateArgv: (prompt, cwd, options) => [
|
|
192
|
-
'--cwd', cwd, '--single', prompt,
|
|
193
|
-
'--permission-mode', options.readOnly ? 'plan' : 'acceptEdits',
|
|
194
|
-
'--sandbox', options.readOnly ? 'read-only' : 'workspace',
|
|
195
|
-
'--no-memory', '--no-subagents', '--disable-web-search',
|
|
196
|
-
'--verbatim',
|
|
197
|
-
'--max-turns', '12',
|
|
198
|
-
'--output-format', 'json',
|
|
199
|
-
],
|
|
200
|
-
}),
|
|
201
|
-
zcode: Object.freeze({
|
|
202
|
-
binary: zcodeBinary(),
|
|
203
|
-
installedRuntimeOnly: true,
|
|
204
|
-
acp: Object.freeze({
|
|
205
|
-
surface: `installed ZCode Desktop runtime through zcode-acp ${ZCODE_ACP_SOURCE.version}`,
|
|
206
|
-
transport: 'stdio',
|
|
207
|
-
protocolVersions: [1],
|
|
208
|
-
conformance: ACP_CONFORMANCE.zcode,
|
|
209
|
-
command: ({ env }) => env.ULTRA_ZCODE_ACP_COMMAND || 'zcode-acp',
|
|
210
|
-
argv: ({ cliCommand }) => ['--zcode-path', cliCommand, '--no-browser'],
|
|
211
|
-
identityProbes: ({ command, cliCommand }) => [
|
|
212
|
-
{
|
|
213
|
-
label: 'zcode_bridge',
|
|
214
|
-
command,
|
|
215
|
-
args: ['--version'],
|
|
216
|
-
expectedStdout: ZCODE_ACP_SOURCE.buildMarker,
|
|
217
|
-
},
|
|
218
|
-
{
|
|
219
|
-
label: 'zcode_runtime',
|
|
220
|
-
command: cliCommand.endsWith('.cjs') ? process.execPath : cliCommand,
|
|
221
|
-
args: cliCommand.endsWith('.cjs') ? [cliCommand, '--version'] : ['--version'],
|
|
222
|
-
expectedStdout: ZCODE_ACP_SOURCE.runtimeVersion,
|
|
223
|
-
},
|
|
224
|
-
],
|
|
225
|
-
}),
|
|
226
|
-
delegateArgv: (prompt, cwd, options) => [
|
|
227
|
-
'--cwd', cwd,
|
|
228
|
-
'--mode', options.readOnly ? 'plan' : 'edit',
|
|
229
|
-
'--json', '--no-color',
|
|
230
|
-
'--disallowedTools', options.readOnly
|
|
231
|
-
? 'Bash Write Edit ApplyPatch Agent WebFetch WebSearch'
|
|
232
|
-
: 'Bash Agent WebFetch WebSearch',
|
|
233
|
-
'--prompt', prompt,
|
|
234
|
-
],
|
|
235
|
-
}),
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
function hostProfile(runtime) {
|
|
239
|
-
const profile = PROFILES[runtime];
|
|
240
|
-
if (!profile) throw new Error(`unsupported delegate host: ${runtime}`);
|
|
241
|
-
return { ...profile, transportMaturity: TRANSPORT_MATURITY[runtime] };
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
// The live delegate surface names honestly what a run actually used. The ZCode
|
|
245
|
-
// headless transports are app-internal surfaces, never the documented ZCode
|
|
246
|
-
// Desktop interactive primary path, so every receipt that records one says so.
|
|
247
|
-
function transportSurface(runtime, binary = PROFILES[runtime] ? PROFILES[runtime].binary : undefined) {
|
|
248
|
-
if (runtime === 'zcode') {
|
|
249
|
-
const source = binary === ZCODE_BUNDLED_CLI ? 'the App-bundled headless CLI' : 'the zcode headless CLI on PATH';
|
|
250
|
-
return `${source} (experimental; not the documented ZCode Desktop interactive surface)`;
|
|
251
|
-
}
|
|
252
|
-
return 'documented non-interactive CLI';
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
module.exports = {
|
|
256
|
-
ACP_CONFORMANCE,
|
|
257
|
-
CLAUDE_ACP_PACKAGE,
|
|
258
|
-
CODEX_ACP_PACKAGE,
|
|
259
|
-
PROFILES,
|
|
260
|
-
TRANSPORT_MATURITY,
|
|
261
|
-
ZCODE_BUNDLED_CLI,
|
|
262
|
-
ZCODE_ACP_SOURCE,
|
|
263
|
-
hostProfile,
|
|
264
|
-
opencodePermission,
|
|
265
|
-
transportSurface,
|
|
266
|
-
zcodeBinary,
|
|
267
|
-
};
|
|
@@ -1,194 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: ultra-deliver
|
|
3
|
-
description: Reconcile one Change whose matching tasks are complete, run aggregate review and refactoring, and report the delivery handoff. Use when the owner wants delivery reconciliation and reporting, or — by current explicit owner invocation only — the separately gated finalization that writes delivery.md, fixes version and package posture, and archives the local workflow record.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Turn current evidence into a recoverable delivery handoff
|
|
7
|
-
|
|
8
|
-
Delivery closes the local Change; readiness grants no commit, push, tag, publish, or deploy authority.
|
|
9
|
-
|
|
10
|
-
## Route modes
|
|
11
|
-
|
|
12
|
-
| Mode | Entry | Observable exit | Next |
|
|
13
|
-
|---|---|---|---|
|
|
14
|
-
| `reconcile` | Explicit invocation or a valid Execution Grant for a tested active Change | Intent, implementation, specifications, documentation, evidence, and report agree, or changed files make the exact stale evidence visible | Recommend `ultra-test/reaudit` after changes, otherwise recommend explicit `ultra-deliver/finalize` |
|
|
15
|
-
| `finalize` | Current explicit owner invocation only | Fresh transport/evidence checks pass, version and package posture are owner-set, `delivery.md` is written, and the Change is locally archived | Report `idle` plus every separately authorized or unfinished release effect |
|
|
16
|
-
|
|
17
|
-
Follow `../ultra-status/references/route-contract.md`. Show a Route Card at entry, after
|
|
18
|
-
reconciliation, before the finalization checkpoint, and after archive or any stop.
|
|
19
|
-
Grant-aware continuation ends with `reconcile`; no Host metadata bit, report, or grant
|
|
20
|
-
turns `finalize` into an implicit mode.
|
|
21
|
-
|
|
22
|
-
## Before you start
|
|
23
|
-
|
|
24
|
-
1. If model-selected, verify the live execution grant in `../ultra-change/references/execution-grant.md` — a current session-local activation or a stably verified durable work-package grant; without either, stop. A model-selected Deliver run under that grant may reconcile, review, and report, and then MUST stop before finalization: its inputs, writes, and effects end at the report. Only a current explicit owner invocation of `ultra-deliver` may finalize — writing `delivery.md`, deciding the version decision and package posture, and archiving the stable Change id with `git mv` are owner-invocation-only in every grant mode, and a grant never covers them.
|
|
25
|
-
2. Read `../ultra-change/references/change-contract.md` and apply its **Active Change
|
|
26
|
-
authority resolution** before reading any active `intent.md` or resolving a current
|
|
27
|
-
`change_id`. This workflow requires its one valid active authority; any zero result
|
|
28
|
-
or typed diagnostic stops before finalization input is read until the stated repair
|
|
29
|
-
or retry succeeds. Read `.ultra/tasks.json`; every matching task must be `completed`
|
|
30
|
-
in that sole task-status authority. Read each `context_file`'s Completion, Task
|
|
31
|
-
Review, and closing Resume Note. For every current Change task,
|
|
32
|
-
require current `ultra-task-evidence-v2` and task-review provenance under
|
|
33
|
-
`../ultra-plan/references/task-evidence-v2.md`, already consumed by the current Test
|
|
34
|
-
report. A legacy context Status or Complexity header and v1 evidence are migration
|
|
35
|
-
diagnostics only and cannot support current delivery.
|
|
36
|
-
3. Read `CONTEXT.md`, relevant `.ultra/decisions/`, active Change intent and evidence.
|
|
37
|
-
Validate `.ultra/north-star.md`; resolve every recorded `FP-*`, `NS-*`, and `HC-*`
|
|
38
|
-
for the delivered Change, tasks, findings, and dispositions against that accepted
|
|
39
|
-
authority. Compare the active Change's recorded **North Star revision** and
|
|
40
|
-
**North Star digest** with the accepted file's revision and current Git blob digest. Any
|
|
41
|
-
missing ID or mismatch stops finalization and recommends explicit owner invocation of
|
|
42
|
-
`ultra-change` for reconciliation; delivery never silently rewrites the trace.
|
|
43
|
-
4. Read `.ultra/test-report.json`, then run the Test Skill's `worktree_digest.cjs` with
|
|
44
|
-
project root and `--change-id`. Require report `task_ids` for the current Change plus
|
|
45
|
-
matching `change_id`, `git_commit`, worktree digest, intent digest, and review
|
|
46
|
-
`admission_digest`, `subject_digest`, and `summary_digest`; otherwise stop. Recheck
|
|
47
|
-
each projected task's declared review branch as recorded: strict-v4 items keep their
|
|
48
|
-
strict receipt and transport bindings, while `external-manual` items reverify their
|
|
49
|
-
receipt bytes and digest through the task-evidence sensor's
|
|
50
|
-
`--verify-external-receipt` mode and take the sensor's `--projection` output
|
|
51
|
-
verbatim — a strict SUMMARY never substitutes for an external receipt and neither
|
|
52
|
-
branch is rewritten into the other.
|
|
53
|
-
The product-worktree digest has one fixed boundary: it excludes `.ultra/evidence/**`,
|
|
54
|
-
whose command and external-observation entries bind raw bytes as
|
|
55
|
-
`raw_evidence_sha256` before stable exact record bytes are bound as `evidence_digest`
|
|
56
|
-
through the report's ordered `task_evidence` projection. For each projected record,
|
|
57
|
-
take every `raw_evidence_ref` to bounded stable repository-contained bytes from an
|
|
58
|
-
ordinary regular non-symlink file opened nonblocking and no-follow, with an 8 MiB
|
|
59
|
-
ceiling and path/descriptor identity checks around the read. Recompute
|
|
60
|
-
`raw_evidence_sha256` and require an exact match, then recompute the stable exact
|
|
61
|
-
`evidence.json` bytes as `evidence_digest` before comparing the projection. Recheck
|
|
62
|
-
the exact review receipts separately; never treat the product exclusion as permission
|
|
63
|
-
to ignore evidence drift or add another exclusion.
|
|
64
|
-
An intent digest changed by North Star reconciliation or any other intent edit always
|
|
65
|
-
requires a fresh `ultra-test` before Deliver can finalize, even if product bytes did
|
|
66
|
-
not change.
|
|
67
|
-
5. Preserve every typed acceptance authority. The owner alone supplies the semantic
|
|
68
|
-
result for `owner-judgment`; Deliver may verify its cited source and freshness but no
|
|
69
|
-
model, command, digest, schema, or validator may replace it.
|
|
70
|
-
|
|
71
|
-
## Definition of done
|
|
72
|
-
|
|
73
|
-
- Outcome, specs, tests, aggregate review, and every document match the actual diff.
|
|
74
|
-
- Every changed export has a non-test consumer or a recorded owner disposition.
|
|
75
|
-
- Every omitted stage is explicitly recorded with its evidence-based rationale.
|
|
76
|
-
- Delivery explains whether evidence realizes the traced first principles and outcome,
|
|
77
|
-
and preserves contradictions or stale trace as findings instead of mirroring or
|
|
78
|
-
silently revising North Star prose.
|
|
79
|
-
- Build and release checks have exact commands and real results.
|
|
80
|
-
- The Change is archived with `git mv`, and rollback remains a normal Git operation.
|
|
81
|
-
|
|
82
|
-
## Review and refactor
|
|
83
|
-
|
|
84
|
-
Follow `../ultra-review/SKILL.md` across the aggregate Change; refactor only observed
|
|
85
|
-
duplication, coupling, or boundary defects. Rerun affected checks and refresh the report.
|
|
86
|
-
After the aggregate review and the current Test report are consumed, Deliver does not
|
|
87
|
-
refactor product source: it reconciles delivery artifacts and documentation only. A
|
|
88
|
-
post-approval implementation issue routes as at most one new owner-approved Dev task
|
|
89
|
-
for a P0/P1, or as recorded backlog and residual risk for P2/P3; an unbounded
|
|
90
|
-
Test ↔ Deliver bounce is not a valid recovery path, and any re-entry through Test
|
|
91
|
-
requires an explicit owner disposition.
|
|
92
|
-
|
|
93
|
-
## Reconcile the handoff
|
|
94
|
-
|
|
95
|
-
1. Compare accepted intent and task traces with delivered behavior.
|
|
96
|
-
2. Apply justified specification corrections; route any REDUCTION to the owner.
|
|
97
|
-
3. List documentation, compare every file with the full Change diff, and repair stale
|
|
98
|
-
behavior, examples, flags, or fields. Record bounded debt only in active
|
|
99
|
-
`delivery.md` under `## Technical Debt`.
|
|
100
|
-
4. Defer build, non-publishing package inspection, version selection, and the canonical
|
|
101
|
-
`delivery.md` until the fresh-snapshot finalization pass below. Reconciliation that
|
|
102
|
-
changed files must return through Test first.
|
|
103
|
-
|
|
104
|
-
Entry reconciliation prevents inherited drift; this exit reconciliation prevents the
|
|
105
|
-
Change from leaving new document drift.
|
|
106
|
-
|
|
107
|
-
## Reconcile, then finalize on a fresh snapshot
|
|
108
|
-
|
|
109
|
-
Delivery has two observable passes, not a hidden state machine:
|
|
110
|
-
|
|
111
|
-
1. Reconcile and review. If this pass changes source, tests, task/context/evidence,
|
|
112
|
-
specifications, maintained documentation, or `intent.md`, stop after writing the
|
|
113
|
-
reconciled files. The existing report is stale; recommend `ultra-test` and make no
|
|
114
|
-
delivery or release claim.
|
|
115
|
-
2. After an unchanged pass or fresh Test, resolve the report's canonical
|
|
116
|
-
`review.summary_ref` as `<validated-summary-path>` and run the current strict transport
|
|
117
|
-
consumer against the current report:
|
|
118
|
-
|
|
119
|
-
`node <ultra-test-skill-dir>/scripts/validate_review_transport.cjs --summary <validated-summary-path> --report .ultra/test-report.json`
|
|
120
|
-
|
|
121
|
-
Require exit 0 and a JSON `"valid": true` field. This one existing consumer verifies
|
|
122
|
-
the exact
|
|
123
|
-
retained `ADMISSION.json` and `SUMMARY.json`, then binds the report's
|
|
124
|
-
`admission_digest`, `subject_digest`, and `summary_digest` to those bytes. A missing or
|
|
125
|
-
invalid receipt, summary, or binding makes the current Test claim `INCOMPLETE`: start
|
|
126
|
-
a fresh Review and Test. Do not write `delivery.md`, archive the Change, create a
|
|
127
|
-
release package, or make a delivery claim while that receipt evidence is missing or
|
|
128
|
-
invalid. Never use `--legacy-v4` for this current-session check; v3 and pre-admission
|
|
129
|
-
v4 are read-only historical evidence, not current Test or Deliver evidence.
|
|
130
|
-
|
|
131
|
-
After the transport succeeds, recheck Change/task/HEAD/product/intent identities.
|
|
132
|
-
Apply the gate, run build and non-publishing package inspection, determine version
|
|
133
|
-
impact, and use `references/baseline-reconciliation.md` for canonical `delivery.md`.
|
|
134
|
-
Archive the Change. Excluded delivery metadata and the directory move cannot
|
|
135
|
-
self-invalidate the product digest; intent stays independently bound. Retain the
|
|
136
|
-
review session through this successful Deliver consumption; only then may its derived
|
|
137
|
-
artifacts be garbage-collected.
|
|
138
|
-
|
|
139
|
-
Transport and task-evidence validators establish exact structural, identity,
|
|
140
|
-
provenance, and freshness facts only. Their success never means that the Change is
|
|
141
|
-
semantically accepted or that its outcome is ready to describe as delivered.
|
|
142
|
-
|
|
143
|
-
Do not draft a success narrative around stale evidence. A current `passed: false`
|
|
144
|
-
report may still reach finalization only after every finding has an explicit owner
|
|
145
|
-
disposition and the one hard gate below is clear; `passed` is evidence summary, not a
|
|
146
|
-
second mechanical release gate.
|
|
147
|
-
|
|
148
|
-
## The one delivery gate
|
|
149
|
-
|
|
150
|
-
This gate applies only after the owner explicitly invokes `ultra-deliver`; it does not
|
|
151
|
-
attach itself to ordinary repository packaging outside this workflow.
|
|
152
|
-
|
|
153
|
-
Everything else in this workflow reports and hands over. This is the exception, and it
|
|
154
|
-
is deliberately narrow:
|
|
155
|
-
|
|
156
|
-
**Do not produce a release package while an export this Change added or changed has no
|
|
157
|
-
non-test consumer and no recorded owner disposition.**
|
|
158
|
-
|
|
159
|
-
| | |
|
|
160
|
-
|---|---|
|
|
161
|
-
| Invariant | Every changed export is either reachable from a non-test caller or explicitly declared internal |
|
|
162
|
-
| Fact source | The Wiring Verification finding and its owner disposition in `.ultra/test-report.json`, bound to the current Change id, task ids, intent, HEAD, and product-worktree digest — the audit already found these; this is not a fresh opinion |
|
|
163
|
-
| Blocked effect | Release-package creation and the separately authorized release effects after it. A non-publishing package inspection is diagnostic; local commit and archival are untouched |
|
|
164
|
-
| Repair | Wire the export to its caller, or record the owner's disposition on the finding in `.ultra/test-report.json`, then carry it into `delivery.md`. Either one clears the gate |
|
|
165
|
-
|
|
166
|
-
"Written but never connected" can leave tests and review green while the feature is
|
|
167
|
-
absent. Keep this gate at finalization, after the audit can distinguish unfinished work.
|
|
168
|
-
|
|
169
|
-
## Archive locally
|
|
170
|
-
|
|
171
|
-
After the fresh check, `git mv` active `<id>` to archive. The id stays stable in task
|
|
172
|
-
rows; never store a movable intent path or create a second delivery summary. Archived
|
|
173
|
-
delivery, test report, evidence, and Git history are the handoff.
|
|
174
|
-
|
|
175
|
-
For separately authorized effects, perform and verify each independently. Ask for
|
|
176
|
-
authority at the point of effect: commit, then push, then tag, package publication and
|
|
177
|
-
deployment as applicable. A failure in one does not imply permission to attempt another.
|
|
178
|
-
|
|
179
|
-
## When the owner decides
|
|
180
|
-
|
|
181
|
-
The owner accepts residual risk, reductions, the version, and every external effect.
|
|
182
|
-
Without release authority, stop after the recoverable local archive and report it.
|
|
183
|
-
|
|
184
|
-
## References
|
|
185
|
-
|
|
186
|
-
- `../ultra-change/references/change-contract.md` — canonical Active Change authority resolution.
|
|
187
|
-
- `../ultra-review/SKILL.md` — read before aggregate review and refactoring.
|
|
188
|
-
- `../ultra-plan/references/task-evidence-v2.md` — canonical current task evidence and task-review contract.
|
|
189
|
-
- `../ultra-think/SKILL.md` — read when version or release posture is a consequential
|
|
190
|
-
trade-off rather than an established repository rule.
|
|
191
|
-
- `../ultra-think/references/autonomy-boundary.md` — read before scope or evidence shrinks.
|
|
192
|
-
- `../ultra-change/references/execution-grant.md` — read only for grant-activated continuation.
|
|
193
|
-
- `../ultra-status/references/route-contract.md` — owner-visible route, checkpoint, and recovery output.
|
|
194
|
-
- `references/baseline-reconciliation.md` — exact `delivery.md` reconciliation contract.
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
# Delivery reconciliation contract
|
|
2
|
-
|
|
3
|
-
Write exactly one `.ultra/changes/active/<change-id>/delivery.md`. It is editable while
|
|
4
|
-
the Change is active and moves with the directory when archived.
|
|
5
|
-
|
|
6
|
-
```markdown
|
|
7
|
-
# Delivery: <change-id>
|
|
8
|
-
|
|
9
|
-
## Outcome Reconciliation
|
|
10
|
-
<accepted outcome versus observed result, with path#anchor evidence>
|
|
11
|
-
|
|
12
|
-
## Specification and Documentation Updates
|
|
13
|
-
<changed files and why, or an evidence-backed no-change statement>
|
|
14
|
-
|
|
15
|
-
## Verification
|
|
16
|
-
| Command | Exit | Evidence | Freshness |
|
|
17
|
-
|---|---:|---|---|
|
|
18
|
-
|
|
19
|
-
## Review
|
|
20
|
-
<SUMMARY.json path, packet digest, verdict, and unresolved findings>
|
|
21
|
-
|
|
22
|
-
## Technical Debt
|
|
23
|
-
<bounded debt, consequence, owner, and upgrade path; or None>
|
|
24
|
-
|
|
25
|
-
## Residual Risks and Omissions
|
|
26
|
-
<owner disposition for every material item>
|
|
27
|
-
|
|
28
|
-
## Recovery
|
|
29
|
-
<rollback or recovery procedure and verification>
|
|
30
|
-
|
|
31
|
-
## External Effects
|
|
32
|
-
<commit, push, tag, publish, deploy: authorized and observed status separately>
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
Every semantic update cites a repository-relative `path#anchor`. A reduction requires
|
|
36
|
-
the owner decision before the affected specification changes. Exact command evidence
|
|
37
|
-
must match the stable Change id, exact current task ids, intent digest, HEAD, and
|
|
38
|
-
product-worktree digest identified by `.ultra/test-report.json`; stale results stay
|
|
39
|
-
visible and never become a pass. Reconcile before finalizing. If reconciliation changes
|
|
40
|
-
semantic or product files, obtain a fresh Test snapshot before writing final delivery
|
|
41
|
-
metadata or archiving. Do not create a second JSON or Markdown delivery summary.
|