cli-aimlock 7.0.29 → 7.0.31
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/aimlock-runtime.mjs +100 -9
- package/cli.mjs +2 -1
- package/package.json +2 -2
- package/skill/SKILL.md +4 -3
- package/skill/skill.json +1 -1
package/aimlock-runtime.mjs
CHANGED
|
@@ -14,6 +14,11 @@ const CLASSIFY_RULES = [
|
|
|
14
14
|
];
|
|
15
15
|
const HIGH_RISK_PATTERNS = [/生产数据|支付|用户隐私|财务|密码|密钥|线上环境|production/i];
|
|
16
16
|
const RISK_LEVEL = Object.freeze({ low: 0, medium: 1, high: 2 });
|
|
17
|
+
const CONFIRM_PROTOCOL_REQUEST_SCHEMA = "confirm-protocol.skill.request/1.0";
|
|
18
|
+
const CONFIRM_INTERACTION_SCHEMA = "confirm.interaction/1.0";
|
|
19
|
+
const CONFIRM_AUDIT_SCHEMA = "confirm.audit-entry/1.0";
|
|
20
|
+
const CONFIRM_STEP = "confirm-protocol";
|
|
21
|
+
const CONFIRM_APPROVE = "approve";
|
|
17
22
|
|
|
18
23
|
function strongestRisk(...values) {
|
|
19
24
|
return values.filter((value) => value in RISK_LEVEL)
|
|
@@ -58,6 +63,67 @@ function resolvedStepIds(input) {
|
|
|
58
63
|
return { steps };
|
|
59
64
|
}
|
|
60
65
|
|
|
66
|
+
function confirmationFinding(ruleId, message, example) {
|
|
67
|
+
return { severity: "P0", ruleId, entityRef: "input.confirmationResult", message,
|
|
68
|
+
evidence: { example } };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function confirmationRequest(chain, risk, requestId) {
|
|
72
|
+
return {
|
|
73
|
+
schemaVersion: CONFIRM_PROTOCOL_REQUEST_SCHEMA,
|
|
74
|
+
requestId: `confirm-${requestId}`,
|
|
75
|
+
operation: "interaction-request",
|
|
76
|
+
input: { interaction: {
|
|
77
|
+
schemaVersion: CONFIRM_INTERACTION_SCHEMA,
|
|
78
|
+
requestId,
|
|
79
|
+
type: "confirm",
|
|
80
|
+
question: `Approve execution of the ${chain} chain?`,
|
|
81
|
+
options: [
|
|
82
|
+
{ id: CONFIRM_APPROVE, label: "Approve", hint: "Continue the guarded chain." },
|
|
83
|
+
{ id: "reject", label: "Reject", hint: "Keep the chain blocked." },
|
|
84
|
+
],
|
|
85
|
+
default: null,
|
|
86
|
+
timeout: null,
|
|
87
|
+
timeoutAction: "wait",
|
|
88
|
+
risk: risk === "high" ? "high" : "low",
|
|
89
|
+
riskDescription: risk === "high"
|
|
90
|
+
? "This high-risk chain cannot continue without an explicit human decision." : "",
|
|
91
|
+
rememberable: false,
|
|
92
|
+
memoryKey: "",
|
|
93
|
+
callback: { operation: "resume-aimlock-chain", payload: { chain } },
|
|
94
|
+
} },
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function validateConfirmationResult(value, chain, risk, requestId) {
|
|
99
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
100
|
+
return [confirmationFinding("CONFIRMATION_RESULT_REQUIRED",
|
|
101
|
+
"a Confirm Protocol interaction-answer result is required before the chain can continue", {})];
|
|
102
|
+
}
|
|
103
|
+
const audit = value.auditEntry;
|
|
104
|
+
const callback = value.callbackRequest;
|
|
105
|
+
const payload = callback?.payload;
|
|
106
|
+
const findings = [];
|
|
107
|
+
if (!audit || audit.schemaVersion !== CONFIRM_AUDIT_SCHEMA || audit.answer !== CONFIRM_APPROVE) {
|
|
108
|
+
findings.push(confirmationFinding("CONFIRMATION_AUDIT_INVALID",
|
|
109
|
+
"confirmation audit entry must record an explicit approve answer", { schemaVersion: CONFIRM_AUDIT_SCHEMA, answer: CONFIRM_APPROVE }));
|
|
110
|
+
}
|
|
111
|
+
if (!callback || callback.operation !== "resume-aimlock-chain" || payload?.chain !== chain) {
|
|
112
|
+
findings.push(confirmationFinding("CONFIRMATION_CALLBACK_INVALID",
|
|
113
|
+
"confirmation callback must resume the same Aimlock chain", { operation: "resume-aimlock-chain", chain }));
|
|
114
|
+
}
|
|
115
|
+
if (payload?.answer !== CONFIRM_APPROVE || payload?.requestId !== audit?.requestId
|
|
116
|
+
|| audit?.requestId !== requestId) {
|
|
117
|
+
findings.push(confirmationFinding("CONFIRMATION_DECISION_INVALID",
|
|
118
|
+
"confirmation callback and audit entry must bind the same approved request", { answer: CONFIRM_APPROVE }));
|
|
119
|
+
}
|
|
120
|
+
if (risk === "high" && audit?.risk !== "high") {
|
|
121
|
+
findings.push(confirmationFinding("CONFIRMATION_RISK_INVALID",
|
|
122
|
+
"high-risk chains require an isolated high-risk confirmation", { risk: "high" }));
|
|
123
|
+
}
|
|
124
|
+
return findings;
|
|
125
|
+
}
|
|
126
|
+
|
|
61
127
|
function buildChainPlan(input) {
|
|
62
128
|
const chain = String(input?.chain ?? "").trim();
|
|
63
129
|
if (!CHAIN_KINDS.includes(chain)) {
|
|
@@ -65,15 +131,22 @@ function buildChainPlan(input) {
|
|
|
65
131
|
}
|
|
66
132
|
const resolved = resolvedStepIds(input);
|
|
67
133
|
if (resolved.findings) return resolved;
|
|
68
|
-
const
|
|
134
|
+
const expandedSteps = resolved.steps.flatMap((step) => step === "swarm"
|
|
69
135
|
? ["coordinator.conflict-scan", "swarm"] : [step]);
|
|
70
136
|
const risk = String(input?.risk ?? "").trim();
|
|
71
137
|
if (!["low", "medium", "high"].includes(risk)) {
|
|
72
138
|
return { findings: [{ severity: "P0", ruleId: "CHAIN_RISK", entityRef: "input.risk", message: "risk must be low, medium, or high", evidence: { example: "medium" } }] };
|
|
73
139
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
140
|
+
const steps = expandedSteps.includes(CONFIRM_STEP)
|
|
141
|
+
? [CONFIRM_STEP, ...expandedSteps.filter((step) => step !== CONFIRM_STEP)] : expandedSteps;
|
|
142
|
+
const highRiskFindings = [];
|
|
143
|
+
if (risk === "high" && !steps.includes(CONFIRM_STEP)) highRiskFindings.push({ severity: "P0",
|
|
144
|
+
ruleId: "HIGH_RISK_CONFIRMATION", entityRef: "input.steps",
|
|
145
|
+
message: "high-risk work requires a server-resolved confirm-protocol step", evidence: { example: [CONFIRM_STEP] } });
|
|
146
|
+
if (risk === "high" && !steps.includes("validator")) highRiskFindings.push({ severity: "P0",
|
|
147
|
+
ruleId: "HIGH_RISK_VALIDATOR", entityRef: "input.steps",
|
|
148
|
+
message: "high-risk work requires a server-resolved validator step", evidence: { example: ["validator"] } });
|
|
149
|
+
if (highRiskFindings.length) return { findings: highRiskFindings };
|
|
77
150
|
const completed = Array.isArray(input?.completed) ? input.completed : [];
|
|
78
151
|
const expected = steps.slice(0, completed.length);
|
|
79
152
|
if (new Set(completed).size !== completed.length
|
|
@@ -81,9 +154,20 @@ function buildChainPlan(input) {
|
|
|
81
154
|
return { findings: [{ severity: "P0", ruleId: "CHAIN_ORDER", entityRef: "input.completed", message: "completed must be an exact chain prefix", evidence: { example: expected } }] };
|
|
82
155
|
}
|
|
83
156
|
const current = steps[completed.length] ?? null;
|
|
157
|
+
const requestId = String(input?.confirmationRequestId ?? "").trim();
|
|
158
|
+
if (steps.includes(CONFIRM_STEP) && !requestId) {
|
|
159
|
+
return { findings: [confirmationFinding("CONFIRMATION_REQUEST_ID",
|
|
160
|
+
"confirmationRequestId is required to bind the Confirm Protocol request", { confirmationRequestId: "chain-request-1" })] };
|
|
161
|
+
}
|
|
162
|
+
if (completed.includes(CONFIRM_STEP)) {
|
|
163
|
+
const confirmationFindings = validateConfirmationResult(input.confirmationResult, chain, risk, requestId);
|
|
164
|
+
if (confirmationFindings.length) return { findings: confirmationFindings };
|
|
165
|
+
}
|
|
84
166
|
return { chain: steps, chainKind: chain, ready: current ? [current] : [], current,
|
|
85
167
|
blocked: current ? steps.slice(completed.length + 1).map((step) => ({ step, waitingFor: [current] })) : [],
|
|
86
|
-
totalSteps: steps.length, completedSteps: completed.length, risk
|
|
168
|
+
totalSteps: steps.length, completedSteps: completed.length, risk,
|
|
169
|
+
confirmationRequired: steps.includes(CONFIRM_STEP),
|
|
170
|
+
...(current === CONFIRM_STEP ? { confirmProtocolRequest: confirmationRequest(chain, risk, requestId) } : {}) };
|
|
87
171
|
}
|
|
88
172
|
|
|
89
173
|
function submitFeedback(input) {
|
|
@@ -125,7 +209,7 @@ const RESPONSE_SCHEMA = "aimlock.skill.response/1.1";
|
|
|
125
209
|
const ERROR_SCHEMA = "aimlock.skill.error/1.0";
|
|
126
210
|
const CONTRACT_SCHEMA = "aimlock.scope-contract/1.0";
|
|
127
211
|
const COMPILER_NAME = "aimlock";
|
|
128
|
-
const COMPILER_VERSION = "v7.0.
|
|
212
|
+
const COMPILER_VERSION = "v7.0.31";
|
|
129
213
|
const KEEP_ALIVE_SECONDS = 90;
|
|
130
214
|
const KEEP_ALIVE_MESSAGE = "智能目标持续执行中,请勿关闭!";
|
|
131
215
|
const BYPASS_LINE_BUDGET = 500;
|
|
@@ -445,6 +529,10 @@ const OPERATION_SCHEMAS = Object.freeze({
|
|
|
445
529
|
risk: { type: "string", enum: ["low", "medium", "high"] },
|
|
446
530
|
steps: { type: "array", items: { type: "string" } },
|
|
447
531
|
completed: { type: "array", items: { type: "string" }, optional: true },
|
|
532
|
+
confirmationRequestId: { type: "string", optional: true,
|
|
533
|
+
description: "stable request id returned for the Confirm Protocol round trip" },
|
|
534
|
+
confirmationResult: { type: "object", optional: true,
|
|
535
|
+
description: "authoritative interaction-answer response from Confirm Protocol" },
|
|
448
536
|
},
|
|
449
537
|
},
|
|
450
538
|
output: {
|
|
@@ -456,6 +544,8 @@ const OPERATION_SCHEMAS = Object.freeze({
|
|
|
456
544
|
current: { type: ["string", "null"] },
|
|
457
545
|
totalSteps: { type: "number" },
|
|
458
546
|
completedSteps: { type: "number" },
|
|
547
|
+
confirmationRequired: { type: "boolean" },
|
|
548
|
+
confirmProtocolRequest: { type: "object", optional: true },
|
|
459
549
|
},
|
|
460
550
|
},
|
|
461
551
|
},
|
|
@@ -847,7 +937,7 @@ function officialMatchAllowed(slug, demand) {
|
|
|
847
937
|
const active = demand.mode !== "bypass";
|
|
848
938
|
const codeGoal = demand.goalKind === "code" || demand.goalKind === "mixed";
|
|
849
939
|
if (slug === "calctool") return demand.goalKind === "calculator" || demand.requiresCalculator;
|
|
850
|
-
if (slug === "confirm-protocol") return demand.requiresConfirmation;
|
|
940
|
+
if (slug === "confirm-protocol") return demand.requiresConfirmation || demand.risk === "high";
|
|
851
941
|
if (slug === "archguard") return codeGoal && (demand.hasArchitectureContract || demand.newProject);
|
|
852
942
|
if (slug === "blueprint") return active && ["probe", "swarm"].includes(demand.mode)
|
|
853
943
|
&& demand.contractUnclear && !demand.hasBlueprint;
|
|
@@ -900,7 +990,7 @@ function routeSkills(input) {
|
|
|
900
990
|
const demand = { mode, goalKind, risk: risk.value, hasBlueprint: input.hasBlueprint,
|
|
901
991
|
contractUnclear: input.contractUnclear,
|
|
902
992
|
hasArchitectureContract: input.hasArchitectureContract, newProject: input.newProject,
|
|
903
|
-
requiresConfirmation: input.requiresConfirmation, requiresCalculator: input.requiresCalculator,
|
|
993
|
+
requiresConfirmation: input.requiresConfirmation || risk.value === "high", requiresCalculator: input.requiresCalculator,
|
|
904
994
|
requiresMerge: input.requiresMerge, requiresValidation: input.requiresValidation };
|
|
905
995
|
const resolved = validateResolvedSkills(input, demand);
|
|
906
996
|
if (resolved.findings) return resolved;
|
|
@@ -1292,7 +1382,8 @@ async function executeRun(request) {
|
|
|
1292
1382
|
if (operation === "snapshot-verify") return finish(requestId, snapshotVerify(input));
|
|
1293
1383
|
if (operation === "run-status") return finish(requestId, runStatus(input));
|
|
1294
1384
|
if (operation === "chain-plan") {
|
|
1295
|
-
const result = buildChainPlan(input
|
|
1385
|
+
const result = buildChainPlan({ ...input,
|
|
1386
|
+
confirmationRequestId: input.confirmationRequestId ?? requestId });
|
|
1296
1387
|
if (result.findings) return blockedResponse(requestId, result.findings);
|
|
1297
1388
|
return okResponse(requestId, { ...result, nextStep: result.ready.length ? { operation: result.ready[0], instruction: `Execute first ready step: ${result.ready[0]}` } : { operation: "chain-status", instruction: "All steps blocked or complete." } });
|
|
1298
1389
|
}
|
package/cli.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { realpathSync } from 'node:fs'
|
|
2
3
|
import { dirname, resolve } from 'node:path'
|
|
3
4
|
import { cwd, stdin, stdout } from 'node:process'
|
|
4
5
|
import { createInterface } from 'node:readline/promises'
|
|
@@ -182,7 +183,7 @@ async function dispatchLocal(args) {
|
|
|
182
183
|
}
|
|
183
184
|
|
|
184
185
|
const cliPath = fileURLToPath(import.meta.url)
|
|
185
|
-
if (process.argv[1] && resolve(process.argv[1]) === cliPath) {
|
|
186
|
+
if (process.argv[1] && realpathSync(resolve(process.argv[1])) === cliPath) {
|
|
186
187
|
if (process.argv[2] === 'local') {
|
|
187
188
|
try {
|
|
188
189
|
console.log(JSON.stringify(await dispatchLocal(process.argv.slice(3))))
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"cli-aimlock": "./cli.mjs"
|
|
4
4
|
},
|
|
5
5
|
"dependencies": {
|
|
6
|
-
"cli-swarm": "7.0.
|
|
6
|
+
"cli-swarm": "7.0.31"
|
|
7
7
|
},
|
|
8
8
|
"description": "Aimlock skill installer for CLI.Tax: lock a user request into an executable aim and route Blueprint, Swarm, and Calctool.",
|
|
9
9
|
"exports": {
|
|
@@ -32,5 +32,5 @@
|
|
|
32
32
|
"url": "https://github.com/88208555/aimlock-clitax.git"
|
|
33
33
|
},
|
|
34
34
|
"type": "module",
|
|
35
|
-
"version": "7.0.
|
|
35
|
+
"version": "7.0.31"
|
|
36
36
|
}
|
package/skill/SKILL.md
CHANGED
|
@@ -5,7 +5,7 @@ description: "Aimlock 仅用于大型、深度、跨模块、高风险、需要
|
|
|
5
5
|
|
|
6
6
|
# Aimlock Skill
|
|
7
7
|
|
|
8
|
-
Package version: v7.0.
|
|
8
|
+
Package version: v7.0.31
|
|
9
9
|
|
|
10
10
|
Endpoint: https://cli.tax/R3mQ8kWpXn
|
|
11
11
|
|
|
@@ -84,7 +84,7 @@ Aimlock contains no static full-skill registry. `capabilities` does not preload
|
|
|
84
84
|
Required routing facts include `mode`, `goalKind`, `risk`, `contractUnclear`, blueprint/architecture state, and explicit booleans for confirmation, calculator, merge, and final validation needs.
|
|
85
85
|
|
|
86
86
|
- Calctool: only for a calculator demand or explicit calculation requirement. It must not appear in a non-calculation result.
|
|
87
|
-
- Confirm Protocol:
|
|
87
|
+
- Confirm Protocol: when a structured user decision is required, and always for high-risk work even if the caller sends a false hint.
|
|
88
88
|
- ArchGuard: only for code/mixed work in a new project or under an existing architecture contract.
|
|
89
89
|
- Blueprint: only for active Probe/Swarm work when `contractUnclear=true` and no blueprint exists.
|
|
90
90
|
- Swarm: only for active Swarm mode.
|
|
@@ -106,7 +106,7 @@ Caller-supplied full catalogs and local registry flags are forbidden. `serverRes
|
|
|
106
106
|
|
|
107
107
|
Trusted local operations: `capabilities`, `probe`, `reassess`, `budget-init`, `budget-read`, `budget-status`, `budget-extend`, `gate-issue`, `gate-verify`, and `guarded-write`. Invoke them as `cli-aimlock local <operation> <repositoryRoot>` with JSON stdin and call local `capabilities` first for every input Schema.
|
|
108
108
|
|
|
109
|
-
`chain-plan` accepts only server-resolved skill IDs. High-risk work is blocked
|
|
109
|
+
`chain-plan` accepts only server-resolved skill IDs. High-risk work is blocked unless both Confirm Protocol and Validator were resolved. Confirm Protocol is forced to the first step; the caller must invoke the returned `confirmProtocolRequest`, then submit its authoritative `interaction-answer` response with the same `confirmationRequestId`. Replayed or mismatched approval remains blocked. When `swarm` is present, the plan inserts the internal `coordinator.conflict-scan` step immediately before it; no unrelated external skill is added.
|
|
110
110
|
|
|
111
111
|
## Interrupt and keep-alive
|
|
112
112
|
|
|
@@ -134,6 +134,7 @@ Aimlock returns the protocol; it does not start a timer.
|
|
|
134
134
|
| A5 | 真实分档与逐级升级 | 已实现 | 本地读取真实路径、Git 历史、包边界和 import 图;可从新鲜 ContextBase 地图解析精确目标符号;调用方自报复杂度不能覆盖探测,升级继承现有证据。 |
|
|
135
135
|
| A6 | 读取预算与截止 | 已实现(需宿主路由) | Lock/Probe/Swarm 限制 3/10/30 文件与 2/8/15 分钟;Probe/Swarm 另限 30K/100K 估算 token,并用进程间锁阻止并发超额。 |
|
|
136
136
|
| A7 | AutoCoord 物理联锁 | 已实现(需宿主路由) | `gate-issue` 显式选择是否需要协调;协调凭证绑定 Swarm 签名文件租约,`guarded-write` 在同一临界区校验凭证、活动锁和路径范围。活动依赖等待会阻断预算读取。 |
|
|
137
|
+
| A8 | 高风险确认联锁 | 已实现(需宿主调用) | 高风险需求自动路由 Confirm Protocol;`chain-plan` 在权威 `interaction-answer` 返回前保持阻断,并校验请求 ID、审计与回调绑定。 |
|
|
137
138
|
|
|
138
139
|
## Safety
|
|
139
140
|
|
package/skill/skill.json
CHANGED