@akagilnc/pi-workflow-roles 0.1.3262 → 0.1.3280

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 (35) hide show
  1. package/README.md +8 -122
  2. package/README.zh-CN.md +9 -123
  3. package/dist/gatekeeper-role.js +22 -16
  4. package/dist/grok/production-host.js +745 -571
  5. package/dist/package-contracts/gatekeeper-output.js +71 -0
  6. package/dist/package-contracts/navigator-output.js +48 -0
  7. package/dist/package-contracts/terminating-tools.js +18 -2
  8. package/dist/packaged-role-registry.js +24 -0
  9. package/dist/public-cli/config.js +7 -21
  10. package/dist/public-cli/main.js +689 -365
  11. package/dist/public-cli/registry.js +2 -14
  12. package/dist/session-opening-materials.js +6 -11
  13. package/extensions/role-runtime.ts +3 -1
  14. package/package.json +1 -1
  15. package/resources/navigator-route-playbook.md +1 -1
  16. package/src/gatekeeper-role.ts +32 -17
  17. package/src/grok/production-host.ts +3 -1
  18. package/src/host-contracts.ts +3 -1
  19. package/src/navigator-role.ts +17 -0
  20. package/src/package-contracts/gatekeeper-output.ts +89 -0
  21. package/src/package-contracts/navigator-output.ts +59 -0
  22. package/src/package-contracts/terminating-tools.ts +24 -2
  23. package/src/packaged-role-registry.ts +25 -2
  24. package/src/pi/role-turn-host.ts +4 -0
  25. package/src/public-cli/cli.ts +37 -10
  26. package/src/public-cli/config.ts +6 -30
  27. package/src/public-cli/instruction-seat-run.ts +147 -0
  28. package/src/public-cli/invocation.ts +47 -3
  29. package/src/public-cli/option-definitions.ts +36 -3
  30. package/src/public-cli/registry.ts +3 -26
  31. package/src/public-cli/run-lifecycle.ts +8 -2
  32. package/src/public-cli/settlement.ts +115 -3
  33. package/src/public-cli/terminal.ts +3 -1
  34. package/src/role-runtime.ts +64 -1
  35. package/src/session-opening-materials.ts +6 -11
@@ -540,104 +540,6 @@ var init_collector_output = __esm({
540
540
  }
541
541
  });
542
542
 
543
- // src/package-contracts/judge-output.ts
544
- function validateAcceptedJudgeDetails(verdict) {
545
- if (verdict === null || typeof verdict !== "object" || Array.isArray(verdict)) throw new Error("Judge verdict has no execution discriminator");
546
- let judgeStatus;
547
- try {
548
- judgeStatus = verdict.judgeStatus;
549
- } catch {
550
- throw new Error("Judge verdict has no execution discriminator");
551
- }
552
- if (typeof judgeStatus !== "string") {
553
- throw new Error("Judge verdict has no execution discriminator");
554
- }
555
- if (["converged", "continue", "escalate"].includes(judgeStatus)) {
556
- return verdict;
557
- }
558
- throw new Error("Judge verdict has no execution discriminator");
559
- }
560
- var JUDGE_OUTPUT_TOOL_NAME;
561
- var init_judge_output = __esm({
562
- "src/package-contracts/judge-output.ts"() {
563
- "use strict";
564
- JUDGE_OUTPUT_TOOL_NAME = "ak_judge_output";
565
- }
566
- });
567
-
568
- // src/package-contracts/reviewer-output.ts
569
- function isRecord(value) {
570
- return typeof value === "object" && value !== null && !Array.isArray(value);
571
- }
572
- function read(value, key) {
573
- if (!isRecord(value)) return void 0;
574
- try {
575
- return value[key];
576
- } catch {
577
- return void 0;
578
- }
579
- }
580
- function validateRuntimeReviewerReceipt(output) {
581
- const status = read(output, "status");
582
- const acceptedBatch = read(output, "acceptedBatch");
583
- const identities = read(output, "identities");
584
- const construction = read(identities, "construction");
585
- const target = read(identities, "target");
586
- const reports = read(output, "reports");
587
- const outcomes = read(output, "outcomes");
588
- const legs = read(acceptedBatch, "legs");
589
- if (acceptedBatch !== void 0 || construction !== void 0 || target !== void 0) {
590
- if (!isRecord(acceptedBatch) || !isRecord(construction) || !isRecord(target) || !Array.isArray(legs))
591
- throw new Error("Incomplete Reviewer accepted-batch identity");
592
- const objectFormat = read(target, "objectFormat");
593
- const objectId = (value) => typeof value === "string" && new RegExp(objectFormat === "sha1" ? "^[0-9a-f]{40}$" : "^[0-9a-f]{64}$").test(value);
594
- const refs = read(target, "refs");
595
- const skillText = read(read(identities, "canonicalSkill"), "text");
596
- if (typeof skillText !== "string" || read(construction, "recipe") !== "reviewer-common-bundle-v1" || objectFormat !== "sha1" && objectFormat !== "sha256" || !objectId(read(target, "targetHead")) || !isRecord(refs) || Object.values(refs).some((ref) => !isRecord(ref) || !objectId(read(ref, "objectId")) || read(ref, "peeledCommitId") !== null && !objectId(read(ref, "peeledCommitId"))))
597
- throw new Error("Invalid Reviewer construction or target identity");
598
- const expectedAxes = legs.map((leg) => read(leg, "axis"));
599
- if (expectedAxes[0] !== "standards" || expectedAxes.length === 2 && expectedAxes[1] !== "spec" || expectedAxes.length < 1 || expectedAxes.length > 2)
600
- throw new Error("Invalid Reviewer accepted-leg projection");
601
- if (!isRecord(outcomes) || !isRecord(reports)) throw new Error("Accepted Reviewer batch lacks outcomes or reports");
602
- const outcomeAxes = Object.keys(outcomes).filter((axis) => axis === "standards" || axis === "spec");
603
- if (outcomeAxes.length !== expectedAxes.length || outcomeAxes.some((axis, index) => axis !== expectedAxes[index]))
604
- throw new Error("Reviewer outcomes must exactly cover accepted legs in canonical order");
605
- for (const [index, axisValue] of expectedAxes.entries()) {
606
- const axis = axisValue;
607
- const outcome = read(outcomes, axis);
608
- if (!isRecord(outcome)) throw new Error("Reviewer accepted leg lacks outcome");
609
- const expectedPrompt = read(read(legs[index], "prompt"), "text");
610
- const actualPrompt = read(read(outcome, "prompt"), "text");
611
- if (expectedPrompt !== actualPrompt) throw new Error("Reviewer outcome prompt disagrees with accepted leg");
612
- const status2 = read(outcome, "status");
613
- const report = read(reports, axis);
614
- if (status2 === "successful" && report === void 0)
615
- throw new Error("Successful Reviewer outcome lacks report");
616
- if (status2 === "failed" && report !== void 0) throw new Error("Failed Reviewer outcome cannot bind a report");
617
- }
618
- const specDisposition = read(output, "specDisposition");
619
- if (specDisposition === "launched") {
620
- if (expectedAxes.length !== 2 || expectedAxes[0] !== "standards" || expectedAxes[1] !== "spec") {
621
- throw new Error("Reviewer specDisposition launched requires Standards+Spec accepted legs");
622
- }
623
- } else if (specDisposition === "skipped-missing") {
624
- if (expectedAxes.length !== 1 || expectedAxes[0] !== "standards") {
625
- throw new Error("Reviewer specDisposition skipped-missing requires Standards-only accepted legs");
626
- }
627
- } else if (specDisposition !== void 0) {
628
- throw new Error("Invalid Reviewer specDisposition");
629
- }
630
- }
631
- return output;
632
- }
633
- var REVIEWER_OUTPUT_TOOL_NAME;
634
- var init_reviewer_output = __esm({
635
- "src/package-contracts/reviewer-output.ts"() {
636
- "use strict";
637
- REVIEWER_OUTPUT_TOOL_NAME = "ak_reviewer_output";
638
- }
639
- });
640
-
641
543
  // node_modules/.pnpm/typebox@1.3.8/node_modules/typebox/build/system/memory/metrics.mjs
642
544
  var Metrics;
643
545
  var init_metrics = __esm({
@@ -8382,6 +8284,288 @@ var init_build = __esm({
8382
8284
  }
8383
8285
  });
8384
8286
 
8287
+ // src/open-tool-schema.ts
8288
+ function described(name, schema) {
8289
+ if (typeof schema.description === "string") return schema;
8290
+ throw new Error(`Tool field ${name} has no semantic description at its schema owner`);
8291
+ }
8292
+ function declarationIdentity(schema) {
8293
+ const { description: _description, ...semantic } = schema;
8294
+ return JSON.stringify(semantic);
8295
+ }
8296
+ function openToolObjectFromUnion(schema) {
8297
+ const declarations = /* @__PURE__ */ new Map();
8298
+ for (const variant of schema.anyOf) {
8299
+ for (const [name, declaration] of Object.entries(variant.properties ?? {})) {
8300
+ const entries = declarations.get(name) ?? [];
8301
+ const identity = declarationIdentity(declaration);
8302
+ if (!entries.some((entry) => declarationIdentity(entry) === identity)) entries.push(declaration);
8303
+ declarations.set(name, entries);
8304
+ }
8305
+ }
8306
+ const properties = Object.fromEntries([...declarations].map(([name, entries]) => {
8307
+ const descriptions = [...new Set(entries.map((entry) => entry.description).filter((value) => typeof value === "string"))].join(" ");
8308
+ const declaration = entries.length === 1 ? entries[0] : typebox_exports.Union(entries, descriptions === "" ? {} : { description: descriptions });
8309
+ return [name, typebox_exports.Optional(described(name, declaration))];
8310
+ }));
8311
+ const object = typebox_exports.Object(properties, { additionalProperties: true });
8312
+ object.required = [];
8313
+ return object;
8314
+ }
8315
+ function openToolObject(schema) {
8316
+ const object = typebox_exports.Object(
8317
+ Object.fromEntries(Object.entries(schema.properties).map(([name, declaration]) => [name, typebox_exports.Optional(described(name, declaration))])),
8318
+ { additionalProperties: true }
8319
+ );
8320
+ object.required = [];
8321
+ return object;
8322
+ }
8323
+ var init_open_tool_schema = __esm({
8324
+ "src/open-tool-schema.ts"() {
8325
+ "use strict";
8326
+ init_build();
8327
+ }
8328
+ });
8329
+
8330
+ // src/package-contracts/terminating-infrastructure.ts
8331
+ function withInfrastructureFailureDeclaration(schema) {
8332
+ const baseProperties = schema.properties;
8333
+ const properties = {
8334
+ ...baseProperties ?? {},
8335
+ [INFRASTRUCTURE_FAILURE_DECLARATION_KEY]: infrastructureFailureDeclarationSchema.properties[INFRASTRUCTURE_FAILURE_DECLARATION_KEY]
8336
+ };
8337
+ const object = typebox_exports.Object(properties, { additionalProperties: true });
8338
+ object.required = [];
8339
+ return object;
8340
+ }
8341
+ var INFRASTRUCTURE_FAILURE_DECLARATION_KEY, INFRASTRUCTURE_FAILURE_DIAGNOSTIC_KEY, infrastructureFailureDeclarationSchema;
8342
+ var init_terminating_infrastructure = __esm({
8343
+ "src/package-contracts/terminating-infrastructure.ts"() {
8344
+ "use strict";
8345
+ init_build();
8346
+ INFRASTRUCTURE_FAILURE_DECLARATION_KEY = "infrastructureFailure";
8347
+ INFRASTRUCTURE_FAILURE_DIAGNOSTIC_KEY = "diagnostic";
8348
+ infrastructureFailureDeclarationSchema = typebox_exports.Object(
8349
+ {
8350
+ [INFRASTRUCTURE_FAILURE_DECLARATION_KEY]: typebox_exports.Object(
8351
+ {
8352
+ [INFRASTRUCTURE_FAILURE_DIAGNOSTIC_KEY]: typebox_exports.String({
8353
+ minLength: 1,
8354
+ description: "\u975E\u7A7A\u57FA\u7840\u8BBE\u65BD\u5931\u8D25\u8BCA\u65AD"
8355
+ })
8356
+ },
8357
+ {
8358
+ additionalProperties: true,
8359
+ description: "\u57FA\u7840\u8BBE\u65BD\u5931\u8D25\u58F0\u660E"
8360
+ }
8361
+ )
8362
+ },
8363
+ { additionalProperties: true }
8364
+ );
8365
+ }
8366
+ });
8367
+
8368
+ // src/package-contracts/gatekeeper-output.ts
8369
+ function isRecord(value) {
8370
+ return typeof value === "object" && value !== null && !Array.isArray(value);
8371
+ }
8372
+ function asStringArray(value) {
8373
+ if (!Array.isArray(value)) return [];
8374
+ return value.filter((item) => typeof item === "string");
8375
+ }
8376
+ function projectLawfulGatekeeperOutput(value) {
8377
+ if (!isRecord(value)) return void 0;
8378
+ if (value.status === "pass") {
8379
+ return Array.isArray(value.findings) ? { status: "pass", findings: asStringArray(value.findings) } : { status: "pass" };
8380
+ }
8381
+ if (value.status === "dispatch" && (value.officer === "inspector" || value.officer === "notary")) {
8382
+ return { status: "dispatch", officer: value.officer };
8383
+ }
8384
+ return void 0;
8385
+ }
8386
+ function validateRecordedGatekeeperOutput(value) {
8387
+ const projected = projectLawfulGatekeeperOutput(value);
8388
+ if (projected === void 0) {
8389
+ throw new Error("Gatekeeper output has no recognized execution discriminator");
8390
+ }
8391
+ return projected;
8392
+ }
8393
+ function gatekeeperDecisiveFacts(output) {
8394
+ const facts = { status: output.status };
8395
+ if (output.status === "dispatch") {
8396
+ facts.officer = output.officer;
8397
+ } else if (Array.isArray(output.findings)) {
8398
+ facts.findingsCount = output.findings.length;
8399
+ }
8400
+ return facts;
8401
+ }
8402
+ var GATEKEEPER_OUTPUT_TOOL_NAME, gatekeeperDecisionSchema, gatekeeperOutputSchema;
8403
+ var init_gatekeeper_output = __esm({
8404
+ "src/package-contracts/gatekeeper-output.ts"() {
8405
+ "use strict";
8406
+ init_build();
8407
+ init_open_tool_schema();
8408
+ init_terminating_infrastructure();
8409
+ GATEKEEPER_OUTPUT_TOOL_NAME = "ak_gatekeeper_output";
8410
+ gatekeeperDecisionSchema = openToolObject(
8411
+ typebox_exports.Object({
8412
+ status: typebox_exports.Unknown({
8413
+ description: "dispatch | pass \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8"
8414
+ }),
8415
+ officer: typebox_exports.Unknown({
8416
+ description: "status \u4E3A dispatch \u65F6\u4E3A inspector | notary"
8417
+ }),
8418
+ findings: typebox_exports.Unknown({
8419
+ description: "status \u4E3A pass \u65F6\u53EF\u9009 string[] findings"
8420
+ })
8421
+ })
8422
+ );
8423
+ gatekeeperOutputSchema = withInfrastructureFailureDeclaration(
8424
+ gatekeeperDecisionSchema
8425
+ );
8426
+ }
8427
+ });
8428
+
8429
+ // src/package-contracts/navigator-output.ts
8430
+ function isRecord2(value) {
8431
+ return typeof value === "object" && value !== null && !Array.isArray(value);
8432
+ }
8433
+ function projectLawfulNavigatorOutput(value) {
8434
+ if (!isRecord2(value) || !Array.isArray(value.candidates)) return void 0;
8435
+ if (value.status !== "advice") return void 0;
8436
+ return { status: "advice", candidates: value.candidates.filter(isRecord2) };
8437
+ }
8438
+ function validateRecordedNavigatorOutput(value) {
8439
+ const projected = projectLawfulNavigatorOutput(value);
8440
+ if (projected === void 0) {
8441
+ throw new Error("Navigator output has no recognized execution discriminator");
8442
+ }
8443
+ return projected;
8444
+ }
8445
+ function navigatorDecisiveFacts(output) {
8446
+ return { status: "advice", candidates: output.candidates };
8447
+ }
8448
+ var NAVIGATOR_OUTPUT_TOOL_NAME, navigatorOutputSchema;
8449
+ var init_navigator_output = __esm({
8450
+ "src/package-contracts/navigator-output.ts"() {
8451
+ "use strict";
8452
+ init_build();
8453
+ init_open_tool_schema();
8454
+ init_terminating_infrastructure();
8455
+ NAVIGATOR_OUTPUT_TOOL_NAME = "ak_navigator_output";
8456
+ navigatorOutputSchema = withInfrastructureFailureDeclaration(
8457
+ openToolObject(
8458
+ typebox_exports.Object({
8459
+ status: typebox_exports.Unknown({
8460
+ description: "advice \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8"
8461
+ }),
8462
+ candidates: typebox_exports.Unknown({
8463
+ description: "\u6392\u597D\u5E8F\u7684\u8DEF\u7EBF\u5EFA\u8BAE\u6570\u7EC4\uFF0C\u5143\u7D20\u542B next/phase/reason \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8"
8464
+ })
8465
+ })
8466
+ )
8467
+ );
8468
+ }
8469
+ });
8470
+
8471
+ // src/package-contracts/judge-output.ts
8472
+ function validateAcceptedJudgeDetails(verdict) {
8473
+ if (verdict === null || typeof verdict !== "object" || Array.isArray(verdict)) throw new Error("Judge verdict has no execution discriminator");
8474
+ let judgeStatus;
8475
+ try {
8476
+ judgeStatus = verdict.judgeStatus;
8477
+ } catch {
8478
+ throw new Error("Judge verdict has no execution discriminator");
8479
+ }
8480
+ if (typeof judgeStatus !== "string") {
8481
+ throw new Error("Judge verdict has no execution discriminator");
8482
+ }
8483
+ if (["converged", "continue", "escalate"].includes(judgeStatus)) {
8484
+ return verdict;
8485
+ }
8486
+ throw new Error("Judge verdict has no execution discriminator");
8487
+ }
8488
+ var JUDGE_OUTPUT_TOOL_NAME;
8489
+ var init_judge_output = __esm({
8490
+ "src/package-contracts/judge-output.ts"() {
8491
+ "use strict";
8492
+ JUDGE_OUTPUT_TOOL_NAME = "ak_judge_output";
8493
+ }
8494
+ });
8495
+
8496
+ // src/package-contracts/reviewer-output.ts
8497
+ function isRecord3(value) {
8498
+ return typeof value === "object" && value !== null && !Array.isArray(value);
8499
+ }
8500
+ function read(value, key) {
8501
+ if (!isRecord3(value)) return void 0;
8502
+ try {
8503
+ return value[key];
8504
+ } catch {
8505
+ return void 0;
8506
+ }
8507
+ }
8508
+ function validateRuntimeReviewerReceipt(output) {
8509
+ const status = read(output, "status");
8510
+ const acceptedBatch = read(output, "acceptedBatch");
8511
+ const identities = read(output, "identities");
8512
+ const construction = read(identities, "construction");
8513
+ const target = read(identities, "target");
8514
+ const reports = read(output, "reports");
8515
+ const outcomes = read(output, "outcomes");
8516
+ const legs = read(acceptedBatch, "legs");
8517
+ if (acceptedBatch !== void 0 || construction !== void 0 || target !== void 0) {
8518
+ if (!isRecord3(acceptedBatch) || !isRecord3(construction) || !isRecord3(target) || !Array.isArray(legs))
8519
+ throw new Error("Incomplete Reviewer accepted-batch identity");
8520
+ const objectFormat = read(target, "objectFormat");
8521
+ const objectId = (value) => typeof value === "string" && new RegExp(objectFormat === "sha1" ? "^[0-9a-f]{40}$" : "^[0-9a-f]{64}$").test(value);
8522
+ const refs = read(target, "refs");
8523
+ const skillText = read(read(identities, "canonicalSkill"), "text");
8524
+ if (typeof skillText !== "string" || read(construction, "recipe") !== "reviewer-common-bundle-v1" || objectFormat !== "sha1" && objectFormat !== "sha256" || !objectId(read(target, "targetHead")) || !isRecord3(refs) || Object.values(refs).some((ref) => !isRecord3(ref) || !objectId(read(ref, "objectId")) || read(ref, "peeledCommitId") !== null && !objectId(read(ref, "peeledCommitId"))))
8525
+ throw new Error("Invalid Reviewer construction or target identity");
8526
+ const expectedAxes = legs.map((leg) => read(leg, "axis"));
8527
+ if (expectedAxes[0] !== "standards" || expectedAxes.length === 2 && expectedAxes[1] !== "spec" || expectedAxes.length < 1 || expectedAxes.length > 2)
8528
+ throw new Error("Invalid Reviewer accepted-leg projection");
8529
+ if (!isRecord3(outcomes) || !isRecord3(reports)) throw new Error("Accepted Reviewer batch lacks outcomes or reports");
8530
+ const outcomeAxes = Object.keys(outcomes).filter((axis) => axis === "standards" || axis === "spec");
8531
+ if (outcomeAxes.length !== expectedAxes.length || outcomeAxes.some((axis, index) => axis !== expectedAxes[index]))
8532
+ throw new Error("Reviewer outcomes must exactly cover accepted legs in canonical order");
8533
+ for (const [index, axisValue] of expectedAxes.entries()) {
8534
+ const axis = axisValue;
8535
+ const outcome = read(outcomes, axis);
8536
+ if (!isRecord3(outcome)) throw new Error("Reviewer accepted leg lacks outcome");
8537
+ const expectedPrompt = read(read(legs[index], "prompt"), "text");
8538
+ const actualPrompt = read(read(outcome, "prompt"), "text");
8539
+ if (expectedPrompt !== actualPrompt) throw new Error("Reviewer outcome prompt disagrees with accepted leg");
8540
+ const status2 = read(outcome, "status");
8541
+ const report = read(reports, axis);
8542
+ if (status2 === "successful" && report === void 0)
8543
+ throw new Error("Successful Reviewer outcome lacks report");
8544
+ if (status2 === "failed" && report !== void 0) throw new Error("Failed Reviewer outcome cannot bind a report");
8545
+ }
8546
+ const specDisposition = read(output, "specDisposition");
8547
+ if (specDisposition === "launched") {
8548
+ if (expectedAxes.length !== 2 || expectedAxes[0] !== "standards" || expectedAxes[1] !== "spec") {
8549
+ throw new Error("Reviewer specDisposition launched requires Standards+Spec accepted legs");
8550
+ }
8551
+ } else if (specDisposition === "skipped-missing") {
8552
+ if (expectedAxes.length !== 1 || expectedAxes[0] !== "standards") {
8553
+ throw new Error("Reviewer specDisposition skipped-missing requires Standards-only accepted legs");
8554
+ }
8555
+ } else if (specDisposition !== void 0) {
8556
+ throw new Error("Invalid Reviewer specDisposition");
8557
+ }
8558
+ }
8559
+ return output;
8560
+ }
8561
+ var REVIEWER_OUTPUT_TOOL_NAME;
8562
+ var init_reviewer_output = __esm({
8563
+ "src/package-contracts/reviewer-output.ts"() {
8564
+ "use strict";
8565
+ REVIEWER_OUTPUT_TOOL_NAME = "ak_reviewer_output";
8566
+ }
8567
+ });
8568
+
8385
8569
  // node_modules/.pnpm/typebox@1.3.8/node_modules/typebox/build/schema/types/_refine.mjs
8386
8570
  function IsRefine2(value) {
8387
8571
  return guard_exports.HasPropertyKey(value, "~refine") && guard_exports.IsArray(value["~refine"]) && guard_exports.Every(value["~refine"], 0, (value2) => guard_exports.IsObject(value2) && guard_exports.HasPropertyKey(value2, "check") && guard_exports.HasPropertyKey(value2, "error") && guard_exports.IsFunction(value2.check) && guard_exports.IsFunction(value2.error));
@@ -14329,128 +14513,47 @@ function validateFixerPrerequisites(value) {
14329
14513
  if (!value_exports.Check(fixerPrerequisitesSchema, value)) parseFailure(value);
14330
14514
  const entries = value;
14331
14515
  const ids = /* @__PURE__ */ new Set();
14332
- const prerequisites = entries.map((entry) => {
14333
- if (ids.has(entry.id)) {
14334
- fail(new Error(`Fixer prerequisites contain duplicate id: ${entry.id}`));
14335
- }
14336
- ids.add(entry.id);
14337
- return Object.freeze({ id: entry.id, requirement: entry.requirement });
14338
- });
14339
- return Object.freeze(prerequisites);
14340
- }
14341
- function parseFixerPrerequisites(source) {
14342
- let decoded;
14343
- try {
14344
- decoded = JSON.parse(source);
14345
- } catch (error) {
14346
- fail(error);
14347
- }
14348
- return validateFixerPrerequisites(decoded);
14349
- }
14350
- var FIXER_PREREQUISITE_ID_PATTERN, fixerPrerequisiteSchema, fixerPrerequisitesSchema, FixerPacketValidationError;
14351
- var init_fixer_packet = __esm({
14352
- "src/package-contracts/fixer-packet.ts"() {
14353
- "use strict";
14354
- init_build();
14355
- init_value2();
14356
- FIXER_PREREQUISITE_ID_PATTERN = "^[A-Za-z0-9][A-Za-z0-9._-]*$";
14357
- fixerPrerequisiteSchema = typebox_exports.Object({
14358
- id: typebox_exports.String({ pattern: FIXER_PREREQUISITE_ID_PATTERN }),
14359
- requirement: typebox_exports.String({ pattern: "\\S" })
14360
- }, { additionalProperties: false });
14361
- fixerPrerequisitesSchema = typebox_exports.Array(fixerPrerequisiteSchema);
14362
- FixerPacketValidationError = class extends Error {
14363
- code = "AK_INVALID_FIX_PACKET";
14364
- constructor(cause) {
14365
- const prefix = "Fixer prerequisites or instructions violate the invocation contract";
14366
- super(
14367
- cause === void 0 ? prefix : `${prefix}: ${causeMessage(cause)}`,
14368
- cause === void 0 ? void 0 : { cause }
14369
- );
14370
- this.name = "FixerPacketValidationError";
14371
- }
14372
- };
14373
- }
14374
- });
14375
-
14376
- // src/open-tool-schema.ts
14377
- function described(name, schema) {
14378
- if (typeof schema.description === "string") return schema;
14379
- throw new Error(`Tool field ${name} has no semantic description at its schema owner`);
14380
- }
14381
- function declarationIdentity(schema) {
14382
- const { description: _description, ...semantic } = schema;
14383
- return JSON.stringify(semantic);
14384
- }
14385
- function openToolObjectFromUnion(schema) {
14386
- const declarations = /* @__PURE__ */ new Map();
14387
- for (const variant of schema.anyOf) {
14388
- for (const [name, declaration] of Object.entries(variant.properties ?? {})) {
14389
- const entries = declarations.get(name) ?? [];
14390
- const identity = declarationIdentity(declaration);
14391
- if (!entries.some((entry) => declarationIdentity(entry) === identity)) entries.push(declaration);
14392
- declarations.set(name, entries);
14393
- }
14394
- }
14395
- const properties = Object.fromEntries([...declarations].map(([name, entries]) => {
14396
- const descriptions = [...new Set(entries.map((entry) => entry.description).filter((value) => typeof value === "string"))].join(" ");
14397
- const declaration = entries.length === 1 ? entries[0] : typebox_exports.Union(entries, descriptions === "" ? {} : { description: descriptions });
14398
- return [name, typebox_exports.Optional(described(name, declaration))];
14399
- }));
14400
- const object = typebox_exports.Object(properties, { additionalProperties: true });
14401
- object.required = [];
14402
- return object;
14403
- }
14404
- function openToolObject(schema) {
14405
- const object = typebox_exports.Object(
14406
- Object.fromEntries(Object.entries(schema.properties).map(([name, declaration]) => [name, typebox_exports.Optional(described(name, declaration))])),
14407
- { additionalProperties: true }
14408
- );
14409
- object.required = [];
14410
- return object;
14516
+ const prerequisites = entries.map((entry) => {
14517
+ if (ids.has(entry.id)) {
14518
+ fail(new Error(`Fixer prerequisites contain duplicate id: ${entry.id}`));
14519
+ }
14520
+ ids.add(entry.id);
14521
+ return Object.freeze({ id: entry.id, requirement: entry.requirement });
14522
+ });
14523
+ return Object.freeze(prerequisites);
14411
14524
  }
14412
- var init_open_tool_schema = __esm({
14413
- "src/open-tool-schema.ts"() {
14414
- "use strict";
14415
- init_build();
14525
+ function parseFixerPrerequisites(source) {
14526
+ let decoded;
14527
+ try {
14528
+ decoded = JSON.parse(source);
14529
+ } catch (error) {
14530
+ fail(error);
14416
14531
  }
14417
- });
14418
-
14419
- // src/package-contracts/terminating-infrastructure.ts
14420
- function withInfrastructureFailureDeclaration(schema) {
14421
- const baseProperties = schema.properties;
14422
- const properties = {
14423
- ...baseProperties ?? {},
14424
- [INFRASTRUCTURE_FAILURE_DECLARATION_KEY]: infrastructureFailureDeclarationSchema.properties[INFRASTRUCTURE_FAILURE_DECLARATION_KEY]
14425
- };
14426
- const object = typebox_exports.Object(properties, { additionalProperties: true });
14427
- object.required = [];
14428
- return object;
14532
+ return validateFixerPrerequisites(decoded);
14429
14533
  }
14430
- var INFRASTRUCTURE_FAILURE_DECLARATION_KEY, INFRASTRUCTURE_FAILURE_DIAGNOSTIC_KEY, infrastructureFailureDeclarationSchema;
14431
- var init_terminating_infrastructure = __esm({
14432
- "src/package-contracts/terminating-infrastructure.ts"() {
14534
+ var FIXER_PREREQUISITE_ID_PATTERN, fixerPrerequisiteSchema, fixerPrerequisitesSchema, FixerPacketValidationError;
14535
+ var init_fixer_packet = __esm({
14536
+ "src/package-contracts/fixer-packet.ts"() {
14433
14537
  "use strict";
14434
14538
  init_build();
14435
- INFRASTRUCTURE_FAILURE_DECLARATION_KEY = "infrastructureFailure";
14436
- INFRASTRUCTURE_FAILURE_DIAGNOSTIC_KEY = "diagnostic";
14437
- infrastructureFailureDeclarationSchema = typebox_exports.Object(
14438
- {
14439
- [INFRASTRUCTURE_FAILURE_DECLARATION_KEY]: typebox_exports.Object(
14440
- {
14441
- [INFRASTRUCTURE_FAILURE_DIAGNOSTIC_KEY]: typebox_exports.String({
14442
- minLength: 1,
14443
- description: "\u975E\u7A7A\u57FA\u7840\u8BBE\u65BD\u5931\u8D25\u8BCA\u65AD"
14444
- })
14445
- },
14446
- {
14447
- additionalProperties: true,
14448
- description: "\u57FA\u7840\u8BBE\u65BD\u5931\u8D25\u58F0\u660E"
14449
- }
14450
- )
14451
- },
14452
- { additionalProperties: true }
14453
- );
14539
+ init_value2();
14540
+ FIXER_PREREQUISITE_ID_PATTERN = "^[A-Za-z0-9][A-Za-z0-9._-]*$";
14541
+ fixerPrerequisiteSchema = typebox_exports.Object({
14542
+ id: typebox_exports.String({ pattern: FIXER_PREREQUISITE_ID_PATTERN }),
14543
+ requirement: typebox_exports.String({ pattern: "\\S" })
14544
+ }, { additionalProperties: false });
14545
+ fixerPrerequisitesSchema = typebox_exports.Array(fixerPrerequisiteSchema);
14546
+ FixerPacketValidationError = class extends Error {
14547
+ code = "AK_INVALID_FIX_PACKET";
14548
+ constructor(cause) {
14549
+ const prefix = "Fixer prerequisites or instructions violate the invocation contract";
14550
+ super(
14551
+ cause === void 0 ? prefix : `${prefix}: ${causeMessage(cause)}`,
14552
+ cause === void 0 ? void 0 : { cause }
14553
+ );
14554
+ this.name = "FixerPacketValidationError";
14555
+ }
14556
+ };
14454
14557
  }
14455
14558
  });
14456
14559
 
@@ -14532,11 +14635,11 @@ var init_canonical_json = __esm({
14532
14635
  });
14533
14636
 
14534
14637
  // src/doctor-contracts.ts
14535
- function isRecord2(value) {
14638
+ function isRecord4(value) {
14536
14639
  return typeof value === "object" && value !== null && !Array.isArray(value);
14537
14640
  }
14538
14641
  function read2(value, key) {
14539
- if (!isRecord2(value)) return void 0;
14642
+ if (!isRecord4(value)) return void 0;
14540
14643
  try {
14541
14644
  return value[key];
14542
14645
  } catch {
@@ -14754,25 +14857,25 @@ var init_merger_contracts = __esm({
14754
14857
  });
14755
14858
 
14756
14859
  // src/notary-contracts.ts
14757
- function isRecord3(value) {
14860
+ function isRecord5(value) {
14758
14861
  return typeof value === "object" && value !== null && !Array.isArray(value);
14759
14862
  }
14760
- function asStringArray(value) {
14863
+ function asStringArray2(value) {
14761
14864
  if (!Array.isArray(value)) return [];
14762
14865
  return value.filter((item) => typeof item === "string");
14763
14866
  }
14764
14867
  function projectLawfulNotaryOutput(value) {
14765
- if (!isRecord3(value)) return void 0;
14868
+ if (!isRecord5(value)) return void 0;
14766
14869
  const status = typeof value.status === "string" ? value.status : void 0;
14767
14870
  if (status === "bounce") {
14768
14871
  const clone = structuredClone(value);
14769
14872
  if (clone.disposition === void 0) clone.disposition = "rewrite";
14770
- if (!Array.isArray(clone.findings)) clone.findings = asStringArray(clone.findings);
14873
+ if (!Array.isArray(clone.findings)) clone.findings = asStringArray2(clone.findings);
14771
14874
  return clone;
14772
14875
  }
14773
14876
  if (status === "pass") {
14774
14877
  const clone = structuredClone(value);
14775
- if (!Array.isArray(clone.findings)) clone.findings = asStringArray(clone.findings);
14878
+ if (!Array.isArray(clone.findings)) clone.findings = asStringArray2(clone.findings);
14776
14879
  return clone;
14777
14880
  }
14778
14881
  return void 0;
@@ -14916,6 +15019,8 @@ var init_packaged_role_registry = __esm({
14916
15019
  "src/packaged-role-registry.ts"() {
14917
15020
  "use strict";
14918
15021
  init_collector_output();
15022
+ init_gatekeeper_output();
15023
+ init_navigator_output();
14919
15024
  init_judge_output();
14920
15025
  init_reviewer_output();
14921
15026
  init_worker_output();
@@ -15068,6 +15173,28 @@ var init_packaged_role_registry = __esm({
15068
15173
  phaseFlag: void 0,
15069
15174
  activationStage: "load-and-install",
15070
15175
  sessionMaterials: INSPECTOR_SESSION_MATERIALS
15176
+ },
15177
+ // #639: gatekeeper and navigator are roles like any other — public ak-role
15178
+ // entries; automatic attendance (province dispatch, navigator sidecar) is
15179
+ // unchanged and orthogonal to callability.
15180
+ {
15181
+ role: "gatekeeper",
15182
+ phases: [null],
15183
+ outputTool: GATEKEEPER_OUTPUT_TOOL_NAME,
15184
+ inputFlag: void 0,
15185
+ phaseFlag: void 0,
15186
+ activationStage: "load-and-install",
15187
+ // Province materials; officers reuse their own public records below.
15188
+ sessionMaterials: ["CLAUDE.md", "souls/gatekeeper.md", "souls/quality-law.md", "souls/gate-output-guide.md"]
15189
+ },
15190
+ {
15191
+ role: "navigator",
15192
+ phases: [null],
15193
+ outputTool: NAVIGATOR_OUTPUT_TOOL_NAME,
15194
+ inputFlag: void 0,
15195
+ phaseFlag: void 0,
15196
+ activationStage: "load-and-install",
15197
+ sessionMaterials: ["CLAUDE.md", "souls/navigator.md"]
15071
15198
  }
15072
15199
  ];
15073
15200
  ONE_SHOT_ROLES = [
@@ -15081,9 +15208,6 @@ var init_packaged_role_registry = __esm({
15081
15208
  });
15082
15209
 
15083
15210
  // src/public-cli/registry.ts
15084
- function isAutomaticConfigurableSeat(value) {
15085
- return AUTOMATIC_CONFIGURABLE_SEATS.includes(value);
15086
- }
15087
15211
  function seatModelOnly(seat) {
15088
15212
  if (seat?.provider === void 0 || seat.model === void 0) return void 0;
15089
15213
  return seat.thinking === void 0 ? { provider: seat.provider, model: seat.model } : { provider: seat.provider, model: seat.model, thinking: seat.thinking };
@@ -15123,7 +15247,7 @@ function isPublicConfigurableSeat(value) {
15123
15247
  function isPublicCliSupportCommand(value) {
15124
15248
  return PUBLIC_CLI_SUPPORT_COMMANDS.includes(value);
15125
15249
  }
15126
- var INTERNAL_ROLE_ENTRYPOINT_RELATIVE, PUBLIC_CALLABLE_ROLES, AUTOMATIC_NAVIGATOR_SEAT, AUTOMATIC_GATEKEEPER_SEAT, AUTOMATIC_CONFIGURABLE_SEATS, PUBLIC_CONFIGURABLE_SEATS, PUBLIC_CLI_SUPPORT_COMMANDS, STARTUP_CANDIDATES, PUBLIC_DETERMINISTIC_COMMANDS;
15250
+ var INTERNAL_ROLE_ENTRYPOINT_RELATIVE, PUBLIC_CALLABLE_ROLES, PUBLIC_CONFIGURABLE_SEATS, PUBLIC_CLI_SUPPORT_COMMANDS, STARTUP_CANDIDATES, PUBLIC_DETERMINISTIC_COMMANDS;
15127
15251
  var init_registry2 = __esm({
15128
15252
  "src/public-cli/registry.ts"() {
15129
15253
  "use strict";
@@ -15132,15 +15256,8 @@ var init_registry2 = __esm({
15132
15256
  PUBLIC_CALLABLE_ROLES = PACKAGED_ROLE_REGISTRY.map(
15133
15257
  (entry) => entry.role
15134
15258
  );
15135
- AUTOMATIC_NAVIGATOR_SEAT = "navigator";
15136
- AUTOMATIC_GATEKEEPER_SEAT = "gatekeeper";
15137
- AUTOMATIC_CONFIGURABLE_SEATS = [
15138
- AUTOMATIC_GATEKEEPER_SEAT,
15139
- AUTOMATIC_NAVIGATOR_SEAT
15140
- ];
15141
15259
  PUBLIC_CONFIGURABLE_SEATS = [
15142
- ...PUBLIC_CALLABLE_ROLES,
15143
- ...AUTOMATIC_CONFIGURABLE_SEATS
15260
+ ...PUBLIC_CALLABLE_ROLES
15144
15261
  ];
15145
15262
  PUBLIC_CLI_SUPPORT_COMMANDS = [
15146
15263
  "roles",
@@ -15187,7 +15304,8 @@ var init_registry2 = __esm({
15187
15304
  ],
15188
15305
  // #620: subordinate officers inherit gatekeeper; no package startup model.
15189
15306
  notary: [],
15190
- // #453/#620: gatekeeper unset inherits audited session (province path only).
15307
+ // #453/#620/#639: gatekeeper callable but no package startup model — caller
15308
+ // configures it or the institutional resolution applies on the province path.
15191
15309
  gatekeeper: [],
15192
15310
  inspector: [],
15193
15311
  navigator: [
@@ -15387,11 +15505,6 @@ function setAutoResumeLimit(config, limit) {
15387
15505
  function validatePublicCliConfigAxes(config, _packageRoot) {
15388
15506
  for (const seat of Object.keys(config.seats)) {
15389
15507
  const row = config.seats[seat];
15390
- if ((row?.engine !== void 0 || row?.host !== void 0) && !isPublicCallableRole(seat)) {
15391
- throw new Error(
15392
- `config seat ${seat} cannot persist call axes: no independent activation path; storing would be silently ineffective`
15393
- );
15394
- }
15395
15508
  if (row?.engine === void 0) continue;
15396
15509
  try {
15397
15510
  assertLegalEngineName(row.engine);
@@ -15584,12 +15697,10 @@ function attachEngineAxis(seat, config, invocation) {
15584
15697
  };
15585
15698
  }
15586
15699
  function resolveBaseSeat(config, seat, credentials) {
15587
- const automatic = isAutomaticConfigurableSeat(seat);
15588
15700
  if (seat === "notary" || seat === "inspector") {
15589
15701
  const resolved = resolveConfiguredProvinceOfficer(config, seat);
15590
15702
  return {
15591
15703
  seat,
15592
- automatic,
15593
15704
  source: resolved.source,
15594
15705
  ...resolved.selection === void 0 ? {} : { selection: resolved.selection },
15595
15706
  engineSource: "unconfigured"
@@ -15599,7 +15710,6 @@ function resolveBaseSeat(config, seat, credentials) {
15599
15710
  if (persistentModel !== void 0) {
15600
15711
  return {
15601
15712
  seat,
15602
- automatic,
15603
15713
  source: "persistent",
15604
15714
  selection: persistentModel,
15605
15715
  engineSource: "unconfigured"
@@ -15609,16 +15719,14 @@ function resolveBaseSeat(config, seat, credentials) {
15609
15719
  if (startup !== void 0) {
15610
15720
  return {
15611
15721
  seat,
15612
- automatic,
15613
15722
  source: "startup",
15614
15723
  selection: startup,
15615
15724
  engineSource: "unconfigured"
15616
15725
  };
15617
15726
  }
15618
- return { seat, automatic, source: "unconfigured", engineSource: "unconfigured" };
15727
+ return { seat, source: "unconfigured", engineSource: "unconfigured" };
15619
15728
  }
15620
15729
  function resolveEffectiveSeat(config, seat, credentials, invocation) {
15621
- const automatic = isAutomaticConfigurableSeat(seat);
15622
15730
  const hasModelInvocation = invocation !== void 0 && (invocation.model !== void 0 || invocation.thinking !== void 0);
15623
15731
  let modelSeat;
15624
15732
  if (!hasModelInvocation || invocation === void 0) {
@@ -15627,7 +15735,6 @@ function resolveEffectiveSeat(config, seat, credentials, invocation) {
15627
15735
  const spec = invocation.model.includes(":") || invocation.thinking === void 0 ? invocation.model : `${invocation.model}:${invocation.thinking}`;
15628
15736
  modelSeat = {
15629
15737
  seat,
15630
- automatic,
15631
15738
  source: "invocation",
15632
15739
  selection: parseModelSpec(spec),
15633
15740
  engineSource: "unconfigured"
@@ -15637,14 +15744,12 @@ function resolveEffectiveSeat(config, seat, credentials, invocation) {
15637
15744
  if (base.selection === void 0 || invocation.thinking === void 0) {
15638
15745
  modelSeat = {
15639
15746
  seat,
15640
- automatic,
15641
15747
  source: "unconfigured",
15642
15748
  engineSource: "unconfigured"
15643
15749
  };
15644
15750
  } else {
15645
15751
  modelSeat = {
15646
15752
  seat,
15647
- automatic,
15648
15753
  source: "invocation",
15649
15754
  selection: { ...base.selection, thinking: invocation.thinking },
15650
15755
  engineSource: "unconfigured"
@@ -15935,7 +16040,7 @@ import {
15935
16040
  writeFileSync
15936
16041
  } from "node:fs";
15937
16042
  import { basename as basename3, dirname as dirname5, join as join9, resolve as resolve3 } from "node:path";
15938
- function isRecord4(value) {
16043
+ function isRecord6(value) {
15939
16044
  return typeof value === "object" && value !== null && !Array.isArray(value);
15940
16045
  }
15941
16046
  function errorCodeOf(error) {
@@ -15963,7 +16068,7 @@ function findIdentityPointer(recordFile, identity, kind, level) {
15963
16068
  if (!trimmed) continue;
15964
16069
  try {
15965
16070
  const parsed = JSON.parse(trimmed);
15966
- if (isRecord4(parsed) && parsed.identity === identity) {
16071
+ if (isRecord6(parsed) && parsed.identity === identity) {
15967
16072
  return { identity, recordFile, kind, level };
15968
16073
  }
15969
16074
  } catch {
@@ -16151,7 +16256,7 @@ var init_sitian_appender = __esm({
16151
16256
  // src/sitian-reader.ts
16152
16257
  import { existsSync as existsSync5 } from "node:fs";
16153
16258
  import { readFile as readFile3 } from "node:fs/promises";
16154
- function isRecord5(value) {
16259
+ function isRecord7(value) {
16155
16260
  return typeof value === "object" && value !== null && !Array.isArray(value);
16156
16261
  }
16157
16262
  async function readSitianRecords(recordFile) {
@@ -16167,7 +16272,7 @@ async function readSitianRecords(recordFile) {
16167
16272
  if (!line2.trim()) continue;
16168
16273
  try {
16169
16274
  const parsed = JSON.parse(line2);
16170
- if (isRecord5(parsed)) {
16275
+ if (isRecord7(parsed)) {
16171
16276
  records2.push(parsed);
16172
16277
  } else {
16173
16278
  const typeDesc = parsed === null ? "null" : Array.isArray(parsed) ? "array" : typeof parsed;
@@ -16302,6 +16407,10 @@ function buildActivationFlagArgs(activation) {
16302
16407
  ];
16303
16408
  case "inspector":
16304
16409
  return ["--ak-role", "inspector"];
16410
+ case "gatekeeper":
16411
+ return ["--ak-role", "gatekeeper"];
16412
+ case "navigator":
16413
+ return ["--ak-role", "navigator"];
16305
16414
  default: {
16306
16415
  const _exhaustive = activation;
16307
16416
  return _exhaustive;
@@ -16671,7 +16780,9 @@ function validateAcceptedDetails(toolName, details) {
16671
16780
  [NOTARY_OUTPUT_TOOL_NAME]: ["pass", "bounce"],
16672
16781
  [COUNTERSIGN_OUTPUT_TOOL_NAME]: ["converged", "continue", "escalate"],
16673
16782
  [GLEANER_LEFT_OUTPUT_TOOL_NAME]: ["completed"],
16674
- [INSPECTOR_OUTPUT_TOOL_NAME]: ["pass", "bounce"]
16783
+ [INSPECTOR_OUTPUT_TOOL_NAME]: ["pass", "bounce"],
16784
+ [GATEKEEPER_OUTPUT_TOOL_NAME]: ["dispatch", "pass"],
16785
+ [NAVIGATOR_OUTPUT_TOOL_NAME]: ["advice"]
16675
16786
  };
16676
16787
  const collectorDiscriminator = toolName === COLLECTOR_OUTPUT_TOOL && Array.isArray(candidate?.groups);
16677
16788
  const baseDiscriminator = discriminator;
@@ -16703,6 +16814,10 @@ function validateAcceptedDetails(toolName, details) {
16703
16814
  return validateRecordedGleanerLeftOutput(details);
16704
16815
  case INSPECTOR_OUTPUT_TOOL_NAME:
16705
16816
  return validateRecordedInspectorOutput(details);
16817
+ case GATEKEEPER_OUTPUT_TOOL_NAME:
16818
+ return validateRecordedGatekeeperOutput(details);
16819
+ case NAVIGATOR_OUTPUT_TOOL_NAME:
16820
+ return validateRecordedNavigatorOutput(details);
16706
16821
  }
16707
16822
  } catch (error) {
16708
16823
  if (error instanceof Error && error.constructor === Error) throw new AcceptedDetailsContractError(error.message, { cause: error });
@@ -16718,6 +16833,8 @@ function acceptedFacts(toolName, details) {
16718
16833
  case NOTARY_OUTPUT_TOOL_NAME:
16719
16834
  case GLEANER_LEFT_OUTPUT_TOOL_NAME:
16720
16835
  case INSPECTOR_OUTPUT_TOOL_NAME:
16836
+ case GATEKEEPER_OUTPUT_TOOL_NAME:
16837
+ case NAVIGATOR_OUTPUT_TOOL_NAME:
16721
16838
  return { status: details.status };
16722
16839
  case JUDGE_OUTPUT_TOOL_NAME:
16723
16840
  return { status: details.judgeStatus };
@@ -16742,6 +16859,8 @@ var init_terminating_tools = __esm({
16742
16859
  init_audit_escalation();
16743
16860
  init_submission_correctable_error();
16744
16861
  init_doctor_contracts();
16862
+ init_gatekeeper_output();
16863
+ init_navigator_output();
16745
16864
  init_merger_contracts();
16746
16865
  init_notary_contracts();
16747
16866
  init_countersign_contracts();
@@ -16759,7 +16878,9 @@ var init_terminating_tools = __esm({
16759
16878
  NOTARY_OUTPUT_TOOL_NAME,
16760
16879
  COUNTERSIGN_OUTPUT_TOOL_NAME,
16761
16880
  GLEANER_LEFT_OUTPUT_TOOL_NAME,
16762
- INSPECTOR_OUTPUT_TOOL_NAME
16881
+ INSPECTOR_OUTPUT_TOOL_NAME,
16882
+ GATEKEEPER_OUTPUT_TOOL_NAME,
16883
+ NAVIGATOR_OUTPUT_TOOL_NAME
16763
16884
  ];
16764
16885
  AcceptedDetailsContractError = class extends CorrectableSubmissionError {
16765
16886
  code = "accepted_details_contract";
@@ -17204,7 +17325,7 @@ async function readRoleRunStateDisk(runDirectory) {
17204
17325
  if (typeof record4.runId !== "string" || record4.runId.trim() === "") {
17205
17326
  return void 0;
17206
17327
  }
17207
- if (record4.role !== "judge" && record4.role !== "coder" && record4.role !== "fixer" && record4.role !== "collector" && record4.role !== "doctor" && record4.role !== "reviewer" && record4.role !== "merger" && record4.role !== "notary" && record4.role !== "countersign" && record4.role !== "gleaner-left" && record4.role !== "inspector") {
17328
+ if (record4.role !== "judge" && record4.role !== "coder" && record4.role !== "fixer" && record4.role !== "collector" && record4.role !== "doctor" && record4.role !== "reviewer" && record4.role !== "merger" && record4.role !== "notary" && record4.role !== "countersign" && record4.role !== "gleaner-left" && record4.role !== "inspector" && record4.role !== "gatekeeper" && record4.role !== "navigator") {
17208
17329
  return void 0;
17209
17330
  }
17210
17331
  if (record4.state !== "admitted" && record4.state !== "running" && record4.state !== "resumable" && record4.state !== "terminal") {
@@ -18371,7 +18492,7 @@ function renderHumanOwnerOptionLines(owner, locale2 = "en") {
18371
18492
  }
18372
18493
  return lines;
18373
18494
  }
18374
- var ANALYST_REQUIRE_ANY_OF, ANALYST_DEFAULT_MODE, REJECTED_PUBLIC_SPELLINGS, GLOBAL_OPTIONS, SHARED_PROJECT_SEMANTICS, SHARED_ATTACH_SEMANTICS, JUDGE_OPTIONS, GLEANER_LEFT_OPTIONS, INSPECTOR_OPTIONS, COUNTERSIGN_OPTIONS, CODER_OPTIONS, FIXER_OPTIONS, REVIEWER_OPTIONS, COLLECTOR_OPTIONS, DOCTOR_OPTIONS, NOTARY_OPTIONS, MERGER_OPTIONS, ANALYST_OPTIONS, PUBLIC_OPTION_TABLE, PUBLIC_NAVIGATOR_HELP_NOTE, TOP_LEVEL_HELP, ROLE_COMMAND_HELP, SUPPORT_COMMAND_HELP, PUBLIC_COMMAND_HELP;
18495
+ var ANALYST_REQUIRE_ANY_OF, ANALYST_DEFAULT_MODE, REJECTED_PUBLIC_SPELLINGS, GLOBAL_OPTIONS, SHARED_PROJECT_SEMANTICS, SHARED_ATTACH_SEMANTICS, JUDGE_OPTIONS, GLEANER_LEFT_OPTIONS, INSPECTOR_OPTIONS, GATEKEEPER_OPTIONS, NAVIGATOR_OPTIONS, COUNTERSIGN_OPTIONS, CODER_OPTIONS, FIXER_OPTIONS, REVIEWER_OPTIONS, COLLECTOR_OPTIONS, DOCTOR_OPTIONS, NOTARY_OPTIONS, MERGER_OPTIONS, ANALYST_OPTIONS, PUBLIC_OPTION_TABLE, PUBLIC_NAVIGATOR_HELP_NOTE, TOP_LEVEL_HELP, ROLE_COMMAND_HELP, SUPPORT_COMMAND_HELP, PUBLIC_COMMAND_HELP;
18375
18496
  var init_option_definitions = __esm({
18376
18497
  "src/public-cli/option-definitions.ts"() {
18377
18498
  "use strict";
@@ -18536,6 +18657,14 @@ var init_option_definitions = __esm({
18536
18657
  bindOwner("inspector", SHARED_PROJECT_SEMANTICS),
18537
18658
  bindOwner("inspector", SHARED_ATTACH_SEMANTICS)
18538
18659
  ];
18660
+ GATEKEEPER_OPTIONS = [
18661
+ bindOwner("gatekeeper", SHARED_PROJECT_SEMANTICS),
18662
+ bindOwner("gatekeeper", SHARED_ATTACH_SEMANTICS)
18663
+ ];
18664
+ NAVIGATOR_OPTIONS = [
18665
+ bindOwner("navigator", SHARED_PROJECT_SEMANTICS),
18666
+ bindOwner("navigator", SHARED_ATTACH_SEMANTICS)
18667
+ ];
18539
18668
  COUNTERSIGN_OPTIONS = [
18540
18669
  bindOwner("countersign", SHARED_PROJECT_SEMANTICS),
18541
18670
  bindOwner("countersign", SHARED_ATTACH_SEMANTICS),
@@ -18911,9 +19040,11 @@ var init_option_definitions = __esm({
18911
19040
  merger: MERGER_OPTIONS,
18912
19041
  notary: NOTARY_OPTIONS,
18913
19042
  inspector: INSPECTOR_OPTIONS,
19043
+ gatekeeper: GATEKEEPER_OPTIONS,
19044
+ navigator: NAVIGATOR_OPTIONS,
18914
19045
  analyst: ANALYST_OPTIONS
18915
19046
  };
18916
- PUBLIC_NAVIGATOR_HELP_NOTE = "Navigator attends automatically on every run; configure with `ak-role config set navigator <provider/model[:thinking]>` (not a caller command).";
19047
+ PUBLIC_NAVIGATOR_HELP_NOTE = "Navigator also attends automatically on every run; that sidecar is unchanged by direct `ak-role navigator` calls.";
18917
19048
  TOP_LEVEL_HELP = {
18918
19049
  command: "top",
18919
19050
  summary: "public role CLI",
@@ -19013,6 +19144,22 @@ var init_option_definitions = __esm({
19013
19144
  'ak-role inspector --attach ./change.patch "Review this material."'
19014
19145
  ]
19015
19146
  },
19147
+ gatekeeper: {
19148
+ command: "gatekeeper",
19149
+ summary: "Direct Gatekeeper (\u95E8\u4E0B\u7701) review: dispatch an officer or pass.",
19150
+ usage: ["ak-role gatekeeper [options] [instruction]"],
19151
+ examples: [
19152
+ 'ak-role gatekeeper --attach ./submission.json "\u5BA1\uFF1A\u8FD9\u6279\u6750\u6599\u8BE5\u8C01\u5BA1\uFF1F"'
19153
+ ]
19154
+ },
19155
+ navigator: {
19156
+ command: "navigator",
19157
+ summary: "Direct Navigator (\u6E38\u5955\u4F7F) route advice: ordered next-role candidates.",
19158
+ usage: ["ak-role navigator [options] [instruction]"],
19159
+ examples: [
19160
+ 'ak-role navigator "\u521A\u5B8C\u6210 coder apply \u6536\u655B\uFF0C\u4E0B\u4E00\u6B65\uFF1F"'
19161
+ ]
19162
+ },
19016
19163
  notary: {
19017
19164
  command: "notary",
19018
19165
  summary: "Direct Notary document check (quote fidelity + ticket alignment); zero prompt/attachment.",
@@ -19373,6 +19520,12 @@ function parseCountersignArgv(args) {
19373
19520
  function parseInspectorArgv(args) {
19374
19521
  return parseInstructionArgv(args, "inspector");
19375
19522
  }
19523
+ function parseGatekeeperArgv(args) {
19524
+ return parseInstructionArgv(args, "gatekeeper");
19525
+ }
19526
+ function parseNavigatorArgv(args) {
19527
+ return parseInstructionArgv(args, "navigator");
19528
+ }
19376
19529
  function parseCoderArgv(args) {
19377
19530
  const attachmentPaths = [];
19378
19531
  let project;
@@ -19591,6 +19744,12 @@ async function admitJudgeInvocation(options) {
19591
19744
  async function admitInspectorInvocation(options) {
19592
19745
  return admitStandardMaterialInvocation("inspector", options);
19593
19746
  }
19747
+ async function admitGatekeeperInvocation(options) {
19748
+ return admitStandardMaterialInvocation("gatekeeper", options);
19749
+ }
19750
+ async function admitNavigatorInvocation(options) {
19751
+ return admitStandardMaterialInvocation("navigator", options);
19752
+ }
19594
19753
  function buildInstructionTransportPrompt(admitted, engineMaterial) {
19595
19754
  const lines = [admitted.instructionEmpty ? "" : admitted.instruction];
19596
19755
  if (admitted.attachments.length > 0) {
@@ -21242,11 +21401,11 @@ function resolvePackagedMethodSkillRoot(packageRoot2, name) {
21242
21401
  function resolvePackagedMethodSkillPath(packageRoot2, name) {
21243
21402
  return join15(resolvePackagedMethodSkillRoot(packageRoot2, name), "SKILL.md");
21244
21403
  }
21245
- function isRecord6(value) {
21404
+ function isRecord8(value) {
21246
21405
  return typeof value === "object" && value !== null && !Array.isArray(value);
21247
21406
  }
21248
21407
  function parseProvenance(raw, expectedName) {
21249
- if (!isRecord6(raw)) {
21408
+ if (!isRecord8(raw)) {
21250
21409
  throw new Error(`Packaged method provenance must be an object for ${expectedName}`);
21251
21410
  }
21252
21411
  if (raw.name !== expectedName) {
@@ -21260,7 +21419,7 @@ function parseProvenance(raw, expectedName) {
21260
21419
  if (typeof raw.packageAdaptation !== "string" || raw.packageAdaptation.trim() === "") {
21261
21420
  throw new Error(`Packaged method provenance packageAdaptation must be nonblank`);
21262
21421
  }
21263
- if (!isRecord6(raw.upstream)) {
21422
+ if (!isRecord8(raw.upstream)) {
21264
21423
  throw new Error(`Packaged method provenance upstream must be an object`);
21265
21424
  }
21266
21425
  const upstream = raw.upstream;
@@ -21287,12 +21446,12 @@ function parseProvenance(raw, expectedName) {
21287
21446
  `Packaged method provenance upstream must include nonblank tag or version`
21288
21447
  );
21289
21448
  }
21290
- if (!isRecord6(raw.files)) {
21449
+ if (!isRecord8(raw.files)) {
21291
21450
  throw new Error(`Packaged method provenance files must be an object`);
21292
21451
  }
21293
21452
  const files = {};
21294
21453
  for (const [rel, entry] of Object.entries(raw.files)) {
21295
- if (!isRecord6(entry)) {
21454
+ if (!isRecord8(entry)) {
21296
21455
  throw new Error(`Packaged method provenance file entry must be an object: ${rel}`);
21297
21456
  }
21298
21457
  if (typeof entry.sha256 !== "string" || !SHA256_RE.test(entry.sha256)) {
@@ -21451,7 +21610,7 @@ var init_method_skill = __esm({
21451
21610
 
21452
21611
  // src/ledger-session-read.ts
21453
21612
  import { readFile as readFile11 } from "node:fs/promises";
21454
- function isRecord7(value) {
21613
+ function isRecord9(value) {
21455
21614
  return typeof value === "object" && value !== null && !Array.isArray(value);
21456
21615
  }
21457
21616
  async function readLedgerSessionJsonl(path) {
@@ -21475,7 +21634,7 @@ async function readLedgerSessionJsonl(path) {
21475
21634
  }
21476
21635
  break;
21477
21636
  }
21478
- if (!isRecord7(row)) {
21637
+ if (!isRecord9(row)) {
21479
21638
  const kind = row === null ? "null" : Array.isArray(row) ? "array" : typeof row;
21480
21639
  throw new LedgerSessionJsonlError(
21481
21640
  `complete non-object JSONL record in ${path} at line ${index + 1}: expected object, got ${kind}`,
@@ -21512,7 +21671,7 @@ function extractSessionModelSequence(rows) {
21512
21671
  if (row.type === "model_change" && typeof row.modelId === "string") {
21513
21672
  push(row.modelId);
21514
21673
  }
21515
- const message = isRecord7(row.message) ? row.message : void 0;
21674
+ const message = isRecord9(row.message) ? row.message : void 0;
21516
21675
  if (message?.role === "assistant" && typeof message.model === "string") {
21517
21676
  push(message.model);
21518
21677
  }
@@ -21528,11 +21687,11 @@ function extractSessionToolIntervals(rows) {
21528
21687
  const openById = /* @__PURE__ */ new Map();
21529
21688
  for (const row of rows) {
21530
21689
  const rowTimestamp = typeof row.timestamp === "string" ? row.timestamp : void 0;
21531
- const message = isRecord7(row.message) ? row.message : void 0;
21690
+ const message = isRecord9(row.message) ? row.message : void 0;
21532
21691
  if (message?.role === "assistant" && Array.isArray(message.content)) {
21533
21692
  const callTimestamp = typeof message.timestamp === "string" && message.timestamp ? message.timestamp : rowTimestamp;
21534
21693
  for (const part of message.content) {
21535
- if (!isRecord7(part) || part.type !== "toolCall") continue;
21694
+ if (!isRecord9(part) || part.type !== "toolCall") continue;
21536
21695
  if (typeof part.id !== "string" || part.id.length === 0) {
21537
21696
  throw new Error("toolCall frame missing string id");
21538
21697
  }
@@ -21545,7 +21704,7 @@ function extractSessionToolIntervals(rows) {
21545
21704
  if (openById.has(part.id)) {
21546
21705
  throw new Error(`duplicate toolCall id ${part.id}`);
21547
21706
  }
21548
- const args = isRecord7(part.arguments) ? part.arguments : void 0;
21707
+ const args = isRecord9(part.arguments) ? part.arguments : void 0;
21549
21708
  const command = part.name === "bash" && args !== void 0 && typeof args.command === "string" ? bashCommandFirstLine(args.command) : void 0;
21550
21709
  const interval = {
21551
21710
  toolCallId: part.id,
@@ -21614,7 +21773,7 @@ var init_ledger_session_read = __esm({
21614
21773
  // src/analyst-gate-cycles-read.ts
21615
21774
  import { readdir as readdir3 } from "node:fs/promises";
21616
21775
  import { join as join16 } from "node:path";
21617
- function isRecord8(value) {
21776
+ function isRecord10(value) {
21618
21777
  return typeof value === "object" && value !== null && !Array.isArray(value);
21619
21778
  }
21620
21779
  function isMissingDirectoryError(error) {
@@ -21639,7 +21798,7 @@ function isGateTerminatingToolName(toolName) {
21639
21798
  function acceptedGateReceiptIds(rows) {
21640
21799
  const accepted = /* @__PURE__ */ new Set();
21641
21800
  for (const row of rows) {
21642
- const message = isRecord8(row.message) ? row.message : void 0;
21801
+ const message = isRecord10(row.message) ? row.message : void 0;
21643
21802
  if (message?.role !== "toolResult") continue;
21644
21803
  if (typeof message.toolCallId !== "string" || message.toolCallId.length === 0) continue;
21645
21804
  if (message.isError === false) accepted.add(message.toolCallId);
@@ -21650,17 +21809,17 @@ function extractLastAcceptedGateToolCall(rows) {
21650
21809
  const acceptedIds = acceptedGateReceiptIds(rows);
21651
21810
  let last;
21652
21811
  for (const row of rows) {
21653
- const message = isRecord8(row.message) ? row.message : void 0;
21812
+ const message = isRecord10(row.message) ? row.message : void 0;
21654
21813
  if (message?.role !== "assistant" || !Array.isArray(message.content)) continue;
21655
21814
  for (const part of message.content) {
21656
- if (!isRecord8(part) || part.type !== "toolCall") continue;
21815
+ if (!isRecord10(part) || part.type !== "toolCall") continue;
21657
21816
  if (typeof part.id !== "string" || part.id.length === 0) continue;
21658
21817
  if (!acceptedIds.has(part.id)) continue;
21659
21818
  if (typeof part.name !== "string" || part.name.length === 0) continue;
21660
21819
  if (!isGateTerminatingToolName(part.name)) continue;
21661
21820
  last = {
21662
21821
  toolName: part.name,
21663
- args: isRecord8(part.arguments) ? part.arguments : void 0
21822
+ args: isRecord10(part.arguments) ? part.arguments : void 0
21664
21823
  };
21665
21824
  }
21666
21825
  }
@@ -21826,14 +21985,14 @@ function isMissingPathError2(error) {
21826
21985
  function errorText2(error) {
21827
21986
  return error instanceof Error ? error.message : String(error);
21828
21987
  }
21829
- function isRecord9(value) {
21988
+ function isRecord11(value) {
21830
21989
  return typeof value === "object" && value !== null && !Array.isArray(value);
21831
21990
  }
21832
21991
  function readUsableTerminalArtifactBody(body) {
21833
21992
  if (body === null) {
21834
21993
  return { ok: false, reason: "terminal artifact JSON value is null" };
21835
21994
  }
21836
- if (!isRecord9(body)) {
21995
+ if (!isRecord11(body)) {
21837
21996
  return {
21838
21997
  ok: false,
21839
21998
  reason: `terminal artifact JSON value is not a typed object (${Array.isArray(body) ? "array" : typeof body})`
@@ -22044,7 +22203,7 @@ function resolvePackageRootDir(moduleUrl = import.meta.url) {
22044
22203
  }
22045
22204
  return fileURLToPath(new URL("..", moduleUrl));
22046
22205
  }
22047
- var packageRootUrl, MAIN_ROLE_SESSION_MATERIALS;
22206
+ var packageRootUrl, MAIN_ROLE_SESSION_MATERIALS, GATEKEEPER_SESSION_MATERIALS;
22048
22207
  var init_session_opening_materials = __esm({
22049
22208
  "src/session-opening-materials.ts"() {
22050
22209
  "use strict";
@@ -22053,8 +22212,13 @@ var init_session_opening_materials = __esm({
22053
22212
  MAIN_ROLE_SESSION_MATERIALS = {
22054
22213
  ...Object.fromEntries(
22055
22214
  PUBLIC_ROLE_RECORDS.map((record4) => [record4.role, record4.sessionMaterials])
22056
- ),
22057
- navigator: ["CLAUDE.md", "souls/navigator.md"]
22215
+ )
22216
+ };
22217
+ GATEKEEPER_SESSION_MATERIALS = {
22218
+ // #639: single authority — the public gatekeeper record owns the province list.
22219
+ gatekeeper: PUBLIC_ROLE_RECORDS.find((entry) => entry.role === "gatekeeper").sessionMaterials,
22220
+ inspector: INSPECTOR_SESSION_MATERIALS,
22221
+ notary: NOTARY_SESSION_MATERIALS
22058
22222
  };
22059
22223
  }
22060
22224
  });
@@ -22129,11 +22293,11 @@ var init_navigator_session_contracts = __esm({
22129
22293
  });
22130
22294
 
22131
22295
  // src/receipt-delivery-policy.ts
22132
- function isRecord10(value) {
22296
+ function isRecord12(value) {
22133
22297
  return typeof value === "object" && value !== null && !Array.isArray(value);
22134
22298
  }
22135
22299
  function parseNoReceiptLifecycleFacts(input) {
22136
- if (!isRecord10(input) || typeof input.terminalToolCalled !== "boolean" || input.deliveryTurns !== RECEIPT_DELIVERY_TURN_LIMIT || input.sessionCompletion !== "settled-without-accepted-receipt" || input.acceptedReceipt !== false || typeof input.runPointer !== "string" || input.runPointer.trim() === "" || typeof input.attemptPointer !== "string" || input.attemptPointer.trim() === "" || !Array.isArray(input.rejectedReceipts) || !input.rejectedReceipts.every((item) => isRecord10(item) && typeof item.reason === "string")) {
22300
+ if (!isRecord12(input) || typeof input.terminalToolCalled !== "boolean" || input.deliveryTurns !== RECEIPT_DELIVERY_TURN_LIMIT || input.sessionCompletion !== "settled-without-accepted-receipt" || input.acceptedReceipt !== false || typeof input.runPointer !== "string" || input.runPointer.trim() === "" || typeof input.attemptPointer !== "string" || input.attemptPointer.trim() === "" || !Array.isArray(input.rejectedReceipts) || !input.rejectedReceipts.every((item) => isRecord12(item) && typeof item.reason === "string")) {
22137
22301
  throw new TypeError("malformed no-receipt lifecycle facts");
22138
22302
  }
22139
22303
  return {
@@ -22505,7 +22669,7 @@ var init_collector_evidence = __esm({
22505
22669
 
22506
22670
  // src/collector-github.ts
22507
22671
  import { spawn as spawn3 } from "node:child_process";
22508
- function isRecord11(value) {
22672
+ function isRecord13(value) {
22509
22673
  return typeof value === "object" && value !== null && !Array.isArray(value);
22510
22674
  }
22511
22675
  function requireString(value, label) {
@@ -22546,25 +22710,25 @@ function commentFailureCause(error) {
22546
22710
  };
22547
22711
  }
22548
22712
  function requireUserLogin(raw) {
22549
- if (!isRecord11(raw) || typeof raw["login"] !== "string") {
22713
+ if (!isRecord13(raw) || typeof raw["login"] !== "string") {
22550
22714
  throw new Error("GitHub payload missing user.login");
22551
22715
  }
22552
22716
  return raw["login"];
22553
22717
  }
22554
22718
  function optionalUserLogin(raw) {
22555
22719
  if (raw === null) return null;
22556
- if (!isRecord11(raw) || typeof raw["login"] !== "string") {
22720
+ if (!isRecord13(raw) || typeof raw["login"] !== "string") {
22557
22721
  throw new Error("GitHub payload missing user.login");
22558
22722
  }
22559
22723
  return raw["login"];
22560
22724
  }
22561
22725
  function machineIdentity(raw) {
22562
22726
  const user = raw["user"];
22563
- if (!isRecord11(user) || typeof user["type"] !== "string" || typeof user["id"] !== "number") {
22727
+ if (!isRecord13(user) || typeof user["type"] !== "string" || typeof user["id"] !== "number") {
22564
22728
  return null;
22565
22729
  }
22566
22730
  const app = raw["performed_via_github_app"];
22567
- const appId = isRecord11(app) && typeof app["id"] === "number" ? app["id"] : void 0;
22731
+ const appId = isRecord13(app) && typeof app["id"] === "number" ? app["id"] : void 0;
22568
22732
  return {
22569
22733
  userType: user["type"],
22570
22734
  userId: user["id"],
@@ -22572,9 +22736,9 @@ function machineIdentity(raw) {
22572
22736
  };
22573
22737
  }
22574
22738
  function normalizePullRequest(raw) {
22575
- if (!isRecord11(raw)) throw new Error("GitHub pull request payload must be an object");
22739
+ if (!isRecord13(raw)) throw new Error("GitHub pull request payload must be an object");
22576
22740
  const head = raw["head"];
22577
- if (!isRecord11(head) || typeof head["sha"] !== "string" || head["sha"].length === 0) {
22741
+ if (!isRecord13(head) || typeof head["sha"] !== "string" || head["sha"].length === 0) {
22578
22742
  throw new Error("GitHub pull request payload missing head.sha");
22579
22743
  }
22580
22744
  const number = requireNumber(raw["number"], "number");
@@ -22590,7 +22754,7 @@ function normalizePullRequest(raw) {
22590
22754
  };
22591
22755
  }
22592
22756
  function normalizePullRequestReaction(raw) {
22593
- if (!isRecord11(raw)) throw new Error("GitHub reaction payload must be an object");
22757
+ if (!isRecord13(raw)) throw new Error("GitHub reaction payload must be an object");
22594
22758
  return {
22595
22759
  id: requireNumber(raw["id"], "reaction.id"),
22596
22760
  userLogin: optionalUserLogin(raw["user"]),
@@ -22601,7 +22765,7 @@ function normalizePullRequestReaction(raw) {
22601
22765
  };
22602
22766
  }
22603
22767
  function normalizeReview(raw) {
22604
- if (!isRecord11(raw)) throw new Error("GitHub review payload must be an object");
22768
+ if (!isRecord13(raw)) throw new Error("GitHub review payload must be an object");
22605
22769
  return {
22606
22770
  id: requireNumber(raw["id"], "review.id"),
22607
22771
  ...typeof raw["node_id"] === "string" ? { nodeId: raw["node_id"] } : {},
@@ -22616,7 +22780,7 @@ function normalizeReview(raw) {
22616
22780
  };
22617
22781
  }
22618
22782
  function normalizeIssueComment(raw) {
22619
- if (!isRecord11(raw)) throw new Error("GitHub issue comment payload must be an object");
22783
+ if (!isRecord13(raw)) throw new Error("GitHub issue comment payload must be an object");
22620
22784
  return {
22621
22785
  id: requireNumber(raw["id"], "comment.id"),
22622
22786
  userLogin: optionalUserLogin(raw["user"]),
@@ -22629,7 +22793,7 @@ function normalizeIssueComment(raw) {
22629
22793
  };
22630
22794
  }
22631
22795
  function normalizeReviewComment(raw) {
22632
- if (!isRecord11(raw)) throw new Error("GitHub review comment payload must be an object");
22796
+ if (!isRecord13(raw)) throw new Error("GitHub review comment payload must be an object");
22633
22797
  return {
22634
22798
  id: requireNumber(raw["id"], "review_comment.id"),
22635
22799
  pullRequestReviewId: typeof raw["pull_request_review_id"] === "number" ? raw["pull_request_review_id"] : null,
@@ -22938,11 +23102,11 @@ function createGhCollectorGitHubTransport(runner = createGhApiRunner()) {
22938
23102
  if (input.signal?.aborted) {
22939
23103
  throw error;
22940
23104
  }
22941
- if (isRecord11(error) && error["ambiguousGhFailure"] === true) {
23105
+ if (isRecord13(error) && error["ambiguousGhFailure"] === true) {
22942
23106
  const cause = commentFailureCause(error);
22943
23107
  return { kind: "ambiguous_loss", diagnostics: cause.message, cause };
22944
23108
  }
22945
- if (isRecord11(error) && error["name"] === "AbortError") {
23109
+ if (isRecord13(error) && error["name"] === "AbortError") {
22946
23110
  throw error;
22947
23111
  }
22948
23112
  throw error;
@@ -23122,7 +23286,7 @@ var init_navigator_invocation_identity = __esm({
23122
23286
 
23123
23287
  // src/public-command-renderer.ts
23124
23288
  function isPublicCallableRole2(role) {
23125
- return PUBLIC_CALLABLE_ROLES2.has(role);
23289
+ return PUBLIC_CALLABLE_ROLES3.has(role);
23126
23290
  }
23127
23291
  function renderPublicAkRoleCommand(target) {
23128
23292
  if (!isPublicCallableRole2(target.role)) return void 0;
@@ -23139,12 +23303,12 @@ function renderPublicAkRoleCommand(target) {
23139
23303
  }
23140
23304
  return `ak-role ${role}`;
23141
23305
  }
23142
- var PUBLIC_CALLABLE_ROLES2;
23306
+ var PUBLIC_CALLABLE_ROLES3;
23143
23307
  var init_public_command_renderer = __esm({
23144
23308
  "src/public-command-renderer.ts"() {
23145
23309
  "use strict";
23146
23310
  init_packaged_role_registry();
23147
- PUBLIC_CALLABLE_ROLES2 = new Set(
23311
+ PUBLIC_CALLABLE_ROLES3 = new Set(
23148
23312
  PACKAGED_ROLE_REGISTRY.map((entry) => entry.role)
23149
23313
  );
23150
23314
  }
@@ -23570,7 +23734,7 @@ async function readSitianRetainedAuditorProviderStop(sessionFile) {
23570
23734
  const { records: records2 } = await readSitianRecords(recordFile);
23571
23735
  for (let i = records2.length - 1; i >= 0; i -= 1) {
23572
23736
  const payload = records2[i]?.payload;
23573
- if (!isRecord12(payload) || !isRecord12(payload.response)) continue;
23737
+ if (!isRecord14(payload) || !isRecord14(payload.response)) continue;
23574
23738
  if (typeof payload.type === "string") continue;
23575
23739
  const stop = sessionProviderStopFromAssistant(payload.response);
23576
23740
  if (stop !== void 0) return stop;
@@ -23607,7 +23771,7 @@ async function readBoundEvidenceChildKnownFailure(sessionFile) {
23607
23771
  throw sessionReadFailure(error, "failed to read discovered evidence-child session");
23608
23772
  }
23609
23773
  const header = entries.find((entry) => entry.type === "session");
23610
- if (!isRecord12(header) || header.parentSession !== sessionFile) continue;
23774
+ if (!isRecord14(header) || header.parentSession !== sessionFile) continue;
23611
23775
  const stop = extractSessionProviderStop(entries);
23612
23776
  if (stop === void 0) continue;
23613
23777
  const primary = knownFailureFromProviderStop(stop);
@@ -23639,12 +23803,12 @@ async function loadBoundAuditorVolumes(sessionFile) {
23639
23803
  return firstLine === RESUME_ENVELOPE;
23640
23804
  };
23641
23805
  const isResumeEnvelope = (msg) => {
23642
- if (!isRecord12(msg) || msg.role !== "user") return false;
23806
+ if (!isRecord14(msg) || msg.role !== "user") return false;
23643
23807
  const text = typeof msg.text === "string" ? msg.text : typeof msg.content === "string" ? msg.content : void 0;
23644
23808
  if (isResumeEnvelopeBytes(text)) return true;
23645
23809
  const content = msg.content;
23646
23810
  if (Array.isArray(content)) {
23647
- return content.some((p) => isRecord12(p) && (isResumeEnvelopeBytes(p.text) || isResumeEnvelopeBytes(p.content)));
23811
+ return content.some((p) => isRecord14(p) && (isResumeEnvelopeBytes(p.text) || isResumeEnvelopeBytes(p.content)));
23648
23812
  }
23649
23813
  return false;
23650
23814
  };
@@ -23673,9 +23837,9 @@ async function loadBoundAuditorVolumes(sessionFile) {
23673
23837
  throw sessionReadFailure(error, "failed to read discovered auditor session");
23674
23838
  }
23675
23839
  const header = entries.find((entry) => entry.type === "session");
23676
- if (!isRecord12(header) || header.parentSession !== sessionFile) continue;
23840
+ if (!isRecord14(header) || header.parentSession !== sessionFile) continue;
23677
23841
  const bindingEntry = entries.find((entry) => entry.type === "custom" && entry.customType === AUDITOR_PARENT_ATTEMPT_BINDING_ENTRY_TYPE);
23678
- const bindingParent = isRecord12(bindingEntry?.data) && isRecord12(bindingEntry.data.parent) ? bindingEntry.data.parent : void 0;
23842
+ const bindingParent = isRecord14(bindingEntry?.data) && isRecord14(bindingEntry.data.parent) ? bindingEntry.data.parent : void 0;
23679
23843
  const attemptEntryId = typeof bindingParent?.attemptEntryId === "string" ? bindingParent.attemptEntryId : void 0;
23680
23844
  const attemptEntryIndex = attemptEntryId === void 0 ? -1 : parentEntries.findIndex((entry) => entry.id === attemptEntryId);
23681
23845
  if (bindingParent?.sessionId !== parentId || bindingParent.sessionFile !== sessionFile || attemptEntryIndex < latestParentUserIndex) continue;
@@ -23694,11 +23858,11 @@ function complianceFailureFromAuditorVolumes(volumes) {
23694
23858
  if (stop === void 0) continue;
23695
23859
  for (let i = entries.length - 1; i >= 0; i -= 1) {
23696
23860
  const entry = entries[i];
23697
- if (entry?.type !== "custom" || entry.customType !== AUDITOR_COMPLIANCE_FAILURE_ENTRY_TYPE || !isRecord12(entry.data)) continue;
23698
- const parent = isRecord12(entry.data.parent) ? entry.data.parent : void 0;
23699
- const failure = isRecord12(entry.data.failure) ? entry.data.failure : void 0;
23861
+ if (entry?.type !== "custom" || entry.customType !== AUDITOR_COMPLIANCE_FAILURE_ENTRY_TYPE || !isRecord14(entry.data)) continue;
23862
+ const parent = isRecord14(entry.data.parent) ? entry.data.parent : void 0;
23863
+ const failure = isRecord14(entry.data.failure) ? entry.data.failure : void 0;
23700
23864
  if (parent?.sessionId !== parentId || parent.sessionFile !== sessionFile || parent.attemptEntryId !== attemptEntryId || failure?.cause !== "provider" && failure?.cause !== "unrecognized") continue;
23701
- const identity = isRecord12(failure.identity) ? failure.identity : void 0;
23865
+ const identity = isRecord14(failure.identity) ? failure.identity : void 0;
23702
23866
  return {
23703
23867
  cause: failure.cause === "provider" ? "provider" : "unrecognized",
23704
23868
  ...identity === void 0 ? {} : { identity: {
@@ -23706,7 +23870,7 @@ function complianceFailureFromAuditorVolumes(volumes) {
23706
23870
  ...typeof identity.code === "string" || typeof identity.code === "number" ? { code: identity.code } : {}
23707
23871
  } },
23708
23872
  ...typeof failure.diagnostic === "string" ? { diagnostic: failure.diagnostic } : {},
23709
- ...isRecord12(failure.details) ? { details: failure.details } : {}
23873
+ ...isRecord14(failure.details) ? { details: failure.details } : {}
23710
23874
  };
23711
23875
  }
23712
23876
  }
@@ -23753,9 +23917,9 @@ function typedFailedTerminatingToolKnownFailure(entries) {
23753
23917
  if (classification.kind !== "infrastructure") continue;
23754
23918
  if (typeof message.toolCallId !== "string" || typeof message.toolName !== "string") continue;
23755
23919
  if (boundRoleToolCallForResult(attemptEntries, i, message, message.toolName) === void 0) continue;
23756
- const textPart = Array.isArray(message.content) ? message.content.find((part) => isRecord12(part) && part.type === "text" && typeof part.text === "string") : void 0;
23757
- const diagnostic = isRecord12(textPart) ? textPart.text : void 0;
23758
- const details = isRecord12(message.details) ? message.details : classification.fact;
23920
+ const textPart = Array.isArray(message.content) ? message.content.find((part) => isRecord14(part) && part.type === "text" && typeof part.text === "string") : void 0;
23921
+ const diagnostic = isRecord14(textPart) ? textPart.text : void 0;
23922
+ const details = isRecord14(message.details) ? message.details : classification.fact;
23759
23923
  return {
23760
23924
  cause: "output",
23761
23925
  identity: { name: message.toolName, code: message.toolCallId },
@@ -23913,7 +24077,7 @@ function controlledFailureInputFromResolution(resolution) {
23913
24077
  } : {}
23914
24078
  };
23915
24079
  }
23916
- function isRecord12(value) {
24080
+ function isRecord14(value) {
23917
24081
  return typeof value === "object" && value !== null && !Array.isArray(value);
23918
24082
  }
23919
24083
  function safelyRead(object, key) {
@@ -23936,7 +24100,7 @@ function countersignDecisiveFacts(verdict, countersignStatus) {
23936
24100
  const facts = { countersignStatus };
23937
24101
  if (countersignStatus === "continue") {
23938
24102
  const fix = safelyRead(verdict, "fix");
23939
- if (fix.readable && isRecord12(fix.value)) {
24103
+ if (fix.readable && isRecord14(fix.value)) {
23940
24104
  const summary = safelyRead(fix.value, "summary");
23941
24105
  if (summary.readable && typeof summary.value === "string") {
23942
24106
  facts.fixSummary = summary.value;
@@ -23945,7 +24109,7 @@ function countersignDecisiveFacts(verdict, countersignStatus) {
23945
24109
  }
23946
24110
  if (countersignStatus === "escalate") {
23947
24111
  const gate = safelyRead(verdict, "decisionGate");
23948
- if (gate.readable && isRecord12(gate.value)) {
24112
+ if (gate.readable && isRecord14(gate.value)) {
23949
24113
  const question = safelyRead(gate.value, "question");
23950
24114
  const options = safelyRead(gate.value, "options");
23951
24115
  if (question.readable && typeof question.value === "string") {
@@ -23970,7 +24134,7 @@ function judgeDecisiveFacts(verdict, judgeStatus) {
23970
24134
  const statusBase = judgeStatus;
23971
24135
  if (statusBase === "continue") {
23972
24136
  const fix = safelyRead(verdict, "fix");
23973
- if (fix.readable && isRecord12(fix.value)) {
24137
+ if (fix.readable && isRecord14(fix.value)) {
23974
24138
  const summary = safelyRead(fix.value, "summary");
23975
24139
  if (summary.readable && typeof summary.value === "string") {
23976
24140
  facts.fixSummary = summary.value;
@@ -23980,7 +24144,7 @@ function judgeDecisiveFacts(verdict, judgeStatus) {
23980
24144
  if (classes.readable && Array.isArray(classes.value)) {
23981
24145
  try {
23982
24146
  facts.classes = classes.value.map((entry) => {
23983
- if (!isRecord12(entry)) throw new Error("unreadable Judge class");
24147
+ if (!isRecord14(entry)) throw new Error("unreadable Judge class");
23984
24148
  return {
23985
24149
  name: entry.name,
23986
24150
  owner: entry.owner,
@@ -23995,7 +24159,7 @@ function judgeDecisiveFacts(verdict, judgeStatus) {
23995
24159
  }
23996
24160
  if (statusBase === "escalate") {
23997
24161
  const gate = safelyRead(verdict, "decisionGate");
23998
- if (gate.readable && isRecord12(gate.value)) {
24162
+ if (gate.readable && isRecord14(gate.value)) {
23999
24163
  const question = safelyRead(gate.value, "question");
24000
24164
  const options = safelyRead(gate.value, "options");
24001
24165
  if (question.readable && typeof question.value === "string") {
@@ -24041,7 +24205,7 @@ function fixerDecisiveFacts(output) {
24041
24205
  facts.reason = reason.value;
24042
24206
  }
24043
24207
  const blockerRead = safelyRead(candidate, "blocker");
24044
- if (statusBase === "refused" && blockerRead.readable && isRecord12(blockerRead.value)) {
24208
+ if (statusBase === "refused" && blockerRead.readable && isRecord14(blockerRead.value)) {
24045
24209
  const cause = safelyRead(blockerRead.value, "cause");
24046
24210
  if (cause.readable && typeof cause.value === "string") facts.blockerCause = cause.value;
24047
24211
  const prerequisiteId = safelyRead(blockerRead.value, "prerequisiteId");
@@ -24053,13 +24217,13 @@ function fixerDecisiveFacts(output) {
24053
24217
  const blockers = [];
24054
24218
  try {
24055
24219
  for (const entry of classResults.value) {
24056
- if (!isRecord12(entry)) throw new Error("unreadable class result");
24220
+ if (!isRecord14(entry)) throw new Error("unreadable class result");
24057
24221
  const name = safelyRead(entry, "name");
24058
24222
  const disposition = safelyRead(entry, "disposition");
24059
24223
  if (!name.readable || !disposition.readable) throw new Error("unreadable class result");
24060
24224
  rows.push({ name: name.value, disposition: disposition.value });
24061
24225
  const blocker = safelyRead(entry, "blocker");
24062
- if (disposition.value === "refused" && blocker.readable && isRecord12(blocker.value)) blockers.push(blocker.value);
24226
+ if (disposition.value === "refused" && blocker.readable && isRecord14(blocker.value)) blockers.push(blocker.value);
24063
24227
  }
24064
24228
  facts.classResultCount = rows.length;
24065
24229
  facts.classDispositions = rows;
@@ -24092,7 +24256,7 @@ function collectorDecisiveFacts(receipt) {
24092
24256
  if (groups.readable && Array.isArray(groups.value)) {
24093
24257
  try {
24094
24258
  facts.groups = groups.value.map((group) => {
24095
- if (!isRecord12(group)) throw new Error("unreadable Collector group");
24259
+ if (!isRecord14(group)) throw new Error("unreadable Collector group");
24096
24260
  const identity = safelyRead(group, "identity");
24097
24261
  const attendance = safelyRead(group, "attendance");
24098
24262
  const materials = safelyRead(group, "materials");
@@ -24126,7 +24290,7 @@ function doctorDecisiveFacts(output) {
24126
24290
  return facts;
24127
24291
  }
24128
24292
  const caseValue = safelyRead(candidate, "case");
24129
- if (caseValue.readable && isRecord12(caseValue.value)) {
24293
+ if (caseValue.readable && isRecord14(caseValue.value)) {
24130
24294
  const issueNumber = safelyRead(caseValue.value, "issueNumber");
24131
24295
  const runsPath = safelyRead(caseValue.value, "runsPath");
24132
24296
  if (issueNumber.readable && issueNumber.value !== void 0) facts.issueNumber = issueNumber.value;
@@ -24137,7 +24301,7 @@ function doctorDecisiveFacts(output) {
24137
24301
  return facts;
24138
24302
  }
24139
24303
  function reviewerAxes(value) {
24140
- if (!isRecord12(value)) return [];
24304
+ if (!isRecord14(value)) return [];
24141
24305
  return ["standards", "spec"].filter((axis) => {
24142
24306
  const projected = safelyRead(value, axis);
24143
24307
  return projected.readable && projected.value !== void 0;
@@ -24265,7 +24429,7 @@ function boundRoleToolCallForResult(entries, resultIndex, message, outputToolNam
24265
24429
  const candidateMessage = entries[index]?.message;
24266
24430
  if (candidateMessage?.role === "assistant" && Array.isArray(candidateMessage.content)) {
24267
24431
  for (const part of candidateMessage.content) {
24268
- if (!isRecord12(part) || part.type !== "toolCall" || part.id !== callId) {
24432
+ if (!isRecord14(part) || part.type !== "toolCall" || part.id !== callId) {
24269
24433
  continue;
24270
24434
  }
24271
24435
  if (part.name !== outputToolName) return void 0;
@@ -24337,7 +24501,7 @@ function parseNavigatorAttendanceDetails(details) {
24337
24501
  const advisoryDiagnostic = typeof details.routePlaybookReadFailure === "string" ? { advisoryDiagnostic: details.routePlaybookReadFailure } : {};
24338
24502
  if (disposition === "recommendation") {
24339
24503
  const next = details.next;
24340
- if (!isRecord12(next) || typeof next.role !== "string") {
24504
+ if (!isRecord14(next) || typeof next.role !== "string") {
24341
24505
  return {
24342
24506
  disposition: "unavailable",
24343
24507
  source: "unknown",
@@ -24345,7 +24509,7 @@ function parseNavigatorAttendanceDetails(details) {
24345
24509
  };
24346
24510
  }
24347
24511
  const reason = typeof details.reason === "string" ? details.reason : "";
24348
- const route = Array.isArray(details.route) ? details.route.filter(isRecord12).map((target) => ({
24512
+ const route = Array.isArray(details.route) ? details.route.filter(isRecord14).map((target) => ({
24349
24513
  role: String(target.role),
24350
24514
  phase: navigatorPhaseValue(target.phase)
24351
24515
  })) : void 0;
@@ -24413,7 +24577,7 @@ async function extractGateFactFromSessionDirectory(sessionDirectory) {
24413
24577
  }
24414
24578
  async function withOptionalGateProjection(base, sessionDirectory) {
24415
24579
  const secondaryEvidence = base.roleOutcome.kind === "failure" ? base.roleOutcome.decisiveFacts.secondaryEvidence : void 0;
24416
- if (isRecord12(secondaryEvidence) && secondaryEvidence.kind === "role_infrastructure_failure" && (secondaryEvidence.stage === "gatekeeper" || secondaryEvidence.stage === "inspector" || secondaryEvidence.stage === "notary")) return base;
24580
+ if (isRecord14(secondaryEvidence) && secondaryEvidence.kind === "role_infrastructure_failure" && (secondaryEvidence.stage === "gatekeeper" || secondaryEvidence.stage === "inspector" || secondaryEvidence.stage === "notary")) return base;
24417
24581
  const gate = await extractGateFactFromSessionDirectory(sessionDirectory);
24418
24582
  return gate === void 0 ? base : { ...base, gate };
24419
24583
  }
@@ -24453,7 +24617,7 @@ function extractNavigatorFact(entries) {
24453
24617
  const entry = entries[i];
24454
24618
  if (entry?.type === "custom_message" && entry.customType === "ak-navigator-attendance") {
24455
24619
  const details = entry.message?.details ?? entry.details;
24456
- if (!isRecord12(details)) {
24620
+ if (!isRecord14(details)) {
24457
24621
  return {
24458
24622
  disposition: "unavailable",
24459
24623
  source: "unknown",
@@ -24867,7 +25031,7 @@ async function settleLawfulCollectorTerminalResult(admitted, authority) {
24867
25031
  const residual = boundErroredToolCandidate(entries, index, message, COLLECTOR_WAIT_TOOL);
24868
25032
  if (residual === void 0) continue;
24869
25033
  const candidate = residual.candidate;
24870
- const duration = isRecord12(candidate) ? candidate.durationMs : void 0;
25034
+ const duration = isRecord14(candidate) ? candidate.durationMs : void 0;
24871
25035
  if (Number.isSafeInteger(duration) && duration >= 1 && duration <= 9e5) {
24872
25036
  continue;
24873
25037
  }
@@ -25067,10 +25231,22 @@ async function settleLawfulOneShotAcceptedTerminalResult(admitted, authority, sp
25067
25231
  }
25068
25232
  return void 0;
25069
25233
  }
25234
+ if (!spec.tryAcceptDetails(roleOutcome.decisiveFacts)) {
25235
+ return settleFailureTerminalResult(
25236
+ admitted,
25237
+ {
25238
+ cause: "output",
25239
+ diagnostic: spec.nonUsableDiagnostic,
25240
+ details: { candidate: roleOutcome.decisiveFacts, acceptedReceipt: false }
25241
+ },
25242
+ authority
25243
+ );
25244
+ }
25245
+ const acceptedOutcome = spec.projectAccepted(roleOutcome);
25070
25246
  const navigator = extractNavigatorFact(entries);
25071
25247
  return withOptionalGateProjection(
25072
25248
  {
25073
- roleOutcome: spec.projectAccepted(roleOutcome),
25249
+ roleOutcome: acceptedOutcome,
25074
25250
  navigator,
25075
25251
  artifacts: [],
25076
25252
  runId: admitted.runId
@@ -25174,6 +25350,48 @@ async function settleLawfulInspectorTerminalResult(admitted, authority) {
25174
25350
  async function trySettleInspectorTerminalResult(admitted, authority) {
25175
25351
  return settleLawfulInspectorTerminalResult(admitted, authority);
25176
25352
  }
25353
+ async function settleLawfulGatekeeperTerminalResult(admitted, authority) {
25354
+ return settleLawfulOneShotAcceptedTerminalResult(admitted, authority, {
25355
+ role: "gatekeeper",
25356
+ toolName: GATEKEEPER_OUTPUT_TOOL_NAME,
25357
+ nonUsableDiagnostic: "\u95E8\u4E0B\u7701\u51B3\u8BAE\u65E0\u663E\u5F0F dispatch/pass",
25358
+ tryAcceptDetails: tryAcceptWithValidator(validateRecordedGatekeeperOutput),
25359
+ projectAccepted: (sealed) => {
25360
+ const output = validateRecordedGatekeeperOutput(sealed.decisiveFacts);
25361
+ const accepted = {
25362
+ kind: "accepted",
25363
+ role: "gatekeeper",
25364
+ status: output.status,
25365
+ decisiveFacts: gatekeeperDecisiveFacts(output)
25366
+ };
25367
+ return accepted;
25368
+ }
25369
+ });
25370
+ }
25371
+ async function trySettleGatekeeperTerminalResult(admitted, authority) {
25372
+ return settleLawfulGatekeeperTerminalResult(admitted, authority);
25373
+ }
25374
+ async function settleLawfulNavigatorTerminalResult(admitted, authority) {
25375
+ return settleLawfulOneShotAcceptedTerminalResult(admitted, authority, {
25376
+ role: "navigator",
25377
+ toolName: NAVIGATOR_OUTPUT_TOOL_NAME,
25378
+ nonUsableDiagnostic: "\u6E38\u5955\u4F7F\u56DE\u6267\u65E0\u663E\u5F0F\u8DEF\u7EBF\u5EFA\u8BAE",
25379
+ tryAcceptDetails: tryAcceptWithValidator(validateRecordedNavigatorOutput),
25380
+ projectAccepted: (sealed) => {
25381
+ const output = validateRecordedNavigatorOutput(sealed.decisiveFacts);
25382
+ const accepted = {
25383
+ kind: "accepted",
25384
+ role: "navigator",
25385
+ status: "advice",
25386
+ decisiveFacts: navigatorDecisiveFacts(output)
25387
+ };
25388
+ return accepted;
25389
+ }
25390
+ });
25391
+ }
25392
+ async function trySettleNavigatorTerminalResult(admitted, authority) {
25393
+ return settleLawfulNavigatorTerminalResult(admitted, authority);
25394
+ }
25177
25395
  async function trySettleCoderTerminalResult(admitted, authority, options = {}) {
25178
25396
  return settleLawfulCoderTerminalResult(admitted, authority, options);
25179
25397
  }
@@ -25419,7 +25637,7 @@ async function settleLawfulMergerTerminalResult(admitted, authority, options) {
25419
25637
  if (message?.role !== "toolResult") continue;
25420
25638
  const residual = boundErroredToolCandidate(entries, index, message, MERGER_OUTPUT_TOOL_NAME);
25421
25639
  if (residual === void 0) continue;
25422
- const attemptId = isRecord12(residual.candidate) ? safelyRead(residual.candidate, "attemptId") : { readable: true, value: void 0 };
25640
+ const attemptId = isRecord14(residual.candidate) ? safelyRead(residual.candidate, "attemptId") : { readable: true, value: void 0 };
25423
25641
  if (!attemptId.readable || attemptId.value !== admitted.runId) continue;
25424
25642
  try {
25425
25643
  validateMergerOutput(residual.candidate, admitted.runId);
@@ -25802,6 +26020,8 @@ var init_settlement = __esm({
25802
26020
  init_countersign_contracts();
25803
26021
  init_gleaner_left_contracts();
25804
26022
  init_inspector_contracts();
26023
+ init_gatekeeper_output();
26024
+ init_navigator_output();
25805
26025
  init_method_skill();
25806
26026
  init_navigator_invocation_identity();
25807
26027
  init_receipt_delivery_policy();
@@ -26880,6 +27100,90 @@ var init_coder_run = __esm({
26880
27100
  }
26881
27101
  });
26882
27102
 
27103
+ // src/public-cli/instruction-seat-run.ts
27104
+ function buildInstructionSeatTurnRequest(admitted, options) {
27105
+ return projectRoleTurnRequest(
27106
+ admitted,
27107
+ {
27108
+ activation: {
27109
+ role: admitted.role
27110
+ }
27111
+ },
27112
+ options
27113
+ );
27114
+ }
27115
+ function instructionSeatAdapters() {
27116
+ return {
27117
+ trySettle: (admitted, authority) => admitted.role === "gatekeeper" ? trySettleGatekeeperTerminalResult(admitted, authority) : trySettleNavigatorTerminalResult(admitted, authority),
27118
+ // Accepted receipts and failure terminals both present via shared path.
27119
+ shouldPresentSettled: () => true
27120
+ };
27121
+ }
27122
+ async function runPublicInstructionSeat(argv, env, io, role, parseArgv2) {
27123
+ let admitted;
27124
+ try {
27125
+ const parsed = parseArgv2(argv);
27126
+ const options = {
27127
+ home: env.home,
27128
+ principalAuthority: env.principalAuthority,
27129
+ cwd: env.cwd,
27130
+ instruction: parsed.instruction,
27131
+ attachmentPaths: parsed.attachmentPaths,
27132
+ ...parsed.project === void 0 ? {} : { project: parsed.project },
27133
+ ...env.createRunId === void 0 ? {} : { createRunId: env.createRunId },
27134
+ ...env.model === void 0 ? {} : { model: env.model },
27135
+ ...env.correlationId === void 0 ? {} : { correlationId: env.correlationId }
27136
+ };
27137
+ admitted = role === "gatekeeper" ? await admitGatekeeperInvocation(options) : await admitNavigatorInvocation(options);
27138
+ } catch (error) {
27139
+ if (error instanceof CliUsageError) {
27140
+ presentStructuralRejection(error, io);
27141
+ return { exitCode: 2 };
27142
+ }
27143
+ throw error;
27144
+ }
27145
+ await markRunAdmitted(admitted, env.principalAuthority);
27146
+ const turnRequest = buildInstructionSeatTurnRequest(admitted, {
27147
+ packageRoot: env.packageRoot,
27148
+ home: env.home,
27149
+ agentDir: env.agentDir,
27150
+ ...env.model === void 0 ? {} : { model: env.model },
27151
+ ...env.engine === void 0 ? {} : { engine: env.engine },
27152
+ ...env.timeoutMs === void 0 ? {} : { timeoutMs: env.timeoutMs },
27153
+ ...env.correlationId === void 0 || env.correlationId.trim() === "" ? {} : { correlationId: env.correlationId },
27154
+ continuation: {
27155
+ kind: "initial",
27156
+ prompt: buildInstructionTransportPrompt(
27157
+ admitted,
27158
+ engineSessionMaterialFromOptions({
27159
+ ...env.engine === void 0 ? {} : { engine: env.engine },
27160
+ packageRoot: env.packageRoot
27161
+ })
27162
+ )
27163
+ }
27164
+ });
27165
+ return await runPostAdmissionOneShot({
27166
+ admitted,
27167
+ env,
27168
+ io,
27169
+ request: turnRequest,
27170
+ adapters: instructionSeatAdapters(),
27171
+ ...env.engine === void 0 ? {} : { effectiveEngine: env.engine }
27172
+ });
27173
+ }
27174
+ var init_instruction_seat_run = __esm({
27175
+ "src/public-cli/instruction-seat-run.ts"() {
27176
+ "use strict";
27177
+ init_engine_material();
27178
+ init_cli_errors();
27179
+ init_invocation();
27180
+ init_post_admission();
27181
+ init_run_lifecycle();
27182
+ init_settlement();
27183
+ init_turn_request();
27184
+ }
27185
+ });
27186
+
26883
27187
  // src/public-cli/collector-run.ts
26884
27188
  function buildCollectorTurnRequest(admitted, options) {
26885
27189
  return projectRoleTurnRequest(
@@ -27037,12 +27341,12 @@ function encodeClaudeProjectDir(cwd) {
27037
27341
  const abs = cwd.startsWith("/") ? cwd : `/${cwd}`;
27038
27342
  return abs.replace(/\//g, "-");
27039
27343
  }
27040
- function isRecord13(value) {
27344
+ function isRecord15(value) {
27041
27345
  return typeof value === "object" && value !== null && !Array.isArray(value);
27042
27346
  }
27043
27347
  function messageText(message) {
27044
27348
  if (typeof message === "string") return message;
27045
- if (!isRecord13(message)) return "";
27349
+ if (!isRecord15(message)) return "";
27046
27350
  const content = message.content;
27047
27351
  if (typeof content === "string") return content;
27048
27352
  if (!Array.isArray(content)) return "";
@@ -27052,7 +27356,7 @@ function messageText(message) {
27052
27356
  parts.push(part);
27053
27357
  continue;
27054
27358
  }
27055
- if (!isRecord13(part)) continue;
27359
+ if (!isRecord15(part)) continue;
27056
27360
  if (typeof part.text === "string") parts.push(part.text);
27057
27361
  else if (typeof part.content === "string") parts.push(part.content);
27058
27362
  }
@@ -27138,7 +27442,7 @@ function readCcSessionBlocks(options) {
27138
27442
  { cause: error }
27139
27443
  );
27140
27444
  }
27141
- if (!isRecord13(parsed)) continue;
27445
+ if (!isRecord15(parsed)) continue;
27142
27446
  const type = typeof parsed.type === "string" ? parsed.type : "";
27143
27447
  if (type !== "user" && type !== "assistant") continue;
27144
27448
  const transcript = messageText(parsed.message ?? parsed);
@@ -27342,7 +27646,7 @@ import { fileURLToPath as fileURLToPath2 } from "node:url";
27342
27646
  function resolveDiaristCollectMethodPath(packageRoot2 = fileURLToPath2(packageRootUrl2)) {
27343
27647
  return join25(packageRoot2, DIARIST_COLLECT_METHOD_RELATIVE);
27344
27648
  }
27345
- function isRecord14(value) {
27649
+ function isRecord16(value) {
27346
27650
  return typeof value === "object" && value !== null && !Array.isArray(value);
27347
27651
  }
27348
27652
  function parseDiaristLlmStdout(stdout, candidateCount) {
@@ -27360,7 +27664,7 @@ function parseDiaristLlmStdout(stdout, candidateCount) {
27360
27664
  { cause: error }
27361
27665
  );
27362
27666
  }
27363
- if (!isRecord14(parsed)) {
27667
+ if (!isRecord16(parsed)) {
27364
27668
  throw new DiaristLlmStdoutError(
27365
27669
  "not-object",
27366
27670
  "diarist collector stdout must be one JSON object"
@@ -27381,7 +27685,7 @@ function parseDiaristLlmStdout(stdout, candidateCount) {
27381
27685
  const out = [];
27382
27686
  for (let rowIndex = 0; rowIndex < parsed.selections.length; rowIndex += 1) {
27383
27687
  const row = parsed.selections[rowIndex];
27384
- if (!isRecord14(row)) {
27688
+ if (!isRecord16(row)) {
27385
27689
  throw new DiaristLlmStdoutError(
27386
27690
  "selection-uninterpretable",
27387
27691
  `diarist collector selection[${rowIndex}] is not an object`
@@ -27523,11 +27827,11 @@ var init_diarist_llm_collector = __esm({
27523
27827
  });
27524
27828
 
27525
27829
  // src/ticket-provenance-contracts.ts
27526
- function isRecord15(value) {
27830
+ function isRecord17(value) {
27527
27831
  return typeof value === "object" && value !== null && !Array.isArray(value);
27528
27832
  }
27529
27833
  function projectTicketProvenanceDiagnostic(value) {
27530
- if (!isRecord15(value)) return void 0;
27834
+ if (!isRecord17(value)) return void 0;
27531
27835
  if (value.recordClass !== TICKET_PROVENANCE_RECORD_CLASS_DIAGNOSTIC) {
27532
27836
  return void 0;
27533
27837
  }
@@ -27549,18 +27853,18 @@ function projectTicketProvenanceDiagnostic(value) {
27549
27853
  };
27550
27854
  }
27551
27855
  function projectTicketProvenanceEntry(value) {
27552
- if (!isRecord15(value)) return void 0;
27856
+ if (!isRecord17(value)) return void 0;
27553
27857
  if (value.recordClass === TICKET_PROVENANCE_RECORD_CLASS_DIAGNOSTIC) {
27554
27858
  return void 0;
27555
27859
  }
27556
- if (!isRecord15(value.basis)) return void 0;
27860
+ if (!isRecord17(value.basis)) return void 0;
27557
27861
  if (typeof value.basis.method !== "string" || !BASIS_METHODS.has(value.basis.method)) {
27558
27862
  return void 0;
27559
27863
  }
27560
27864
  if (typeof value.sourceKind !== "string" || !SOURCE_KINDS.has(value.sourceKind)) {
27561
27865
  return void 0;
27562
27866
  }
27563
- if (!isRecord15(value.sourceRef)) return void 0;
27867
+ if (!isRecord17(value.sourceRef)) return void 0;
27564
27868
  if (typeof value.transcript !== "string" || value.transcript.length === 0) {
27565
27869
  return void 0;
27566
27870
  }
@@ -30203,7 +30507,7 @@ function isMissingPathError5(error) {
30203
30507
  function errorText3(error) {
30204
30508
  return error instanceof Error ? error.message : String(error);
30205
30509
  }
30206
- function isRecord16(value) {
30510
+ function isRecord18(value) {
30207
30511
  return typeof value === "object" && value !== null && !Array.isArray(value);
30208
30512
  }
30209
30513
  async function readExistingRunLifecycleState(runDirectory) {
@@ -30211,7 +30515,7 @@ async function readExistingRunLifecycleState(runDirectory) {
30211
30515
  const raw = JSON.parse(
30212
30516
  await readFile17(join31(runDirectory, "run-state.json"), "utf8")
30213
30517
  );
30214
- if (!isRecord16(raw) || typeof raw.state !== "string") return void 0;
30518
+ if (!isRecord18(raw) || typeof raw.state !== "string") return void 0;
30215
30519
  return raw.state;
30216
30520
  } catch {
30217
30521
  return void 0;
@@ -30247,7 +30551,7 @@ async function readInvocationScopeFields(runDirectory) {
30247
30551
  throw error;
30248
30552
  }
30249
30553
  const parsed = JSON.parse(raw);
30250
- if (!isRecord16(parsed)) return void 0;
30554
+ if (!isRecord18(parsed)) return void 0;
30251
30555
  if (typeof parsed.projectRoot !== "string" || parsed.projectRoot.trim() === "") {
30252
30556
  return void 0;
30253
30557
  }
@@ -30275,7 +30579,7 @@ async function resolveSessionFile(runDirectory) {
30275
30579
  try {
30276
30580
  const raw = await readFile17(join31(runDirectory, "invocation.json"), "utf8");
30277
30581
  const parsed = JSON.parse(raw);
30278
- if (isRecord16(parsed) && typeof parsed.sessionFile === "string" && parsed.sessionFile.trim() !== "") {
30582
+ if (isRecord18(parsed) && typeof parsed.sessionFile === "string" && parsed.sessionFile.trim() !== "") {
30279
30583
  return parsed.sessionFile;
30280
30584
  }
30281
30585
  } catch (error) {
@@ -30516,7 +30820,7 @@ var init_analyst_ledger = __esm({
30516
30820
  });
30517
30821
 
30518
30822
  // src/analyst-metric-families/acceptance-success-rework.ts
30519
- function isRecord17(value) {
30823
+ function isRecord19(value) {
30520
30824
  return typeof value === "object" && value !== null && !Array.isArray(value);
30521
30825
  }
30522
30826
  function wallMsFromSpan(span) {
@@ -30525,21 +30829,21 @@ function wallMsFromSpan(span) {
30525
30829
  function findCollectorGroups(body) {
30526
30830
  if (Array.isArray(body.groups)) return body.groups;
30527
30831
  const receipt = body.receipt;
30528
- if (isRecord17(receipt) && Array.isArray(receipt.groups)) return receipt.groups;
30832
+ if (isRecord19(receipt) && Array.isArray(receipt.groups)) return receipt.groups;
30529
30833
  const outcome = body.outcome;
30530
- if (isRecord17(outcome)) {
30834
+ if (isRecord19(outcome)) {
30531
30835
  const facts = outcome.decisiveFacts;
30532
- if (isRecord17(facts) && Array.isArray(facts.groups)) return facts.groups;
30836
+ if (isRecord19(facts) && Array.isArray(facts.groups)) return facts.groups;
30533
30837
  }
30534
30838
  return void 0;
30535
30839
  }
30536
30840
  function extractStatus(body) {
30537
30841
  const outcome = body.outcome;
30538
- if (isRecord17(outcome) && typeof outcome.status === "string" && outcome.status.trim() !== "") {
30842
+ if (isRecord19(outcome) && typeof outcome.status === "string" && outcome.status.trim() !== "") {
30539
30843
  return outcome.status;
30540
30844
  }
30541
30845
  const receipt = body.receipt;
30542
- if (isRecord17(receipt) && typeof receipt.status === "string" && receipt.status.trim() !== "") {
30846
+ if (isRecord19(receipt) && typeof receipt.status === "string" && receipt.status.trim() !== "") {
30543
30847
  return receipt.status;
30544
30848
  }
30545
30849
  if (typeof body.status === "string" && body.status.trim() !== "") {
@@ -31163,21 +31467,21 @@ var init_leg_wall_clock = __esm({
31163
31467
  });
31164
31468
 
31165
31469
  // src/analyst-metric-families/round-timeline.ts
31166
- function isRecord18(value) {
31470
+ function isRecord20(value) {
31167
31471
  return typeof value === "object" && value !== null && !Array.isArray(value);
31168
31472
  }
31169
31473
  function wallMsFromSpan2(startedAt, endedAt) {
31170
31474
  return Date.parse(endedAt) - Date.parse(startedAt);
31171
31475
  }
31172
31476
  function readOutcomeStatus(body) {
31173
- if (!isRecord18(body.outcome)) return void 0;
31477
+ if (!isRecord20(body.outcome)) return void 0;
31174
31478
  const status = body.outcome.status;
31175
31479
  if (typeof status !== "string" || status.trim() === "") return void 0;
31176
31480
  return status;
31177
31481
  }
31178
31482
  function readClassCount(body) {
31179
- if (!isRecord18(body.outcome)) return void 0;
31180
- if (!isRecord18(body.outcome.decisiveFacts)) return void 0;
31483
+ if (!isRecord20(body.outcome)) return void 0;
31484
+ if (!isRecord20(body.outcome.decisiveFacts)) return void 0;
31181
31485
  const classCount = body.outcome.decisiveFacts.classCount;
31182
31486
  if (typeof classCount !== "number" || !Number.isFinite(classCount)) {
31183
31487
  return void 0;
@@ -32105,11 +32409,6 @@ function requireLegalEngineName(name) {
32105
32409
  }
32106
32410
  }
32107
32411
  function requireCallableSeat(seat, axis, verb) {
32108
- if (isAutomaticConfigurableSeat(seat)) {
32109
- throw new CliUsageError(
32110
- `config ${verb} refuses ${seat}: no independent activation path; storing would be silently ineffective`
32111
- );
32112
- }
32113
32412
  if (!isPublicCallableRole(seat)) {
32114
32413
  throw new CliUsageError(`unknown ${axis}-axis seat: ${seat}`);
32115
32414
  }
@@ -32240,11 +32539,10 @@ function renderCommandHelp(command) {
32240
32539
  `;
32241
32540
  }
32242
32541
  function renderRoles(seats) {
32243
- const lines = ["seat kind source model"];
32542
+ const lines = ["seat source model"];
32244
32543
  for (const seat of seats) {
32245
- const kind = seat.automatic ? "automatic" : "callable";
32246
32544
  const model = seat.selection === void 0 ? "-" : formatModelSpec(seat.selection);
32247
- lines.push(`${seat.seat} ${kind} ${seat.source} ${model}`);
32545
+ lines.push(`${seat.seat} ${seat.source} ${model}`);
32248
32546
  }
32249
32547
  return `${lines.join("\n")}
32250
32548
  `;
@@ -32889,6 +33187,29 @@ async function runAkRole(argv, env) {
32889
33187
  ...result2.terminal === void 0 ? {} : { terminal: result2.terminal }
32890
33188
  };
32891
33189
  }
33190
+ if (parsed.command === "gatekeeper" || parsed.command === "navigator") {
33191
+ const agentDir = resolveAgentDir(env, home);
33192
+ const cwd = env.cwd ?? process.cwd();
33193
+ const config = await loadAndValidateConfig(home, env.packageRoot);
33194
+ const credentials = env.credentials ?? await loadCredentialProviders(agentDir);
33195
+ const seat = resolveEffectiveSeat(
33196
+ config,
33197
+ parsed.command,
33198
+ credentials,
33199
+ invocationFromParsed(parsed)
33200
+ );
33201
+ const result2 = await runPublicInstructionSeat(
33202
+ parsed.args,
33203
+ createRoleEnvironment(env, { role: parsed.command, home, agentDir, cwd, credentials, seat, config }),
33204
+ io,
33205
+ parsed.command,
33206
+ parsed.command === "gatekeeper" ? PUBLIC_ROLE_ARGV.gatekeeper.parse : PUBLIC_ROLE_ARGV.navigator.parse
33207
+ );
33208
+ return {
33209
+ exitCode: result2.exitCode,
33210
+ ...result2.terminal === void 0 ? {} : { terminal: result2.terminal }
33211
+ };
33212
+ }
32892
33213
  if (parsed.command === "analyst") {
32893
33214
  const result2 = await runPublicAnalyst(
32894
33215
  parsed.args,
@@ -32934,6 +33255,7 @@ var init_cli = __esm({
32934
33255
  init_invocation();
32935
33256
  init_option_definitions();
32936
33257
  init_coder_run();
33258
+ init_instruction_seat_run();
32937
33259
  init_collector_run();
32938
33260
  init_countersign_run();
32939
33261
  init_gleaner_left_run();
@@ -32963,6 +33285,8 @@ var init_cli = __esm({
32963
33285
  notary: { parse: parseNotaryArgv, options: optionsForOwner("notary") },
32964
33286
  inspector: { parse: parseInspectorArgv, options: optionsForOwner("inspector") },
32965
33287
  reviewer: { parse: parseReviewerArgv, options: optionsForOwner("reviewer") },
33288
+ gatekeeper: { parse: parseGatekeeperArgv, options: optionsForOwner("gatekeeper") },
33289
+ navigator: { parse: parseNavigatorArgv, options: optionsForOwner("navigator") },
32966
33290
  /** Deterministic analysis seat (#336) — argv parse only; no LLM admission. */
32967
33291
  analyst: { parse: parseAnalystArgv, options: optionsForOwner("analyst") }
32968
33292
  };