@akagilnc/pi-workflow-roles 0.1.5015 → 0.1.5063
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/THIRD_PARTY_NOTICES.md +8 -8
- package/dist/acp-host/production-host.js +525 -978
- package/dist/headless-host/description.js +0 -2
- package/dist/headless-host/production-host.js +528 -1014
- package/dist/host-descriptions.js +2 -3
- package/dist/migrate-book-topology.js +7 -12
- package/dist/packaged-role-registry.js +20 -18
- package/dist/pi/role-turn-host.js +3 -27
- package/dist/public-cli/cli.js +23 -2
- package/dist/public-cli/countersign-run.js +13 -8
- package/dist/public-cli/instruction-seat-run.js +75 -107
- package/dist/public-cli/invocation.js +13 -32
- package/dist/public-cli/machine-method-skills.js +150 -0
- package/dist/public-cli/main.js +549 -679
- package/dist/public-cli/post-admission.js +10 -5
- package/dist/public-cli/registry.js +2 -1
- package/dist/public-cli/run-lifecycle.js +12 -15
- package/dist/public-cli/seat-ticket-binding.js +5 -8
- package/dist/public-cli/settlement.js +12 -99
- package/dist/public-cli/turn-request.js +16 -8
- package/dist/public-role-summons.js +8 -3
- package/package.json +5 -1
- package/resources/countersign-ticket-issue.md +5 -0
- package/resources/diarist-collect.md +1 -0
- package/resources/secretariat-ticket-identity.md +15 -0
- package/scripts/build-package.mjs +1 -6
- package/src/headless-host/description.ts +0 -3
- package/src/headless-host/role-turn-host.ts +2 -23
- package/src/host-contracts.ts +2 -23
- package/src/host-descriptions.ts +2 -3
- package/src/packaged-role-registry.ts +17 -16
- package/src/pi/adapter.ts +0 -27
- package/src/pi/role-turn-host.ts +3 -31
- package/src/public-cli/cli.ts +24 -2
- package/src/public-cli/countersign-run.ts +17 -10
- package/src/public-cli/instruction-seat-run.ts +75 -105
- package/src/public-cli/invocation.ts +10 -38
- package/src/public-cli/machine-method-skills.ts +153 -0
- package/src/public-cli/post-admission.ts +12 -6
- package/src/public-cli/registry.ts +1 -0
- package/src/public-cli/run-lifecycle.ts +12 -13
- package/src/public-cli/seat-ticket-binding.ts +5 -8
- package/src/public-cli/settlement.ts +6 -138
- package/src/public-cli/turn-request.ts +24 -16
- package/src/public-role-summons.ts +16 -3
- package/src/reviewer-role.ts +1 -12
- package/src/role-envelope.ts +0 -13
- package/src/role-runtime-dependencies.ts +0 -13
- package/src/role-runtime.ts +4 -56
- package/src/worker-role.ts +1 -81
- package/dist/method-host-plugin/.claude-plugin/plugin.json +0 -5
- package/dist/method-host-plugin/skills/ak-cross-m-review/CONTEXT.md +0 -48
- package/dist/method-host-plugin/skills/ak-cross-m-review/LICENSE +0 -21
- package/dist/method-host-plugin/skills/ak-cross-m-review/SKILL.md +0 -170
- package/dist/method-host-plugin/skills/ak-cross-m-review/prompts/cmr-completeness.md +0 -118
- package/dist/method-host-plugin/skills/ak-cross-m-review/prompts/cmr-reviewer.md +0 -128
- package/dist/method-host-plugin/skills/ak-cross-m-review/provenance.json +0 -41
- package/dist/method-host-plugin/skills/diagnosing-bugs/SKILL.md +0 -134
- package/dist/method-host-plugin/skills/diagnosing-bugs/agents/openai.yaml +0 -3
- package/dist/method-host-plugin/skills/diagnosing-bugs/provenance.json +0 -31
- package/dist/method-host-plugin/skills/diagnosing-bugs/scripts/hitl-loop.template.sh +0 -41
- package/dist/method-host-plugin/skills/resolving-merge-conflicts/SKILL.md +0 -14
- package/dist/method-host-plugin/skills/resolving-merge-conflicts/agents/openai.yaml +0 -3
- package/dist/method-host-plugin/skills/resolving-merge-conflicts/provenance.json +0 -26
- package/dist/method-host-plugin/skills/tdd/SKILL.md +0 -38
- package/dist/method-host-plugin/skills/tdd/agents/openai.yaml +0 -3
- package/dist/method-host-plugin/skills/tdd/mocking.md +0 -59
- package/dist/method-host-plugin/skills/tdd/provenance.json +0 -36
- package/dist/method-host-plugin/skills/tdd/tests.md +0 -77
- package/dist/package-resources/method-skill.js +0 -259
- package/resources/method-host-plugin/.claude-plugin/plugin.json +0 -5
- package/resources/methods/ak-cross-m-review/CONTEXT.md +0 -48
- package/resources/methods/ak-cross-m-review/LICENSE +0 -21
- package/resources/methods/ak-cross-m-review/SKILL.md +0 -170
- package/resources/methods/ak-cross-m-review/prompts/cmr-completeness.md +0 -118
- package/resources/methods/ak-cross-m-review/prompts/cmr-reviewer.md +0 -128
- package/resources/methods/ak-cross-m-review/provenance.json +0 -41
- package/resources/methods/diagnosing-bugs/SKILL.md +0 -134
- package/resources/methods/diagnosing-bugs/agents/openai.yaml +0 -3
- package/resources/methods/diagnosing-bugs/provenance.json +0 -31
- package/resources/methods/diagnosing-bugs/scripts/hitl-loop.template.sh +0 -41
- package/resources/methods/resolving-merge-conflicts/SKILL.md +0 -14
- package/resources/methods/resolving-merge-conflicts/agents/openai.yaml +0 -3
- package/resources/methods/resolving-merge-conflicts/provenance.json +0 -26
- package/resources/methods/tdd/SKILL.md +0 -38
- package/resources/methods/tdd/agents/openai.yaml +0 -3
- package/resources/methods/tdd/mocking.md +0 -59
- package/resources/methods/tdd/provenance.json +0 -36
- package/resources/methods/tdd/tests.md +0 -77
- package/src/canonical-skill-binding.ts +0 -118
- package/src/host-native-method.ts +0 -185
- package/src/package-resources/method-skill-binding.ts +0 -60
- package/src/package-resources/method-skill.ts +0 -363
|
@@ -1,259 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Package-owned role method Skill seam (ADR 0052 / #109).
|
|
3
|
-
* Forced methods load from the installed package copy — never ambient home discovery.
|
|
4
|
-
*
|
|
5
|
-
* This module is intentionally free of @earendil-works/pi-coding-agent so the
|
|
6
|
-
* public ak-role bin can load provenance/path without bundling peer runtime.
|
|
7
|
-
*/
|
|
8
|
-
import { createHash } from "node:crypto";
|
|
9
|
-
import { readFile, realpath } from "node:fs/promises";
|
|
10
|
-
import { join } from "node:path";
|
|
11
|
-
import { sha256Hex } from "../sha256.js";
|
|
12
|
-
/** Package-side unavailable method Skill (mirrors CanonicalSkillUnavailableError identity). */
|
|
13
|
-
export class PackagedMethodSkillUnavailableError extends Error {
|
|
14
|
-
skillName;
|
|
15
|
-
code = "canonical-skill-unavailable";
|
|
16
|
-
constructor(skillName, path, cause) {
|
|
17
|
-
super(`Canonical ${skillName} Skill is unavailable at ${path}`, { cause });
|
|
18
|
-
this.skillName = skillName;
|
|
19
|
-
this.name = "CanonicalSkillUnavailableError";
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
const METHOD_SKILL_RELATIVE_ROOT = "resources/methods";
|
|
23
|
-
const GIT_COMMIT_RE = /^[0-9a-f]{40}$/;
|
|
24
|
-
const GIT_BLOB_RE = /^[0-9a-f]{40}$/;
|
|
25
|
-
const SHA256_RE = /^[0-9a-f]{64}$/;
|
|
26
|
-
const REQUIRED_COMPANIONS = {
|
|
27
|
-
tdd: ["tests.md", "mocking.md", "agents/openai.yaml"],
|
|
28
|
-
"diagnosing-bugs": ["agents/openai.yaml", "scripts/hitl-loop.template.sh"],
|
|
29
|
-
"ak-cross-m-review": [
|
|
30
|
-
"CONTEXT.md",
|
|
31
|
-
"LICENSE",
|
|
32
|
-
"prompts/cmr-completeness.md",
|
|
33
|
-
"prompts/cmr-reviewer.md",
|
|
34
|
-
],
|
|
35
|
-
"resolving-merge-conflicts": ["agents/openai.yaml"],
|
|
36
|
-
};
|
|
37
|
-
/** Git blob OID for raw file bytes (sha1 of `blob <size>\\0` + content). */
|
|
38
|
-
export function gitBlobOid(bytes) {
|
|
39
|
-
const body = typeof bytes === "string" ? Buffer.from(bytes, "utf8") : Buffer.from(bytes);
|
|
40
|
-
const header = Buffer.from(`blob ${body.byteLength}\0`, "utf8");
|
|
41
|
-
return createHash("sha1").update(header).update(body).digest("hex");
|
|
42
|
-
}
|
|
43
|
-
/** Minimal frontmatter strip — body after closing `---` fence (or full text). */
|
|
44
|
-
export function stripSkillFrontmatter(content) {
|
|
45
|
-
if (!content.startsWith("---"))
|
|
46
|
-
return content;
|
|
47
|
-
const end = content.indexOf("\n---", 3);
|
|
48
|
-
if (end === -1)
|
|
49
|
-
return content;
|
|
50
|
-
const after = content.slice(end + "\n---".length);
|
|
51
|
-
return after.replace(/^\r?\n/, "");
|
|
52
|
-
}
|
|
53
|
-
export function packagedMethodSkillRelativeDirectory(name) {
|
|
54
|
-
return `${METHOD_SKILL_RELATIVE_ROOT}/${name}`;
|
|
55
|
-
}
|
|
56
|
-
export function resolvePackagedMethodSkillRoot(packageRoot, name) {
|
|
57
|
-
return join(packageRoot, packagedMethodSkillRelativeDirectory(name));
|
|
58
|
-
}
|
|
59
|
-
export function resolvePackagedMethodSkillPath(packageRoot, name) {
|
|
60
|
-
return join(resolvePackagedMethodSkillRoot(packageRoot, name), "SKILL.md");
|
|
61
|
-
}
|
|
62
|
-
function isRecord(value) {
|
|
63
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
64
|
-
}
|
|
65
|
-
function parseProvenance(raw, expectedName) {
|
|
66
|
-
if (!isRecord(raw)) {
|
|
67
|
-
throw new Error(`Packaged method provenance must be an object for ${expectedName}`);
|
|
68
|
-
}
|
|
69
|
-
if (raw.name !== expectedName) {
|
|
70
|
-
throw new Error(`Packaged method provenance name mismatch: expected ${expectedName}, got ${String(raw.name)}`);
|
|
71
|
-
}
|
|
72
|
-
if (raw.kind !== "role-method-skill") {
|
|
73
|
-
throw new Error(`Packaged method provenance kind must be role-method-skill`);
|
|
74
|
-
}
|
|
75
|
-
if (typeof raw.packageAdaptation !== "string" || raw.packageAdaptation.trim() === "") {
|
|
76
|
-
throw new Error(`Packaged method provenance packageAdaptation must be nonblank`);
|
|
77
|
-
}
|
|
78
|
-
if (!isRecord(raw.upstream)) {
|
|
79
|
-
throw new Error(`Packaged method provenance upstream must be an object`);
|
|
80
|
-
}
|
|
81
|
-
const upstream = raw.upstream;
|
|
82
|
-
for (const key of [
|
|
83
|
-
"repository",
|
|
84
|
-
"path",
|
|
85
|
-
"license",
|
|
86
|
-
"copyright",
|
|
87
|
-
"attribution",
|
|
88
|
-
]) {
|
|
89
|
-
if (typeof upstream[key] !== "string" || upstream[key].trim() === "") {
|
|
90
|
-
throw new Error(`Packaged method provenance upstream.${key} must be nonblank`);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
if (typeof upstream.commit !== "string" || !GIT_COMMIT_RE.test(upstream.commit)) {
|
|
94
|
-
throw new Error(`Packaged method provenance upstream.commit must be a 40-char lowercase git object id`);
|
|
95
|
-
}
|
|
96
|
-
const tag = typeof upstream.tag === "string" && upstream.tag.trim() !== ""
|
|
97
|
-
? upstream.tag.trim()
|
|
98
|
-
: undefined;
|
|
99
|
-
const version = typeof upstream.version === "string" && upstream.version.trim() !== ""
|
|
100
|
-
? upstream.version.trim()
|
|
101
|
-
: undefined;
|
|
102
|
-
if (tag === undefined && version === undefined) {
|
|
103
|
-
throw new Error(`Packaged method provenance upstream must include nonblank tag or version`);
|
|
104
|
-
}
|
|
105
|
-
if (!isRecord(raw.files)) {
|
|
106
|
-
throw new Error(`Packaged method provenance files must be an object`);
|
|
107
|
-
}
|
|
108
|
-
const files = {};
|
|
109
|
-
for (const [rel, entry] of Object.entries(raw.files)) {
|
|
110
|
-
if (!isRecord(entry)) {
|
|
111
|
-
throw new Error(`Packaged method provenance file entry must be an object: ${rel}`);
|
|
112
|
-
}
|
|
113
|
-
if (typeof entry.sha256 !== "string" || !SHA256_RE.test(entry.sha256)) {
|
|
114
|
-
throw new Error(`Packaged method provenance file sha256 invalid: ${rel}`);
|
|
115
|
-
}
|
|
116
|
-
if (typeof entry.byteLength !== "number" ||
|
|
117
|
-
!Number.isInteger(entry.byteLength) ||
|
|
118
|
-
entry.byteLength < 0) {
|
|
119
|
-
throw new Error(`Packaged method provenance file byteLength invalid: ${rel}`);
|
|
120
|
-
}
|
|
121
|
-
if (typeof entry.gitBlob !== "string" || !GIT_BLOB_RE.test(entry.gitBlob)) {
|
|
122
|
-
throw new Error(`Packaged method provenance file gitBlob must be a 40-char lowercase git object id: ${rel}`);
|
|
123
|
-
}
|
|
124
|
-
files[rel] = {
|
|
125
|
-
sha256: entry.sha256,
|
|
126
|
-
byteLength: entry.byteLength,
|
|
127
|
-
gitBlob: entry.gitBlob,
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
if (files["SKILL.md"] === undefined) {
|
|
131
|
-
throw new Error(`Packaged method provenance must include SKILL.md`);
|
|
132
|
-
}
|
|
133
|
-
return Object.freeze({
|
|
134
|
-
name: expectedName,
|
|
135
|
-
kind: "role-method-skill",
|
|
136
|
-
packageAdaptation: raw.packageAdaptation,
|
|
137
|
-
upstream: Object.freeze({
|
|
138
|
-
repository: upstream.repository,
|
|
139
|
-
path: upstream.path,
|
|
140
|
-
commit: upstream.commit,
|
|
141
|
-
...(tag === undefined ? {} : { tag }),
|
|
142
|
-
...(version === undefined ? {} : { version }),
|
|
143
|
-
license: upstream.license,
|
|
144
|
-
copyright: upstream.copyright,
|
|
145
|
-
attribution: upstream.attribution,
|
|
146
|
-
}),
|
|
147
|
-
files: Object.freeze(files),
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
* Load a package-owned method Skill and verify per-file provenance digests.
|
|
152
|
-
* Does not consult HOME or ambient Skill discovery paths.
|
|
153
|
-
*/
|
|
154
|
-
export async function loadPackagedMethodSkillMaterial(packageRoot, name) {
|
|
155
|
-
const rootDirectory = resolvePackagedMethodSkillRoot(packageRoot, name);
|
|
156
|
-
const skillPathConfigured = join(rootDirectory, "SKILL.md");
|
|
157
|
-
const provenancePath = join(rootDirectory, "provenance.json");
|
|
158
|
-
let provenanceRaw;
|
|
159
|
-
try {
|
|
160
|
-
provenanceRaw = await readFile(provenancePath, "utf8");
|
|
161
|
-
}
|
|
162
|
-
catch (error) {
|
|
163
|
-
throw new PackagedMethodSkillUnavailableError(name, provenancePath, error);
|
|
164
|
-
}
|
|
165
|
-
let provenanceJson;
|
|
166
|
-
try {
|
|
167
|
-
provenanceJson = JSON.parse(provenanceRaw);
|
|
168
|
-
}
|
|
169
|
-
catch (error) {
|
|
170
|
-
throw new Error(`Packaged method provenance is not valid JSON at ${provenancePath}`, {
|
|
171
|
-
cause: error,
|
|
172
|
-
});
|
|
173
|
-
}
|
|
174
|
-
const provenance = parseProvenance(provenanceJson, name);
|
|
175
|
-
// Verify every declared file digest + independent git blob against package bytes (no network).
|
|
176
|
-
for (const [rel, expected] of Object.entries(provenance.files)) {
|
|
177
|
-
const absolute = join(rootDirectory, rel);
|
|
178
|
-
let bytes;
|
|
179
|
-
try {
|
|
180
|
-
bytes = await readFile(absolute);
|
|
181
|
-
}
|
|
182
|
-
catch (error) {
|
|
183
|
-
throw new PackagedMethodSkillUnavailableError(name, absolute, error);
|
|
184
|
-
}
|
|
185
|
-
const actualSha = sha256Hex(bytes);
|
|
186
|
-
const actualBlob = gitBlobOid(bytes);
|
|
187
|
-
if (actualSha !== expected.sha256 ||
|
|
188
|
-
bytes.byteLength !== expected.byteLength ||
|
|
189
|
-
actualBlob !== expected.gitBlob) {
|
|
190
|
-
throw new Error(`Packaged method file digest mismatch for ${name}/${rel}: expected sha256=${expected.sha256} byteLength=${expected.byteLength} gitBlob=${expected.gitBlob}, got sha256=${actualSha} byteLength=${bytes.byteLength} gitBlob=${actualBlob}`);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
let skillPath;
|
|
194
|
-
let raw;
|
|
195
|
-
try {
|
|
196
|
-
skillPath = await realpath(skillPathConfigured);
|
|
197
|
-
raw = await readFile(skillPath, "utf8");
|
|
198
|
-
}
|
|
199
|
-
catch (error) {
|
|
200
|
-
throw new PackagedMethodSkillUnavailableError(name, skillPathConfigured, error);
|
|
201
|
-
}
|
|
202
|
-
const body = stripSkillFrontmatter(raw).trim();
|
|
203
|
-
if (body.length === 0) {
|
|
204
|
-
throw new Error(`Canonical ${name} Skill is empty at ${skillPath}`);
|
|
205
|
-
}
|
|
206
|
-
const companionRelativePaths = REQUIRED_COMPANIONS[name].filter((rel) => provenance.files[rel] !== undefined);
|
|
207
|
-
for (const rel of REQUIRED_COMPANIONS[name]) {
|
|
208
|
-
if (provenance.files[rel] === undefined) {
|
|
209
|
-
throw new Error(`Packaged method ${name} missing required companion in provenance: ${rel}`);
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
return Object.freeze({
|
|
213
|
-
name,
|
|
214
|
-
rootDirectory,
|
|
215
|
-
skillPath,
|
|
216
|
-
raw,
|
|
217
|
-
body,
|
|
218
|
-
provenance,
|
|
219
|
-
companionRelativePaths: Object.freeze([...companionRelativePaths]),
|
|
220
|
-
});
|
|
221
|
-
}
|
|
222
|
-
/**
|
|
223
|
-
* Observe one Pi-native packaged method Skill expansion from a user-turn text.
|
|
224
|
-
* Matches the structured `<skill name location>` block format only; rejects ambient
|
|
225
|
-
* home locations that are not in the allowed package path set.
|
|
226
|
-
*/
|
|
227
|
-
export function observePackagedMethodSkillInvocation(text, expected) {
|
|
228
|
-
// Structured skill-block grammar (same shape Pi expands); not free-text classification.
|
|
229
|
-
if (!text.startsWith("<skill name=\""))
|
|
230
|
-
return undefined;
|
|
231
|
-
const nameStart = "<skill name=\"".length;
|
|
232
|
-
const nameEnd = text.indexOf("\"", nameStart);
|
|
233
|
-
if (nameEnd <= nameStart)
|
|
234
|
-
return undefined;
|
|
235
|
-
const name = text.slice(nameStart, nameEnd);
|
|
236
|
-
if (name !== expected.name)
|
|
237
|
-
return undefined;
|
|
238
|
-
const locationMarker = "\" location=\"";
|
|
239
|
-
if (!text.startsWith(locationMarker, nameEnd))
|
|
240
|
-
return undefined;
|
|
241
|
-
const locationStart = nameEnd + locationMarker.length;
|
|
242
|
-
const locationEnd = text.indexOf("\"", locationStart);
|
|
243
|
-
if (locationEnd <= locationStart)
|
|
244
|
-
return undefined;
|
|
245
|
-
const location = text.slice(locationStart, locationEnd);
|
|
246
|
-
const openTail = ">\n";
|
|
247
|
-
if (!text.startsWith(openTail, locationEnd + 1))
|
|
248
|
-
return undefined;
|
|
249
|
-
const closeTag = "\n</skill>";
|
|
250
|
-
const closeAt = text.indexOf(closeTag, locationEnd + 1 + openTail.length);
|
|
251
|
-
if (closeAt === -1)
|
|
252
|
-
return undefined;
|
|
253
|
-
const afterClose = text.slice(closeAt + closeTag.length);
|
|
254
|
-
if (afterClose.length > 0 && !afterClose.startsWith("\n"))
|
|
255
|
-
return undefined;
|
|
256
|
-
if (!expected.allowedLocations.includes(location))
|
|
257
|
-
return undefined;
|
|
258
|
-
return Object.freeze({ name: expected.name, location });
|
|
259
|
-
}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
# ak-cross-m-review
|
|
2
|
-
|
|
3
|
-
Local, pre-PR review gate: two independent lenses against a pinned diff, one verdict each; a single lens runs in the invoking session, `all` runs both as parallel sub-agent legs. `SKILL.md` plus the selected lens prompt is the complete active authority; this file is vocabulary only.
|
|
4
|
-
|
|
5
|
-
## Language
|
|
6
|
-
|
|
7
|
-
**Fixed target**:
|
|
8
|
-
The pinned base-to-HEAD snapshot under review, resolved to two literal SHAs
|
|
9
|
-
before anything is dispatched.
|
|
10
|
-
_Avoid_: range, worktree diff, working changes
|
|
11
|
-
|
|
12
|
-
**Authority set**:
|
|
13
|
-
The ordered sources that govern the review — user decisions first, then
|
|
14
|
-
ratified ADRs / specs, then repository contracts.
|
|
15
|
-
_Avoid_: spec (alone), reference docs
|
|
16
|
-
|
|
17
|
-
**Lens**:
|
|
18
|
-
One review question with its own prompt file — `completeness` (was the
|
|
19
|
-
authority delivered?) or `correctness` (is what exists right?).
|
|
20
|
-
_Avoid_: axis, gate, mode, pass
|
|
21
|
-
|
|
22
|
-
**Leg**:
|
|
23
|
-
One independent sub-agent running exactly one lens inside an independent copy of the target at `PRE_HEAD`, dispatched only by `all`; the copy is provided by the harness when it can, otherwise created by the caller. A single-lens invocation has no leg: the invoking session applies the lens itself.
|
|
24
|
-
_Avoid_: panel, member, reviewer squad, vendor leg
|
|
25
|
-
|
|
26
|
-
**Candidate**:
|
|
27
|
-
An evidence-backed claim a leg submits for judgment; never a verdict.
|
|
28
|
-
_Avoid_: finding (before judgment), vote
|
|
29
|
-
|
|
30
|
-
**Judge**:
|
|
31
|
-
The invoking session, which verifies each candidate against the fixed target
|
|
32
|
-
and authority set and disposes it as live or refuted.
|
|
33
|
-
_Avoid_: orchestrator, runner, merger
|
|
34
|
-
|
|
35
|
-
**Verdict**:
|
|
36
|
-
The single terminal line a lens ends with, labelled by lens
|
|
37
|
-
(`CMR-VERDICT: completeness=…` / `CMR-VERDICT: correctness=…`).
|
|
38
|
-
_Avoid_: gate result, concur, convergence
|
|
39
|
-
|
|
40
|
-
**Preset**:
|
|
41
|
-
A named wrapper skill that invokes the engine with one lens and returns its
|
|
42
|
-
report unchanged.
|
|
43
|
-
_Avoid_: gate skill, entry point
|
|
44
|
-
|
|
45
|
-
**Review only**:
|
|
46
|
-
The outcome boundary — the invocation reports and stops; the caller owns every
|
|
47
|
-
repair, commit, retry, and later review.
|
|
48
|
-
_Avoid_: read-only (that is a filesystem property, not this boundary)
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 Akagi
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: ak-cross-m-review
|
|
3
|
-
description: Use when the user requests CMR (cross-model review) of a fixed target, or a CMR preset delegates here.
|
|
4
|
-
allowed-tools:
|
|
5
|
-
- Agent
|
|
6
|
-
- Bash
|
|
7
|
-
- Read
|
|
8
|
-
- Grep
|
|
9
|
-
- Glob
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
# /ak-cross-m-review — fixed-target review engine
|
|
13
|
-
|
|
14
|
-
This file plus each selected prompt is the complete active authority. See `CONTEXT.md` for vocabulary.
|
|
15
|
-
|
|
16
|
-
**REVIEW ONLY.** Pin one fixed target and authority set, run the selected
|
|
17
|
-
lenses, judge their candidates independently, report, and stop. The caller owns
|
|
18
|
-
every repair, commit, retry, and later review.
|
|
19
|
-
|
|
20
|
-
Model composition is the caller's: a single lens runs in the invoking session; `all` runs each lens as one leg on whatever the harness supplies.
|
|
21
|
-
|
|
22
|
-
## Invocation
|
|
23
|
-
|
|
24
|
-
Direct invocation must provide every required input; these are agent-chat
|
|
25
|
-
arguments, not a shell CLI:
|
|
26
|
-
|
|
27
|
-
```text
|
|
28
|
-
/ak-cross-m-review --base FIXED_POINT --lens completeness|correctness|all
|
|
29
|
-
--authority SOURCE [--authority SOURCE ...]
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
- `--base` supplies the fixed point compared with committed `HEAD`.
|
|
33
|
-
- `--lens` is required and has no default.
|
|
34
|
-
- `--authority` names a governing repository path or labelled user source.
|
|
35
|
-
|
|
36
|
-
## Step 1 — Pin the fixed target
|
|
37
|
-
|
|
38
|
-
Run from the target repository:
|
|
39
|
-
|
|
40
|
-
1. Run this status gate and require no output, excluding only harness worktrees:
|
|
41
|
-
```text
|
|
42
|
-
git status --porcelain=v1 --untracked-files=all -- :/ ':(top,exclude).claude/worktrees/**'
|
|
43
|
-
```
|
|
44
|
-
2. Resolve literal `PRE_HEAD` with `git rev-parse --verify 'HEAD^{commit}'`,
|
|
45
|
-
`BASE_SHA` with `git rev-parse --verify '<base>^{commit}'`, and `TARGET_ROOT`
|
|
46
|
-
with `git rev-parse --show-toplevel`.
|
|
47
|
-
3. Substitute those SHAs and freeze these commands exactly:
|
|
48
|
-
|
|
49
|
-
```text
|
|
50
|
-
git log --oneline BASE_SHA..PRE_HEAD
|
|
51
|
-
git diff --binary BASE_SHA...PRE_HEAD
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
4. Run the frozen log command and require the frozen diff command to produce a
|
|
55
|
-
non-empty diff.
|
|
56
|
-
|
|
57
|
-
A dirty tree, unresolved required ref, unexpected failed command, or empty diff is a `hard-stop`. Record the exact failing command and its native output in one sentence.
|
|
58
|
-
|
|
59
|
-
Completion criterion: clean status, literal pin values, and one non-empty diff represented by the two frozen commands.
|
|
60
|
-
|
|
61
|
-
## Step 2 — Pin the authority set
|
|
62
|
-
|
|
63
|
-
Freeze one ordered authority set before dispatch:
|
|
64
|
-
|
|
65
|
-
1. user decisions and supplied sources;
|
|
66
|
-
2. ratified ADRs, acceptance text, PRD/spec, and originating issue;
|
|
67
|
-
3. repository contracts such as AGENTS/CLAUDE/CONTRIBUTING, public APIs, and
|
|
68
|
-
behavior tests;
|
|
69
|
-
4. surrounding code as evidence of an established contract only.
|
|
70
|
-
|
|
71
|
-
Follow references named by higher authority; lower authority cannot override
|
|
72
|
-
higher authority. List repository authority by relative path. Put exact
|
|
73
|
-
user-supplied text in the brief under a stable label such as
|
|
74
|
-
`user-authority-1`, with stable line addresses.
|
|
75
|
-
|
|
76
|
-
Completeness, alone or inside `all`, requires clause authority addressable as
|
|
77
|
-
repository `path:line` or brief `source-label:line`. If no source states what
|
|
78
|
-
had to be delivered, that lens is a `hard-stop` with
|
|
79
|
-
`missing completeness authority`.
|
|
80
|
-
Correctness may proceed from repository contracts when no feature spec exists: AGENTS/CLAUDE/CONTRIBUTING, public APIs, and behavior tests.
|
|
81
|
-
|
|
82
|
-
Completion criterion: a frozen ordered list; each selected lens has sufficient
|
|
83
|
-
authority or its own evidenced `hard-stop`.
|
|
84
|
-
|
|
85
|
-
## Step 3 — Select lenses
|
|
86
|
-
|
|
87
|
-
`--lens completeness|correctness|all` is required; omission is a usage error (report it; no verdict line).
|
|
88
|
-
|
|
89
|
-
- `completeness` loads `prompts/cmr-completeness.md` and applies
|
|
90
|
-
Clause–Wire–Exercise.
|
|
91
|
-
- `correctness` loads `prompts/cmr-reviewer.md` and applies
|
|
92
|
-
Trace–Break–Prove.
|
|
93
|
-
- `all` launches both lenses as sub-agent legs in one parallel batch.
|
|
94
|
-
|
|
95
|
-
Each lens has its own prompt, context, candidates, judgment, and verdict; none
|
|
96
|
-
is shared with the other lens.
|
|
97
|
-
|
|
98
|
-
Completion criterion: each selected lens is ready for one batch or has its own
|
|
99
|
-
evidenced `hard-stop`.
|
|
100
|
-
|
|
101
|
-
## Step 4 — Run the selected lenses
|
|
102
|
-
|
|
103
|
-
A single lens runs in the invoking session: apply the selected lens prompt yourself in `TARGET_ROOT` at `PRE_HEAD`, run the frozen commands, read the authority and the repository, probe where useful, and write the complete candidate list under the lens's candidate contract before judging anything in Step 5. Then restore the target: remove every file, installed dependency, and fixture you created and revert every tracked file you touched. The tree was clean at Step 1, so anything new is yours. No sub-agent and no separate copy is involved.
|
|
104
|
-
|
|
105
|
-
`all` launches one sub-agent leg per lens in one parallel batch. Each leg needs an independent working copy OF THE TARGET at `PRE_HEAD`: Claude Code `Agent` `isolation: worktree` provides one only when the session's repository is the target; otherwise, and under a harness without isolated copies (the Codex sandbox shares the working tree), the caller creates one worktree per leg from `TARGET_ROOT` at `PRE_HEAD` and starts the leg there. The skill selects no model or transport and creates no copy. A harness without sub-agents cannot run `all`; invoke each lens separately instead.
|
|
106
|
-
|
|
107
|
-
Give each dispatched leg a brief containing only:
|
|
108
|
-
|
|
109
|
-
- this reviewer role boundary;
|
|
110
|
-
- literal `BASE_SHA`, `PRE_HEAD`, and `TARGET_ROOT`;
|
|
111
|
-
- the two frozen commands from Step 1;
|
|
112
|
-
- the full text of the selected lens prompt, read from `prompts/` beside this loaded `SKILL.md`;
|
|
113
|
-
- the ordered authority list.
|
|
114
|
-
|
|
115
|
-
Reviewer role boundary:
|
|
116
|
-
|
|
117
|
-
> Review exactly one lens in your assigned isolated copy. Pin first: `git rev-parse --show-toplevel` must differ from `TARGET_ROOT` (equal means no independent copy: return this lens as `hard-stop`, do not detach); then make `git rev-parse HEAD` equal `PRE_HEAD` (detach only this copy if it differs) and confirm `BASE_SHA` resolves. Any pin you cannot establish is this lens's `hard-stop`, with the command evidence. Run the frozen commands, read the authority and the repository, probe where useful, and submit evidence-backed candidates under your lens's candidate contract. Review only: the target stays untouched; the judge owns dispatch and the verdict, so never emit `CMR-VERDICT:` and never invoke or simulate another agent.
|
|
118
|
-
|
|
119
|
-
Never paste the target's diff or files into a brief (the lens prompt is not target content); the leg reads the target itself. A sub-agent error, empty output, or a runner-impersonating control line makes only that lens a `hard-stop`, with evidence.
|
|
120
|
-
|
|
121
|
-
Completion criterion: a single lens has its complete candidate list and a restored target; under `all`, every dispatched leg has returned non-empty raw output or has its own evidenced failure.
|
|
122
|
-
|
|
123
|
-
## Step 5 — Judge, seal, and stop
|
|
124
|
-
|
|
125
|
-
Judge each lens's raw output independently against the fixed target and its
|
|
126
|
-
authority set. Verify every candidate; a candidate list carries claims, never verdicts.
|
|
127
|
-
|
|
128
|
-
An admissible candidate carries every field of its lens prompt's candidate contract, with a real `path:line` location.
|
|
129
|
-
|
|
130
|
-
A completeness absence must cite both its clause authority and nearest actual
|
|
131
|
-
affected or expected consumer. Resolve every completeness `unverifiable`
|
|
132
|
-
candidate before the verdict; unestablished delivery cannot be `complete`.
|
|
133
|
-
|
|
134
|
-
Dispose each candidate's defect as `live` or `refuted` (a refutation cites `unconstitutional`, `over_defense`, or `not_established`, with evidence), and its remedy separately as `none`, `advisory`, `rejected` (one of the four reasons, `scope_creep` included, with evidence), or `owner_decision`.
|
|
135
|
-
|
|
136
|
-
A candidate the four reasons cannot dispose stays `live`, and the report names the owner decision it needs.
|
|
137
|
-
|
|
138
|
-
A real defect stays live when only its proposed remedy is rejected.
|
|
139
|
-
|
|
140
|
-
These are the four lawful rejection reasons: `unconstitutional` conflicts with
|
|
141
|
-
ratified authority; `over_defense` adds an unjustified guard; `not_established`
|
|
142
|
-
lacks proof in the fixed target; `scope_creep` applies only when a remedy
|
|
143
|
-
invents unauthorized behavior. A pre-existing or adjacent defect remains
|
|
144
|
-
eligible. Difficulty is never a rejection reason. Deletion or simplification
|
|
145
|
-
outranks an equivalent added mechanism.
|
|
146
|
-
|
|
147
|
-
After every selected lens has a judgment or evidenced failure, seal once from `TARGET_ROOT` (run the commands there):
|
|
148
|
-
|
|
149
|
-
1. require `git rev-parse 'HEAD^{commit}'` to equal `PRE_HEAD`;
|
|
150
|
-
2. run this status gate and require no output, excluding only harness worktrees:
|
|
151
|
-
```text
|
|
152
|
-
git status --porcelain=v1 --untracked-files=all -- :/ ':(top,exclude).claude/worktrees/**'
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
A moved HEAD is a `hard-stop` with before/after evidence. Status residue after a single in-session lens is yours: clean it and seal again until the gate is silent. Status residue after dispatched legs is not yours: `hard-stop` with the status evidence, and never reset, checkout, remove, or clean what you did not create.
|
|
156
|
-
|
|
157
|
-
End each selected lens with exactly one labelled line:
|
|
158
|
-
|
|
159
|
-
```text
|
|
160
|
-
CMR-VERDICT: completeness=complete|gaps|hard-stop
|
|
161
|
-
CMR-VERDICT: correctness=converged|findings|hard-stop
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
Completeness is `complete` when no live gap or unresolved `unverifiable` row
|
|
165
|
-
remains; otherwise it is `gaps`. Correctness is `converged` when no live defect
|
|
166
|
-
remains; otherwise it is `findings`.
|
|
167
|
-
`hard-stop` means a prerequisite, seal, or leg failure as defined above; Step 1 pin and seal failures apply to every selected lens, while Step 2 and leg failures apply only to that lens. A `--lens` usage error emits no verdict line.
|
|
168
|
-
|
|
169
|
-
Completion criterion: after the single successful seal, every selected lens has an independent judgment or evidenced failure and exactly one labelled verdict;
|
|
170
|
-
or, on an evidenced pin or seal failure, every selected lens carries its labelled `hard-stop`. Stop unconditionally.
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
# Completeness lens — Clause–Wire–Exercise
|
|
2
|
-
|
|
3
|
-
You are one independent completeness leg for a fixed, complete diff. Your
|
|
4
|
-
output is evidence-backed **candidate gaps** for a separate judge. You do not
|
|
5
|
-
decide the verdict or fill the gaps yourself. Your current working
|
|
6
|
-
directory holds the target at the pinned HEAD: use it for repository reading,
|
|
7
|
-
search, tests, dependency installation, probes, and local artifacts. Do not
|
|
8
|
-
commit, push, mutate remote state, or implement a repair.
|
|
9
|
-
|
|
10
|
-
Completeness starts from authority, never from imagination. Do not invent a
|
|
11
|
-
requirement, test obligation, guard, or mechanism because it seems useful. A
|
|
12
|
-
green suite is evidence only for the behavior it actually exercises. Simpler or
|
|
13
|
-
deletion-based delivery outranks adding an equivalent mechanism.
|
|
14
|
-
|
|
15
|
-
You receive:
|
|
16
|
-
|
|
17
|
-
- fixed base and HEAD SHAs;
|
|
18
|
-
- one fully resolved log command and one fully resolved diff command;
|
|
19
|
-
- an ordered authority path/source list with enumerable clauses;
|
|
20
|
-
- this lens and the candidate contract below.
|
|
21
|
-
|
|
22
|
-
Run the supplied log and diff commands yourself. Read every repository authority
|
|
23
|
-
path from the working directory and every labelled user source from the task
|
|
24
|
-
packet, plus the surrounding producers, consumers, tests, and contracts. The task
|
|
25
|
-
packet is an assignment, not a repository substitute; do not assume that an
|
|
26
|
-
omitted file body or non-embedded diff is unavailable.
|
|
27
|
-
|
|
28
|
-
## 1. Clause
|
|
29
|
-
|
|
30
|
-
Keep a private ledger of every authoritative requirement. Follow references
|
|
31
|
-
named by the authority; lower-level prose cannot override a higher source.
|
|
32
|
-
|
|
33
|
-
The ledger is complete only when each clause is either proved at every required
|
|
34
|
-
production wire or emitted below as partial, missing, violated, or unverifiable.
|
|
35
|
-
`unverifiable` names the exact missing evidence. Every candidate gap must name
|
|
36
|
-
its governing authority clause.
|
|
37
|
-
|
|
38
|
-
## 2. Wire
|
|
39
|
-
|
|
40
|
-
For each executable clause that appears delivered, trace the real wire:
|
|
41
|
-
|
|
42
|
-
```text
|
|
43
|
-
production instruction/producer → binding/schema → decoder/consumer → externally visible effect
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
Confirm that the consumer is invoked on the relevant path and that the effect
|
|
47
|
-
matches the clause. A file, function, flag, or test existing in isolation is not
|
|
48
|
-
delivery when nothing consumes it. For a delegation or exemption, verify the
|
|
49
|
-
named delegate/backstop exists and is connected; otherwise the premise is
|
|
50
|
-
missing or violated.
|
|
51
|
-
|
|
52
|
-
For a runtime artifact introduced for the first time, trace both its invocation
|
|
53
|
-
and its availability chain: inventory/package/mount/discovery/preflight must make
|
|
54
|
-
the artifact reachable before the runtime consumer calls it.
|
|
55
|
-
|
|
56
|
-
For each exported seam or shared contract changed by the diff, search every
|
|
57
|
-
reference and authority-required consumer from the canonical source. Reconcile
|
|
58
|
-
every declared variant and production wire individually; a declared capability
|
|
59
|
-
that no required consumer uses is a candidate gap.
|
|
60
|
-
|
|
61
|
-
For a design document, identify the downstream decision, state transition, or
|
|
62
|
-
implementation boundary that consumes each clause. Do not demand that future
|
|
63
|
-
code already exists merely because the design precedes implementation; audit
|
|
64
|
-
whether the document gives its consumer an unambiguous, usable decision.
|
|
65
|
-
|
|
66
|
-
## 3. Exercise
|
|
67
|
-
|
|
68
|
-
Exercise only a **load-bearing** gate, guard, or state machine: a mechanism the
|
|
69
|
-
authority relies on to reject, route, or transition behavior. Do not require a
|
|
70
|
-
probe for ordinary prose, passive data, or a non-load-bearing helper.
|
|
71
|
-
|
|
72
|
-
When safe and runnable:
|
|
73
|
-
|
|
74
|
-
1. choose the input/state the mechanism is required to handle;
|
|
75
|
-
2. run the real entry path or the narrowest faithful probe;
|
|
76
|
-
3. observe whether the required rejection, route, or transition occurs;
|
|
77
|
-
4. record the command, injected condition, and result.
|
|
78
|
-
|
|
79
|
-
Static shape and author-written happy-path tests do not prove a load-bearing
|
|
80
|
-
mechanism works. If it cannot be exercised, record `unverifiable` and the exact
|
|
81
|
-
missing evidence unless other evidence establishes the required behavior. Do
|
|
82
|
-
not manufacture a gap beyond the authority.
|
|
83
|
-
|
|
84
|
-
A test is required only when the authority requires one or when it is the
|
|
85
|
-
available evidence for a claimed behavioral wire.
|
|
86
|
-
|
|
87
|
-
## 4. Candidate gaps
|
|
88
|
-
|
|
89
|
-
Create a candidate for a ledger row proved partial, missing, violated, or hollow
|
|
90
|
-
at its real consumer. Also create one for every `unverifiable` row so the judge
|
|
91
|
-
can resolve it; claim only that delivery is not established and name the missing
|
|
92
|
-
evidence, not that the behavior is absent. Each candidate contains:
|
|
93
|
-
|
|
94
|
-
```text
|
|
95
|
-
location: nearest actual affected or expected consumer path:line
|
|
96
|
-
claim: what required delivery is absent, contradicted, hollow, or not yet established
|
|
97
|
-
failure scenario: trigger → consumer/path → wrong effect, or required path/effect still unproved
|
|
98
|
-
authority: repository path:line or task-packet source-label:line + governing clause
|
|
99
|
-
evidence: ledger row, files read, commands/probes, and observed result
|
|
100
|
-
severity_hint: impact if the judge establishes the gap
|
|
101
|
-
remedy: optional; omit when uncertain
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
Even an absence needs both real anchors: the authority repository `path:line` or
|
|
105
|
-
task-packet `source-label:line` that requires the behavior, and the nearest
|
|
106
|
-
affected/expected consumer `path:line`. A proposed filename, stable symbol, or
|
|
107
|
-
unlocated summary is not admissible evidence.
|
|
108
|
-
|
|
109
|
-
Check the project's constitution as authority. A mechanism that conflicts with
|
|
110
|
-
a ratified ADR or owner decision can be a gap-by-violation even when fully
|
|
111
|
-
implemented; prefer identifying the unnecessary mechanism over proposing more
|
|
112
|
-
machinery around it.
|
|
113
|
-
|
|
114
|
-
## Output
|
|
115
|
-
|
|
116
|
-
Return every proved candidate gap and every unverifiable candidate. If none
|
|
117
|
-
exist, state that outcome. Keep the private clause ledger and coverage work
|
|
118
|
-
internal. The judge owns the terminal verdict and every later action.
|