@akagilnc/pi-workflow-roles 0.1.5845 → 0.1.5853
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/README.zh-CN.md +4 -4
- package/dist/acp-host/production-host.js +348 -1254
- package/dist/acp-host/role-turn-host.js +4 -98
- package/dist/headless-host/production-host.js +15731 -16582
- package/dist/headless-host/role-turn-host.js +6 -31
- package/dist/migrate-book-topology.js +31 -16
- package/dist/navigator-attendance.js +54 -404
- package/dist/navigator-invocation-identity.js +0 -2
- package/dist/navigator-lookup-host.js +41 -0
- package/dist/navigator-lookup.js +68 -0
- package/dist/navigator-route-table.js +42 -0
- package/dist/package-contracts/navigator-output.js +3 -11
- package/dist/packaged-role-registry.js +3 -27
- package/dist/public-cli/instruction-seat-run.js +4 -1
- package/dist/public-cli/invocation.js +13 -26
- package/dist/public-cli/main.js +286 -114
- package/dist/public-cli/option-definitions.js +24 -4
- package/dist/public-cli/post-admission.js +0 -9
- package/dist/public-cli/role-seat-runtime.js +14 -0
- package/dist/public-cli/settlement.js +14 -40
- package/dist/public-cli/terminal.js +1 -8
- package/dist/public-cli/turn-request.js +0 -3
- package/dist/public-role-summons.js +0 -1
- package/dist/receipt-delivery-policy.js +0 -23
- package/dist/role-runtime-dependencies.js +4 -11
- package/dist/role-runtime.js +18 -194
- package/dist/submission-ledger.js +19 -15
- package/dist/ticket-progress.js +23 -5
- package/extensions/role-runtime.ts +0 -16
- package/package.json +1 -1
- package/scripts/build-package.mjs +3 -7
- package/src/acp-host/role-turn-host.ts +8 -97
- package/src/headless-host/description.ts +0 -2
- package/src/headless-host/role-turn-host.ts +7 -32
- package/src/host-contracts.ts +5 -7
- package/src/navigator-attendance.ts +86 -549
- package/src/navigator-invocation-identity.ts +0 -2
- package/src/navigator-lookup-host.ts +45 -0
- package/src/navigator-lookup.ts +98 -0
- package/src/navigator-route-table.ts +92 -0
- package/src/package-contracts/navigator-output.ts +4 -15
- package/src/packaged-role-registry.ts +3 -32
- package/src/public-cli/instruction-seat-run.ts +3 -0
- package/src/public-cli/invocation.ts +18 -30
- package/src/public-cli/option-definitions.ts +25 -4
- package/src/public-cli/post-admission.ts +0 -11
- package/src/public-cli/role-seat-runtime.ts +14 -0
- package/src/public-cli/settlement.ts +23 -51
- package/src/public-cli/terminal.ts +3 -18
- package/src/public-cli/turn-request.ts +0 -5
- package/src/public-role-summons.ts +0 -8
- package/src/receipt-delivery-policy.ts +0 -21
- package/src/role-runtime-dependencies.ts +4 -11
- package/src/role-runtime.ts +19 -210
- package/src/submission-ledger.ts +23 -16
- package/src/ticket-progress.ts +32 -5
- package/dist/navigator-public-session.js +0 -205
- package/dist/navigator-role.js +0 -6
- package/dist/navigator-session-contracts.js +0 -227
- package/dist/navigator-work-context.js +0 -72
- package/resources/navigator-route-playbook.md +0 -33
- package/src/navigator-public-session.ts +0 -305
- package/src/navigator-role.ts +0 -15
- package/src/navigator-session-contracts.ts +0 -320
- package/src/navigator-work-context.ts +0 -97
package/dist/role-runtime.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { randomUUID } from "node:crypto";
|
|
2
1
|
import { readPageSync, RUN_STATE_FILE } from "./run-dossier.js";
|
|
3
2
|
import { admittedSourceRunPath } from "./public-cli/invocation.js";
|
|
4
3
|
import { readFileSync, writeSync } from "node:fs";
|
|
@@ -7,14 +6,13 @@ import { ExplicitInternalActivationError, runDirectoryFromHostContext, } from ".
|
|
|
7
6
|
import { Value } from "typebox/value";
|
|
8
7
|
import { sitianReport } from "./sitian-facade.js";
|
|
9
8
|
import { sitianReportSafe } from "./host-session-record.js";
|
|
10
|
-
import { createSubmissionLedgerHost
|
|
9
|
+
import { createSubmissionLedgerHost } from "./submission-ledger.js";
|
|
11
10
|
import { registerFiledSubmissionTool } from "./filed-submission.js";
|
|
12
11
|
import { registerReportTicketTool, reportTicketFromHostContext, REPORT_TICKET_TOOL_NAME, } from "./report-ticket-tool.js";
|
|
13
12
|
import { activationTraceRecordSchema, namedActivationCause } from "./activation-trace.js";
|
|
14
13
|
import { homeFromRunDirectory } from "./activation-ledger-topology.js";
|
|
15
14
|
import { isSafePositiveTicketNumber, parseTicketNumber, } from "./run-ticket-number.js";
|
|
16
15
|
import { durableSessionPointer, resolveBookKeyFromGit, } from "./activation-ledger.js";
|
|
17
|
-
import { readPackageMaterial } from "./session-opening-materials.js";
|
|
18
16
|
import { writeStderrJsonlRecord } from "./stderr-jsonl.js";
|
|
19
17
|
import { ENGINE_DETOUR_TOOL_NAME, ENGINE_MODEL_FLAG_NAME, resolveEngineModel, resolveEngineName, } from "./engine-detour.js";
|
|
20
18
|
import { engineSessionMaterialFromOptions, engineSessionReadingMaterial, } from "./package-resources/engine-material.js";
|
|
@@ -36,14 +34,13 @@ import { projectDiaristSessions, projectDiaristTicketSessions, } from "./diarist
|
|
|
36
34
|
import { commitDiaristProjection } from "./diarist.js";
|
|
37
35
|
import { TicketProvenanceInputError } from "./ticket-provenance.js";
|
|
38
36
|
import { GATEKEEPER_TOOL_SPEC, } from "./gatekeeper-role.js";
|
|
39
|
-
import { NAVIGATOR_TOOL_SPEC, } from "./navigator-role.js";
|
|
40
37
|
import { AUDITOR_TOOL_SPEC, } from "./auditor-role.js";
|
|
41
38
|
import { auditedRunIdentityFromDirectory, auditedRunIdentityMaterial, } from "./audited-run-identity.js";
|
|
42
|
-
import { formatNavigatorReport, NAVIGATOR_EVENT_TYPE,
|
|
39
|
+
import { formatNavigatorReport, NAVIGATOR_EVENT_TYPE, subjectPath } from "./navigator-attendance.js";
|
|
43
40
|
import { AK_ROLE_AUDITOR_SOURCE_RUN_ENV } from "./auditor-soul.js";
|
|
44
41
|
import { buildNavigatorInfrastructureFailureFact, classifyPackagedRoleTerminalResult, packagedRoleOutputRejectionReason, extractInfrastructureFailureEvidence, NAVIGATOR_INVOCATION_ENTRY, resolveLifecycleInvocationPrincipal, } from "./navigator-invocation-identity.js";
|
|
45
42
|
import { NAVIGATOR_POST_ROLE_GRACE_MS, raceNavigatorGrace } from "./public-cli/settlement.js";
|
|
46
|
-
import { PACKAGED_ROLE_REGISTRY,
|
|
43
|
+
import { PACKAGED_ROLE_REGISTRY, isNavigatorSeat, packagedRoleActivationFlags, packagedRoleMetadata, packagedRoleOutputTool, packagedRolePhaseFlag, } from "./packaged-role-registry.js";
|
|
47
44
|
import { createJudgeRoleRuntime, } from "./judge-role.js";
|
|
48
45
|
import { createReviewerRoleRuntime, } from "./reviewer-role.js";
|
|
49
46
|
/**
|
|
@@ -398,52 +395,6 @@ export function createGatekeeperRoleRuntime(roleHost, dependencies) {
|
|
|
398
395
|
soulTag: "gatekeeper",
|
|
399
396
|
}, dependencies);
|
|
400
397
|
}
|
|
401
|
-
/** #639: direct Navigator public seat on the shared filed-officer envelope. */
|
|
402
|
-
export function createNavigatorRoleRuntime(roleHost, dependencies) {
|
|
403
|
-
const base = createFiledOfficerRuntime(roleHost, {
|
|
404
|
-
role: "navigator",
|
|
405
|
-
tool: NAVIGATOR_TOOL_SPEC,
|
|
406
|
-
soulTag: "navigator",
|
|
407
|
-
}, dependencies);
|
|
408
|
-
let playbookBound = false;
|
|
409
|
-
return {
|
|
410
|
-
async activate() {
|
|
411
|
-
await base.activate();
|
|
412
|
-
if (playbookBound)
|
|
413
|
-
return;
|
|
414
|
-
playbookBound = true;
|
|
415
|
-
// Standing system prompt, not a per-turn user message. Native read failure
|
|
416
|
-
// is the explanation (ADR 0061); no code-written sentence.
|
|
417
|
-
const loadRoutePlaybook = dependencies.loadRoutePlaybook
|
|
418
|
-
?? (() => readPackageMaterial("resources/navigator-route-playbook.md"));
|
|
419
|
-
let playbookRead;
|
|
420
|
-
roleHost.on("before_agent_start", async (event, ctx) => {
|
|
421
|
-
const basePrompt = typeof event.systemPrompt === "string" ? event.systemPrompt : "";
|
|
422
|
-
const parts = [];
|
|
423
|
-
try {
|
|
424
|
-
playbookRead ??= loadRoutePlaybook();
|
|
425
|
-
const content = await playbookRead;
|
|
426
|
-
dependencies.recordRoutePlaybookReadFailure?.(undefined);
|
|
427
|
-
if (content.trim() !== "")
|
|
428
|
-
parts.push(content);
|
|
429
|
-
}
|
|
430
|
-
catch (error) {
|
|
431
|
-
const message = errorText(error);
|
|
432
|
-
if (message.trim() !== "") {
|
|
433
|
-
dependencies.recordRoutePlaybookReadFailure?.(message);
|
|
434
|
-
parts.push(message);
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
if (parts.length === 0)
|
|
438
|
-
return;
|
|
439
|
-
const text = parts.join("\n\n");
|
|
440
|
-
return {
|
|
441
|
-
systemPrompt: basePrompt.trim() === "" ? text : `${basePrompt}\n\n${text}`,
|
|
442
|
-
};
|
|
443
|
-
});
|
|
444
|
-
},
|
|
445
|
-
};
|
|
446
|
-
}
|
|
447
398
|
/** #675: public 审刑院 seat on the shared filed-officer envelope. */
|
|
448
399
|
export function createAuditorRoleRuntime(roleHost, dependencies) {
|
|
449
400
|
return createFiledOfficerRuntime(roleHost, {
|
|
@@ -641,27 +592,6 @@ export function createCountersignRoleRuntime(roleHost, dependencies) {
|
|
|
641
592
|
soulTag: "countersign",
|
|
642
593
|
}, dependencies);
|
|
643
594
|
}
|
|
644
|
-
/**
|
|
645
|
-
* #959: last assistant text parts as navigator prose exit.
|
|
646
|
-
* Tool-call-only messages yield undefined — those already ride the tool path.
|
|
647
|
-
*/
|
|
648
|
-
function lastAssistantProse(messages) {
|
|
649
|
-
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
650
|
-
const message = messages[index];
|
|
651
|
-
if (message?.role !== "assistant" || !Array.isArray(message.content))
|
|
652
|
-
continue;
|
|
653
|
-
const texts = [];
|
|
654
|
-
for (const part of message.content) {
|
|
655
|
-
if (part.type === "text" && typeof part.text === "string" && part.text.length > 0) {
|
|
656
|
-
texts.push(part.text);
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
if (texts.length === 0)
|
|
660
|
-
continue;
|
|
661
|
-
return texts.join("");
|
|
662
|
-
}
|
|
663
|
-
return undefined;
|
|
664
|
-
}
|
|
665
595
|
export function createRoleRuntimeExtension(dependencies,
|
|
666
596
|
/**
|
|
667
597
|
* Effective ceiling already resolved for this turn (#1132). Absent only on
|
|
@@ -721,7 +651,7 @@ deliveryRequestLimit) {
|
|
|
721
651
|
let navigatorActivation = 0;
|
|
722
652
|
let navigatorDeliveryClosed = false;
|
|
723
653
|
let pendingNavigatorSettlement;
|
|
724
|
-
let
|
|
654
|
+
let navigatorSubjectKey;
|
|
725
655
|
let navigatorSessionParent;
|
|
726
656
|
let navigatorCwd;
|
|
727
657
|
/** toolCallId → fact+evidence; one-shot projected onto durable tool_result (#475). */
|
|
@@ -776,7 +706,7 @@ deliveryRequestLimit) {
|
|
|
776
706
|
const attendance = navigatorAttendance;
|
|
777
707
|
if (settlement === undefined || attendance === undefined)
|
|
778
708
|
return;
|
|
779
|
-
const
|
|
709
|
+
const subjectKey = navigatorSubjectKey;
|
|
780
710
|
const pending = (async () => {
|
|
781
711
|
// ADR 0052 / #959 / #1160: every settlement that waits on parallel prepare
|
|
782
712
|
// (accepted, human_decision, role_infrastructure_failure) shares one grace
|
|
@@ -795,7 +725,6 @@ deliveryRequestLimit) {
|
|
|
795
725
|
disposition: "unavailable",
|
|
796
726
|
unavailableReason: "Navigator exceeded post-role delivery grace",
|
|
797
727
|
unavailableSource: "unknown",
|
|
798
|
-
unavailableCause: "unknown",
|
|
799
728
|
};
|
|
800
729
|
const event = {
|
|
801
730
|
version: 1,
|
|
@@ -803,10 +732,9 @@ deliveryRequestLimit) {
|
|
|
803
732
|
invocationId: "post-role-grace-timeout",
|
|
804
733
|
role: settlement.role,
|
|
805
734
|
phase: settlement.phase,
|
|
806
|
-
subjectKey:
|
|
735
|
+
subjectKey: subjectKey ?? "",
|
|
807
736
|
unavailableReason: "Navigator exceeded post-role delivery grace",
|
|
808
737
|
unavailableSource: "unknown",
|
|
809
|
-
unavailableCause: "unknown",
|
|
810
738
|
};
|
|
811
739
|
pendingNavigatorPresentation = { event, report };
|
|
812
740
|
}
|
|
@@ -861,30 +789,6 @@ deliveryRequestLimit) {
|
|
|
861
789
|
ctx.sessionManager.appendCustomEntry?.(NOTARY_SESSION_BOUND_ENTRY, bound);
|
|
862
790
|
}
|
|
863
791
|
}
|
|
864
|
-
if (navigatorAttendance !== undefined && navigatorWorkContext !== undefined && navigatorWorkContext.contextError === undefined) {
|
|
865
|
-
// Flagged roles already have a concrete packet/task/case/review input.
|
|
866
|
-
// A bare Judge (and other bare packaged entrypoint) gets its concrete
|
|
867
|
-
// user task at this seam; do not copy the assembled system prompt.
|
|
868
|
-
// Replacement is keyed by typed subject provenance, never prose prefixes.
|
|
869
|
-
// Soft session_start placeholders (no materials yet) recover here; hard
|
|
870
|
-
// contextError from true loader failures stays poisoned and honest.
|
|
871
|
-
if (navigatorWorkContext.subjectProvenance === "placeholder") {
|
|
872
|
-
// Navigator's own input bootstrap (#836): human prompt bytes key the
|
|
873
|
-
// identity when nothing else has supplied a concrete subject yet.
|
|
874
|
-
// Auto prepare stays identity-only — no subject/authority material copy.
|
|
875
|
-
const subject = prompt.trim();
|
|
876
|
-
if (subject !== "") {
|
|
877
|
-
const root = subjectPath(ctx.sessionManager.getSessionDir(), ctx.cwd);
|
|
878
|
-
const subjectProvenance = "user_prompt";
|
|
879
|
-
navigatorWorkContext = {
|
|
880
|
-
subjectKey: navigatorSubjectKey(root, subject, subjectProvenance),
|
|
881
|
-
subjectProvenance,
|
|
882
|
-
};
|
|
883
|
-
await navigatorAttendance.setWorkContext(navigatorWorkContext);
|
|
884
|
-
}
|
|
885
|
-
}
|
|
886
|
-
}
|
|
887
|
-
navigatorAttendance?.prepare();
|
|
888
792
|
// Reviewer parent prompt assembly.
|
|
889
793
|
if (activeReviewerParent !== undefined && selectedRole === role) {
|
|
890
794
|
return {
|
|
@@ -1006,49 +910,6 @@ deliveryRequestLimit) {
|
|
|
1006
910
|
}
|
|
1007
911
|
return;
|
|
1008
912
|
}
|
|
1009
|
-
const role = selectedRole ?? roleHost.getFlag(ROLE_FLAG.name);
|
|
1010
|
-
// #959: navigator prose exit — final assistant text is the receipt.
|
|
1011
|
-
// No typed-tool 催交; no JSON required. Tool path still wins when already accepted.
|
|
1012
|
-
if (typeof role === "string"
|
|
1013
|
-
&& packagedRoleOutputTool(role) === NAVIGATOR_TOOL_SPEC.name
|
|
1014
|
-
&& receiptDelivery.nextAction() !== "accepted") {
|
|
1015
|
-
const prose = lastAssistantProse(event.messages);
|
|
1016
|
-
if (prose !== undefined && prose.trim() !== "") {
|
|
1017
|
-
const accepted = { prose };
|
|
1018
|
-
const toolCallId = `navigator-prose-exit:${randomUUID()}`;
|
|
1019
|
-
await sealAcceptedSubmission({
|
|
1020
|
-
context: ctx,
|
|
1021
|
-
role: "navigator",
|
|
1022
|
-
accepted,
|
|
1023
|
-
toolCallId,
|
|
1024
|
-
});
|
|
1025
|
-
await projectClosedSubmission({ role: "navigator", kind: "accepted", accepted }, ctx, toolCallId);
|
|
1026
|
-
return;
|
|
1027
|
-
}
|
|
1028
|
-
// Attended with neither tool nor prose → honest no_receipt (not typed 催交).
|
|
1029
|
-
// Close the budget without sending prompts; the fact stays the real count.
|
|
1030
|
-
if (!noReceiptRecorded) {
|
|
1031
|
-
const runPointer = runDirectoryFromHostContext(ctx);
|
|
1032
|
-
if (runPointer !== undefined) {
|
|
1033
|
-
noReceiptRecorded = true;
|
|
1034
|
-
receiptDelivery.closeBudget();
|
|
1035
|
-
const facts = receiptDelivery.facts({
|
|
1036
|
-
runPointer,
|
|
1037
|
-
attemptPointer: receiptAttemptPointer(runPointer, ctx.invocationScopeId),
|
|
1038
|
-
});
|
|
1039
|
-
envelopeHost.appendEntry(NO_RECEIPT_LIFECYCLE_ENTRY_TYPE, facts);
|
|
1040
|
-
sitianReportSafe({
|
|
1041
|
-
level: "event",
|
|
1042
|
-
kind: "no-receipt-lifecycle",
|
|
1043
|
-
cwd: ctx.cwd,
|
|
1044
|
-
sessionParent: ctx.sessionManager.getSessionFile(),
|
|
1045
|
-
payload: facts,
|
|
1046
|
-
source: "role-runtime",
|
|
1047
|
-
});
|
|
1048
|
-
}
|
|
1049
|
-
}
|
|
1050
|
-
return;
|
|
1051
|
-
}
|
|
1052
913
|
if (receiptDelivery.nextAction() === "request-delivery") {
|
|
1053
914
|
receiptDelivery.recordDeliveryRequest();
|
|
1054
915
|
// Keep the package-owned continuation off the public input lifecycle:
|
|
@@ -1196,14 +1057,6 @@ deliveryRequestLimit) {
|
|
|
1196
1057
|
const gatekeeper = createGatekeeperRoleRuntime(roleHost, {
|
|
1197
1058
|
loadSoul: () => requireRoleSoul("gatekeeper"),
|
|
1198
1059
|
});
|
|
1199
|
-
const navigator = createNavigatorRoleRuntime(roleHost, {
|
|
1200
|
-
loadSoul: () => requireRoleSoul("navigator"),
|
|
1201
|
-
recordRoutePlaybookReadFailure: (message) => {
|
|
1202
|
-
envelopeHost.appendEntry(NAVIGATOR_ROUTE_PLAYBOOK_FAILURE_ENTRY, {
|
|
1203
|
-
message: message ?? "",
|
|
1204
|
-
});
|
|
1205
|
-
},
|
|
1206
|
-
});
|
|
1207
1060
|
const auditor = createAuditorRoleRuntime(roleHost, {
|
|
1208
1061
|
loadSoul: () => requireRoleSoul("auditor"),
|
|
1209
1062
|
});
|
|
@@ -1301,7 +1154,7 @@ deliveryRequestLimit) {
|
|
|
1301
1154
|
navigatorDeliveryClosed = false;
|
|
1302
1155
|
pendingNavigatorSettlement = undefined;
|
|
1303
1156
|
pendingInfrastructureFailures.clear();
|
|
1304
|
-
|
|
1157
|
+
navigatorSubjectKey = undefined;
|
|
1305
1158
|
// #351: OAuth keepalive is orthogonal to --ak-role; start before role early-return
|
|
1306
1159
|
// so role-less sessions (and reload after shutdown stop) still keep tokens alive.
|
|
1307
1160
|
envelopeHost.startKeepalive(ctx);
|
|
@@ -1335,7 +1188,9 @@ deliveryRequestLimit) {
|
|
|
1335
1188
|
"gleaner-left": () => gleanerLeft.activate(),
|
|
1336
1189
|
inspector: () => inspector.activate(),
|
|
1337
1190
|
gatekeeper: () => gatekeeper.activate(),
|
|
1338
|
-
navigator: () =>
|
|
1191
|
+
navigator: async () => {
|
|
1192
|
+
throw new Error("navigator is a table lookup (#1192); no host runtime serves it");
|
|
1193
|
+
},
|
|
1339
1194
|
auditor: () => auditor.activate(),
|
|
1340
1195
|
diarist: () => diarist.activate(),
|
|
1341
1196
|
secretariat: () => secretariat.activate(),
|
|
@@ -1356,39 +1211,14 @@ deliveryRequestLimit) {
|
|
|
1356
1211
|
}
|
|
1357
1212
|
// Station children (court diarist, inner-gate summons) omit navigator sidecar (#840).
|
|
1358
1213
|
// Top-level public entry legs still attend automatically.
|
|
1359
|
-
//
|
|
1360
|
-
// public activation (prevents summonPublicRole navigator ↔ attendance recursion).
|
|
1214
|
+
// The navigator seat never attends itself (summonPublicRole navigator ↔ attendance recursion).
|
|
1361
1215
|
const isStationChild = roleHost.getFlag(STATION_CHILD_FLAG.name) === true;
|
|
1362
1216
|
if (dependencies.createNavigatorAttendance !== undefined
|
|
1363
|
-
&& entry.
|
|
1217
|
+
&& !isNavigatorSeat(entry.role)
|
|
1364
1218
|
&& !isStationChild) {
|
|
1365
1219
|
navigatorSessionParent = ctx.sessionManager.getSessionFile();
|
|
1366
1220
|
navigatorCwd = ctx.cwd;
|
|
1367
|
-
|
|
1368
|
-
let contextError;
|
|
1369
|
-
if (dependencies.loadNavigatorWorkContext === undefined) {
|
|
1370
|
-
const fallbackSubjectKey = subjectPath(ctx.sessionManager.getSessionDir(), ctx.cwd);
|
|
1371
|
-
contextError = new Error("Navigator work context loader is not configured");
|
|
1372
|
-
work = { subjectKey: fallbackSubjectKey, subjectProvenance: "placeholder" };
|
|
1373
|
-
}
|
|
1374
|
-
else {
|
|
1375
|
-
try {
|
|
1376
|
-
work = await dependencies.loadNavigatorWorkContext({
|
|
1377
|
-
context: ctx,
|
|
1378
|
-
role: entry.role,
|
|
1379
|
-
phase: navigatorPhase(roleHost, entry.role),
|
|
1380
|
-
getFlag: (name) => roleHost.getFlag(name),
|
|
1381
|
-
});
|
|
1382
|
-
contextError = work.contextError;
|
|
1383
|
-
}
|
|
1384
|
-
catch (error) {
|
|
1385
|
-
// Contract: README.md#Navigator-attendance — a failed context load continues with a typed placeholder work context; the original cause is retained in contextError for the typed unavailable report.
|
|
1386
|
-
contextError = navigatorUnavailableError("context", error);
|
|
1387
|
-
const fallbackSubjectKey = subjectPath(ctx.sessionManager.getSessionDir(), ctx.cwd);
|
|
1388
|
-
work = { subjectKey: fallbackSubjectKey, subjectProvenance: "placeholder" };
|
|
1389
|
-
}
|
|
1390
|
-
}
|
|
1391
|
-
navigatorWorkContext = { ...work, ...(contextError === undefined ? {} : { contextError }) };
|
|
1221
|
+
navigatorSubjectKey = subjectPath(ctx.sessionManager.getSessionDir(), ctx.cwd);
|
|
1392
1222
|
// Shared envelope owns exact invocation principal from admitted session lifecycle.
|
|
1393
1223
|
// session_start is process activation: resume unfinished principal only when marker
|
|
1394
1224
|
// role/phase/subjectKey still match; mint for contradictory marker, malformed nearest,
|
|
@@ -1398,7 +1228,7 @@ deliveryRequestLimit) {
|
|
|
1398
1228
|
const lifecyclePrincipal = resolveLifecycleInvocationPrincipal(sessionEntries, {
|
|
1399
1229
|
role: entry.role,
|
|
1400
1230
|
phase: invocationPhase,
|
|
1401
|
-
subjectKey:
|
|
1231
|
+
subjectKey: navigatorSubjectKey,
|
|
1402
1232
|
});
|
|
1403
1233
|
const invocationId = lifecyclePrincipal.invocationId;
|
|
1404
1234
|
if (!lifecyclePrincipal.resume) {
|
|
@@ -1406,7 +1236,7 @@ deliveryRequestLimit) {
|
|
|
1406
1236
|
invocationId,
|
|
1407
1237
|
role: entry.role,
|
|
1408
1238
|
phase: invocationPhase,
|
|
1409
|
-
subjectKey:
|
|
1239
|
+
subjectKey: navigatorSubjectKey,
|
|
1410
1240
|
};
|
|
1411
1241
|
envelopeHost.appendEntry(NAVIGATOR_INVOCATION_ENTRY, data);
|
|
1412
1242
|
sitianReportSafe({
|
|
@@ -1423,22 +1253,16 @@ deliveryRequestLimit) {
|
|
|
1423
1253
|
context: ctx,
|
|
1424
1254
|
role: entry.role,
|
|
1425
1255
|
phase: invocationPhase,
|
|
1426
|
-
subjectKey:
|
|
1256
|
+
subjectKey: navigatorSubjectKey,
|
|
1427
1257
|
invocationId,
|
|
1428
|
-
deliveryRequestLimit: deliveryLimit,
|
|
1429
|
-
...(contextError === undefined ? {} : { contextError }),
|
|
1430
1258
|
onEvent: (navigatorEvent, report) => {
|
|
1431
1259
|
if (activation === navigatorActivation && !navigatorDeliveryClosed) {
|
|
1432
1260
|
pendingNavigatorPresentation = { event: navigatorEvent, report };
|
|
1433
1261
|
}
|
|
1434
1262
|
},
|
|
1435
1263
|
});
|
|
1436
|
-
//
|
|
1437
|
-
|
|
1438
|
-
if (navigatorWorkContext.contextError === undefined &&
|
|
1439
|
-
navigatorWorkContext.subjectProvenance !== "placeholder") {
|
|
1440
|
-
navigatorAttendance.prepare();
|
|
1441
|
-
}
|
|
1264
|
+
// The lookup starts with the parent role (#1160 / #1192).
|
|
1265
|
+
navigatorAttendance.prepare();
|
|
1442
1266
|
}
|
|
1443
1267
|
await executeActivationStage(entry.role, activationStage(entry.role, activateByRole), { clock, writeTrace });
|
|
1444
1268
|
// #1171: same registration mouth as submission tools; when-to-call is on the tool itself.
|
|
@@ -7,7 +7,7 @@ import { findRunDirectoryById } from "./public-cli/run-lifecycle.js";
|
|
|
7
7
|
import { isCorrectableExecuteError } from "./submission-correctable-error.js";
|
|
8
8
|
import { reportTicketFromHostContext } from "./report-ticket-tool.js";
|
|
9
9
|
import { readDeclaredTicketNumber } from "./run-ticket-number.js";
|
|
10
|
-
import { captureWorktreeHead, landTicketProgressForSealedSubmission, } from "./ticket-progress.js";
|
|
10
|
+
import { captureWorktreeHead, landTicketProgress, landTicketProgressForSealedSubmission, } from "./ticket-progress.js";
|
|
11
11
|
import { isRecord, errorText } from "./unknown-value.js";
|
|
12
12
|
/**
|
|
13
13
|
* Admitted run identity for the ledger subject.
|
|
@@ -293,17 +293,19 @@ function homeFromHostContext(context, home) {
|
|
|
293
293
|
return sessionParent !== undefined ? tryHomeFromAkRolesPath(sessionParent) : undefined;
|
|
294
294
|
}
|
|
295
295
|
/**
|
|
296
|
-
* #
|
|
297
|
-
* Same ledger
|
|
298
|
-
*
|
|
296
|
+
* #1192: seal one accepted submission without a model tool call or host session
|
|
297
|
+
* (the navigator lookup run). Same sealed ledger event and the same original
|
|
298
|
+
* receipt / progress landing as the terminating-tool wrap; the progress line
|
|
299
|
+
* names no session because the run has none.
|
|
299
300
|
*/
|
|
300
|
-
export
|
|
301
|
-
const runId =
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
const
|
|
305
|
-
|
|
306
|
-
const
|
|
301
|
+
export function sealAcceptedSubmission(options) {
|
|
302
|
+
const runId = runIdFromRunDirectory(options.runDirectory);
|
|
303
|
+
if (runId === undefined)
|
|
304
|
+
throw new Error("提交账需要已受理的 run 身份");
|
|
305
|
+
const attemptId = options.courtAttemptId ?? `${runId}:initial`;
|
|
306
|
+
const sealHead = captureWorktreeHead(options.cwd);
|
|
307
|
+
const sessionParent = sessionFileOf(options.runDirectory);
|
|
308
|
+
const home = options.home ?? tryHomeFromAkRolesPath(sessionParent);
|
|
307
309
|
sitianReport({
|
|
308
310
|
level: "event",
|
|
309
311
|
kind: "sealed",
|
|
@@ -316,15 +318,17 @@ export async function sealAcceptedSubmission(options) {
|
|
|
316
318
|
accepted: options.accepted,
|
|
317
319
|
},
|
|
318
320
|
source: "role-runtime",
|
|
319
|
-
cwd: options.
|
|
321
|
+
cwd: options.cwd,
|
|
320
322
|
...(home !== undefined ? { home } : {}),
|
|
321
|
-
|
|
323
|
+
sessionParent,
|
|
322
324
|
});
|
|
323
|
-
|
|
324
|
-
|
|
325
|
+
landTicketProgress({
|
|
326
|
+
runDirectory: options.runDirectory,
|
|
325
327
|
role: options.role,
|
|
326
328
|
accepted: options.accepted,
|
|
327
329
|
sealHead,
|
|
330
|
+
sessionFile: undefined,
|
|
331
|
+
instruction: options.instruction ?? "",
|
|
328
332
|
});
|
|
329
333
|
}
|
|
330
334
|
/**
|
package/dist/ticket-progress.js
CHANGED
|
@@ -197,6 +197,25 @@ export function landTicketProgressForSealedSubmission(input) {
|
|
|
197
197
|
const runDirectory = runDirectoryFromHostContext(input.context);
|
|
198
198
|
if (runDirectory === undefined)
|
|
199
199
|
return undefined;
|
|
200
|
+
return landTicketProgress({
|
|
201
|
+
runDirectory,
|
|
202
|
+
role: input.role,
|
|
203
|
+
accepted: input.accepted,
|
|
204
|
+
sealHead: input.sealHead,
|
|
205
|
+
...(input.lens === undefined ? {} : { lens: input.lens }),
|
|
206
|
+
sessionFile: progressSessionAbsolute(runDirectory, input.context),
|
|
207
|
+
instruction: typeof input.context.summonsInstruction === "string"
|
|
208
|
+
? input.context.summonsInstruction
|
|
209
|
+
: "",
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Original receipt plus progress line for one sealed submission.
|
|
214
|
+
* `sessionFile` is absent for a run that never had a host session (the
|
|
215
|
+
* navigator lookup, #1192): the line then names no session.
|
|
216
|
+
*/
|
|
217
|
+
export function landTicketProgress(input) {
|
|
218
|
+
const { runDirectory } = input;
|
|
200
219
|
const subjectDirectory = subjectDirectoryOfRun(runDirectory);
|
|
201
220
|
if (subjectDirectory === undefined)
|
|
202
221
|
return undefined;
|
|
@@ -225,12 +244,11 @@ export function landTicketProgressForSealedSubmission(input) {
|
|
|
225
244
|
: readTicketProgressLines(subjectDirectory);
|
|
226
245
|
// Unbound: round stays empty until whole-leg bind publishes into ticket current.
|
|
227
246
|
const round = unbound ? "" : nextRoundFromLines(existing, input.role, lens);
|
|
228
|
-
const
|
|
229
|
-
|
|
247
|
+
const sessionRelative = input.sessionFile === undefined
|
|
248
|
+
? ""
|
|
249
|
+
: relative(subjectDirectory, input.sessionFile).split(sep).join("/");
|
|
230
250
|
const { status, summary } = statusAndSummaryFromPayload(input.role, input.accepted);
|
|
231
|
-
const instruction =
|
|
232
|
-
? input.context.summonsInstruction
|
|
233
|
-
: "";
|
|
251
|
+
const instruction = input.instruction;
|
|
234
252
|
const line = {
|
|
235
253
|
at: new Date().toISOString(),
|
|
236
254
|
seat: input.role,
|
|
@@ -11,10 +11,6 @@ import {
|
|
|
11
11
|
} from "@earendil-works/pi-coding-agent";
|
|
12
12
|
import type { Message } from "@earendil-works/pi-ai";
|
|
13
13
|
|
|
14
|
-
import {
|
|
15
|
-
registerNavigatorModelCommand,
|
|
16
|
-
} from "../src/navigator-attendance.ts";
|
|
17
|
-
import { loadNavigatorWorkContext as loadHostNeutralNavigatorWorkContext } from "../src/navigator-work-context.ts";
|
|
18
14
|
import { JUDGE_OUTPUT_TOOL_NAME } from "../src/package-contracts/judge-output.ts";
|
|
19
15
|
import { readOAuthKeepaliveProviders } from "../src/oauth-keepalive.ts";
|
|
20
16
|
import {
|
|
@@ -53,17 +49,6 @@ export function transcriptFromContext(ctx: ExtensionContext): string {
|
|
|
53
49
|
);
|
|
54
50
|
}
|
|
55
51
|
|
|
56
|
-
export async function loadNavigatorWorkContext(
|
|
57
|
-
pi: Pick<ExtensionAPI, "getFlag">,
|
|
58
|
-
options: { context: ExtensionContext | import("../src/host-contracts.ts").HostContext; role: string },
|
|
59
|
-
) {
|
|
60
|
-
return loadHostNeutralNavigatorWorkContext({
|
|
61
|
-
context: options.context as import("../src/host-contracts.ts").HostContext,
|
|
62
|
-
role: options.role,
|
|
63
|
-
getFlag: (name) => pi.getFlag(name),
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
|
|
67
52
|
/** Pi extension deps are the shared packaged factory. Host flags stay on the envelope. */
|
|
68
53
|
export function createPiRoleRuntimeDependencies(
|
|
69
54
|
_pi: ExtensionAPI,
|
|
@@ -73,7 +58,6 @@ export function createPiRoleRuntimeDependencies(
|
|
|
73
58
|
|
|
74
59
|
export default function roleRuntime(pi: ExtensionAPI): void {
|
|
75
60
|
const oauthKeepaliveProviders = readOAuthKeepaliveProviders();
|
|
76
|
-
registerNavigatorModelCommand(pi);
|
|
77
61
|
createPiRoleRuntimeExtension(createPiRoleRuntimeDependencies(pi), {
|
|
78
62
|
transcriptFromContext,
|
|
79
63
|
oauthKeepalive: { providers: oauthKeepaliveProviders },
|
package/package.json
CHANGED
|
@@ -10,14 +10,10 @@ const entries = [
|
|
|
10
10
|
// Static import of navigator-invocation-identity (#603: non-bundle graph closure).
|
|
11
11
|
"uuidv7",
|
|
12
12
|
"navigator-attendance",
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
|
|
16
|
-
"navigator-public-session",
|
|
17
|
-
// Static import of navigator-public-session (sitianReportSafe).
|
|
13
|
+
// Static import of navigator-attendance: the lookup (summons the navigator run)
|
|
14
|
+
// and the package-relative modules it reaches (#590 closure).
|
|
15
|
+
"navigator-lookup",
|
|
18
16
|
"host-session-record",
|
|
19
|
-
"navigator-session-contracts",
|
|
20
|
-
// Static import of navigator-attendance and navigator-public-session.
|
|
21
17
|
"atomic-write",
|
|
22
18
|
"public-role-summons",
|
|
23
19
|
"activation-ledger-git",
|