@akagilnc/pi-workflow-roles 0.1.4403 → 0.1.4419
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 +4 -3
- package/README.zh-CN.md +5 -4
- package/THIRD_PARTY_NOTICES.md +8 -6
- package/dist/acp-host/production-host.js +249 -624
- package/dist/headless-host/production-host.js +251 -626
- package/dist/migrate-book-topology.js +23 -6
- package/dist/package-resources/method-skill.js +6 -1
- package/dist/pi/role-turn-host.js +3 -1
- package/dist/public-cli/invocation.js +83 -32
- package/dist/public-cli/main.js +240 -306
- package/dist/public-cli/option-definitions.js +23 -6
- package/dist/public-cli/post-admission.js +0 -4
- package/dist/public-cli/run-lifecycle.js +25 -4
- package/dist/public-cli/settlement.js +6 -77
- package/dist/role-activation-flags.js +1 -0
- package/extensions/role-runtime.ts +3 -5
- package/package.json +1 -1
- package/resources/836-deleted-machine-instruction-inventory.md +1 -1
- package/resources/methods/ak-cross-m-review/CONTEXT.md +48 -0
- package/resources/methods/ak-cross-m-review/LICENSE +21 -0
- package/resources/methods/ak-cross-m-review/SKILL.md +170 -0
- package/resources/methods/ak-cross-m-review/prompts/cmr-completeness.md +118 -0
- package/resources/methods/ak-cross-m-review/prompts/cmr-reviewer.md +128 -0
- package/resources/methods/ak-cross-m-review/provenance.json +41 -0
- package/souls/judge.md +1 -1
- package/souls/reviewer.md +1 -1
- package/src/archivist-record-entry.ts +1 -1
- package/src/canonical-skill-binding.ts +2 -2
- package/src/host-contracts.ts +2 -0
- package/src/package-contracts/reviewer-output.ts +4 -2
- package/src/package-resources/method-skill.ts +7 -2
- package/src/pi/role-turn-host.ts +3 -1
- package/src/public-cli/invocation.ts +108 -39
- package/src/public-cli/option-definitions.ts +23 -6
- package/src/public-cli/post-admission.ts +0 -4
- package/src/public-cli/reviewer-run.ts +39 -16
- package/src/public-cli/run-lifecycle.ts +33 -3
- package/src/public-cli/settlement.ts +8 -73
- package/src/reviewer-role.ts +27 -16
- package/src/role-activation-flags.ts +1 -0
- package/src/role-runtime-dependencies.ts +2 -4
- package/src/role-runtime.ts +9 -26
- package/src/worker-role.ts +1 -1
- package/dist/adr-path-refs.js +0 -23
- package/dist/public-cli/reviewer-dispatch-rejection.js +0 -77
- package/dist/reviewer-dispatch.js +0 -14
- package/dist/reviewer-git-snapshot.js +0 -32
- package/dist/reviewer-pinned-git.js +0 -308
- package/dist/reviewer-preflight-error.js +0 -15
- package/dist/reviewer-prompt-identity.js +0 -10
- package/resources/methods/code-review/SKILL.md +0 -92
- package/resources/methods/code-review/agents/openai.yaml +0 -3
- package/resources/methods/code-review/provenance.json +0 -26
- package/src/adr-path-refs.ts +0 -25
- package/src/public-cli/reviewer-dispatch-rejection.ts +0 -106
- package/src/reviewer-dispatch.ts +0 -39
- package/src/reviewer-git-snapshot.ts +0 -45
- package/src/reviewer-pinned-git.ts +0 -330
- package/src/reviewer-preflight-error.ts +0 -14
- package/src/reviewer-prompt-identity.ts +0 -17
|
@@ -430,18 +430,32 @@ const REVIEWER_OPTIONS = [
|
|
|
430
430
|
zh: "必填;钉住审查目标的 fixed-point revision。",
|
|
431
431
|
},
|
|
432
432
|
},
|
|
433
|
+
{
|
|
434
|
+
id: "lens",
|
|
435
|
+
owner: "reviewer",
|
|
436
|
+
canonical: "--lens",
|
|
437
|
+
aliases: [],
|
|
438
|
+
valueMetavar: "completeness|correctness",
|
|
439
|
+
required: true,
|
|
440
|
+
repeatable: false,
|
|
441
|
+
form: "option",
|
|
442
|
+
description: {
|
|
443
|
+
en: "Required single review lens: completeness or correctness (no default).",
|
|
444
|
+
zh: "必填单 lens:completeness 或 correctness(无默认值)。",
|
|
445
|
+
},
|
|
446
|
+
},
|
|
433
447
|
{
|
|
434
448
|
id: "authority-ref",
|
|
435
449
|
owner: "reviewer",
|
|
436
450
|
canonical: "--authority-ref",
|
|
437
451
|
aliases: [],
|
|
438
452
|
valueMetavar: "ref",
|
|
439
|
-
required:
|
|
453
|
+
required: true,
|
|
440
454
|
repeatable: true,
|
|
441
455
|
form: "option",
|
|
442
456
|
description: {
|
|
443
|
-
en: "
|
|
444
|
-
zh: "
|
|
457
|
+
en: "Required durable authority reference/URL (repeatable; refs only, not inline prose).",
|
|
458
|
+
zh: "必填持久 authority 引用/URL(可重复;仅 ref,非内联散文)。",
|
|
445
459
|
},
|
|
446
460
|
},
|
|
447
461
|
];
|
|
@@ -983,10 +997,13 @@ const ROLE_COMMAND_HELP = {
|
|
|
983
997
|
},
|
|
984
998
|
reviewer: {
|
|
985
999
|
command: "reviewer",
|
|
986
|
-
summary: "Fixed-target
|
|
987
|
-
usage: [
|
|
1000
|
+
summary: "Fixed-target single-lens review (completeness or correctness).",
|
|
1001
|
+
usage: [
|
|
1002
|
+
"ak-role reviewer --base <revision> --lens completeness|correctness --authority-ref <ref> [options] <instruction>",
|
|
1003
|
+
],
|
|
988
1004
|
examples: [
|
|
989
|
-
'ak-role reviewer --base main "Review the branch
|
|
1005
|
+
'ak-role reviewer --base main --lens completeness --authority-ref docs/adr/0001.md "Review the branch."',
|
|
1006
|
+
'ak-role reviewer --base main --lens correctness --authority-ref CLAUDE.md --authority-ref docs/adr/0001.md',
|
|
990
1007
|
],
|
|
991
1008
|
},
|
|
992
1009
|
collector: {
|
|
@@ -38,7 +38,6 @@ import { projectHostTransitionPriorNative } from "../host-transition-prior-nativ
|
|
|
38
38
|
import { missingCredentialPreDispatchFailure, postRunMissingCredentialFailure, } from "./public-run-credentials.js";
|
|
39
39
|
import { acquireRunWriterLease, clearCurrentCourt, clearTypedProviderHttpObservation, describeErrorIdentity, markRunRunning, readCurrentCourt, recordCurrentCourt, renderResumeCommand, RunWriterLeaseHeldError, } from "./run-lifecycle.js";
|
|
40
40
|
import { homeFromRunDirectory } from "../activation-ledger-topology.js";
|
|
41
|
-
import { clearReviewerDispatchRejection } from "./reviewer-dispatch-rejection.js";
|
|
42
41
|
import { attemptProducedFreshSubmission, classifyPostAdmissionFailure, controlledFailureInputFromResolution, exitCodeForTerminalOutcome, explicitInternalKnownFailureClassificationInput, formatCliDiagnostic, formatTerminalResult, inspectJudgeSession, isLawfulTypedTerminalOutcome, presentFailureTerminal, presentStructuralRejection, resolveAuditedRunnerFailureResolution, resolveControlledFailureResumeObservation, settleFailureTerminalResult, settleHostEndedNoReceipt, attachRecordedSubmissions, } from "./settlement.js";
|
|
43
42
|
import {} from "./terminal.js";
|
|
44
43
|
import { ensureRealArtifactsDirectory, persistReturnedRunState, runWithAutoResumeLoop, TurnDispatchedFailure, } from "./auto-resume.js";
|
|
@@ -345,9 +344,6 @@ export async function dispatchPostAdmissionTurn(input) {
|
|
|
345
344
|
};
|
|
346
345
|
}
|
|
347
346
|
await clearTypedProviderHttpObservation(admitted.runDirectory);
|
|
348
|
-
// Per-attempt hygiene: stale Reviewer rejection pages must not ride into
|
|
349
|
-
// auto-resume. ENOENT-safe for every seat.
|
|
350
|
-
await clearReviewerDispatchRejection(admitted.runDirectory);
|
|
351
347
|
// The authoritative host write (markRunRunning) is delayed to just before
|
|
352
348
|
// executeTurn — not merely past beforeDispatch (#840 r9 判词 class 2). Any
|
|
353
349
|
// pre-turn retry (beforeDispatch, dossier projection, continuation
|
|
@@ -16,7 +16,7 @@ export { clearTypedProviderHttpObservation, recordTypedProviderHttpStatus, readL
|
|
|
16
16
|
import { parseCollectorRepository } from "../collector-config.js";
|
|
17
17
|
import { interpretDurableCourtTicketNumbers, sameCourtTicketNumbers, } from "../diarist-contracts.js";
|
|
18
18
|
import { appendEngineSessionMaterial, engineSessionMaterialFromOptions, pickEngineAxis, } from "../package-resources/engine-material.js";
|
|
19
|
-
import { recordEffectiveInvocationModel, requireAuthorityRef, } from "./invocation.js";
|
|
19
|
+
import { recordEffectiveInvocationModel, requireAuthorityRef, isReviewerLens, } from "./invocation.js";
|
|
20
20
|
/** Providers eligible for v1 typed-429 resume (Codex / xAI only).
|
|
21
21
|
* @deprecated v1 429-only gate removed by #416 (owner 2026-08-22: "根本不要有限制"). Kept for compatibility; do not use for new branching.
|
|
22
22
|
*/
|
|
@@ -970,6 +970,7 @@ async function loadResumableRunRecord(home, runId, authority) {
|
|
|
970
970
|
let prerequisitesPath;
|
|
971
971
|
let prerequisites;
|
|
972
972
|
let baseRevision;
|
|
973
|
+
let lens;
|
|
973
974
|
let authorityRefs;
|
|
974
975
|
let mergerInputPath;
|
|
975
976
|
let derived;
|
|
@@ -1023,6 +1024,9 @@ async function loadResumableRunRecord(home, runId, authority) {
|
|
|
1023
1024
|
record.baseRevision.trim() !== "") {
|
|
1024
1025
|
baseRevision = record.baseRevision;
|
|
1025
1026
|
}
|
|
1027
|
+
if (isReviewerLens(record.lens)) {
|
|
1028
|
+
lens = record.lens;
|
|
1029
|
+
}
|
|
1026
1030
|
// Collector — admitted repository/PR identity (#633 resume).
|
|
1027
1031
|
if (typeof record.prNumber === "number" && Number.isSafeInteger(record.prNumber) && record.prNumber >= 1) {
|
|
1028
1032
|
prNumber = record.prNumber;
|
|
@@ -1189,6 +1193,7 @@ async function loadResumableRunRecord(home, runId, authority) {
|
|
|
1189
1193
|
...(prerequisitesPath === undefined ? {} : { prerequisitesPath }),
|
|
1190
1194
|
...(prerequisites === undefined ? {} : { prerequisites }),
|
|
1191
1195
|
...(baseRevision === undefined ? {} : { baseRevision }),
|
|
1196
|
+
...(lens === undefined ? {} : { lens }),
|
|
1192
1197
|
...(authorityRefs === undefined ? {} : { authorityRefs }),
|
|
1193
1198
|
...(mergerInputPath === undefined ? {} : { mergerInputPath }),
|
|
1194
1199
|
...(derived === undefined ? {} : { derived }),
|
|
@@ -1332,15 +1337,31 @@ export async function loadResumableReviewerRun(home, runId, authority) {
|
|
|
1332
1337
|
if (loaded.run.role !== "reviewer") {
|
|
1333
1338
|
throw new CliUsageError(`role run ${runId} belongs to ${loaded.run.role}, not reviewer`);
|
|
1334
1339
|
}
|
|
1335
|
-
|
|
1336
|
-
|
|
1340
|
+
// Durable restore keeps run identity — never rebrand record damage as fresh --base/--lens.
|
|
1341
|
+
const rawBase = loaded.admittedFields.baseRevision;
|
|
1342
|
+
if (rawBase === undefined || rawBase.trim() === "") {
|
|
1337
1343
|
throw new CliUsageError(`role run admitted reviewer base revision is missing: ${runId}`);
|
|
1338
1344
|
}
|
|
1345
|
+
if (/\s/.test(rawBase) || rawBase.startsWith("-")) {
|
|
1346
|
+
throw new CliUsageError(`role run admitted reviewer base revision is damaged: ${runId}`);
|
|
1347
|
+
}
|
|
1348
|
+
const baseRevision = rawBase;
|
|
1349
|
+
const lens = loaded.admittedFields.lens;
|
|
1350
|
+
if (!isReviewerLens(lens)) {
|
|
1351
|
+
throw new CliUsageError(`role run admitted reviewer lens is missing: ${runId}`);
|
|
1352
|
+
}
|
|
1353
|
+
const authorityRefs = Object.freeze([
|
|
1354
|
+
...(loaded.admittedFields.authorityRefs ?? []),
|
|
1355
|
+
]);
|
|
1356
|
+
if (authorityRefs.length === 0) {
|
|
1357
|
+
throw new CliUsageError(`role run admitted reviewer authority refs are missing: ${runId}`);
|
|
1358
|
+
}
|
|
1339
1359
|
const admitted = {
|
|
1340
1360
|
role: "reviewer",
|
|
1341
1361
|
...resumedBaseAdmitted(loaded),
|
|
1342
1362
|
baseRevision,
|
|
1343
|
-
|
|
1363
|
+
lens,
|
|
1364
|
+
authorityRefs,
|
|
1344
1365
|
};
|
|
1345
1366
|
return seatLoadedResult(loaded, admitted);
|
|
1346
1367
|
}
|
|
@@ -14,7 +14,6 @@ import { AUDITOR_SOUL_ROLES } from "../auditor-soul.js";
|
|
|
14
14
|
import { DOCTOR_AUDIT_TOOL_NAME } from "../doctor-auditor.js";
|
|
15
15
|
import { JUDGE_AUDIT_TOOL_NAME } from "../judge-auditor.js";
|
|
16
16
|
import { knownFailureFromProviderStop } from "../pi/known-failure.js";
|
|
17
|
-
import { readReviewerDispatchRejection } from "./reviewer-dispatch-rejection.js";
|
|
18
17
|
import { isV1ResumableProvider, readLatestTypedProviderHttpObservation, readTypedHttp429Observation, } from "./run-lifecycle.js";
|
|
19
18
|
import { AUDITOR_COMPLIANCE_FAILURE_ENTRY_TYPE, AUDITOR_PARENT_ATTEMPT_BINDING_ENTRY_TYPE, COMPLIANCE_RESPONSE_ENTRY_TYPE, readComplianceCandidate, } from "../compliance-transport.js";
|
|
20
19
|
// COMPLIANCE_RESPONSE_ENTRY_TYPE remains for boundRetainedAuditResponse (call/result
|
|
@@ -566,7 +565,7 @@ export function extractSessionProviderStop(entries) {
|
|
|
566
565
|
const message = entry.message;
|
|
567
566
|
if (message?.role !== "assistant")
|
|
568
567
|
continue;
|
|
569
|
-
// Latest assistant in the current attempt only
|
|
568
|
+
// Latest assistant in the current attempt only.
|
|
570
569
|
return sessionProviderStopFromAssistant(message);
|
|
571
570
|
}
|
|
572
571
|
return undefined;
|
|
@@ -619,47 +618,6 @@ export async function readSessionProviderStop(sessionFile) {
|
|
|
619
618
|
return undefined;
|
|
620
619
|
}
|
|
621
620
|
}
|
|
622
|
-
/**
|
|
623
|
-
* Recover a provider stop from Reviewer fixed-axis evidence children bound to this parent.
|
|
624
|
-
* Dispatch runs during activation before the parent model turn; leg failures leave durable
|
|
625
|
-
* stops under session/evidence-children/ and must not wash into generic activation.
|
|
626
|
-
*/
|
|
627
|
-
export async function readBoundEvidenceChildKnownFailure(sessionFile) {
|
|
628
|
-
const childDirectory = join(dirname(sessionFile), "evidence-children");
|
|
629
|
-
let names;
|
|
630
|
-
try {
|
|
631
|
-
names = await readdir(childDirectory);
|
|
632
|
-
}
|
|
633
|
-
catch (error) {
|
|
634
|
-
if (isMissingPathError(error))
|
|
635
|
-
return undefined;
|
|
636
|
-
throw sessionReadFailure(error, "failed to read bound evidence-child session directory");
|
|
637
|
-
}
|
|
638
|
-
for (const file of names.filter((name) => name.endsWith(".jsonl")).sort().reverse()) {
|
|
639
|
-
let entries;
|
|
640
|
-
try {
|
|
641
|
-
entries = await readBoundSessionEntries(join(childDirectory, file));
|
|
642
|
-
}
|
|
643
|
-
catch (error) {
|
|
644
|
-
throw sessionReadFailure(error, "failed to read discovered evidence-child session");
|
|
645
|
-
}
|
|
646
|
-
const header = entries.find((entry) => entry.type === "session");
|
|
647
|
-
if (!isRecord(header) || header.parentSession !== sessionFile)
|
|
648
|
-
continue;
|
|
649
|
-
const stop = extractSessionProviderStop(entries);
|
|
650
|
-
if (stop === undefined)
|
|
651
|
-
continue;
|
|
652
|
-
const primary = knownFailureFromProviderStop(stop);
|
|
653
|
-
return {
|
|
654
|
-
...primary,
|
|
655
|
-
details: {
|
|
656
|
-
...(primary.details ?? {}),
|
|
657
|
-
secondaryEvidence: "evidence-child",
|
|
658
|
-
},
|
|
659
|
-
};
|
|
660
|
-
}
|
|
661
|
-
return undefined;
|
|
662
|
-
}
|
|
663
621
|
async function loadBoundAuditorVolumes(sessionFile) {
|
|
664
622
|
let parentEntries;
|
|
665
623
|
try {
|
|
@@ -865,21 +823,6 @@ function resolutionOf(knownFailure, typedHttp = { settled: false }) {
|
|
|
865
823
|
export async function resolveAuditedRunnerFailureResolution(input) {
|
|
866
824
|
if (input.runner !== undefined)
|
|
867
825
|
return resolutionOf(input.runner);
|
|
868
|
-
if (input.runDirectory !== undefined) {
|
|
869
|
-
try {
|
|
870
|
-
const rejection = await readReviewerDispatchRejection(input.runDirectory);
|
|
871
|
-
if (rejection !== undefined)
|
|
872
|
-
return resolutionOf(rejection);
|
|
873
|
-
}
|
|
874
|
-
catch (error) {
|
|
875
|
-
const failure = error instanceof Error ? error : new Error(String(error));
|
|
876
|
-
return resolutionOf({
|
|
877
|
-
cause: "activation",
|
|
878
|
-
identity: thrownIdentity(failure),
|
|
879
|
-
diagnostic: failure.message || failure.name,
|
|
880
|
-
});
|
|
881
|
-
}
|
|
882
|
-
}
|
|
883
826
|
// Bound auditor compliance-failure retention outranks a parent failure that the
|
|
884
827
|
// auditor path itself caused (retention EISDIR race). A typed terminating-tool
|
|
885
828
|
// host failure is next — it outranks weaker auditor provider-stop fallback so
|
|
@@ -925,22 +868,7 @@ export async function resolveAuditedRunnerFailureResolution(input) {
|
|
|
925
868
|
diagnostic: failure.message || failure.name,
|
|
926
869
|
});
|
|
927
870
|
}
|
|
928
|
-
//
|
|
929
|
-
// during activation with only child stops durable. Parent stop remains the
|
|
930
|
-
// fallback; credential is last.
|
|
931
|
-
try {
|
|
932
|
-
const evidenceChildFailure = await readBoundEvidenceChildKnownFailure(input.sessionFile);
|
|
933
|
-
if (evidenceChildFailure !== undefined)
|
|
934
|
-
return resolutionOf(evidenceChildFailure);
|
|
935
|
-
}
|
|
936
|
-
catch (error) {
|
|
937
|
-
const failure = sessionReadFailure(error, "failed to recover bound evidence-child failure");
|
|
938
|
-
return resolutionOf({
|
|
939
|
-
cause: "session",
|
|
940
|
-
identity: thrownIdentity(failure),
|
|
941
|
-
diagnostic: failure.message || failure.name,
|
|
942
|
-
});
|
|
943
|
-
}
|
|
871
|
+
// Parent session provider-stop is next; credential is last.
|
|
944
872
|
const parentStop = await readSessionProviderStop(input.sessionFile);
|
|
945
873
|
// Typed HTTP observation: ENOENT=absence; other read/parse/shape failures keep real cause.
|
|
946
874
|
// This is the single sidecar read for both knownFailure projection and v1 resume.
|
|
@@ -2369,7 +2297,7 @@ export async function trySettleFixerTerminalResult(admitted, authority, options,
|
|
|
2369
2297
|
return settleLawfulFixerTerminalResult(admitted, authority, options, scope);
|
|
2370
2298
|
}
|
|
2371
2299
|
/**
|
|
2372
|
-
* Observe forced Reviewer
|
|
2300
|
+
* Observe forced Reviewer ak-cross-m-review Skill expansions from the session.
|
|
2373
2301
|
* Expansion evidence is package-path only; ambient home locations never count.
|
|
2374
2302
|
*/
|
|
2375
2303
|
export function extractReviewerMethodInvocations(entries, options) {
|
|
@@ -2384,7 +2312,7 @@ export function extractReviewerMethodInvocations(entries, options) {
|
|
|
2384
2312
|
if (text.length === 0)
|
|
2385
2313
|
continue;
|
|
2386
2314
|
const hit = observePackagedMethodSkillInvocation(text, {
|
|
2387
|
-
name: "
|
|
2315
|
+
name: "ak-cross-m-review",
|
|
2388
2316
|
allowedLocations: options.allowedLocations,
|
|
2389
2317
|
});
|
|
2390
2318
|
if (hit !== undefined)
|
|
@@ -2394,7 +2322,7 @@ export function extractReviewerMethodInvocations(entries, options) {
|
|
|
2394
2322
|
}
|
|
2395
2323
|
/**
|
|
2396
2324
|
* Publish lawful Reviewer success Artifacts on the shared #106 success interface.
|
|
2397
|
-
* Evidence records package
|
|
2325
|
+
* Evidence records package ak-cross-m-review provenance and typed expansion
|
|
2398
2326
|
* observation without ambient home Skill paths.
|
|
2399
2327
|
*/
|
|
2400
2328
|
export async function publishReviewerArtifacts(admitted, roleOutcome, coordinates, options) {
|
|
@@ -2414,6 +2342,7 @@ export async function publishReviewerArtifacts(admitted, roleOutcome, coordinate
|
|
|
2414
2342
|
sessionFile: coordinates.sessionFile,
|
|
2415
2343
|
admittedRequestPath: admitted.admittedRequestPath,
|
|
2416
2344
|
baseRevision: admitted.baseRevision,
|
|
2345
|
+
lens: admitted.lens,
|
|
2417
2346
|
authorityRefs: [...admitted.authorityRefs],
|
|
2418
2347
|
...(admitted.instructionEmpty
|
|
2419
2348
|
? {}
|
|
@@ -25,6 +25,7 @@ export function projectActivationFlags(request) {
|
|
|
25
25
|
}
|
|
26
26
|
if (activation.role === "reviewer") {
|
|
27
27
|
flags.set("ak-review-base", activation.baseRevision);
|
|
28
|
+
flags.set("ak-review-lens", activation.lens);
|
|
28
29
|
flags.set("ak-review-authority-refs", JSON.stringify(activation.authorityRefs));
|
|
29
30
|
if (activation.ticketNumber !== undefined) {
|
|
30
31
|
flags.set("ak-review-ticket-number", String(activation.ticketNumber));
|
|
@@ -15,7 +15,6 @@ import {
|
|
|
15
15
|
import type { Message } from "@earendil-works/pi-ai";
|
|
16
16
|
|
|
17
17
|
import { createGhCollectorGitHubTransport } from "../src/collector-github.ts";
|
|
18
|
-
import { createReviewerPinnedGitReader } from "../src/reviewer-dispatch.ts";
|
|
19
18
|
import { createPiDoctorAuditor } from "../src/doctor-auditor.ts";
|
|
20
19
|
import {
|
|
21
20
|
createNativeNavigatorSessionFactory,
|
|
@@ -118,7 +117,6 @@ export default function roleRuntime(pi: ExtensionAPI): void {
|
|
|
118
117
|
loadCoderSoul: () => loadMainRoleSessionMaterials("coder"),
|
|
119
118
|
loadCoderTask: (path) => readFile(path, "utf8"),
|
|
120
119
|
loadReviewerSoul: () => loadMainRoleSessionMaterials("reviewer"),
|
|
121
|
-
createReviewerPinnedGitReader: () => createReviewerPinnedGitReader(),
|
|
122
120
|
loadCollectorSoul: () => loadMainRoleSessionMaterials("collector"),
|
|
123
121
|
loadCollectorHandbookSeed: () => readFile(collectorHandbookSeedPath, "utf8"),
|
|
124
122
|
createCollectorTransport: () => createGhCollectorGitHubTransport(),
|
|
@@ -159,13 +157,13 @@ export default function roleRuntime(pi: ExtensionAPI): void {
|
|
|
159
157
|
loadMergerSoul: () => loadMainRoleSessionMaterials("merger"),
|
|
160
158
|
loadMergerInput: async (path) => JSON.parse(await readFile(path, "utf8")),
|
|
161
159
|
async loadCanonicalSkillBinding(name) {
|
|
162
|
-
// Coder TDD (#109) and Reviewer
|
|
160
|
+
// Coder TDD (#109) and Reviewer ak-cross-m-review (#917) are package-owned.
|
|
163
161
|
// Optional Fixer diagnosing-bugs is available via --skill without this binding.
|
|
164
162
|
if (name === "tdd") {
|
|
165
163
|
return loadPackagedCanonicalSkillBinding(packageRoot, "tdd");
|
|
166
164
|
}
|
|
167
|
-
if (name === "
|
|
168
|
-
return loadPackagedCanonicalSkillBinding(packageRoot, "
|
|
165
|
+
if (name === "ak-cross-m-review") {
|
|
166
|
+
return loadPackagedCanonicalSkillBinding(packageRoot, "ak-cross-m-review");
|
|
169
167
|
}
|
|
170
168
|
return loadHomeCanonicalSkillBinding(name);
|
|
171
169
|
},
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
| `compliance-transport.ts` `AUDITOR_DOSSIER_PROMPT` | `本 run 卷宗已就绪。` | 改为台院同形路径指针。 |
|
|
10
10
|
| `doctor-role.ts` case catalog | `provenance: "由留存 session 字节推导,封入受理回执。"` | 删。catalog 只留 cost 与证据指针。 |
|
|
11
11
|
| `collector-role.ts` bounceInfrastructure | `请省略该字段后重新提交。` | 代码打回推翻自报已删。 |
|
|
12
|
-
| `reviewer-role.ts` output description | `Standards/Spec 评审腿由 runtime 以取证子会话代跑…` | 改为「本席自调 code-review skill
|
|
12
|
+
| `reviewer-role.ts` output description | `Standards/Spec 评审腿由 runtime 以取证子会话代跑…` | #836 改为「本席自调 code-review skill」。#917 后随包方法为 `ak-cross-m-review`;`resources/methods/code-review/` 已删,现役指针见 `resources/methods/ak-cross-m-review/SKILL.md`。 |
|
|
13
13
|
| `run-lifecycle.ts` A4.1 | `[ak-role:resume-continue]` | 生产码不再含此字面量。结算只跳过空轮与引擎指针续跑。 |
|
|
14
14
|
| `run-lifecycle.ts` A4.2 | `重新读 <path>` | 前轮已删改写。 |
|
|
15
15
|
| `submission-correctable-error.ts` A4.5 | `终局交卷并非本轮唯一工具调用。` | 删。Pi/ACP `deliverSubmissionRejection` 不再注入该句。 |
|
|
@@ -0,0 +1,48 @@
|
|
|
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)
|
|
@@ -0,0 +1,21 @@
|
|
|
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.
|
|
@@ -0,0 +1,170 @@
|
|
|
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.
|