@rosenfan/matrix 0.1.7 → 0.1.8
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/README.md +2 -2
- package/README.zh-CN.md +2 -2
- package/assets/skills/matrix/SKILL.md +1 -1
- package/assets/skills/matrix-design/SKILL.md +4 -4
- package/assets/skills/matrix-open/SKILL.md +2 -2
- package/assets/skills-zh-CN/matrix/SKILL.md +1 -1
- package/assets/skills-zh-CN/matrix-design/SKILL.md +4 -4
- package/assets/skills-zh-CN/matrix-open/SKILL.md +2 -2
- package/package.json +1 -1
- package/src/distribution.js +2 -2
- package/src/matt-catalog.mjs +1 -1
- package/src/workflow.js +22 -6
package/README.md
CHANGED
|
@@ -219,8 +219,8 @@ matrix workflow guard open
|
|
|
219
219
|
# Advance (only if guard passes)
|
|
220
220
|
matrix workflow transition design
|
|
221
221
|
|
|
222
|
-
# Lightweight: approve the compact proposal and enter Build
|
|
223
|
-
matrix workflow transition build --confirmed
|
|
222
|
+
# Lightweight: approve the compact proposal and enter Build (executor choice merged into the same pause)
|
|
223
|
+
matrix workflow transition build --confirmed --executor <current|model|handoff:<agent-id>>
|
|
224
224
|
|
|
225
225
|
# Return from verification failure; stale evidence is retained in history
|
|
226
226
|
matrix workflow return build --reason verification-failed
|
package/README.zh-CN.md
CHANGED
|
@@ -216,8 +216,8 @@ matrix workflow guard open
|
|
|
216
216
|
# 推进(仅在守卫通过时)
|
|
217
217
|
matrix workflow transition design
|
|
218
218
|
|
|
219
|
-
# lightweight:确认紧凑 proposal 后进入 Build
|
|
220
|
-
matrix workflow transition build --confirmed
|
|
219
|
+
# lightweight:确认紧凑 proposal 后进入 Build(执行主体选择并入同一次暂停)
|
|
220
|
+
matrix workflow transition build --confirmed --executor <current|model|handoff:<agent-id>>
|
|
221
221
|
|
|
222
222
|
# 验证失败时返回 Build;旧证据保留在历史目录
|
|
223
223
|
matrix workflow return build --reason verification-failed
|
|
@@ -84,5 +84,5 @@ Matrix never nests user-invoked Matt Skills. When relevant, explain the reason a
|
|
|
84
84
|
- `node <matrix-skill-directory>/scripts/matrix-runtime.mjs doctor` is read-only. Every transaction or stale-lock repair must explicitly bind the identity reported by doctor; do not edit or delete `.matrix/transactions/` or `.matrix/workflow.lock`.
|
|
85
85
|
- Do not replace required evidence with an assertion that work is complete.
|
|
86
86
|
- Pause for user confirmation at material architecture/scope decisions and before archive/commit.
|
|
87
|
-
- Before entering Build (full: after the design guard; lightweight: merged into the `transition build --confirmed` pause), present the implementation-actor choice — continue with the current agent/model, switch the model in the user's client, or switch the implementation agent via `$matrix-handoff` — and
|
|
87
|
+
- Before entering Build (full: after the design guard; lightweight: merged into the `transition build --confirmed` pause), present the implementation-actor choice — continue with the current agent/model, switch the model in the user's client, or switch the implementation agent via `$matrix-handoff` — and pass the recorded choice to the Runtime with `transition build --executor <current|model|handoff:<agent-id>>` (lightweight also carries `--confirmed`). The Runtime rejects Build entry without it and stores the choice as `implementation_actor`.
|
|
88
88
|
- On shortcut scope expansion, run `node <matrix-skill-directory>/scripts/matrix-runtime.mjs return design --reason design-gap`; Runtime upgrades the change to `full`. Never silently continue the old contract.
|
|
@@ -44,25 +44,25 @@ node <matrix-skill-directory>/scripts/matrix-runtime.mjs guard design
|
|
|
44
44
|
|
|
45
45
|
## Implementation Decision Point
|
|
46
46
|
|
|
47
|
-
After the design guard passes and before `transition build`, pause and present the implementation-actor choice to the user. Do not transition without an explicit choice:
|
|
47
|
+
After the design guard passes and before `transition build`, pause and present the implementation-actor choice to the user. Do not transition without an explicit choice. The Runtime enforces this gate: `transition build` fails with `EXECUTOR_CONFIRMATION_REQUIRED` unless it carries the recorded choice, which is stored as `implementation_actor` in the change state.
|
|
48
48
|
|
|
49
49
|
### Option A: Continue with the current agent / model (default)
|
|
50
50
|
|
|
51
51
|
Run transition and enter `$matrix-build`:
|
|
52
52
|
|
|
53
53
|
```powershell
|
|
54
|
-
node <matrix-skill-directory>/scripts/matrix-runtime.mjs transition build
|
|
54
|
+
node <matrix-skill-directory>/scripts/matrix-runtime.mjs transition build --executor current
|
|
55
55
|
```
|
|
56
56
|
|
|
57
57
|
Then enter `$matrix-build` to implement directly in this session.
|
|
58
58
|
|
|
59
59
|
### Option B: Switch the model, keep this agent
|
|
60
60
|
|
|
61
|
-
The user switches the model in their own client (for example, a stronger model for design, an efficient one for implementation), returns to this session, and confirms. Then run transition
|
|
61
|
+
The user switches the model in their own client (for example, a stronger model for design, an efficient one for implementation), returns to this session, and confirms. Then run the transition with `--executor model`. Matrix cannot see the client-side model; it provides the mandatory pause point only.
|
|
62
62
|
|
|
63
63
|
### Option C: Switch the implementation agent
|
|
64
64
|
|
|
65
|
-
First approve the frozen contract by transitioning to Build, then run `$matrix-handoff` to export a bounded task package for
|
|
65
|
+
First approve the frozen contract by transitioning to Build with the chosen agent recorded (`--executor handoff:<agent-id>`), then run `$matrix-handoff` to export a bounded task package for that agent (for example Codex designs, Claude Code implements; or zcode designs, opencode implements). This:
|
|
66
66
|
- Does not change the Build phase or state beyond the preceding transition
|
|
67
67
|
- Creates `artifacts/handoff-task-<task-id>.md` with all implementation details
|
|
68
68
|
- Includes acceptance criteria, test seams, and required commands
|
|
@@ -48,6 +48,6 @@ Companion output is evidence for the Matrix proposal. It must not create another
|
|
|
48
48
|
node <matrix-skill-directory>/scripts/matrix-runtime.mjs guard open
|
|
49
49
|
# full
|
|
50
50
|
node <matrix-skill-directory>/scripts/matrix-runtime.mjs transition design
|
|
51
|
-
# hotfix/tweak, only after explicit confirmation
|
|
52
|
-
node <matrix-skill-directory>/scripts/matrix-runtime.mjs transition build --confirmed
|
|
51
|
+
# hotfix/tweak, only after explicit confirmation (actor choice merged into the same pause)
|
|
52
|
+
node <matrix-skill-directory>/scripts/matrix-runtime.mjs transition build --confirmed --executor <choice>
|
|
53
53
|
```
|
|
@@ -80,5 +80,5 @@ Matrix 不嵌套 user-invoked Skill。适用时只解释原因,并让用户显
|
|
|
80
80
|
- 成功 Archive 必须使用两步乐观提交:先运行 `node <matrix-skill-directory>/scripts/matrix-runtime.mjs archive --dry-run`,再将其精确 hash 传给 `node <matrix-skill-directory>/scripts/matrix-runtime.mjs archive --expect-preflight <sha256>`;不得绕过预演。
|
|
81
81
|
- `node <matrix-skill-directory>/scripts/matrix-runtime.mjs doctor` 始终只读;transaction 与陈旧锁 repair 必须显式绑定 doctor 报告的 identity,不得手工编辑或删除 `.matrix/transactions/`、`.matrix/workflow.lock`。
|
|
82
82
|
- 重大架构/范围决定和 archive/commit 前应暂停等待用户确认。
|
|
83
|
-
- 进入 Build 前(full 在 design guard 之后;lightweight 并入 `transition build --confirmed` 的暂停)必须呈现执行主体选择——当前 agent/原模型继续、用户客户端切换模型、或经 `$matrix-handoff` 切换实现 agent
|
|
83
|
+
- 进入 Build 前(full 在 design guard 之后;lightweight 并入 `transition build --confirmed` 的暂停)必须呈现执行主体选择——当前 agent/原模型继续、用户客户端切换模型、或经 `$matrix-handoff` 切换实现 agent——并以 `transition build --executor <current|model|handoff:<agent-id>>` 把选择传给 Runtime(lightweight 同时携带 `--confirmed`)。缺省时 Runtime 拒绝进入 Build,并把选择存为 `implementation_actor`。
|
|
84
84
|
- shortcut 范围扩大时执行 `node <matrix-skill-directory>/scripts/matrix-runtime.mjs return design --reason design-gap`;Runtime 将其升级为 full。
|
|
@@ -24,15 +24,15 @@ node <matrix-skill-directory>/scripts/matrix-runtime.mjs guard design
|
|
|
24
24
|
|
|
25
25
|
## 执行主体确认点(Build 前)
|
|
26
26
|
|
|
27
|
-
`guard design` 通过后、`transition build`
|
|
27
|
+
`guard design` 通过后、`transition build` 之前,必须暂停并向用户确认执行主体,未确认不得推进。该闸门由 Runtime 强制执行:`transition build` 未携带所记录的选择时报 `EXECUTOR_CONFIRMATION_REQUIRED`,选择会以 `implementation_actor` 写入 change 状态:
|
|
28
28
|
|
|
29
29
|
- **选项 A:当前 agent / 原模型继续(默认)**——直接推进:
|
|
30
30
|
```powershell
|
|
31
|
-
node <matrix-skill-directory>/scripts/matrix-runtime.mjs transition build
|
|
31
|
+
node <matrix-skill-directory>/scripts/matrix-runtime.mjs transition build --executor current
|
|
32
32
|
```
|
|
33
33
|
随后进入 `$matrix-build` 在本会话内实现。
|
|
34
|
-
- **选项 B:切换模型、保留本 agent
|
|
35
|
-
- **选项 C:切换执行 agent
|
|
34
|
+
- **选项 B:切换模型、保留本 agent**——用户在自己的客户端完成模型切换(例如设计用强模型、实现用高性价比模型),回到会话确认后以 `--executor model` 推进。Matrix 无法感知客户端模型,只提供强制暂停点。
|
|
35
|
+
- **选项 C:切换执行 agent**——先以 `--executor handoff:<agent-id>` 记录所选 agent 并推进 Build 批准冻结 Contract,再用 `$matrix-handoff` 为目标 agent 导出有界任务包(例如 Codex 设计、Claude Code 实现,或 zcode 设计、opencode 实现)。实现 agent 完成并补齐 `## Build evidence` 后:
|
|
36
36
|
```powershell
|
|
37
37
|
node <matrix-skill-directory>/scripts/matrix-runtime.mjs guard build
|
|
38
38
|
node <matrix-skill-directory>/scripts/matrix-runtime.mjs transition verify
|
|
@@ -35,6 +35,6 @@ companion 输出只能作为当前 proposal 的证据,不得创建第二套工
|
|
|
35
35
|
node <matrix-skill-directory>/scripts/matrix-runtime.mjs guard open
|
|
36
36
|
# full
|
|
37
37
|
node <matrix-skill-directory>/scripts/matrix-runtime.mjs transition design
|
|
38
|
-
# hotfix/tweak
|
|
39
|
-
node <matrix-skill-directory>/scripts/matrix-runtime.mjs transition build --confirmed
|
|
38
|
+
# hotfix/tweak,仅在用户明确确认后(执行主体选择并入同一次暂停)
|
|
39
|
+
node <matrix-skill-directory>/scripts/matrix-runtime.mjs transition build --confirmed --executor <choice>
|
|
40
40
|
```
|
package/package.json
CHANGED
package/src/distribution.js
CHANGED
|
@@ -40,12 +40,12 @@ const configContent = (existing, defaultOrchestration, scope, language) => {
|
|
|
40
40
|
const values = {
|
|
41
41
|
...existing,
|
|
42
42
|
schema: "matrix/config/v1",
|
|
43
|
-
auto_transition: existing.auto_transition === "false" ? "false" : "true",
|
|
44
43
|
default_orchestration: defaultOrchestration,
|
|
45
44
|
installation_scope: scope,
|
|
46
45
|
language
|
|
47
46
|
};
|
|
48
|
-
|
|
47
|
+
delete values.auto_transition;
|
|
48
|
+
const preferred = ["schema", "default_orchestration", "installation_scope", "language"];
|
|
49
49
|
const keys = [...preferred, ...Object.keys(values).filter((key) => !preferred.includes(key)).sort()];
|
|
50
50
|
return `${keys.map((key) => `${key}: ${values[key]}`).join("\n")}\n`;
|
|
51
51
|
};
|
package/src/matt-catalog.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import crypto from "node:crypto";
|
|
2
2
|
|
|
3
3
|
export const MATT_COMPATIBILITY = Object.freeze({
|
|
4
|
-
matrixVersion: "0.1.
|
|
4
|
+
matrixVersion: "0.1.8",
|
|
5
5
|
release: "v1.3.1",
|
|
6
6
|
commit: "24fe0ef7737efae15c87225755e9f6f5965e4888",
|
|
7
7
|
archive: "https://github.com/mattpocock/skills/archive/24fe0ef7737efae15c87225755e9f6f5965e4888.tar.gz",
|
package/src/workflow.js
CHANGED
|
@@ -337,8 +337,8 @@ function readFlow(p) {
|
|
|
337
337
|
return normalizeFlow(parsed);
|
|
338
338
|
}
|
|
339
339
|
function flowContent(flow) {
|
|
340
|
-
const order = ["schema", "id", "workflow", "workflow_profile", "orchestration", "artifact_language", "arch_catalog_digest", "matt_release", "status", "phase", "revision", "approved_contract_hash", "contract_approved_revision", "title", "created_at", "updated_at", "acceptance", "scope"];
|
|
341
|
-
return `${order.filter((key) => (!["workflow_profile", "artifact_language", "arch_catalog_digest", "matt_release"].includes(key) || flow[key])).map((key) => `${key}: ${flow[key] ?? ""}`).join("\n")}\n`;
|
|
340
|
+
const order = ["schema", "id", "workflow", "workflow_profile", "orchestration", "artifact_language", "arch_catalog_digest", "matt_release", "status", "phase", "revision", "approved_contract_hash", "contract_approved_revision", "implementation_actor", "title", "created_at", "updated_at", "acceptance", "scope"];
|
|
341
|
+
return `${order.filter((key) => (!["workflow_profile", "artifact_language", "arch_catalog_digest", "matt_release", "implementation_actor"].includes(key) || flow[key])).map((key) => `${key}: ${flow[key] ?? ""}`).join("\n")}\n`;
|
|
342
342
|
}
|
|
343
343
|
function active(cwd) { const activeFile = path.join(rootFor(cwd), "active.json"); if (!fs.existsSync(activeFile)) return null; return read(activeFile).change_id; }
|
|
344
344
|
function meaningful(file, headings) {
|
|
@@ -705,7 +705,7 @@ export function invoke(argv, { cwd = process.cwd(), failAfterOperation = null, m
|
|
|
705
705
|
const operations = [
|
|
706
706
|
...(!fs.existsSync(path.join(p.root, "archive")) ? [workflowMkdirOperation(cwd, path.join(p.root, "archive"))] : []),
|
|
707
707
|
workflowMkdirOperation(cwd, p.artifacts),
|
|
708
|
-
...(!fs.existsSync(path.join(p.root, "config.yaml")) ? [workflowWriteOperation(cwd, path.join(p.root, "config.yaml"), `schema: matrix/config/v1\
|
|
708
|
+
...(!fs.existsSync(path.join(p.root, "config.yaml")) ? [workflowWriteOperation(cwd, path.join(p.root, "config.yaml"), `schema: matrix/config/v1\ndefault_orchestration: ${configured.defaultOrchestration}\ninstallation_scope: project\nlanguage: ${configured.artifactLanguage}\n`)] : []),
|
|
709
709
|
...(!fs.existsSync(path.join(p.root, ".gitignore")) ? [workflowWriteOperation(cwd, path.join(p.root, ".gitignore"), "active.json\ninstallation.json\nmatt-installation.json\nchanges/*/events.jsonl\nchanges/*/artifacts/handoff.md\n")] : []),
|
|
710
710
|
workflowWriteOperation(cwd, p.flow, flowContent(flow)),
|
|
711
711
|
...(workspaceBaseline ? [workflowWriteOperation(cwd, p.workspaceBaseline, `${JSON.stringify(workspaceBaseline, null, 2)}\n`)] : []),
|
|
@@ -867,7 +867,13 @@ export function invoke(argv, { cwd = process.cwd(), failAfterOperation = null, m
|
|
|
867
867
|
if (command === "transition") {
|
|
868
868
|
const to = args[0];
|
|
869
869
|
const confirmed = args.includes("--confirmed");
|
|
870
|
-
|
|
870
|
+
const executorFlag = args.indexOf("--executor");
|
|
871
|
+
const executor = executorFlag >= 0 ? args[executorFlag + 1] : null;
|
|
872
|
+
if (args.slice(1).some((arg, offset) => {
|
|
873
|
+
const index = offset + 1;
|
|
874
|
+
if (index === executorFlag || index === executorFlag + 1) return false;
|
|
875
|
+
return arg !== "--confirmed";
|
|
876
|
+
})) return fail("INVALID_INTENT", "Transition accepts only a target phase, optional --confirmed, and optional --executor <choice>.");
|
|
871
877
|
if (flow.status !== "active") return fail("CHANGE_NOT_ACTIVE", `Matrix change is ${flow.status}.`);
|
|
872
878
|
const profile = workflowProfile(p, flow);
|
|
873
879
|
if (profile.next[flow.phase] !== to) return fail("ILLEGAL_TRANSITION", `Illegal ${profile.id} transition ${flow.phase} -> ${to}.`);
|
|
@@ -877,14 +883,24 @@ export function invoke(argv, { cwd = process.cwd(), failAfterOperation = null, m
|
|
|
877
883
|
const order = workspaceOrderGuard(cwd, p);
|
|
878
884
|
if (!order.ok) return order;
|
|
879
885
|
}
|
|
886
|
+
// The implementation-actor gate is runtime-enforced, not prompt-level: Build
|
|
887
|
+
// may not be entered until the actor choice is recorded explicitly.
|
|
888
|
+
if (to === "build") {
|
|
889
|
+
if (executor != null && !/^(current|model|handoff:[a-z0-9]+(?:-[a-z0-9]+)*)$/.test(executor)) {
|
|
890
|
+
return fail("INVALID_INTENT", "Executor choice must be current, model, or handoff:<agent-id>.");
|
|
891
|
+
}
|
|
892
|
+
if (!executor) {
|
|
893
|
+
return fail("EXECUTOR_CONFIRMATION_REQUIRED", "Present the implementation-actor choice to the user before Build: continue with the current agent/model, switch the model in the user's client, or hand off to another agent. Then rerun with --executor <current|model|handoff:<agent-id>>.");
|
|
894
|
+
}
|
|
895
|
+
}
|
|
880
896
|
const before = flow.phase;
|
|
881
897
|
const approval = to === "build" ? contractState(p, flow) : null;
|
|
882
898
|
if (approval && approval.status !== "approved-and-matching" && approval.status !== "unapproved") return { ...contractFailure(flow, approval), change_id: id };
|
|
883
899
|
if (to === "build" && approval.snapshot.missing) return { ...fail("GUARD_FAILED", "Workflow contract artifacts are incomplete."), change_id: id };
|
|
884
|
-
const next = { ...flow, schema: "matrix/change/v2", phase: to, revision: flow.revision + 1, updated_at: stamp(), ...(to === "build" ? { approved_contract_hash: approval.snapshot.hash, contract_approved_revision: flow.revision + 1 } : {}) };
|
|
900
|
+
const next = { ...flow, schema: "matrix/change/v2", phase: to, revision: flow.revision + 1, updated_at: stamp(), ...(to === "build" ? { approved_contract_hash: approval.snapshot.hash, contract_approved_revision: flow.revision + 1, implementation_actor: executor } : {}) };
|
|
885
901
|
const nextProfile = workflowProfile(p, next);
|
|
886
902
|
const details = to === "build"
|
|
887
|
-
? { approved_contract_hash: next.approved_contract_hash, contract_approved_revision: next.contract_approved_revision, ...(shortcut(flow) ? { confirmed, profile: nextProfile.id } : {}) }
|
|
903
|
+
? { approved_contract_hash: next.approved_contract_hash, contract_approved_revision: next.contract_approved_revision, implementation_actor: next.implementation_actor, ...(shortcut(flow) ? { confirmed, profile: nextProfile.id } : {}) }
|
|
888
904
|
: shortcut(flow) ? { profile: nextProfile.id } : {};
|
|
889
905
|
const resultFields = { ok: true, code: "OK", change_id: id, workflow: next.workflow, profile: nextProfile.id, evidence_policy: evidencePolicy(next, nextProfile), orchestration: next.orchestration, artifact_language: next.artifact_language ?? artifactLanguage, status: next.status, phase: to, revision: next.revision, next_skill: skill(to), ...contractFields(next, contractState(p, next)) };
|
|
890
906
|
return runWorkflowTransaction({
|