@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.
Files changed (60) hide show
  1. package/README.md +4 -3
  2. package/README.zh-CN.md +5 -4
  3. package/THIRD_PARTY_NOTICES.md +8 -6
  4. package/dist/acp-host/production-host.js +249 -624
  5. package/dist/headless-host/production-host.js +251 -626
  6. package/dist/migrate-book-topology.js +23 -6
  7. package/dist/package-resources/method-skill.js +6 -1
  8. package/dist/pi/role-turn-host.js +3 -1
  9. package/dist/public-cli/invocation.js +83 -32
  10. package/dist/public-cli/main.js +240 -306
  11. package/dist/public-cli/option-definitions.js +23 -6
  12. package/dist/public-cli/post-admission.js +0 -4
  13. package/dist/public-cli/run-lifecycle.js +25 -4
  14. package/dist/public-cli/settlement.js +6 -77
  15. package/dist/role-activation-flags.js +1 -0
  16. package/extensions/role-runtime.ts +3 -5
  17. package/package.json +1 -1
  18. package/resources/836-deleted-machine-instruction-inventory.md +1 -1
  19. package/resources/methods/ak-cross-m-review/CONTEXT.md +48 -0
  20. package/resources/methods/ak-cross-m-review/LICENSE +21 -0
  21. package/resources/methods/ak-cross-m-review/SKILL.md +170 -0
  22. package/resources/methods/ak-cross-m-review/prompts/cmr-completeness.md +118 -0
  23. package/resources/methods/ak-cross-m-review/prompts/cmr-reviewer.md +128 -0
  24. package/resources/methods/ak-cross-m-review/provenance.json +41 -0
  25. package/souls/judge.md +1 -1
  26. package/souls/reviewer.md +1 -1
  27. package/src/archivist-record-entry.ts +1 -1
  28. package/src/canonical-skill-binding.ts +2 -2
  29. package/src/host-contracts.ts +2 -0
  30. package/src/package-contracts/reviewer-output.ts +4 -2
  31. package/src/package-resources/method-skill.ts +7 -2
  32. package/src/pi/role-turn-host.ts +3 -1
  33. package/src/public-cli/invocation.ts +108 -39
  34. package/src/public-cli/option-definitions.ts +23 -6
  35. package/src/public-cli/post-admission.ts +0 -4
  36. package/src/public-cli/reviewer-run.ts +39 -16
  37. package/src/public-cli/run-lifecycle.ts +33 -3
  38. package/src/public-cli/settlement.ts +8 -73
  39. package/src/reviewer-role.ts +27 -16
  40. package/src/role-activation-flags.ts +1 -0
  41. package/src/role-runtime-dependencies.ts +2 -4
  42. package/src/role-runtime.ts +9 -26
  43. package/src/worker-role.ts +1 -1
  44. package/dist/adr-path-refs.js +0 -23
  45. package/dist/public-cli/reviewer-dispatch-rejection.js +0 -77
  46. package/dist/reviewer-dispatch.js +0 -14
  47. package/dist/reviewer-git-snapshot.js +0 -32
  48. package/dist/reviewer-pinned-git.js +0 -308
  49. package/dist/reviewer-preflight-error.js +0 -15
  50. package/dist/reviewer-prompt-identity.js +0 -10
  51. package/resources/methods/code-review/SKILL.md +0 -92
  52. package/resources/methods/code-review/agents/openai.yaml +0 -3
  53. package/resources/methods/code-review/provenance.json +0 -26
  54. package/src/adr-path-refs.ts +0 -25
  55. package/src/public-cli/reviewer-dispatch-rejection.ts +0 -106
  56. package/src/reviewer-dispatch.ts +0 -39
  57. package/src/reviewer-git-snapshot.ts +0 -45
  58. package/src/reviewer-pinned-git.ts +0 -330
  59. package/src/reviewer-preflight-error.ts +0 -14
  60. package/src/reviewer-prompt-identity.ts +0 -17
@@ -546,18 +546,32 @@ const REVIEWER_OPTIONS = [
546
546
  zh: "必填;钉住审查目标的 fixed-point revision。",
547
547
  },
548
548
  },
549
+ {
550
+ id: "lens",
551
+ owner: "reviewer",
552
+ canonical: "--lens",
553
+ aliases: [],
554
+ valueMetavar: "completeness|correctness",
555
+ required: true,
556
+ repeatable: false,
557
+ form: "option",
558
+ description: {
559
+ en: "Required single review lens: completeness or correctness (no default).",
560
+ zh: "必填单 lens:completeness 或 correctness(无默认值)。",
561
+ },
562
+ },
549
563
  {
550
564
  id: "authority-ref",
551
565
  owner: "reviewer",
552
566
  canonical: "--authority-ref",
553
567
  aliases: [],
554
568
  valueMetavar: "ref",
555
- required: false,
569
+ required: true,
556
570
  repeatable: true,
557
571
  form: "option",
558
572
  description: {
559
- en: "Durable authority reference/URL (repeatable; refs only, not inline prose).",
560
- zh: "持久 authority 引用/URL(可重复;仅 ref,非内联散文)。",
573
+ en: "Required durable authority reference/URL (repeatable; refs only, not inline prose).",
574
+ zh: "必填持久 authority 引用/URL(可重复;仅 ref,非内联散文)。",
561
575
  },
562
576
  },
563
577
  ] as const satisfies readonly PublicOptionDefinition[];
@@ -1213,10 +1227,13 @@ const ROLE_COMMAND_HELP = {
1213
1227
  },
1214
1228
  reviewer: {
1215
1229
  command: "reviewer",
1216
- summary: "Fixed-target two-axis review (Standards + Spec).",
1217
- usage: ["ak-role reviewer --base <revision> [options] <instruction>"],
1230
+ summary: "Fixed-target single-lens review (completeness or correctness).",
1231
+ usage: [
1232
+ "ak-role reviewer --base <revision> --lens completeness|correctness --authority-ref <ref> [options] <instruction>",
1233
+ ],
1218
1234
  examples: [
1219
- 'ak-role reviewer --base main "Review the branch against the governing issue and repository authority."',
1235
+ 'ak-role reviewer --base main --lens completeness --authority-ref docs/adr/0001.md "Review the branch."',
1236
+ 'ak-role reviewer --base main --lens correctness --authority-ref CLAUDE.md --authority-ref docs/adr/0001.md',
1220
1237
  ],
1221
1238
  },
1222
1239
  collector: {
@@ -87,7 +87,6 @@ import {
87
87
  type WriterLeaseDiagnosticKind,
88
88
  } from "./run-lifecycle.ts";
89
89
  import { homeFromRunDirectory } from "../activation-ledger-topology.ts";
90
- import { clearReviewerDispatchRejection } from "./reviewer-dispatch-rejection.ts";
91
90
  import {
92
91
  attemptProducedFreshSubmission,
93
92
  classifyPostAdmissionFailure,
@@ -698,9 +697,6 @@ export async function dispatchPostAdmissionTurn<
698
697
  }
699
698
 
700
699
  await clearTypedProviderHttpObservation(admitted.runDirectory);
701
- // Per-attempt hygiene: stale Reviewer rejection pages must not ride into
702
- // auto-resume. ENOENT-safe for every seat.
703
- await clearReviewerDispatchRejection(admitted.runDirectory);
704
700
  // The authoritative host write (markRunRunning) is delayed to just before
705
701
  // executeTurn — not merely past beforeDispatch (#840 r9 判词 class 2). Any
706
702
  // pre-turn retry (beforeDispatch, dossier projection, continuation
@@ -1,6 +1,6 @@
1
1
  /**
2
- * Public Reviewer Role run: admit → post-admission coordinator → settle Terminal result (#111 / #517).
3
- * Package-owned adapted code-review method is forced; users never submit
2
+ * Public Reviewer Role run: admit → post-admission coordinator → settle Terminal result (#917 / #517).
3
+ * Package-owned ak-cross-m-review method is forced; users never submit
4
4
  * extra packets. Controlled-failure settlement reuses #107.
5
5
  * #526: execution via RoleTurnHost; argv is Pi adapter internal.
6
6
  */
@@ -10,7 +10,11 @@ import type {
10
10
  RoleTurnKnownFailure,
11
11
  RoleTurnRequest,
12
12
  } from "../host-contracts.ts";
13
- import { engineSessionMaterialFromOptions, pickEngineAxis } from "../package-resources/engine-material.ts";
13
+ import {
14
+ appendEngineSessionMaterial,
15
+ engineSessionMaterialFromOptions,
16
+ pickEngineAxis,
17
+ } from "../package-resources/engine-material.ts";
14
18
  import {
15
19
  loadPackagedMethodSkillMaterial,
16
20
  resolvePackagedMethodSkillPath,
@@ -22,11 +26,12 @@ import {
22
26
  admitReviewerInvocation,
23
27
  buildReviewerTransportPrompt,
24
28
  type AdmittedReviewerInvocation,
29
+ type ReviewerLens,
25
30
  } from "./invocation.ts";
26
31
  import {
27
32
  loadResumableReviewerRun,
28
33
  markRunAdmitted,
29
- buildResumeContinuationPrompt,
34
+ RESUME_TRANSPORT_ENVELOPE,
30
35
  type PublicResumeRequest,
31
36
  } from "./run-lifecycle.ts";
32
37
  import {
@@ -55,7 +60,7 @@ export type ReviewerRunEnv = PostAdmissionEnv & {
55
60
  };
56
61
 
57
62
  function reviewerMethods(packageRoot: string): readonly MethodBinding[] {
58
- return [{ kind: "skill", path: resolvePackagedMethodSkillPath(packageRoot, "code-review") }];
63
+ return [{ kind: "skill", path: resolvePackagedMethodSkillPath(packageRoot, "ak-cross-m-review") }];
59
64
  }
60
65
 
61
66
  /** Project admitted Reviewer invocation onto the host-neutral turn request. */
@@ -69,6 +74,7 @@ export function buildReviewerTurnRequest(
69
74
  activation: {
70
75
  role: "reviewer",
71
76
  baseRevision: admitted.baseRevision,
77
+ lens: admitted.lens,
72
78
  authorityRefs: admitted.authorityRefs,
73
79
  ...(admitted.ticketNumber === undefined ? {} : { ticketNumber: admitted.ticketNumber }),
74
80
  },
@@ -94,7 +100,7 @@ function reviewerAdapters(
94
100
  methodSkillPath: methodMaterial.skillPath,
95
101
  methodSkillConfiguredPath: resolvePackagedMethodSkillPath(
96
102
  packageRoot,
97
- "code-review",
103
+ "ak-cross-m-review",
98
104
  ),
99
105
  },
100
106
  scope,
@@ -119,7 +125,20 @@ function reviewerAdapters(
119
125
  async function loadReviewerMethodMaterial(
120
126
  packageRoot: string,
121
127
  ): Promise<PackagedMethodSkillMaterial> {
122
- return await loadPackagedMethodSkillMaterial(packageRoot, "code-review");
128
+ return await loadPackagedMethodSkillMaterial(packageRoot, "ak-cross-m-review");
129
+ }
130
+
131
+ /** Continue the existing method turn; frozen axes remain on typed activation fields. */
132
+ function reviewerResumePrompt(env: ReviewerRunEnv, message?: string): string {
133
+ const lines: string[] = [RESUME_TRANSPORT_ENVELOPE];
134
+ if (message !== undefined) lines.push("", message);
135
+ return appendEngineSessionMaterial(
136
+ lines,
137
+ engineSessionMaterialFromOptions({
138
+ ...pickEngineAxis(env),
139
+ packageRoot: env.packageRoot,
140
+ }),
141
+ ).join("\n");
123
142
  }
124
143
 
125
144
  export async function runPublicReviewer(
@@ -130,6 +149,7 @@ export async function runPublicReviewer(
130
149
  instruction: string;
131
150
  attachmentPaths: string[];
132
151
  baseRevision: string;
152
+ lens: ReviewerLens;
133
153
  authorityRefs: string[];
134
154
  project?: string;
135
155
  },
@@ -148,6 +168,7 @@ export async function runPublicReviewer(
148
168
  instruction: parsed.instruction,
149
169
  attachmentPaths: parsed.attachmentPaths,
150
170
  baseRevision: parsed.baseRevision,
171
+ lens: parsed.lens,
151
172
  authorityRefs: parsed.authorityRefs,
152
173
  ...(parsed.project === undefined ? {} : { project: parsed.project }),
153
174
  ...(env.createRunId === undefined ? {} : { createRunId: env.createRunId }),
@@ -220,10 +241,7 @@ export async function runPublicReviewer(
220
241
  : { correlationId: admitted.correlationId ?? env.correlationId }),
221
242
  continuation: {
222
243
  kind: "resume",
223
- prompt: buildResumeContinuationPrompt({
224
- packageRoot: env.packageRoot,
225
- ...pickEngineAxis(env),
226
- }),
244
+ prompt: reviewerResumePrompt(env),
227
245
  },
228
246
  }),
229
247
  adapters: reviewerAdapters(env.packageRoot, methodMaterial),
@@ -250,11 +268,16 @@ export async function runPublicReviewerResume(
250
268
  io,
251
269
  load: (effective) =>
252
270
  loadResumableReviewerRun(env.home, effective.runId, env.principalAuthority),
253
- buildTurnRequest: (admitted, effective) =>
254
- buildReviewerTurnRequest(
255
- admitted,
256
- resumeTurnRequestProjectionOptions(admitted, effective, env),
257
- ),
271
+ buildTurnRequest: (admitted, effective) => {
272
+ const base = resumeTurnRequestProjectionOptions(admitted, effective, env);
273
+ return buildReviewerTurnRequest(admitted, {
274
+ ...base,
275
+ continuation: {
276
+ kind: "resume",
277
+ prompt: reviewerResumePrompt(env, effective.message),
278
+ },
279
+ });
280
+ },
258
281
  adapters: reviewerAdapters(env.packageRoot),
259
282
  afterAdmittedLoad: (admitted) =>
260
283
  resolveResumeMethodMaterialAdapters({
@@ -50,6 +50,7 @@ import type { PublicThinkingLevel } from "./registry.ts";
50
50
  import {
51
51
  recordEffectiveInvocationModel,
52
52
  requireAuthorityRef,
53
+ isReviewerLens,
53
54
  type AdmittedCoderInvocation,
54
55
  type AdmittedCountersignInvocation,
55
56
  type AdmittedCollectorInvocation,
@@ -69,6 +70,7 @@ import {
69
70
  type DerivedMergerEnvelope,
70
71
  type FrozenAttachment,
71
72
  type InvocationEffectiveModel,
73
+ type ReviewerLens,
72
74
  } from "./invocation.ts";
73
75
 
74
76
  /** Providers eligible for v1 typed-429 resume (Codex / xAI only).
@@ -1194,6 +1196,7 @@ type LoadedAdmittedRequestFields = {
1194
1196
  readonly prerequisitesPath?: string;
1195
1197
  readonly prerequisites?: readonly FixerPrerequisite[];
1196
1198
  readonly baseRevision?: string;
1199
+ readonly lens?: ReviewerLens;
1197
1200
  readonly authorityRefs?: readonly string[];
1198
1201
  readonly mergerInputPath?: string;
1199
1202
  readonly derived?: DerivedMergerEnvelope;
@@ -1373,6 +1376,7 @@ async function loadResumableRunRecord(
1373
1376
  let prerequisitesPath: string | undefined;
1374
1377
  let prerequisites: readonly FixerPrerequisite[] | undefined;
1375
1378
  let baseRevision: string | undefined;
1379
+ let lens: ReviewerLens | undefined;
1376
1380
  let authorityRefs: readonly string[] | undefined;
1377
1381
  let mergerInputPath: string | undefined;
1378
1382
  let derived: DerivedMergerEnvelope | undefined;
@@ -1432,6 +1436,9 @@ async function loadResumableRunRecord(
1432
1436
  ) {
1433
1437
  baseRevision = record.baseRevision;
1434
1438
  }
1439
+ if (isReviewerLens(record.lens)) {
1440
+ lens = record.lens;
1441
+ }
1435
1442
  // Collector — admitted repository/PR identity (#633 resume).
1436
1443
  if (typeof record.prNumber === "number" && Number.isSafeInteger(record.prNumber) && record.prNumber >= 1) {
1437
1444
  prNumber = record.prNumber;
@@ -1626,6 +1633,7 @@ async function loadResumableRunRecord(
1626
1633
  ...(prerequisitesPath === undefined ? {} : { prerequisitesPath }),
1627
1634
  ...(prerequisites === undefined ? {} : { prerequisites }),
1628
1635
  ...(baseRevision === undefined ? {} : { baseRevision }),
1636
+ ...(lens === undefined ? {} : { lens }),
1629
1637
  ...(authorityRefs === undefined ? {} : { authorityRefs }),
1630
1638
  ...(mergerInputPath === undefined ? {} : { mergerInputPath }),
1631
1639
  ...(derived === undefined ? {} : { derived }),
@@ -1879,17 +1887,39 @@ export async function loadResumableReviewerRun(
1879
1887
  `role run ${runId} belongs to ${loaded.run.role}, not reviewer`,
1880
1888
  );
1881
1889
  }
1882
- const baseRevision = loaded.admittedFields.baseRevision;
1883
- if (baseRevision === undefined || baseRevision.trim() === "") {
1890
+ // Durable restore keeps run identity — never rebrand record damage as fresh --base/--lens.
1891
+ const rawBase = loaded.admittedFields.baseRevision;
1892
+ if (rawBase === undefined || rawBase.trim() === "") {
1884
1893
  throw new CliUsageError(
1885
1894
  `role run admitted reviewer base revision is missing: ${runId}`,
1886
1895
  );
1887
1896
  }
1897
+ if (/\s/.test(rawBase) || rawBase.startsWith("-")) {
1898
+ throw new CliUsageError(
1899
+ `role run admitted reviewer base revision is damaged: ${runId}`,
1900
+ );
1901
+ }
1902
+ const baseRevision = rawBase;
1903
+ const lens = loaded.admittedFields.lens;
1904
+ if (!isReviewerLens(lens)) {
1905
+ throw new CliUsageError(
1906
+ `role run admitted reviewer lens is missing: ${runId}`,
1907
+ );
1908
+ }
1909
+ const authorityRefs = Object.freeze([
1910
+ ...(loaded.admittedFields.authorityRefs ?? []),
1911
+ ]);
1912
+ if (authorityRefs.length === 0) {
1913
+ throw new CliUsageError(
1914
+ `role run admitted reviewer authority refs are missing: ${runId}`,
1915
+ );
1916
+ }
1888
1917
  const admitted: AdmittedReviewerInvocation = {
1889
1918
  role: "reviewer",
1890
1919
  ...resumedBaseAdmitted(loaded),
1891
1920
  baseRevision,
1892
- authorityRefs: Object.freeze([...(loaded.admittedFields.authorityRefs ?? [])]),
1921
+ lens,
1922
+ authorityRefs,
1893
1923
  };
1894
1924
  return seatLoadedResult(loaded, admitted);
1895
1925
  }
@@ -26,7 +26,6 @@ import { DOCTOR_AUDIT_TOOL_NAME } from "../doctor-auditor.ts";
26
26
  import { JUDGE_AUDIT_TOOL_NAME } from "../judge-auditor.ts";
27
27
  import type { RoleTurnKnownFailure } from "../host-contracts.ts";
28
28
  import { knownFailureFromProviderStop } from "../pi/known-failure.ts";
29
- import { readReviewerDispatchRejection } from "./reviewer-dispatch-rejection.ts";
30
29
  import {
31
30
  isV1ResumableProvider,
32
31
  readLatestTypedProviderHttpObservation,
@@ -978,7 +977,7 @@ export function extractSessionProviderStop(
978
977
  if (entry?.type !== "message") continue;
979
978
  const message = entry.message;
980
979
  if (message?.role !== "assistant") continue;
981
- // Latest assistant in the current attempt only (reviewer-child-executor lastAssistant pattern).
980
+ // Latest assistant in the current attempt only.
982
981
  return sessionProviderStopFromAssistant(message);
983
982
  }
984
983
  return undefined;
@@ -1032,45 +1031,6 @@ export async function readSessionProviderStop(
1032
1031
  }
1033
1032
  }
1034
1033
 
1035
- /**
1036
- * Recover a provider stop from Reviewer fixed-axis evidence children bound to this parent.
1037
- * Dispatch runs during activation before the parent model turn; leg failures leave durable
1038
- * stops under session/evidence-children/ and must not wash into generic activation.
1039
- */
1040
- export async function readBoundEvidenceChildKnownFailure(
1041
- sessionFile: string,
1042
- ): Promise<RoleTurnKnownFailure | undefined> {
1043
- const childDirectory = join(dirname(sessionFile), "evidence-children");
1044
- let names: string[];
1045
- try {
1046
- names = await readdir(childDirectory);
1047
- } catch (error) {
1048
- if (isMissingPathError(error)) return undefined;
1049
- throw sessionReadFailure(error, "failed to read bound evidence-child session directory");
1050
- }
1051
- for (const file of names.filter((name) => name.endsWith(".jsonl")).sort().reverse()) {
1052
- let entries: SessionEntry[];
1053
- try {
1054
- entries = await readBoundSessionEntries(join(childDirectory, file));
1055
- } catch (error) {
1056
- throw sessionReadFailure(error, "failed to read discovered evidence-child session");
1057
- }
1058
- const header = entries.find((entry) => entry.type === "session");
1059
- if (!isRecord(header) || header.parentSession !== sessionFile) continue;
1060
- const stop = extractSessionProviderStop(entries);
1061
- if (stop === undefined) continue;
1062
- const primary = knownFailureFromProviderStop(stop)!;
1063
- return {
1064
- ...primary,
1065
- details: {
1066
- ...(primary.details ?? {}),
1067
- secondaryEvidence: "evidence-child",
1068
- },
1069
- };
1070
- }
1071
- return undefined;
1072
- }
1073
-
1074
1034
  type BoundAuditorVolume = {
1075
1035
  readonly entries: SessionEntry[];
1076
1036
  readonly attemptEntryId?: string;
@@ -1309,23 +1269,10 @@ export async function resolveAuditedRunnerFailureResolution(input: {
1309
1269
  runner: RoleTurnKnownFailure | undefined;
1310
1270
  sessionFile: string;
1311
1271
  credential: RoleTurnKnownFailure | undefined;
1312
- /** Reviewer only: recover child-written rejection page into knownFailure.details. */
1272
+ /** Optional run directory for typed provider HTTP observation (resume/429). */
1313
1273
  runDirectory?: string;
1314
1274
  }): Promise<AuditedRunnerFailureResolution> {
1315
1275
  if (input.runner !== undefined) return resolutionOf(input.runner);
1316
- if (input.runDirectory !== undefined) {
1317
- try {
1318
- const rejection = await readReviewerDispatchRejection(input.runDirectory);
1319
- if (rejection !== undefined) return resolutionOf(rejection);
1320
- } catch (error) {
1321
- const failure = error instanceof Error ? error : new Error(String(error));
1322
- return resolutionOf({
1323
- cause: "activation",
1324
- identity: thrownIdentity(failure),
1325
- diagnostic: failure.message || failure.name,
1326
- });
1327
- }
1328
- }
1329
1276
  // Bound auditor compliance-failure retention outranks a parent failure that the
1330
1277
  // auditor path itself caused (retention EISDIR race). A typed terminating-tool
1331
1278
  // host failure is next — it outranks weaker auditor provider-stop fallback so
@@ -1367,20 +1314,7 @@ export async function resolveAuditedRunnerFailureResolution(input: {
1367
1314
  diagnostic: failure.message || failure.name,
1368
1315
  });
1369
1316
  }
1370
- // Reviewer axis evidence-children are next: fixed two-axis dispatch fails
1371
- // during activation with only child stops durable. Parent stop remains the
1372
- // fallback; credential is last.
1373
- try {
1374
- const evidenceChildFailure = await readBoundEvidenceChildKnownFailure(input.sessionFile);
1375
- if (evidenceChildFailure !== undefined) return resolutionOf(evidenceChildFailure);
1376
- } catch (error) {
1377
- const failure = sessionReadFailure(error, "failed to recover bound evidence-child failure");
1378
- return resolutionOf({
1379
- cause: "session",
1380
- identity: thrownIdentity(failure),
1381
- diagnostic: failure.message || failure.name,
1382
- });
1383
- }
1317
+ // Parent session provider-stop is next; credential is last.
1384
1318
  const parentStop = await readSessionProviderStop(input.sessionFile);
1385
1319
  // Typed HTTP observation: ENOENT=absence; other read/parse/shape failures keep real cause.
1386
1320
  // This is the single sidecar read for both knownFailure projection and v1 resume.
@@ -1437,7 +1371,7 @@ export async function resolveAuditedRunnerKnownFailure(input: {
1437
1371
  runner: RoleTurnKnownFailure | undefined;
1438
1372
  sessionFile: string;
1439
1373
  credential: RoleTurnKnownFailure | undefined;
1440
- /** Reviewer only: recover child-written rejection page into knownFailure.details. */
1374
+ /** Optional run directory for typed provider HTTP observation (resume/429). */
1441
1375
  runDirectory?: string;
1442
1376
  }): Promise<RoleTurnKnownFailure | undefined> {
1443
1377
  return (await resolveAuditedRunnerFailureResolution(input)).knownFailure;
@@ -3527,7 +3461,7 @@ export async function trySettleFixerTerminalResult(
3527
3461
  }
3528
3462
 
3529
3463
  /**
3530
- * Observe forced Reviewer code-review Skill expansions from the session.
3464
+ * Observe forced Reviewer ak-cross-m-review Skill expansions from the session.
3531
3465
  * Expansion evidence is package-path only; ambient home locations never count.
3532
3466
  */
3533
3467
  export function extractReviewerMethodInvocations(
@@ -3544,7 +3478,7 @@ export function extractReviewerMethodInvocations(
3544
3478
  const text = sessionMessageText(message);
3545
3479
  if (text.length === 0) continue;
3546
3480
  const hit = observePackagedMethodSkillInvocation(text, {
3547
- name: "code-review",
3481
+ name: "ak-cross-m-review",
3548
3482
  allowedLocations: options.allowedLocations,
3549
3483
  });
3550
3484
  if (hit !== undefined) observed.push(hit);
@@ -3554,7 +3488,7 @@ export function extractReviewerMethodInvocations(
3554
3488
 
3555
3489
  /**
3556
3490
  * Publish lawful Reviewer success Artifacts on the shared #106 success interface.
3557
- * Evidence records package code-review provenance and typed expansion
3491
+ * Evidence records package ak-cross-m-review provenance and typed expansion
3558
3492
  * observation without ambient home Skill paths.
3559
3493
  */
3560
3494
  export async function publishReviewerArtifacts(
@@ -3593,6 +3527,7 @@ export async function publishReviewerArtifacts(
3593
3527
  sessionFile: coordinates.sessionFile,
3594
3528
  admittedRequestPath: admitted.admittedRequestPath,
3595
3529
  baseRevision: admitted.baseRevision,
3530
+ lens: admitted.lens,
3596
3531
  authorityRefs: [...admitted.authorityRefs],
3597
3532
  ...(admitted.instructionEmpty
3598
3533
  ? {}
@@ -5,33 +5,45 @@ import { withTerminatingOutputDeclarations } from "./package-contracts/terminati
5
5
 
6
6
  import type { AnyCanonicalSkillBinding, CanonicalSkillBinding } from "./canonical-skill-binding.ts";
7
7
  export type { CanonicalSkillBinding };
8
- import { type ReviewerPinnedGitReader } from "./reviewer-pinned-git.ts";
9
8
  import { REVIEWER_ACCEPTED_TEXT, REVIEWER_OUTPUT_TOOL_NAME, type ReviewerIntent } from "./package-contracts/reviewer-output.ts";
10
9
 
11
10
  export { REVIEWER_OUTPUT_TOOL_NAME };
12
11
  export type { ReviewerIntent };
13
- export const AGENT_TOOL_NAME = "Agent";
14
12
 
15
13
  /** Frozen admitted inputs the behavior layer may consume — no flag surface. */
16
14
  export type ReviewerAdmittedInputs = Readonly<{
17
15
  baseRevision: string;
18
- reviewScopeKeys?: readonly string[];
16
+ /** Caller-selected single lens; required, no default. */
17
+ lens: "completeness" | "correctness";
19
18
  authorityRefs?: readonly string[];
20
19
  /** Typed #176 ticketNumber from admitted invocation (Spec self-fetch primary). */
21
20
  ticketNumber?: number;
22
21
  }>;
23
22
 
24
23
  const reviewerAmendmentsSchema = Type.Object({
25
- standards: Type.Optional(Type.String({ description: "标准轴弹章正文" })),
26
- spec: Type.Optional(Type.String({ description: "规格轴弹章正文" })),
27
- }, { additionalProperties: true, description: "逐轴弹章正文;无弹章的轴可省略。" });
24
+ completeness: Type.Optional(Type.String({
25
+ description:
26
+ "completeness lens 完整报告:candidates、逐条处置与 verdict;非仅 verdict 一行。hard-stop/usage error 为 refused 时,若已产出报告仍照录于此",
27
+ })),
28
+ correctness: Type.Optional(Type.String({
29
+ description:
30
+ "correctness lens 完整报告:candidates、逐条处置与 verdict;非仅 verdict 一行。hard-stop/usage error 为 refused 时,若已产出报告仍照录于此",
31
+ })),
32
+ }, {
33
+ additionalProperties: true,
34
+ description:
35
+ "所选 lens 的 amendments 承载 candidates、逐条处置与 verdict 的完整报告(非仅 verdict 行);未选 lens 可省略。hard-stop/usage error 为 refused 时,已产出报告仍照录进所选 lens 字段。形状指引,非 schema 闸。",
36
+ });
28
37
  // #836 r16 class 1: diagnostic is LLM/human-read narrative content — no code
29
38
  // branches on its length (src/reviewer-role.ts consumer: reviewer content is
30
39
  // returned as submitted, ADR 0057).
31
40
  // #836 (ADR 0003 Amendment): status kept open like countersignStatus
32
41
  // (src/countersign-role.ts) — one shared description across both variants
33
42
  // so openToolObjectFromUnion's identical-declaration collapse drops none of it.
34
- const REVIEWER_STATUS_DESCRIPTION = "completed | refused — 形状指引,非 schema 闸" as const;
43
+ // #917 §6: both normal lens verdicts → completed; hard-stop/usage error → refused
44
+ // (report already produced still lands in selected-lens amendments).
45
+ const REVIEWER_STATUS_DESCRIPTION =
46
+ "completed | refused — 形状指引,非 schema 闸。两种正常 lens verdict(completeness / correctness)均 completed;hard-stop 与 usage error 为 refused(已产出报告仍照录进所选 lens amendments)。" as const;
35
47
  const reviewerOutputVariants = Type.Union([
36
48
  Type.Object({
37
49
  status: Type.Unknown({ description: REVIEWER_STATUS_DESCRIPTION }),
@@ -39,7 +51,7 @@ const reviewerOutputVariants = Type.Union([
39
51
  }, { additionalProperties: false }),
40
52
  Type.Object({
41
53
  status: Type.Unknown({ description: REVIEWER_STATUS_DESCRIPTION }),
42
- diagnostic: Type.String({ description: "拒绝诊断说明" }),
54
+ diagnostic: Type.String({ description: "拒绝诊断说明;hard-stop/usage error 原因进此字段,已产出报告另照录 amendments" }),
43
55
  amendments: Type.Optional(reviewerAmendmentsSchema),
44
56
  }, { additionalProperties: false }),
45
57
  ]);
@@ -48,8 +60,7 @@ export const reviewerOutputSchema = withTerminatingOutputDeclarations(
48
60
  );
49
61
  export type ReviewerRoleDependencies = {
50
62
  loadSoul(): Promise<string>;
51
- loadCanonicalSkillBinding(name: "code-review"): Promise<AnyCanonicalSkillBinding>;
52
- createPinnedGitReader(): Promise<ReviewerPinnedGitReader>;
63
+ loadCanonicalSkillBinding(name: "ak-cross-m-review"): Promise<AnyCanonicalSkillBinding>;
53
64
  };
54
65
  export type ReviewerRoleHostActions = { failInfrastructure(error: unknown, ctx: HostContext, toolCallId?: string): never };
55
66
 
@@ -57,8 +68,8 @@ export type ReviewerRoleHostActions = { failInfrastructure(error: unknown, ctx:
57
68
  export type ReviewerActivation = Readonly<{
58
69
  fixedBaseRevision: string;
59
70
  soul: string;
60
- /** Frozen code-review binding — envelope owns expansion capture against this data. */
61
- skillBinding: CanonicalSkillBinding<"code-review">;
71
+ /** Frozen ak-cross-m-review binding — envelope owns expansion capture against this data. */
72
+ skillBinding: CanonicalSkillBinding<"ak-cross-m-review">;
62
73
  }>;
63
74
 
64
75
  /**
@@ -74,7 +85,7 @@ export function createReviewerRoleRuntime(
74
85
  activate(ctx: HostContext | undefined, admitted: ReviewerAdmittedInputs): Promise<ReviewerActivation>;
75
86
  } {
76
87
  let soul: string | undefined;
77
- let binding: CanonicalSkillBinding<"code-review"> | undefined;
88
+ let binding: CanonicalSkillBinding<"ak-cross-m-review"> | undefined;
78
89
  let registered = false;
79
90
  let fixedBaseRevision: string | undefined;
80
91
 
@@ -83,13 +94,13 @@ export function createReviewerRoleRuntime(
83
94
  soul = (await dependencies.loadSoul()).trim();
84
95
  if (!soul) throw new Error("Reviewer soul is empty");
85
96
  fixedBaseRevision = admitted.baseRevision;
86
- const loaded = await dependencies.loadCanonicalSkillBinding("code-review");
87
- if (loaded.name !== "code-review") throw new Error("Canonical Skill binding loader returned tdd for code-review");
97
+ const loaded = await dependencies.loadCanonicalSkillBinding("ak-cross-m-review");
98
+ if (loaded.name !== "ak-cross-m-review") throw new Error("Canonical Skill binding loader returned tdd for ak-cross-m-review");
88
99
  binding = loaded;
89
100
 
90
101
  if (!registered) {
91
102
  registered = true;
92
- pi.registerTool({ name: REVIEWER_OUTPUT_TOOL_NAME, label: "御史台输出", description: "提交御史台终局回执。本席自调 code-review skill。", promptSnippet: "提交御史台终局回执", parameters: reviewerOutputSchema,
103
+ pi.registerTool({ name: REVIEWER_OUTPUT_TOOL_NAME, label: "御史台输出", description: "提交御史台终局回执。本席自调 ak-cross-m-review skill。", promptSnippet: "提交御史台终局回执", parameters: reviewerOutputSchema,
93
104
  async execute(_id: string, parameters: unknown): Promise<HostToolResult<unknown>> {
94
105
  if (!soul || !binding) throw new Error("御史台输入未装载");
95
106
  return {
@@ -30,6 +30,7 @@ export function projectActivationFlags(request: RoleTurnRequest): Map<string, bo
30
30
  }
31
31
  if (activation.role === "reviewer") {
32
32
  flags.set("ak-review-base", activation.baseRevision);
33
+ flags.set("ak-review-lens", activation.lens);
33
34
  flags.set("ak-review-authority-refs", JSON.stringify(activation.authorityRefs));
34
35
  if (activation.ticketNumber !== undefined) {
35
36
  flags.set("ak-review-ticket-number", String(activation.ticketNumber));
@@ -10,7 +10,6 @@ import { loadNavigatorWorkContext } from "./navigator-work-context.ts";
10
10
  import { loadNotarySourceRunLocator } from "./notary-source-run.ts";
11
11
  import { loadPackagedCanonicalSkillBinding } from "./package-resources/method-skill-binding.ts";
12
12
  import { formatNavigatorRoleHelp, type RoleRuntimeDependencies } from "./role-runtime.ts";
13
- import { createReviewerPinnedGitReader } from "./reviewer-pinned-git.ts";
14
13
  import { loadAuditorSoulFromSubjectInput } from "./auditor-soul.ts";
15
14
  import { loadGatekeeperSessionMaterials, loadMainRoleSessionMaterials } from "./session-opening-materials.ts";
16
15
 
@@ -33,7 +32,6 @@ export function createRoleRuntimeDependencies(packageRoot: string): RoleRuntimeD
33
32
  loadCoderSoul: () => loadMainRoleSessionMaterials("coder"),
34
33
  loadCoderTask: (path) => readFile(path, "utf8"),
35
34
  loadReviewerSoul: () => loadMainRoleSessionMaterials("reviewer"),
36
- createReviewerPinnedGitReader: () => createReviewerPinnedGitReader(),
37
35
  loadCollectorSoul: () => loadMainRoleSessionMaterials("collector"),
38
36
  loadCollectorHandbookSeed: () => readFile(collectorHandbookSeedPath, "utf8"),
39
37
  createCollectorTransport: () => createGhCollectorGitHubTransport(),
@@ -55,8 +53,8 @@ export function createRoleRuntimeDependencies(packageRoot: string): RoleRuntimeD
55
53
  if (name === "tdd") {
56
54
  return loadPackagedCanonicalSkillBinding(packageRoot, "tdd");
57
55
  }
58
- if (name === "code-review") {
59
- return loadPackagedCanonicalSkillBinding(packageRoot, "code-review");
56
+ if (name === "ak-cross-m-review") {
57
+ return loadPackagedCanonicalSkillBinding(packageRoot, "ak-cross-m-review");
60
58
  }
61
59
  return loadHomeCanonicalSkillBinding(name);
62
60
  },