@akagilnc/pi-workflow-roles 0.1.4800 → 0.1.4870
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/acp-host/production-host.js +19434 -18218
- package/dist/analyst-book-key.js +63 -0
- package/dist/analyst-cohort.js +167 -0
- package/dist/analyst-entry.js +320 -0
- package/dist/analyst-index.js +247 -0
- package/dist/analyst-ledger.js +561 -0
- package/dist/analyst-median.js +16 -0
- package/dist/analyst-metric-families/acceptance-success-rework.js +249 -0
- package/dist/analyst-metric-families/b2-frame-buckets-actions.js +189 -0
- package/dist/analyst-metric-families/gate-cycles.js +77 -0
- package/dist/analyst-metric-families/leg-wall-clock.js +56 -0
- package/dist/analyst-metric-families/round-timeline.js +126 -0
- package/dist/analyst-metric-families.js +23 -0
- package/dist/analyst-metric-family.js +11 -0
- package/dist/analyst-model-groups.js +135 -0
- package/dist/analyst-page.js +182 -0
- package/dist/atomic-write.js +23 -0
- package/dist/auditor-soul.js +1 -1
- package/dist/countersign-contracts.js +0 -2
- package/dist/diarist-contracts.js +0 -1
- package/dist/doctor-contracts.js +2 -2
- package/dist/gatekeeper-role.js +15 -16
- package/dist/gleaner-left-contracts.js +0 -2
- package/dist/headless-host/production-host.js +16967 -15749
- package/dist/host-contracts.js +0 -4
- package/dist/inspector-contracts.js +0 -2
- package/dist/institutional-resolution.js +4 -2
- package/dist/merger-contracts.js +0 -2
- package/dist/migrate-book-topology.js +3908 -3089
- package/dist/navigator-public-session.js +4 -3
- package/dist/notary-contracts.js +0 -2
- package/dist/package-contracts/auditor-output.js +0 -1
- package/dist/package-contracts/collector-output.js +0 -2
- package/dist/package-contracts/fixer-output.js +0 -2
- package/dist/package-contracts/gatekeeper-output.js +0 -2
- package/dist/package-contracts/judge-output.js +0 -2
- package/dist/package-contracts/navigator-output.js +0 -2
- package/dist/package-contracts/reviewer-output.js +0 -2
- package/dist/package-contracts/terminating-tools.js +32 -92
- package/dist/package-contracts/worker-output.js +0 -4
- package/dist/packaged-role-registry.js +518 -36
- package/dist/pi/role-turn-host.js +2 -1
- package/dist/public-cli/analyst-run.js +185 -0
- package/dist/public-cli/cli.js +885 -0
- package/dist/public-cli/config.js +12 -9
- package/dist/public-cli/countersign-run.js +4 -311
- package/dist/public-cli/instruction-seat-run.js +628 -158
- package/dist/public-cli/invocation.js +806 -1550
- package/dist/public-cli/main.js +6962 -9882
- package/dist/public-cli/option-definitions.js +51 -99
- package/dist/public-cli/post-admission.js +30 -2
- package/dist/public-cli/run-lifecycle.js +234 -353
- package/dist/public-cli/seat-ticket-binding.js +6 -0
- package/dist/public-cli/settlement.js +261 -675
- package/dist/public-cli/turn-request.js +76 -0
- package/dist/public-role-summons.js +38 -112
- package/dist/role-activation-flags.js +23 -45
- package/dist/secretariat-contracts.js +0 -2
- package/dist/session-identity.js +17 -8
- package/dist/session-opening-materials.js +3 -2
- package/extensions/role-runtime.ts +6 -80
- package/package.json +1 -1
- package/souls/coder.md +1 -2
- package/src/acp-host/role-turn-host.ts +4 -1
- package/src/analyst-metric-families/acceptance-success-rework.ts +3 -2
- package/src/auditor-role.ts +1 -2
- package/src/auditor-soul.ts +1 -1
- package/src/collector-role.ts +2 -2
- package/src/countersign-contracts.ts +0 -1
- package/src/countersign-role.ts +1 -1
- package/src/diarist-contracts.ts +0 -1
- package/src/diarist-role.ts +0 -1
- package/src/doctor-auditor.ts +1 -2
- package/src/doctor-contracts.ts +1 -1
- package/src/doctor-role.ts +3 -2
- package/src/external-host-turn-loop.ts +1 -1
- package/src/factory-board.ts +10 -7
- package/src/gatekeeper-role.ts +16 -10
- package/src/gleaner-left-contracts.ts +0 -1
- package/src/gleaner-left-role.ts +0 -1
- package/src/headless-host/role-turn-host.ts +7 -1
- package/src/host-contracts.ts +10 -6
- package/src/inspector-contracts.ts +0 -1
- package/src/inspector-role.ts +0 -2
- package/src/institutional-resolution.ts +6 -4
- package/src/judge-role.ts +3 -3
- package/src/merger-contracts.ts +0 -1
- package/src/merger-role.ts +2 -2
- package/src/navigator-public-session.ts +7 -6
- package/src/navigator-work-context.ts +6 -8
- package/src/notary-contracts.ts +0 -1
- package/src/notary-role.ts +2 -3
- package/src/package-contracts/auditor-output.ts +0 -1
- package/src/package-contracts/collector-output.ts +0 -1
- package/src/package-contracts/fixer-output.ts +0 -1
- package/src/package-contracts/gatekeeper-output.ts +0 -1
- package/src/package-contracts/judge-output.ts +0 -1
- package/src/package-contracts/navigator-output.ts +0 -1
- package/src/package-contracts/reviewer-output.ts +0 -1
- package/src/package-contracts/terminating-tools.ts +27 -99
- package/src/package-contracts/worker-output.ts +0 -2
- package/src/packaged-role-registry.ts +604 -35
- package/src/pi/role-turn-host.ts +2 -1
- package/src/public-cli/cli.ts +64 -259
- package/src/public-cli/config.ts +18 -10
- package/src/public-cli/countersign-run.ts +14 -449
- package/src/public-cli/instruction-seat-run.ts +758 -277
- package/src/public-cli/invocation.ts +1097 -2051
- package/src/public-cli/option-definitions.ts +62 -127
- package/src/public-cli/post-admission.ts +47 -2
- package/src/public-cli/run-lifecycle.ts +303 -613
- package/src/public-cli/seat-ticket-binding.ts +6 -0
- package/src/public-cli/settlement.ts +399 -1185
- package/src/public-cli/turn-request.ts +92 -1
- package/src/public-role-summons.ts +44 -128
- package/src/reviewer-role.ts +3 -2
- package/src/role-activation-flags.ts +20 -41
- package/src/role-runtime-dependencies.ts +25 -26
- package/src/role-runtime.ts +121 -232
- package/src/secretariat-contracts.ts +0 -1
- package/src/secretariat-role.ts +0 -2
- package/src/session-identity.ts +23 -8
- package/src/session-opening-materials.ts +2 -1
- package/src/worker-role.ts +3 -4
- package/dist/doctor-auditor.js +0 -25
- package/dist/public-cli/diarist-run.js +0 -130
- package/dist/public-cli/doctor-run.js +0 -87
- package/dist/public-cli/inspector-run.js +0 -151
- package/dist/public-cli/judge-run.js +0 -114
- package/dist/public-cli/notary-run.js +0 -174
- package/dist/public-cli/reviewer-run.js +0 -339
- package/src/public-cli/coder-run.ts +0 -255
- package/src/public-cli/collector-run.ts +0 -189
- package/src/public-cli/diarist-run.ts +0 -233
- package/src/public-cli/doctor-run.ts +0 -167
- package/src/public-cli/fixer-run.ts +0 -265
- package/src/public-cli/gleaner-left-run.ts +0 -167
- package/src/public-cli/inspector-run.ts +0 -261
- package/src/public-cli/judge-run.ts +0 -196
- package/src/public-cli/merger-run.ts +0 -294
- package/src/public-cli/notary-run.ts +0 -279
- package/src/public-cli/reviewer-run.ts +0 -480
- package/src/public-cli/secretariat-run.ts +0 -265
package/src/role-runtime.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { readFileSync, writeSync } from "node:fs";
|
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import {
|
|
5
5
|
ExplicitInternalActivationError,
|
|
6
|
-
|
|
6
|
+
|
|
7
7
|
runDirectoryFromHostContext,
|
|
8
8
|
type HostContext,
|
|
9
9
|
type HostToolResult,
|
|
@@ -57,22 +57,21 @@ import {
|
|
|
57
57
|
projectNotaryBoundFromFlags,
|
|
58
58
|
readNotaryTicketFlag,
|
|
59
59
|
} from "./notary-role.ts";
|
|
60
|
-
import { NOTARY_TICKET_FLAG } from "./notary-contracts.ts";
|
|
60
|
+
import { NOTARY_SOURCE_RUN_FLAG, NOTARY_TICKET_FLAG } from "./notary-contracts.ts";
|
|
61
61
|
import {
|
|
62
62
|
COUNTERSIGN_TOOL_SPEC,
|
|
63
63
|
type CountersignRuntimeDependencies,
|
|
64
64
|
} from "./countersign-role.ts";
|
|
65
|
-
import { COUNTERSIGN_ACCEPTED_TEXT } from "./countersign-contracts.ts";
|
|
66
65
|
import {
|
|
67
66
|
GLEANER_LEFT_TOOL_SPEC,
|
|
68
67
|
type GleanerLeftRuntimeDependencies,
|
|
69
68
|
} from "./gleaner-left-role.ts";
|
|
70
|
-
import {
|
|
69
|
+
import { GLEANER_LEFT_BASE_FLAG } from "./gleaner-left-contracts.ts";
|
|
71
70
|
import {
|
|
72
71
|
INSPECTOR_TOOL_SPEC,
|
|
73
72
|
type InspectorRuntimeDependencies,
|
|
74
73
|
} from "./inspector-role.ts";
|
|
75
|
-
import {
|
|
74
|
+
import { INSPECTOR_SOURCE_RUN_FLAG } from "./inspector-contracts.ts";
|
|
76
75
|
import {
|
|
77
76
|
DIARIST_TOOL_SPEC,
|
|
78
77
|
type DiaristRuntimeDependencies,
|
|
@@ -85,12 +84,10 @@ import {
|
|
|
85
84
|
type SecretariatSummonCountersignParameters,
|
|
86
85
|
} from "./secretariat-role.ts";
|
|
87
86
|
import {
|
|
88
|
-
SECRETARIAT_ACCEPTED_TEXT,
|
|
89
87
|
SECRETARIAT_OUTPUT_TOOL_NAME,
|
|
90
88
|
SECRETARIAT_SUMMON_COUNTERSIGN_TOOL_NAME,
|
|
91
89
|
} from "./secretariat-contracts.ts";
|
|
92
90
|
import {
|
|
93
|
-
DIARIST_ACCEPTED_TEXT,
|
|
94
91
|
projectDiaristSessions,
|
|
95
92
|
} from "./diarist-contracts.ts";
|
|
96
93
|
import { commitDiaristProjection } from "./diarist.ts";
|
|
@@ -108,9 +105,7 @@ import {
|
|
|
108
105
|
AUDITOR_TOOL_SPEC,
|
|
109
106
|
type AuditorRuntimeDependencies,
|
|
110
107
|
} from "./auditor-role.ts";
|
|
111
|
-
|
|
112
|
-
import { GATEKEEPER_ACCEPTED_TEXT } from "./package-contracts/gatekeeper-output.ts";
|
|
113
|
-
import { NAVIGATOR_ACCEPTED_TEXT } from "./package-contracts/navigator-output.ts";
|
|
108
|
+
|
|
114
109
|
import { formatNavigatorReport, NAVIGATOR_EVENT_TYPE, navigatorSubjectKey, navigatorUnavailableError, subjectPath, type NavigatorAttendance, type NavigatorAttendanceOptions, type NavigatorEvent, type NavigatorPhase, type NavigatorReport, type NavigatorSettlement, type NavigatorSubjectProvenance, type NavigatorTargetRole, type NavigatorWorkContext } from "./navigator-attendance.ts";
|
|
115
110
|
import {
|
|
116
111
|
buildNavigatorInfrastructureFailureFact,
|
|
@@ -121,7 +116,7 @@ import {
|
|
|
121
116
|
} from "./navigator-invocation-identity.ts";
|
|
122
117
|
import { recordTypedProviderHttpStatus } from "./typed-provider-http.ts";
|
|
123
118
|
import { NAVIGATOR_POST_ROLE_GRACE_MS, raceNavigatorGrace } from "./public-cli/settlement.ts";
|
|
124
|
-
import { PACKAGED_ROLE_REGISTRY, packagedRoleMetadata, packagedRoleOutputTool, packagedRolePhaseFlag, type PackagedRole } from "./packaged-role-registry.ts";
|
|
119
|
+
import { PACKAGED_ROLE_REGISTRY, isOfficerReviewSeat, packagedRoleAcceptedText, packagedRoleActivationFlags, packagedRoleInputFlag, packagedRoleMetadata, packagedRoleOutputTool, packagedRolePhaseFlag, type PackagedRole } from "./packaged-role-registry.ts";
|
|
125
120
|
import { isAuditEscalationProjection } from "./audit-escalation.ts";
|
|
126
121
|
import {
|
|
127
122
|
createJudgeRoleRuntime,
|
|
@@ -397,76 +392,18 @@ export { createProductionMergerGitState } from "./merger-git-state.ts";
|
|
|
397
392
|
export type { MergerGitState, ActiveMergerGitState } from "./merger-git-state.ts";
|
|
398
393
|
export type { MergerRoleDependencies } from "./merger-role.ts";
|
|
399
394
|
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
context: HostContext;
|
|
408
|
-
judge: { activate(): Promise<void> };
|
|
409
|
-
fixer: WorkerArmable;
|
|
410
|
-
coder: WorkerArmable;
|
|
411
|
-
reviewer: {
|
|
412
|
-
activate(
|
|
413
|
-
context: HostContext,
|
|
414
|
-
admitted: ReviewerAdmittedInputs,
|
|
415
|
-
): Promise<ReviewerActivation>;
|
|
416
|
-
};
|
|
417
|
-
/** Envelope decodes Reviewer transport flags inside the activation stage. */
|
|
418
|
-
decodeReviewerAdmitted(): ReviewerAdmittedInputs;
|
|
419
|
-
/** Envelope stores live Reviewer activation for agent_start prompt assembly. */
|
|
420
|
-
bindReviewerParent(activation: ReviewerActivation): void;
|
|
421
|
-
collector: {
|
|
422
|
-
activate(context: HostContext, event: { reason: string }): Promise<void>;
|
|
423
|
-
};
|
|
424
|
-
doctor: { activate(): Promise<void> };
|
|
425
|
-
notary: {
|
|
426
|
-
activate(admitted?: import("./notary-role.ts").NotaryAdmittedTicket): Promise<void>;
|
|
427
|
-
};
|
|
428
|
-
/** Envelope decodes Notary ticket flag inside the activation stage (ADR 0018). */
|
|
429
|
-
decodeNotaryAdmitted(): import("./notary-role.ts").NotaryAdmittedTicket | undefined;
|
|
430
|
-
countersign: { activate(): Promise<void> };
|
|
431
|
-
gleanerLeft: { activate(): Promise<void> };
|
|
432
|
-
inspector: { activate(): Promise<void> };
|
|
433
|
-
gatekeeper: { activate(): Promise<void> };
|
|
434
|
-
navigator: { activate(): Promise<void> };
|
|
435
|
-
auditor: { activate(): Promise<void> };
|
|
436
|
-
diarist: { activate(): Promise<void> };
|
|
437
|
-
secretariat: { activate(): Promise<void> };
|
|
438
|
-
merger(): Promise<void>;
|
|
439
|
-
};
|
|
440
|
-
|
|
441
|
-
function activationStage(role: PackagedRole, runtime: ActivationRuntime): { id: string; run(): Promise<void> } {
|
|
442
|
-
switch (role) {
|
|
443
|
-
case "judge": return { id: "load-and-install", run: async () => runtime.judge.activate() };
|
|
444
|
-
case "fixer": return { id: "load-and-install", run: async () => runtime.fixer.activate() };
|
|
445
|
-
case "coder": return { id: "load-and-install", run: async () => runtime.coder.activate(runtime.context) };
|
|
446
|
-
case "reviewer": return { id: "load-and-install", run: async () => {
|
|
447
|
-
const admitted = runtime.decodeReviewerAdmitted();
|
|
448
|
-
const activation = await runtime.reviewer.activate(runtime.context, admitted);
|
|
449
|
-
runtime.bindReviewerParent(activation);
|
|
450
|
-
} };
|
|
451
|
-
case "collector": return { id: "load-and-install", run: async () => runtime.collector.activate(runtime.context, runtime.event) };
|
|
452
|
-
case "doctor": return { id: "load-and-install", run: async () => runtime.doctor.activate() };
|
|
453
|
-
case "notary": return {
|
|
454
|
-
id: "load-and-install",
|
|
455
|
-
run: async () => {
|
|
456
|
-
// Envelope owns ticket flag read (ADR 0018); role receives admitted value only.
|
|
457
|
-
await runtime.notary.activate(runtime.decodeNotaryAdmitted());
|
|
458
|
-
},
|
|
459
|
-
};
|
|
460
|
-
case "countersign": return { id: "load-and-install", run: async () => runtime.countersign.activate() };
|
|
461
|
-
case "gleaner-left": return { id: "load-and-install", run: async () => runtime.gleanerLeft.activate() };
|
|
462
|
-
case "inspector": return { id: "load-and-install", run: async () => runtime.inspector.activate() };
|
|
463
|
-
case "gatekeeper": return { id: "load-and-install", run: async () => runtime.gatekeeper.activate() };
|
|
464
|
-
case "navigator": return { id: "load-and-install", run: async () => runtime.navigator.activate() };
|
|
465
|
-
case "auditor": return { id: "load-and-install", run: async () => runtime.auditor.activate() };
|
|
466
|
-
case "diarist": return { id: "load-and-install", run: async () => runtime.diarist.activate() };
|
|
467
|
-
case "secretariat": return { id: "load-and-install", run: async () => runtime.secretariat.activate() };
|
|
468
|
-
case "merger": return { id: "prepare-git-and-install", run: async () => runtime.merger() };
|
|
395
|
+
function activationStage(
|
|
396
|
+
role: PackagedRole,
|
|
397
|
+
activate: Record<PackagedRole, () => Promise<void>>,
|
|
398
|
+
): { id: string; run(): Promise<void> } {
|
|
399
|
+
const record = packagedRoleMetadata(role);
|
|
400
|
+
if (record === undefined) {
|
|
401
|
+
throw new Error(`Unsupported workflow role: ${String(role)}`);
|
|
469
402
|
}
|
|
403
|
+
return {
|
|
404
|
+
id: record.activationStage,
|
|
405
|
+
run: () => activate[role](),
|
|
406
|
+
};
|
|
470
407
|
}
|
|
471
408
|
|
|
472
409
|
function validateActivationTraceRecord(record: unknown): ActivationTraceRecord {
|
|
@@ -537,12 +474,14 @@ export function formatNavigatorRoleHelp(role: NavigatorTargetRole): string {
|
|
|
537
474
|
`Usage: ak-role ${role}`,
|
|
538
475
|
ROLE_FLAG.definition.description,
|
|
539
476
|
];
|
|
540
|
-
|
|
541
|
-
|
|
477
|
+
const inputFlag = packagedRoleInputFlag(role);
|
|
478
|
+
if (inputFlag !== undefined) {
|
|
479
|
+
lines.push(` --${inputFlag} <value> ${role} input material`);
|
|
542
480
|
}
|
|
543
|
-
|
|
481
|
+
const phaseFlag = packagedRolePhaseFlag(role);
|
|
482
|
+
if (phaseFlag !== undefined && metadata !== undefined) {
|
|
544
483
|
lines.push(
|
|
545
|
-
` --${
|
|
484
|
+
` --${phaseFlag} <value> ${role} phase: ${(metadata.phases.filter((p) => p !== null) as string[]).join(" | ")}`,
|
|
546
485
|
);
|
|
547
486
|
}
|
|
548
487
|
lines.push(`Public next-command form: ak-role ${role}`);
|
|
@@ -564,29 +503,15 @@ export type RoleRuntimeDependencies = {
|
|
|
564
503
|
hostAdapters?: readonly import("./public-cli/role-turn-host-resolution.ts").NamedRoleTurnHostAdapter[];
|
|
565
504
|
/** Non-identity opening materials delivered in the ordinary role brief. */
|
|
566
505
|
loadRoleReferenceMaterials?(role: PackagedRole): Promise<string>;
|
|
567
|
-
|
|
568
|
-
|
|
506
|
+
/** One soul loader. The role argument selects the registry record. */
|
|
507
|
+
loadRoleSoul(role: PackagedRole): Promise<string>;
|
|
569
508
|
loadFixPacket?(path: string): Promise<string>;
|
|
570
|
-
loadCoderSoul?(): Promise<string>;
|
|
571
509
|
loadCoderTask?(path: string): Promise<string>;
|
|
572
|
-
loadReviewerSoul?(): Promise<string>;
|
|
573
|
-
loadCollectorSoul?(): Promise<string>;
|
|
574
510
|
/** #677: optional packaged seed for first-use general bot handbook. */
|
|
575
511
|
loadCollectorHandbookSeed?(): Promise<string>;
|
|
576
512
|
createCollectorTransport?(): CollectorGitHubTransport;
|
|
577
|
-
loadDoctorSoul?(): Promise<string>;
|
|
578
|
-
loadNotarySoul?(): Promise<string>;
|
|
579
513
|
loadNotarySourceRun?(path: string): Promise<import("./notary-contracts.ts").NotarySourceRunLocator>;
|
|
580
|
-
loadCountersignSoul?(): Promise<string>;
|
|
581
|
-
loadGleanerLeftSoul?(): Promise<string>;
|
|
582
|
-
loadInspectorSoul?(): Promise<string>;
|
|
583
|
-
loadGatekeeperSoul?(): Promise<string>;
|
|
584
|
-
loadNavigatorSoul?(): Promise<string>;
|
|
585
|
-
loadAuditorSoul?(): Promise<string>;
|
|
586
|
-
loadDiaristSoul?(): Promise<string>;
|
|
587
|
-
loadSecretariatSoul?(): Promise<string>;
|
|
588
514
|
loadDoctorCase?(path: string): Promise<import("./doctor-contracts.ts").DoctorCase>;
|
|
589
|
-
loadMergerSoul?(): Promise<string>;
|
|
590
515
|
loadMergerInput?(path: string): Promise<unknown>;
|
|
591
516
|
auditDoctorCompliance?(options: { context: HostContext; signal?: AbortSignal }): Promise<ComplianceDecision>;
|
|
592
517
|
createCollectorClock?(): CollectorClock;
|
|
@@ -643,6 +568,16 @@ function navigatorOutputTool(role: string): string | undefined {
|
|
|
643
568
|
return packagedRoleOutputTool(role);
|
|
644
569
|
}
|
|
645
570
|
|
|
571
|
+
/** Status leaves that are not the shared `status` key, in registry order. */
|
|
572
|
+
function receiptStatusFromRegistry(details: Record<string, unknown>): string | undefined {
|
|
573
|
+
for (const entry of PACKAGED_ROLE_REGISTRY) {
|
|
574
|
+
if (!("receiptStatusKey" in entry)) continue;
|
|
575
|
+
const value = details[entry.receiptStatusKey];
|
|
576
|
+
if (typeof value === "string") return value;
|
|
577
|
+
}
|
|
578
|
+
return undefined;
|
|
579
|
+
}
|
|
580
|
+
|
|
646
581
|
export function publicNavigatorSettlement(role: string, phase: NavigatorPhase, event: { toolName: string; isError?: unknown; details: unknown }): NavigatorSettlement | undefined {
|
|
647
582
|
// One shared classifier owns terminal discriminant (lifecycle + settlement + extractors).
|
|
648
583
|
if (event.toolName !== navigatorOutputTool(role)) return undefined;
|
|
@@ -662,9 +597,7 @@ export function publicNavigatorSettlement(role: string, phase: NavigatorPhase, e
|
|
|
662
597
|
}
|
|
663
598
|
const status = typeof details.status === "string"
|
|
664
599
|
? details.status
|
|
665
|
-
:
|
|
666
|
-
: typeof details.countersignStatus === "string" ? details.countersignStatus
|
|
667
|
-
: typeof details.secretariatStatus === "string" ? details.secretariatStatus : undefined;
|
|
600
|
+
: receiptStatusFromRegistry(details);
|
|
668
601
|
if (status !== undefined && status === "escalate") {
|
|
669
602
|
return { kind: "human_decision", role, phase, status };
|
|
670
603
|
}
|
|
@@ -709,9 +642,8 @@ type FiledOfficerBeforeAccept = (input: {
|
|
|
709
642
|
function createFiledOfficerRuntime(
|
|
710
643
|
roleHost: RoleHost,
|
|
711
644
|
spec: {
|
|
712
|
-
role:
|
|
645
|
+
role: PackagedRole;
|
|
713
646
|
tool: { name: string; label: string; description: string; promptSnippet: string; parameters: unknown };
|
|
714
|
-
acceptedText: string;
|
|
715
647
|
soulTag: string;
|
|
716
648
|
beforeAccept?: FiledOfficerBeforeAccept;
|
|
717
649
|
},
|
|
@@ -741,7 +673,7 @@ function createFiledOfficerRuntime(
|
|
|
741
673
|
// Accept-as-is + terminate only. Shape is not an admission gate
|
|
742
674
|
// (第 0 条 / ADR 0055); sole-final barrier is ledger-owned (#575).
|
|
743
675
|
return {
|
|
744
|
-
content: [{ type: "text" as const, text: spec.
|
|
676
|
+
content: [{ type: "text" as const, text: packagedRoleAcceptedText(spec.role) }],
|
|
745
677
|
details: projected === undefined ? parameters : projected,
|
|
746
678
|
terminate: true as const,
|
|
747
679
|
};
|
|
@@ -761,6 +693,11 @@ function createFiledOfficerRuntime(
|
|
|
761
693
|
};
|
|
762
694
|
}
|
|
763
695
|
|
|
696
|
+
function activationPublishesFlag(role: unknown, flagName: string): boolean {
|
|
697
|
+
if (typeof role !== "string") return false;
|
|
698
|
+
return packagedRoleActivationFlags(role).some((spec) => spec.flag === flagName);
|
|
699
|
+
}
|
|
700
|
+
|
|
764
701
|
export function createGleanerLeftRoleRuntime(
|
|
765
702
|
roleHost: RoleHost,
|
|
766
703
|
dependencies: GleanerLeftRuntimeDependencies,
|
|
@@ -770,7 +707,6 @@ export function createGleanerLeftRoleRuntime(
|
|
|
770
707
|
{
|
|
771
708
|
role: "gleaner-left",
|
|
772
709
|
tool: GLEANER_LEFT_TOOL_SPEC,
|
|
773
|
-
acceptedText: GLEANER_LEFT_ACCEPTED_TEXT,
|
|
774
710
|
soulTag: "gleaner-left",
|
|
775
711
|
},
|
|
776
712
|
dependencies,
|
|
@@ -794,7 +730,6 @@ export function createInspectorRoleRuntime(
|
|
|
794
730
|
{
|
|
795
731
|
role: "inspector",
|
|
796
732
|
tool: INSPECTOR_TOOL_SPEC,
|
|
797
|
-
acceptedText: INSPECTOR_ACCEPTED_TEXT,
|
|
798
733
|
soulTag: "inspector",
|
|
799
734
|
},
|
|
800
735
|
dependencies,
|
|
@@ -811,7 +746,6 @@ export function createGatekeeperRoleRuntime(
|
|
|
811
746
|
{
|
|
812
747
|
role: "gatekeeper",
|
|
813
748
|
tool: GATEKEEPER_TOOL_SPEC,
|
|
814
|
-
acceptedText: GATEKEEPER_ACCEPTED_TEXT,
|
|
815
749
|
soulTag: "gatekeeper",
|
|
816
750
|
},
|
|
817
751
|
dependencies,
|
|
@@ -828,7 +762,6 @@ export function createNavigatorRoleRuntime(
|
|
|
828
762
|
{
|
|
829
763
|
role: "navigator",
|
|
830
764
|
tool: NAVIGATOR_TOOL_SPEC,
|
|
831
|
-
acceptedText: NAVIGATOR_ACCEPTED_TEXT,
|
|
832
765
|
soulTag: "navigator",
|
|
833
766
|
},
|
|
834
767
|
dependencies,
|
|
@@ -845,7 +778,6 @@ export function createAuditorRoleRuntime(
|
|
|
845
778
|
{
|
|
846
779
|
role: "auditor",
|
|
847
780
|
tool: AUDITOR_TOOL_SPEC,
|
|
848
|
-
acceptedText: AUDITOR_ACCEPTED_TEXT,
|
|
849
781
|
soulTag: "auditor",
|
|
850
782
|
},
|
|
851
783
|
dependencies,
|
|
@@ -959,7 +891,6 @@ export function createDiaristRoleRuntime(
|
|
|
959
891
|
{
|
|
960
892
|
role: "diarist",
|
|
961
893
|
tool: DIARIST_TOOL_SPEC,
|
|
962
|
-
acceptedText: DIARIST_ACCEPTED_TEXT,
|
|
963
894
|
soulTag: "diarist",
|
|
964
895
|
beforeAccept: async ({ parameters, ctx }) => {
|
|
965
896
|
const submitted =
|
|
@@ -1048,7 +979,7 @@ export function createSecretariatRoleRuntime(
|
|
|
1048
979
|
let parentInstruction = "";
|
|
1049
980
|
// #969: non-pi submission gate only — pi mid-turn summon path stays untouched.
|
|
1050
981
|
const beforeAccept: FiledOfficerBeforeAccept | undefined =
|
|
1051
|
-
hostActions !== undefined
|
|
982
|
+
hostActions !== undefined
|
|
1052
983
|
? async ({ toolCallId, parameters, signal, ctx }) => {
|
|
1053
984
|
const host =
|
|
1054
985
|
typeof ctx.host === "string" && ctx.host.trim() !== ""
|
|
@@ -1057,6 +988,11 @@ export function createSecretariatRoleRuntime(
|
|
|
1057
988
|
if (host === undefined || !SECRETARIAT_SUBMISSION_GATE_HOSTS.has(host)) {
|
|
1058
989
|
return undefined;
|
|
1059
990
|
}
|
|
991
|
+
if (roleHost.requireGatekeeperPass === undefined) {
|
|
992
|
+
const error = new Error(`host ${host} cannot mount the secretariat submission gate`);
|
|
993
|
+
error.name = "InfrastructureFailure";
|
|
994
|
+
return hostActions.failInfrastructure(error, ctx, toolCallId);
|
|
995
|
+
}
|
|
1060
996
|
const record =
|
|
1061
997
|
parameters !== null && typeof parameters === "object" && !Array.isArray(parameters)
|
|
1062
998
|
? (parameters as Record<string, unknown>)
|
|
@@ -1151,7 +1087,6 @@ export function createSecretariatRoleRuntime(
|
|
|
1151
1087
|
{
|
|
1152
1088
|
role: "secretariat",
|
|
1153
1089
|
tool: SECRETARIAT_OUTPUT_TOOL_SPEC,
|
|
1154
|
-
acceptedText: SECRETARIAT_ACCEPTED_TEXT,
|
|
1155
1090
|
soulTag: "secretariat",
|
|
1156
1091
|
...(beforeAccept === undefined ? {} : { beforeAccept }),
|
|
1157
1092
|
},
|
|
@@ -1277,6 +1212,7 @@ export function createSecretariatRoleRuntime(
|
|
|
1277
1212
|
}
|
|
1278
1213
|
}
|
|
1279
1214
|
},
|
|
1215
|
+
claimsEngineDetour: true,
|
|
1280
1216
|
};
|
|
1281
1217
|
}
|
|
1282
1218
|
|
|
@@ -1290,7 +1226,7 @@ export function createCountersignRoleRuntime(
|
|
|
1290
1226
|
// #753 queue: read countersignStatus only — escalate skips gate (thrown to caller);
|
|
1291
1227
|
// unreadable status returns to countersign; else notary inner gate.
|
|
1292
1228
|
const beforeAccept: FiledOfficerBeforeAccept | undefined =
|
|
1293
|
-
hostActions !== undefined
|
|
1229
|
+
hostActions !== undefined
|
|
1294
1230
|
? async ({ toolCallId, parameters, signal, ctx }) => {
|
|
1295
1231
|
const record =
|
|
1296
1232
|
parameters !== null && typeof parameters === "object" && !Array.isArray(parameters)
|
|
@@ -1309,7 +1245,12 @@ export function createCountersignRoleRuntime(
|
|
|
1309
1245
|
// Parent escalate → throw to caller as-is; notary does not attend (#753).
|
|
1310
1246
|
return undefined;
|
|
1311
1247
|
}
|
|
1312
|
-
|
|
1248
|
+
if (roleHost.requireGatekeeperPass === undefined) {
|
|
1249
|
+
const error = new Error("host cannot mount the countersign gate");
|
|
1250
|
+
error.name = "InfrastructureFailure";
|
|
1251
|
+
return hostActions.failInfrastructure(error, ctx, toolCallId);
|
|
1252
|
+
}
|
|
1253
|
+
await roleHost.requireGatekeeperPass({
|
|
1313
1254
|
context: ctx,
|
|
1314
1255
|
subject: { kind: "countersign_verdict" },
|
|
1315
1256
|
...(signal === undefined ? {} : { signal }),
|
|
@@ -1325,7 +1266,6 @@ export function createCountersignRoleRuntime(
|
|
|
1325
1266
|
{
|
|
1326
1267
|
role: "countersign",
|
|
1327
1268
|
tool: COUNTERSIGN_TOOL_SPEC,
|
|
1328
|
-
acceptedText: COUNTERSIGN_ACCEPTED_TEXT,
|
|
1329
1269
|
soulTag: "countersign",
|
|
1330
1270
|
...(beforeAccept === undefined ? {} : { beforeAccept }),
|
|
1331
1271
|
},
|
|
@@ -1517,9 +1457,9 @@ export function createRoleRuntimeExtension(
|
|
|
1517
1457
|
if (role !== undefined && !admitted) return { action: "handled" as const };
|
|
1518
1458
|
// Reviewer: recover original request; Pi argv may already carry native form.
|
|
1519
1459
|
if (
|
|
1520
|
-
|
|
1521
|
-
&& admitted
|
|
1460
|
+
admitted
|
|
1522
1461
|
&& activeReviewerParent !== undefined
|
|
1462
|
+
&& selectedRole === role
|
|
1523
1463
|
&& reviewerOriginalRequest === undefined
|
|
1524
1464
|
) {
|
|
1525
1465
|
reviewerOriginalRequest =
|
|
@@ -1544,7 +1484,7 @@ export function createRoleRuntimeExtension(
|
|
|
1544
1484
|
}
|
|
1545
1485
|
// Notary session bound: envelope-owned lifecycle write (ADR 0018 / #582).
|
|
1546
1486
|
// Ticket flag register/read + session entry live here; role projects admitted bound only.
|
|
1547
|
-
if (role
|
|
1487
|
+
if (activationPublishesFlag(role, NOTARY_SOURCE_RUN_FLAG.name)) {
|
|
1548
1488
|
const bound = projectNotaryBoundFromFlags((name) => roleHost.getFlag(name));
|
|
1549
1489
|
if (bound !== undefined) {
|
|
1550
1490
|
ctx.sessionManager.appendCustomEntry?.(NOTARY_SESSION_BOUND_ENTRY, bound);
|
|
@@ -1582,7 +1522,7 @@ export function createRoleRuntimeExtension(
|
|
|
1582
1522
|
}
|
|
1583
1523
|
navigatorAttendance?.prepare();
|
|
1584
1524
|
// Envelope-owned Reviewer expansion capture + parent prompt assembly (no role-module callback).
|
|
1585
|
-
if (
|
|
1525
|
+
if (activeReviewerParent !== undefined && selectedRole === role) {
|
|
1586
1526
|
if (!reviewerExpansionCaptured) {
|
|
1587
1527
|
if (reviewerOriginalRequest !== undefined) {
|
|
1588
1528
|
activeReviewerParent.skillBinding.captureExpansion(
|
|
@@ -1600,7 +1540,7 @@ export function createRoleRuntimeExtension(
|
|
|
1600
1540
|
};
|
|
1601
1541
|
}
|
|
1602
1542
|
// #676 E / J1: collector materials + drift gates share this envelope hook (no parallel register).
|
|
1603
|
-
if (
|
|
1543
|
+
if (activeCollector !== undefined && selectedRole === role) {
|
|
1604
1544
|
if (!collectorFirstDispatchDone) {
|
|
1605
1545
|
collectorFirstDispatchDone = true;
|
|
1606
1546
|
activeCollector.ledger.recordActivation(activeCollector.clock);
|
|
@@ -1662,7 +1602,7 @@ export function createRoleRuntimeExtension(
|
|
|
1662
1602
|
const role = selectedRole;
|
|
1663
1603
|
if (role === undefined) return;
|
|
1664
1604
|
// #676 E / J1: collector operational bookkeeping on the shared tool_result seam.
|
|
1665
|
-
if (
|
|
1605
|
+
if (activeCollector !== undefined && selectedRole === roleHost.getFlag(ROLE_FLAG.name)) {
|
|
1666
1606
|
collectorBusiness.onToolResult(activeCollector, event);
|
|
1667
1607
|
}
|
|
1668
1608
|
const pendingInfra = pendingInfrastructureFailures.get(event.toolCallId);
|
|
@@ -1720,7 +1660,11 @@ export function createRoleRuntimeExtension(
|
|
|
1720
1660
|
const role = selectedRole ?? roleHost.getFlag(ROLE_FLAG.name);
|
|
1721
1661
|
// #959: navigator prose exit — final assistant text is the receipt.
|
|
1722
1662
|
// No typed-tool 催交; no JSON required. Tool path still wins when already accepted.
|
|
1723
|
-
if (
|
|
1663
|
+
if (
|
|
1664
|
+
typeof role === "string"
|
|
1665
|
+
&& packagedRoleOutputTool(role) === NAVIGATOR_TOOL_SPEC.name
|
|
1666
|
+
&& receiptDelivery.nextAction() !== "accepted"
|
|
1667
|
+
) {
|
|
1724
1668
|
const prose = lastAssistantProse(event.messages);
|
|
1725
1669
|
if (prose !== undefined && prose.trim() !== "") {
|
|
1726
1670
|
const accepted = { prose };
|
|
@@ -1831,11 +1775,7 @@ export function createRoleRuntimeExtension(
|
|
|
1831
1775
|
fetchWrapped = false;
|
|
1832
1776
|
}
|
|
1833
1777
|
// #676 J4: collector fatal latch must surface nonzero exit on shutdown (envelope-owned).
|
|
1834
|
-
if (
|
|
1835
|
-
selectedRole === "collector"
|
|
1836
|
-
&& activeCollector !== undefined
|
|
1837
|
-
&& activeCollector.ledger.fatal
|
|
1838
|
-
) {
|
|
1778
|
+
if (activeCollector !== undefined && activeCollector.ledger.fatal) {
|
|
1839
1779
|
if (process.exitCode === undefined || process.exitCode === 0) {
|
|
1840
1780
|
process.exitCode = 1;
|
|
1841
1781
|
}
|
|
@@ -1878,22 +1818,18 @@ export function createRoleRuntimeExtension(
|
|
|
1878
1818
|
pendingSubmissionNonPassByToolCallId.set(toolCallId, result);
|
|
1879
1819
|
},
|
|
1880
1820
|
};
|
|
1821
|
+
const requireRoleSoul = (role: PackagedRole): Promise<string> => dependencies.loadRoleSoul(role);
|
|
1881
1822
|
const judge = createJudgeRoleRuntime(
|
|
1882
1823
|
roleHost,
|
|
1883
1824
|
{
|
|
1884
|
-
loadSoul:
|
|
1825
|
+
loadSoul: () => requireRoleSoul("judge"),
|
|
1885
1826
|
},
|
|
1886
1827
|
hostActions,
|
|
1887
1828
|
);
|
|
1888
1829
|
const fixer = createFixerRoleRuntime(
|
|
1889
1830
|
roleHost,
|
|
1890
1831
|
{
|
|
1891
|
-
|
|
1892
|
-
if (dependencies.loadFixerSoul === undefined) {
|
|
1893
|
-
throw new Error("fixer soul loader is not configured");
|
|
1894
|
-
}
|
|
1895
|
-
return dependencies.loadFixerSoul();
|
|
1896
|
-
},
|
|
1832
|
+
loadSoul: () => requireRoleSoul("fixer"),
|
|
1897
1833
|
async loadPacket(path) {
|
|
1898
1834
|
if (dependencies.loadFixPacket === undefined) {
|
|
1899
1835
|
throw new Error("Fixer packet loader is not configured");
|
|
@@ -1906,12 +1842,7 @@ export function createRoleRuntimeExtension(
|
|
|
1906
1842
|
const coder = createCoderRoleRuntime(
|
|
1907
1843
|
roleHost,
|
|
1908
1844
|
{
|
|
1909
|
-
|
|
1910
|
-
if (dependencies.loadCoderSoul === undefined) {
|
|
1911
|
-
throw new Error("coder soul loader is not configured");
|
|
1912
|
-
}
|
|
1913
|
-
return dependencies.loadCoderSoul();
|
|
1914
|
-
},
|
|
1845
|
+
loadSoul: () => requireRoleSoul("coder"),
|
|
1915
1846
|
async loadTask(path) {
|
|
1916
1847
|
if (dependencies.loadCoderTask === undefined) {
|
|
1917
1848
|
throw new Error("Coder task loader is not configured");
|
|
@@ -1930,12 +1861,7 @@ export function createRoleRuntimeExtension(
|
|
|
1930
1861
|
const reviewer = createReviewerRoleRuntime(
|
|
1931
1862
|
roleHost,
|
|
1932
1863
|
{
|
|
1933
|
-
|
|
1934
|
-
if (dependencies.loadReviewerSoul === undefined) {
|
|
1935
|
-
throw new Error("reviewer soul loader is not configured");
|
|
1936
|
-
}
|
|
1937
|
-
return dependencies.loadReviewerSoul();
|
|
1938
|
-
},
|
|
1864
|
+
loadSoul: () => requireRoleSoul("reviewer"),
|
|
1939
1865
|
async loadCanonicalSkillBinding(name) {
|
|
1940
1866
|
if (dependencies.loadCanonicalSkillBinding === undefined) {
|
|
1941
1867
|
throw new Error("Reviewer runtime dependencies are not configured");
|
|
@@ -1946,31 +1872,22 @@ export function createRoleRuntimeExtension(
|
|
|
1946
1872
|
hostActions,
|
|
1947
1873
|
);
|
|
1948
1874
|
const doctor = createDoctorRoleRuntime(roleHost, {
|
|
1949
|
-
|
|
1875
|
+
loadSoul: () => requireRoleSoul("doctor"),
|
|
1950
1876
|
async loadCase(path) { if (!dependencies.loadDoctorCase) throw new Error("Doctor runtime dependencies are not configured"); return dependencies.loadDoctorCase(path); },
|
|
1951
1877
|
async auditCompliance(options) { if (!dependencies.auditDoctorCompliance) throw new Error("Doctor runtime dependencies are not configured"); return dependencies.auditDoctorCompliance(options); },
|
|
1952
1878
|
}, hostActions);
|
|
1953
1879
|
const notary = createNotaryRoleRuntime(roleHost, {
|
|
1954
|
-
|
|
1955
|
-
if (!dependencies.loadNotarySoul) throw new Error("Notary runtime dependencies are not configured");
|
|
1956
|
-
return dependencies.loadNotarySoul();
|
|
1957
|
-
},
|
|
1880
|
+
loadSoul: () => requireRoleSoul("notary"),
|
|
1958
1881
|
async loadSourceRunLocator(path) {
|
|
1959
1882
|
if (!dependencies.loadNotarySourceRun) throw new Error("Notary runtime dependencies are not configured");
|
|
1960
1883
|
return dependencies.loadNotarySourceRun(path);
|
|
1961
1884
|
},
|
|
1962
1885
|
}, hostActions);
|
|
1963
1886
|
const countersign = createCountersignRoleRuntime(roleHost, {
|
|
1964
|
-
|
|
1965
|
-
if (!dependencies.loadCountersignSoul) throw new Error("Countersign runtime dependencies are not configured");
|
|
1966
|
-
return dependencies.loadCountersignSoul();
|
|
1967
|
-
},
|
|
1887
|
+
loadSoul: () => requireRoleSoul("countersign"),
|
|
1968
1888
|
}, hostActions);
|
|
1969
1889
|
const gleanerLeftRuntime = createGleanerLeftRoleRuntime(roleHost, {
|
|
1970
|
-
|
|
1971
|
-
if (!dependencies.loadGleanerLeftSoul) throw new Error("Gleaner-left runtime dependencies are not configured");
|
|
1972
|
-
return dependencies.loadGleanerLeftSoul();
|
|
1973
|
-
},
|
|
1890
|
+
loadSoul: () => requireRoleSoul("gleaner-left"),
|
|
1974
1891
|
});
|
|
1975
1892
|
const gleanerLeft = {
|
|
1976
1893
|
async activate() {
|
|
@@ -1979,43 +1896,25 @@ export function createRoleRuntimeExtension(
|
|
|
1979
1896
|
},
|
|
1980
1897
|
};
|
|
1981
1898
|
const inspector = createInspectorRoleRuntime(roleHost, {
|
|
1982
|
-
|
|
1983
|
-
if (!dependencies.loadInspectorSoul) throw new Error("Inspector runtime dependencies are not configured");
|
|
1984
|
-
return dependencies.loadInspectorSoul();
|
|
1985
|
-
},
|
|
1899
|
+
loadSoul: () => requireRoleSoul("inspector"),
|
|
1986
1900
|
});
|
|
1987
1901
|
const gatekeeper = createGatekeeperRoleRuntime(roleHost, {
|
|
1988
|
-
|
|
1989
|
-
if (!dependencies.loadGatekeeperSoul) throw new Error("Gatekeeper runtime dependencies are not configured");
|
|
1990
|
-
return dependencies.loadGatekeeperSoul();
|
|
1991
|
-
},
|
|
1902
|
+
loadSoul: () => requireRoleSoul("gatekeeper"),
|
|
1992
1903
|
});
|
|
1993
1904
|
const navigator = createNavigatorRoleRuntime(roleHost, {
|
|
1994
|
-
|
|
1995
|
-
if (!dependencies.loadNavigatorSoul) throw new Error("Navigator runtime dependencies are not configured");
|
|
1996
|
-
return dependencies.loadNavigatorSoul();
|
|
1997
|
-
},
|
|
1905
|
+
loadSoul: () => requireRoleSoul("navigator"),
|
|
1998
1906
|
});
|
|
1999
1907
|
const auditor = createAuditorRoleRuntime(roleHost, {
|
|
2000
|
-
|
|
2001
|
-
if (!dependencies.loadAuditorSoul) throw new Error("Auditor runtime dependencies are not configured");
|
|
2002
|
-
return dependencies.loadAuditorSoul();
|
|
2003
|
-
},
|
|
1908
|
+
loadSoul: () => requireRoleSoul("auditor"),
|
|
2004
1909
|
});
|
|
2005
1910
|
const diarist = createDiaristRoleRuntime(
|
|
2006
1911
|
roleHost,
|
|
2007
1912
|
{
|
|
2008
|
-
|
|
2009
|
-
if (!dependencies.loadDiaristSoul) throw new Error("Diarist runtime dependencies are not configured");
|
|
2010
|
-
return dependencies.loadDiaristSoul();
|
|
2011
|
-
},
|
|
1913
|
+
loadSoul: () => requireRoleSoul("diarist"),
|
|
2012
1914
|
},
|
|
2013
1915
|
);
|
|
2014
1916
|
const secretariat = createSecretariatRoleRuntime(roleHost, {
|
|
2015
|
-
|
|
2016
|
-
if (!dependencies.loadSecretariatSoul) throw new Error("Secretariat runtime dependencies are not configured");
|
|
2017
|
-
return dependencies.loadSecretariatSoul();
|
|
2018
|
-
},
|
|
1917
|
+
loadSoul: () => requireRoleSoul("secretariat"),
|
|
2019
1918
|
...(dependencies.packageRoot === undefined
|
|
2020
1919
|
? {}
|
|
2021
1920
|
: { packageRoot: dependencies.packageRoot }),
|
|
@@ -2024,7 +1923,7 @@ export function createRoleRuntimeExtension(
|
|
|
2024
1923
|
: { hostAdapters: dependencies.hostAdapters }),
|
|
2025
1924
|
}, hostActions);
|
|
2026
1925
|
const merger = createMergerRoleRuntime(roleHost, {
|
|
2027
|
-
|
|
1926
|
+
loadSoul: () => requireRoleSoul("merger"),
|
|
2028
1927
|
async loadInput(path) { if (!dependencies.loadMergerInput) throw new Error("Merger runtime dependencies are not configured"); return dependencies.loadMergerInput(path); },
|
|
2029
1928
|
});
|
|
2030
1929
|
// #676 E: shared envelope owns collector lifecycle (mode/fork, tool surface,
|
|
@@ -2034,12 +1933,7 @@ export function createRoleRuntimeExtension(
|
|
|
2034
1933
|
const collectorBusiness = createCollectorRoleRuntime(
|
|
2035
1934
|
roleHost,
|
|
2036
1935
|
{
|
|
2037
|
-
|
|
2038
|
-
if (dependencies.loadCollectorSoul === undefined) {
|
|
2039
|
-
throw new Error("collector soul loader is not configured");
|
|
2040
|
-
}
|
|
2041
|
-
return dependencies.loadCollectorSoul();
|
|
2042
|
-
},
|
|
1936
|
+
loadSoul: () => requireRoleSoul("collector"),
|
|
2043
1937
|
createTransport() {
|
|
2044
1938
|
if (dependencies.createCollectorTransport === undefined) {
|
|
2045
1939
|
throw new Error("Collector GitHub transport is not configured");
|
|
@@ -2142,7 +2036,8 @@ export function createRoleRuntimeExtension(
|
|
|
2142
2036
|
if (!collectorToolCallRegistered) {
|
|
2143
2037
|
collectorToolCallRegistered = true;
|
|
2144
2038
|
roleHost.on("tool_call", (toolEvent) => {
|
|
2145
|
-
|
|
2039
|
+
const liveRole = roleHost.getFlag(ROLE_FLAG.name);
|
|
2040
|
+
if (activeCollector === undefined || selectedRole === undefined || selectedRole !== liveRole) return;
|
|
2146
2041
|
if (!(COLLECTOR_REQUIRED_TOOLS as readonly string[]).includes(toolEvent.toolName)) {
|
|
2147
2042
|
return {
|
|
2148
2043
|
block: true,
|
|
@@ -2264,6 +2159,8 @@ export function createRoleRuntimeExtension(
|
|
|
2264
2159
|
selectedRole = undefined;
|
|
2265
2160
|
roleReferenceMaterials = "";
|
|
2266
2161
|
activeReviewerParent = undefined;
|
|
2162
|
+
activeCollector = undefined;
|
|
2163
|
+
collectorFirstDispatchDone = false;
|
|
2267
2164
|
reviewerOriginalRequest = undefined;
|
|
2268
2165
|
reviewerExpansionCaptured = false;
|
|
2269
2166
|
receiptDelivery = createReceiptDeliveryPolicy();
|
|
@@ -2286,40 +2183,32 @@ export function createRoleRuntimeExtension(
|
|
|
2286
2183
|
selectedRole = entry.role;
|
|
2287
2184
|
await navigatorAttendance?.dispose();
|
|
2288
2185
|
navigatorAttendance = undefined;
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
judge,
|
|
2293
|
-
fixer,
|
|
2294
|
-
coder,
|
|
2295
|
-
reviewer
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
},
|
|
2299
|
-
bindReviewerParent(activation) {
|
|
2300
|
-
activeReviewerParent = activation;
|
|
2186
|
+
// One activation call per seat. Stage id still comes from the registry.
|
|
2187
|
+
// Envelope owns Reviewer and Notary flag reads (ADR 0018).
|
|
2188
|
+
const activateByRole = {
|
|
2189
|
+
judge: () => judge.activate(),
|
|
2190
|
+
fixer: () => fixer.activate(),
|
|
2191
|
+
coder: () => coder.activate(ctx),
|
|
2192
|
+
reviewer: async () => {
|
|
2193
|
+
const admitted = decodeReviewerAdmittedInputs((name) => roleHost.getFlag(name));
|
|
2194
|
+
activeReviewerParent = await reviewer.activate(ctx, admitted);
|
|
2301
2195
|
},
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
);
|
|
2306
|
-
return ticketNumber === undefined ? undefined : { ticketNumber };
|
|
2196
|
+
collector: () => collector.activate(ctx, event),
|
|
2197
|
+
doctor: () => doctor.activate(),
|
|
2198
|
+
notary: () => {
|
|
2199
|
+
const ticketNumber = readNotaryTicketFlag(roleHost.getFlag(NOTARY_TICKET_FLAG.name));
|
|
2200
|
+
return notary.activate(ticketNumber === undefined ? undefined : { ticketNumber });
|
|
2307
2201
|
},
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
secretariat,
|
|
2319
|
-
merger: async () => {
|
|
2320
|
-
await merger.activate();
|
|
2321
|
-
},
|
|
2322
|
-
};
|
|
2202
|
+
countersign: () => countersign.activate(),
|
|
2203
|
+
"gleaner-left": () => gleanerLeft.activate(),
|
|
2204
|
+
inspector: () => inspector.activate(),
|
|
2205
|
+
gatekeeper: () => gatekeeper.activate(),
|
|
2206
|
+
navigator: () => navigator.activate(),
|
|
2207
|
+
auditor: () => auditor.activate(),
|
|
2208
|
+
diarist: () => diarist.activate(),
|
|
2209
|
+
secretariat: () => secretariat.activate(),
|
|
2210
|
+
merger: () => merger.activate(),
|
|
2211
|
+
} satisfies Record<PackagedRole, () => Promise<void>>;
|
|
2323
2212
|
try {
|
|
2324
2213
|
// Production topology only (ADR 0048/0049): no test-only ledger hooks.
|
|
2325
2214
|
// Admit durable session file first so lifecycle getEntries/appendEntry are truthful:
|
|
@@ -2335,7 +2224,7 @@ export function createRoleRuntimeExtension(
|
|
|
2335
2224
|
const isStationChild = roleHost.getFlag(STATION_CHILD_FLAG.name) === true;
|
|
2336
2225
|
if (
|
|
2337
2226
|
dependencies.createNavigatorAttendance !== undefined
|
|
2338
|
-
&& entry.
|
|
2227
|
+
&& entry.outputTool !== NAVIGATOR_TOOL_SPEC.name
|
|
2339
2228
|
&& !isStationChild
|
|
2340
2229
|
) {
|
|
2341
2230
|
navigatorSessionParent = ctx.sessionManager.getSessionFile();
|
|
@@ -2420,7 +2309,7 @@ export function createRoleRuntimeExtension(
|
|
|
2420
2309
|
}
|
|
2421
2310
|
}
|
|
2422
2311
|
|
|
2423
|
-
await executeActivationStage(entry.role, activationStage(entry.role,
|
|
2312
|
+
await executeActivationStage(entry.role, activationStage(entry.role, activateByRole), { clock, writeTrace });
|
|
2424
2313
|
roleReferenceMaterials = await dependencies.loadRoleReferenceMaterials?.(entry.role) ?? "";
|
|
2425
2314
|
// #357 T2 / #378 / #380 / #391 / #818: any role+engine activation registers the package detour tool once.
|
|
2426
2315
|
// Gate is resolveEngineName (RoleHost flag → env fallback) — no per-engine execute branch; no role-module spawn.
|
|
@@ -2430,16 +2319,16 @@ export function createRoleRuntimeExtension(
|
|
|
2430
2319
|
// Secretariat owns a declared active surface. The shared engine detour is
|
|
2431
2320
|
// registered after role activation, so include it here rather than leave
|
|
2432
2321
|
// a newly registered optional tool unreachable until a later reload.
|
|
2433
|
-
if (
|
|
2322
|
+
if (secretariat.claimsEngineDetour === true && engineDetourRegistered) {
|
|
2434
2323
|
roleHost.setActiveTools([
|
|
2435
2324
|
...new Set([...roleHost.getActiveTools(), ENGINE_DETOUR_TOOL_NAME]),
|
|
2436
2325
|
]);
|
|
2437
2326
|
}
|
|
2438
|
-
// Worker gates ①②:
|
|
2327
|
+
// Worker gates ①②: registry declares the worker seats (ADR 0066 / 0070).
|
|
2439
2328
|
// Parent session feeds #216 createRecordSession so baseline/bounce survive resume.
|
|
2440
|
-
if (
|
|
2441
|
-
|
|
2442
|
-
|
|
2329
|
+
if ("worker" in entry && entry.worker === true) {
|
|
2330
|
+
const workerArms = { coder, fixer } as const;
|
|
2331
|
+
workerArms[entry.role].armSubmissionGate(ctx.cwd, ctx.sessionManager);
|
|
2443
2332
|
}
|
|
2444
2333
|
admitted = true;
|
|
2445
2334
|
} catch (error) {
|