@akagilnc/pi-workflow-roles 0.1.5673 → 0.1.5683
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 +28 -101
- package/dist/headless-host/production-host.js +28 -101
- package/dist/navigator-attendance.js +1 -19
- package/dist/public-cli/invocation.js +22 -24
- package/extensions/role-runtime.ts +0 -2
- package/package.json +1 -1
- package/resources/navigator-route-playbook.md +2 -12
- package/souls/navigator.md +2 -4
- package/src/navigator-attendance.ts +6 -31
- package/src/navigator-work-context.ts +25 -61
- package/src/public-cli/invocation.ts +19 -19
- package/src/role-runtime-dependencies.ts +0 -2
- package/src/role-runtime.ts +6 -15
|
@@ -7952,22 +7952,18 @@ async function materializeCountersignInvocation(admitted, options) {
|
|
|
7952
7952
|
);
|
|
7953
7953
|
}
|
|
7954
7954
|
async function loadAdmittedJudgeRequest(runDirectory) {
|
|
7955
|
-
|
|
7956
|
-
|
|
7957
|
-
|
|
7958
|
-
|
|
7959
|
-
|
|
7960
|
-
|
|
7961
|
-
|
|
7962
|
-
|
|
7963
|
-
|
|
7964
|
-
|
|
7965
|
-
|
|
7966
|
-
|
|
7967
|
-
};
|
|
7968
|
-
} catch {
|
|
7969
|
-
return void 0;
|
|
7970
|
-
}
|
|
7955
|
+
const record = readPageSync(runDirectory, "admitted");
|
|
7956
|
+
if (record === void 0) return void 0;
|
|
7957
|
+
if (!packagedPublicInstructionSubject(record.role)) return void 0;
|
|
7958
|
+
if (typeof record.instruction !== "string") return void 0;
|
|
7959
|
+
if (typeof record.instructionEmpty !== "boolean") return void 0;
|
|
7960
|
+
if (!Array.isArray(record.attachments)) return void 0;
|
|
7961
|
+
const attachments = record.attachments.map((item) => normalizeAdmittedAttachment(item)).filter((item) => item !== void 0);
|
|
7962
|
+
return {
|
|
7963
|
+
instruction: record.instruction,
|
|
7964
|
+
instructionEmpty: record.instructionEmpty,
|
|
7965
|
+
attachments
|
|
7966
|
+
};
|
|
7971
7967
|
}
|
|
7972
7968
|
function parsePositivePrOption(raw) {
|
|
7973
7969
|
if (raw === void 0 || raw.trim() === "") throw new CliUsageError("--pr requires a positive pull request number");
|
|
@@ -21572,11 +21568,6 @@ init_navigator_output();
|
|
|
21572
21568
|
init_sha256();
|
|
21573
21569
|
init_unknown_value();
|
|
21574
21570
|
var NAVIGATOR_EVENT_TYPE = "ak-navigator-attendance";
|
|
21575
|
-
function resolveNavigatorAuthorityMaterial(roleInput, fileAuthority) {
|
|
21576
|
-
if (roleInput !== void 0 && roleInput.trim() !== "") return roleInput;
|
|
21577
|
-
if (fileAuthority !== void 0 && fileAuthority.trim() !== "") return fileAuthority;
|
|
21578
|
-
return void 0;
|
|
21579
|
-
}
|
|
21580
21571
|
var NAVIGATOR_TARGETS = PACKAGED_ROLE_REGISTRY.map(({ role, phases }) => ({ role, phases }));
|
|
21581
21572
|
var prepareSchema = navigatorAdviceBodySchema;
|
|
21582
21573
|
var INVOCATION_ENTRY = NAVIGATOR_INVOCATION_ENTRY;
|
|
@@ -21651,8 +21642,6 @@ function createNavigatorAttendance(options) {
|
|
|
21651
21642
|
let sessionReady;
|
|
21652
21643
|
let session;
|
|
21653
21644
|
let subjectKey = options.subjectKey;
|
|
21654
|
-
let subject = options.subject;
|
|
21655
|
-
let authority = options.authority;
|
|
21656
21645
|
let contextError = options.contextError;
|
|
21657
21646
|
let preparedAdvice;
|
|
21658
21647
|
const invocationPrincipal = options.invocationId ?? mintNavigatorInvocationId();
|
|
@@ -21681,12 +21670,6 @@ function createNavigatorAttendance(options) {
|
|
|
21681
21670
|
};
|
|
21682
21671
|
const loadMaterialsAndSession = async (invocationId) => {
|
|
21683
21672
|
if (contextError !== void 0) throw navigatorUnavailableError("context", contextError);
|
|
21684
|
-
if (typeof authority !== "string" || authority.trim() === "") {
|
|
21685
|
-
throw navigatorUnavailableError(
|
|
21686
|
-
"context",
|
|
21687
|
-
new Error("controlling authority content was not supplied as typed work context")
|
|
21688
|
-
);
|
|
21689
|
-
}
|
|
21690
21673
|
const modelPromise = (async () => {
|
|
21691
21674
|
try {
|
|
21692
21675
|
const resolved = await resolveNavigatorSeatSelection(options.context);
|
|
@@ -21772,9 +21755,7 @@ function createNavigatorAttendance(options) {
|
|
|
21772
21755
|
role: options.role,
|
|
21773
21756
|
phase: options.phase,
|
|
21774
21757
|
invocationId,
|
|
21775
|
-
subjectKey
|
|
21776
|
-
subject,
|
|
21777
|
-
authority
|
|
21758
|
+
subjectKey
|
|
21778
21759
|
});
|
|
21779
21760
|
try {
|
|
21780
21761
|
try {
|
|
@@ -21851,8 +21832,6 @@ function createNavigatorAttendance(options) {
|
|
|
21851
21832
|
closing2 = previous.dispose();
|
|
21852
21833
|
}
|
|
21853
21834
|
subjectKey = next.subjectKey;
|
|
21854
|
-
subject = next.subject;
|
|
21855
|
-
authority = next.authority;
|
|
21856
21835
|
contextError = next.contextError;
|
|
21857
21836
|
return closing2;
|
|
21858
21837
|
},
|
|
@@ -23235,12 +23214,8 @@ function createRoleRuntimeExtension(dependencies, deliveryRequestLimit) {
|
|
|
23235
23214
|
if (subject !== "") {
|
|
23236
23215
|
const root = subjectPath(ctx.sessionManager.getSessionDir(), ctx.cwd);
|
|
23237
23216
|
const subjectProvenance = "user_prompt";
|
|
23238
|
-
const priorAuthority = navigatorWorkContext.authority;
|
|
23239
|
-
const authority = typeof priorAuthority === "string" && priorAuthority.trim() !== "" ? priorAuthority : subject;
|
|
23240
23217
|
navigatorWorkContext = {
|
|
23241
23218
|
subjectKey: navigatorSubjectKey(root, subject, subjectProvenance),
|
|
23242
|
-
subject,
|
|
23243
|
-
authority,
|
|
23244
23219
|
subjectProvenance
|
|
23245
23220
|
};
|
|
23246
23221
|
await navigatorAttendance.setWorkContext(navigatorWorkContext);
|
|
@@ -23682,7 +23657,7 @@ function createRoleRuntimeExtension(dependencies, deliveryRequestLimit) {
|
|
|
23682
23657
|
if (dependencies.loadNavigatorWorkContext === void 0) {
|
|
23683
23658
|
const fallbackSubjectKey = subjectPath(ctx.sessionManager.getSessionDir(), ctx.cwd);
|
|
23684
23659
|
contextError = new Error("Navigator work context loader is not configured");
|
|
23685
|
-
work = { subjectKey: fallbackSubjectKey,
|
|
23660
|
+
work = { subjectKey: fallbackSubjectKey, subjectProvenance: "placeholder" };
|
|
23686
23661
|
} else {
|
|
23687
23662
|
try {
|
|
23688
23663
|
work = await dependencies.loadNavigatorWorkContext({
|
|
@@ -23695,7 +23670,7 @@ function createRoleRuntimeExtension(dependencies, deliveryRequestLimit) {
|
|
|
23695
23670
|
} catch (error) {
|
|
23696
23671
|
contextError = navigatorUnavailableError("context", error);
|
|
23697
23672
|
const fallbackSubjectKey = subjectPath(ctx.sessionManager.getSessionDir(), ctx.cwd);
|
|
23698
|
-
work = { subjectKey: fallbackSubjectKey,
|
|
23673
|
+
work = { subjectKey: fallbackSubjectKey, subjectProvenance: "placeholder" };
|
|
23699
23674
|
}
|
|
23700
23675
|
}
|
|
23701
23676
|
navigatorWorkContext = { ...work, ...contextError === void 0 ? {} : { contextError } };
|
|
@@ -23730,8 +23705,6 @@ function createRoleRuntimeExtension(dependencies, deliveryRequestLimit) {
|
|
|
23730
23705
|
role: entry.role,
|
|
23731
23706
|
phase: invocationPhase,
|
|
23732
23707
|
subjectKey: work.subjectKey,
|
|
23733
|
-
subject: work.subject,
|
|
23734
|
-
authority: work.authority,
|
|
23735
23708
|
invocationId,
|
|
23736
23709
|
deliveryRequestLimit: deliveryLimit,
|
|
23737
23710
|
...contextError === void 0 ? {} : { contextError },
|
|
@@ -24379,17 +24352,13 @@ async function prepareRoleEnvelope(options) {
|
|
|
24379
24352
|
}
|
|
24380
24353
|
|
|
24381
24354
|
// src/role-runtime-dependencies.ts
|
|
24382
|
-
import { readFile as
|
|
24355
|
+
import { readFile as readFile15 } from "node:fs/promises";
|
|
24383
24356
|
init_doctor_evidence();
|
|
24384
24357
|
|
|
24385
24358
|
// src/navigator-work-context.ts
|
|
24386
24359
|
init_role_run_placement();
|
|
24387
|
-
init_doctor_evidence();
|
|
24388
|
-
init_unknown_value();
|
|
24389
24360
|
init_host_contracts();
|
|
24390
|
-
import { readFile as readFile15 } from "node:fs/promises";
|
|
24391
24361
|
import { resolve as resolve17 } from "node:path";
|
|
24392
|
-
init_notary_source_run();
|
|
24393
24362
|
init_packaged_role_registry();
|
|
24394
24363
|
init_invocation();
|
|
24395
24364
|
function navigatorInputReference(getFlag, role) {
|
|
@@ -24401,21 +24370,8 @@ function navigatorInputReference(getFlag, role) {
|
|
|
24401
24370
|
async function loadNavigatorWorkContext(options) {
|
|
24402
24371
|
const reference = navigatorInputReference(options.getFlag, options.role);
|
|
24403
24372
|
const subjectMode = packagedNavigatorSubject(options.role);
|
|
24404
|
-
const input = reference === void 0 || subjectMode === "case" || subjectMode === "source-run" ? void 0 : await readFile15(reference, "utf8");
|
|
24405
24373
|
const subjectRoot = subjectPath(reference ?? options.context.sessionManager.getSessionDir(), options.context.cwd);
|
|
24406
|
-
|
|
24407
|
-
let subject = input ?? `work subject: ${subjectKey}`;
|
|
24408
|
-
let subjectProvenance = input === void 0 ? "placeholder" : "role_input";
|
|
24409
|
-
if (subjectMode === "case" && reference !== void 0) {
|
|
24410
|
-
const patient = await loadDoctorCase(reference);
|
|
24411
|
-
subject = JSON.stringify({ identity: patient.identity, cost: patient.cost });
|
|
24412
|
-
subjectProvenance = "role_input";
|
|
24413
|
-
}
|
|
24414
|
-
if (subjectMode === "source-run" && reference !== void 0) {
|
|
24415
|
-
const locator = await loadNotarySourceRunLocator(reference);
|
|
24416
|
-
subject = JSON.stringify({ sourceRun: locator });
|
|
24417
|
-
subjectProvenance = "role_input";
|
|
24418
|
-
}
|
|
24374
|
+
const subjectKey = reference === void 0 ? subjectRoot : navigatorSubjectKeyForInput(subjectRoot, reference, options.context.cwd);
|
|
24419
24375
|
const publicRunDir = runDirectoryFromHostContext(options.context);
|
|
24420
24376
|
const currentSessionDir = options.context.sessionManager.getSessionDir();
|
|
24421
24377
|
const isBoundPublicRun = publicRunDir !== void 0 && resolve17(currentSessionDir) === resolve17(sessionDirectoryOf(publicRunDir));
|
|
@@ -24433,50 +24389,23 @@ async function loadNavigatorWorkContext(options) {
|
|
|
24433
24389
|
);
|
|
24434
24390
|
}
|
|
24435
24391
|
if (!admitted.instructionEmpty && admitted.instruction.trim() !== "") {
|
|
24436
|
-
|
|
24437
|
-
|
|
24438
|
-
|
|
24439
|
-
|
|
24440
|
-
return { subjectKey, subject, authority: prose, subjectProvenance };
|
|
24392
|
+
return {
|
|
24393
|
+
subjectKey: subjectRoot,
|
|
24394
|
+
subjectProvenance: "role_input"
|
|
24395
|
+
};
|
|
24441
24396
|
}
|
|
24442
24397
|
return {
|
|
24443
24398
|
subjectKey: subjectRoot,
|
|
24444
|
-
subject: `work subject: ${subjectRoot}`,
|
|
24445
|
-
authority: "",
|
|
24446
24399
|
subjectProvenance: "placeholder"
|
|
24447
24400
|
};
|
|
24448
24401
|
}
|
|
24449
|
-
if (
|
|
24450
|
-
return { subjectKey,
|
|
24451
|
-
}
|
|
24452
|
-
const workRoot = subjectRoot.includes("/.ak/work/") ? subjectRoot : void 0;
|
|
24453
|
-
const authorityFiles = workRoot === void 0 ? [] : [
|
|
24454
|
-
resolve17(workRoot, "authority.md"),
|
|
24455
|
-
resolve17(workRoot, "authority.txt"),
|
|
24456
|
-
resolve17(workRoot, "design-v2/owner-direction.md")
|
|
24457
|
-
];
|
|
24458
|
-
let authorityMaterial;
|
|
24459
|
-
for (const path of authorityFiles) {
|
|
24460
|
-
try {
|
|
24461
|
-
const content = await readFile15(path, "utf8");
|
|
24462
|
-
if (content.trim() !== "") {
|
|
24463
|
-
authorityMaterial = content;
|
|
24464
|
-
break;
|
|
24465
|
-
}
|
|
24466
|
-
} catch (error) {
|
|
24467
|
-
if (!isEnoent(error)) throw error;
|
|
24468
|
-
}
|
|
24469
|
-
}
|
|
24470
|
-
const authority = resolveNavigatorAuthorityMaterial(input, authorityMaterial);
|
|
24471
|
-
if (authority === void 0) {
|
|
24472
|
-
return {
|
|
24473
|
-
subjectKey: subjectRoot,
|
|
24474
|
-
subject: `work subject: ${subjectRoot}`,
|
|
24475
|
-
authority: "",
|
|
24476
|
-
subjectProvenance: "placeholder"
|
|
24477
|
-
};
|
|
24402
|
+
if (reference !== void 0) {
|
|
24403
|
+
return { subjectKey, subjectProvenance: "role_input" };
|
|
24478
24404
|
}
|
|
24479
|
-
return {
|
|
24405
|
+
return {
|
|
24406
|
+
subjectKey: subjectRoot,
|
|
24407
|
+
subjectProvenance: "placeholder"
|
|
24408
|
+
};
|
|
24480
24409
|
}
|
|
24481
24410
|
|
|
24482
24411
|
// src/role-runtime-dependencies.ts
|
|
@@ -24502,7 +24431,7 @@ function createRoleRuntimeDependencies(packageRoot) {
|
|
|
24502
24431
|
loadRoleSoul: loadRegisteredRoleSoul,
|
|
24503
24432
|
loadDoctorCase,
|
|
24504
24433
|
loadNotarySourceRun: loadNotarySourceRunLocator,
|
|
24505
|
-
loadMergerInput: async (path) => JSON.parse(await
|
|
24434
|
+
loadMergerInput: async (path) => JSON.parse(await readFile15(path, "utf8")),
|
|
24506
24435
|
loadNavigatorWorkContext: (options) => loadNavigatorWorkContext({
|
|
24507
24436
|
context: options.context,
|
|
24508
24437
|
role: options.role,
|
|
@@ -24513,8 +24442,6 @@ function createRoleRuntimeDependencies(packageRoot) {
|
|
|
24513
24442
|
role: options.role,
|
|
24514
24443
|
phase: options.phase,
|
|
24515
24444
|
subjectKey: options.subjectKey,
|
|
24516
|
-
subject: options.subject,
|
|
24517
|
-
authority: options.authority,
|
|
24518
24445
|
invocationId: options.invocationId,
|
|
24519
24446
|
createSession: navigatorSessionFactory,
|
|
24520
24447
|
...options.deliveryRequestLimit === void 0 ? {} : { deliveryRequestLimit: options.deliveryRequestLimit },
|
|
@@ -9028,22 +9028,18 @@ async function materializeCountersignInvocation(admitted, options) {
|
|
|
9028
9028
|
);
|
|
9029
9029
|
}
|
|
9030
9030
|
async function loadAdmittedJudgeRequest(runDirectory) {
|
|
9031
|
-
|
|
9032
|
-
|
|
9033
|
-
|
|
9034
|
-
|
|
9035
|
-
|
|
9036
|
-
|
|
9037
|
-
|
|
9038
|
-
|
|
9039
|
-
|
|
9040
|
-
|
|
9041
|
-
|
|
9042
|
-
|
|
9043
|
-
};
|
|
9044
|
-
} catch {
|
|
9045
|
-
return void 0;
|
|
9046
|
-
}
|
|
9031
|
+
const record = readPageSync(runDirectory, "admitted");
|
|
9032
|
+
if (record === void 0) return void 0;
|
|
9033
|
+
if (!packagedPublicInstructionSubject(record.role)) return void 0;
|
|
9034
|
+
if (typeof record.instruction !== "string") return void 0;
|
|
9035
|
+
if (typeof record.instructionEmpty !== "boolean") return void 0;
|
|
9036
|
+
if (!Array.isArray(record.attachments)) return void 0;
|
|
9037
|
+
const attachments = record.attachments.map((item) => normalizeAdmittedAttachment(item)).filter((item) => item !== void 0);
|
|
9038
|
+
return {
|
|
9039
|
+
instruction: record.instruction,
|
|
9040
|
+
instructionEmpty: record.instructionEmpty,
|
|
9041
|
+
attachments
|
|
9042
|
+
};
|
|
9047
9043
|
}
|
|
9048
9044
|
function parsePositivePrOption(raw) {
|
|
9049
9045
|
if (raw === void 0 || raw.trim() === "") throw new CliUsageError("--pr requires a positive pull request number");
|
|
@@ -20458,7 +20454,7 @@ init_host_descriptions();
|
|
|
20458
20454
|
import { randomUUID as randomUUID11 } from "node:crypto";
|
|
20459
20455
|
|
|
20460
20456
|
// src/role-runtime-dependencies.ts
|
|
20461
|
-
import { readFile as
|
|
20457
|
+
import { readFile as readFile15 } from "node:fs/promises";
|
|
20462
20458
|
init_doctor_evidence();
|
|
20463
20459
|
|
|
20464
20460
|
// src/navigator-attendance.ts
|
|
@@ -20846,11 +20842,6 @@ init_navigator_output();
|
|
|
20846
20842
|
init_sha256();
|
|
20847
20843
|
init_unknown_value();
|
|
20848
20844
|
var NAVIGATOR_EVENT_TYPE = "ak-navigator-attendance";
|
|
20849
|
-
function resolveNavigatorAuthorityMaterial(roleInput, fileAuthority) {
|
|
20850
|
-
if (roleInput !== void 0 && roleInput.trim() !== "") return roleInput;
|
|
20851
|
-
if (fileAuthority !== void 0 && fileAuthority.trim() !== "") return fileAuthority;
|
|
20852
|
-
return void 0;
|
|
20853
|
-
}
|
|
20854
20845
|
var NAVIGATOR_TARGETS = PACKAGED_ROLE_REGISTRY.map(({ role, phases }) => ({ role, phases }));
|
|
20855
20846
|
var prepareSchema = navigatorAdviceBodySchema;
|
|
20856
20847
|
var INVOCATION_ENTRY = NAVIGATOR_INVOCATION_ENTRY;
|
|
@@ -20925,8 +20916,6 @@ function createNavigatorAttendance(options) {
|
|
|
20925
20916
|
let sessionReady;
|
|
20926
20917
|
let session;
|
|
20927
20918
|
let subjectKey = options.subjectKey;
|
|
20928
|
-
let subject = options.subject;
|
|
20929
|
-
let authority = options.authority;
|
|
20930
20919
|
let contextError = options.contextError;
|
|
20931
20920
|
let preparedAdvice;
|
|
20932
20921
|
const invocationPrincipal = options.invocationId ?? mintNavigatorInvocationId();
|
|
@@ -20955,12 +20944,6 @@ function createNavigatorAttendance(options) {
|
|
|
20955
20944
|
};
|
|
20956
20945
|
const loadMaterialsAndSession = async (invocationId) => {
|
|
20957
20946
|
if (contextError !== void 0) throw navigatorUnavailableError("context", contextError);
|
|
20958
|
-
if (typeof authority !== "string" || authority.trim() === "") {
|
|
20959
|
-
throw navigatorUnavailableError(
|
|
20960
|
-
"context",
|
|
20961
|
-
new Error("controlling authority content was not supplied as typed work context")
|
|
20962
|
-
);
|
|
20963
|
-
}
|
|
20964
20947
|
const modelPromise = (async () => {
|
|
20965
20948
|
try {
|
|
20966
20949
|
const resolved = await resolveNavigatorSeatSelection(options.context);
|
|
@@ -21046,9 +21029,7 @@ function createNavigatorAttendance(options) {
|
|
|
21046
21029
|
role: options.role,
|
|
21047
21030
|
phase: options.phase,
|
|
21048
21031
|
invocationId,
|
|
21049
|
-
subjectKey
|
|
21050
|
-
subject,
|
|
21051
|
-
authority
|
|
21032
|
+
subjectKey
|
|
21052
21033
|
});
|
|
21053
21034
|
try {
|
|
21054
21035
|
try {
|
|
@@ -21125,8 +21106,6 @@ function createNavigatorAttendance(options) {
|
|
|
21125
21106
|
closing2 = previous.dispose();
|
|
21126
21107
|
}
|
|
21127
21108
|
subjectKey = next.subjectKey;
|
|
21128
|
-
subject = next.subject;
|
|
21129
|
-
authority = next.authority;
|
|
21130
21109
|
contextError = next.contextError;
|
|
21131
21110
|
return closing2;
|
|
21132
21111
|
},
|
|
@@ -21261,12 +21240,8 @@ function createNavigatorAttendance(options) {
|
|
|
21261
21240
|
|
|
21262
21241
|
// src/navigator-work-context.ts
|
|
21263
21242
|
init_role_run_placement();
|
|
21264
|
-
init_doctor_evidence();
|
|
21265
|
-
init_unknown_value();
|
|
21266
21243
|
init_host_contracts();
|
|
21267
|
-
import { readFile as readFile15 } from "node:fs/promises";
|
|
21268
21244
|
import { resolve as resolve15 } from "node:path";
|
|
21269
|
-
init_notary_source_run();
|
|
21270
21245
|
init_packaged_role_registry();
|
|
21271
21246
|
init_invocation();
|
|
21272
21247
|
function navigatorInputReference(getFlag, role) {
|
|
@@ -21278,21 +21253,8 @@ function navigatorInputReference(getFlag, role) {
|
|
|
21278
21253
|
async function loadNavigatorWorkContext(options) {
|
|
21279
21254
|
const reference = navigatorInputReference(options.getFlag, options.role);
|
|
21280
21255
|
const subjectMode = packagedNavigatorSubject(options.role);
|
|
21281
|
-
const input = reference === void 0 || subjectMode === "case" || subjectMode === "source-run" ? void 0 : await readFile15(reference, "utf8");
|
|
21282
21256
|
const subjectRoot = subjectPath(reference ?? options.context.sessionManager.getSessionDir(), options.context.cwd);
|
|
21283
|
-
|
|
21284
|
-
let subject = input ?? `work subject: ${subjectKey}`;
|
|
21285
|
-
let subjectProvenance = input === void 0 ? "placeholder" : "role_input";
|
|
21286
|
-
if (subjectMode === "case" && reference !== void 0) {
|
|
21287
|
-
const patient = await loadDoctorCase(reference);
|
|
21288
|
-
subject = JSON.stringify({ identity: patient.identity, cost: patient.cost });
|
|
21289
|
-
subjectProvenance = "role_input";
|
|
21290
|
-
}
|
|
21291
|
-
if (subjectMode === "source-run" && reference !== void 0) {
|
|
21292
|
-
const locator = await loadNotarySourceRunLocator(reference);
|
|
21293
|
-
subject = JSON.stringify({ sourceRun: locator });
|
|
21294
|
-
subjectProvenance = "role_input";
|
|
21295
|
-
}
|
|
21257
|
+
const subjectKey = reference === void 0 ? subjectRoot : navigatorSubjectKeyForInput(subjectRoot, reference, options.context.cwd);
|
|
21296
21258
|
const publicRunDir = runDirectoryFromHostContext(options.context);
|
|
21297
21259
|
const currentSessionDir = options.context.sessionManager.getSessionDir();
|
|
21298
21260
|
const isBoundPublicRun = publicRunDir !== void 0 && resolve15(currentSessionDir) === resolve15(sessionDirectoryOf(publicRunDir));
|
|
@@ -21310,50 +21272,23 @@ async function loadNavigatorWorkContext(options) {
|
|
|
21310
21272
|
);
|
|
21311
21273
|
}
|
|
21312
21274
|
if (!admitted.instructionEmpty && admitted.instruction.trim() !== "") {
|
|
21313
|
-
|
|
21314
|
-
|
|
21315
|
-
|
|
21316
|
-
|
|
21317
|
-
return { subjectKey, subject, authority: prose, subjectProvenance };
|
|
21275
|
+
return {
|
|
21276
|
+
subjectKey: subjectRoot,
|
|
21277
|
+
subjectProvenance: "role_input"
|
|
21278
|
+
};
|
|
21318
21279
|
}
|
|
21319
21280
|
return {
|
|
21320
21281
|
subjectKey: subjectRoot,
|
|
21321
|
-
subject: `work subject: ${subjectRoot}`,
|
|
21322
|
-
authority: "",
|
|
21323
21282
|
subjectProvenance: "placeholder"
|
|
21324
21283
|
};
|
|
21325
21284
|
}
|
|
21326
|
-
if (
|
|
21327
|
-
return { subjectKey,
|
|
21328
|
-
}
|
|
21329
|
-
const workRoot = subjectRoot.includes("/.ak/work/") ? subjectRoot : void 0;
|
|
21330
|
-
const authorityFiles = workRoot === void 0 ? [] : [
|
|
21331
|
-
resolve15(workRoot, "authority.md"),
|
|
21332
|
-
resolve15(workRoot, "authority.txt"),
|
|
21333
|
-
resolve15(workRoot, "design-v2/owner-direction.md")
|
|
21334
|
-
];
|
|
21335
|
-
let authorityMaterial;
|
|
21336
|
-
for (const path of authorityFiles) {
|
|
21337
|
-
try {
|
|
21338
|
-
const content = await readFile15(path, "utf8");
|
|
21339
|
-
if (content.trim() !== "") {
|
|
21340
|
-
authorityMaterial = content;
|
|
21341
|
-
break;
|
|
21342
|
-
}
|
|
21343
|
-
} catch (error) {
|
|
21344
|
-
if (!isEnoent(error)) throw error;
|
|
21345
|
-
}
|
|
21346
|
-
}
|
|
21347
|
-
const authority = resolveNavigatorAuthorityMaterial(input, authorityMaterial);
|
|
21348
|
-
if (authority === void 0) {
|
|
21349
|
-
return {
|
|
21350
|
-
subjectKey: subjectRoot,
|
|
21351
|
-
subject: `work subject: ${subjectRoot}`,
|
|
21352
|
-
authority: "",
|
|
21353
|
-
subjectProvenance: "placeholder"
|
|
21354
|
-
};
|
|
21285
|
+
if (reference !== void 0) {
|
|
21286
|
+
return { subjectKey, subjectProvenance: "role_input" };
|
|
21355
21287
|
}
|
|
21356
|
-
return {
|
|
21288
|
+
return {
|
|
21289
|
+
subjectKey: subjectRoot,
|
|
21290
|
+
subjectProvenance: "placeholder"
|
|
21291
|
+
};
|
|
21357
21292
|
}
|
|
21358
21293
|
|
|
21359
21294
|
// src/role-runtime-dependencies.ts
|
|
@@ -23299,12 +23234,8 @@ function createRoleRuntimeExtension(dependencies, deliveryRequestLimit) {
|
|
|
23299
23234
|
if (subject !== "") {
|
|
23300
23235
|
const root = subjectPath(ctx.sessionManager.getSessionDir(), ctx.cwd);
|
|
23301
23236
|
const subjectProvenance = "user_prompt";
|
|
23302
|
-
const priorAuthority = navigatorWorkContext.authority;
|
|
23303
|
-
const authority = typeof priorAuthority === "string" && priorAuthority.trim() !== "" ? priorAuthority : subject;
|
|
23304
23237
|
navigatorWorkContext = {
|
|
23305
23238
|
subjectKey: navigatorSubjectKey(root, subject, subjectProvenance),
|
|
23306
|
-
subject,
|
|
23307
|
-
authority,
|
|
23308
23239
|
subjectProvenance
|
|
23309
23240
|
};
|
|
23310
23241
|
await navigatorAttendance.setWorkContext(navigatorWorkContext);
|
|
@@ -23746,7 +23677,7 @@ function createRoleRuntimeExtension(dependencies, deliveryRequestLimit) {
|
|
|
23746
23677
|
if (dependencies.loadNavigatorWorkContext === void 0) {
|
|
23747
23678
|
const fallbackSubjectKey = subjectPath(ctx.sessionManager.getSessionDir(), ctx.cwd);
|
|
23748
23679
|
contextError = new Error("Navigator work context loader is not configured");
|
|
23749
|
-
work = { subjectKey: fallbackSubjectKey,
|
|
23680
|
+
work = { subjectKey: fallbackSubjectKey, subjectProvenance: "placeholder" };
|
|
23750
23681
|
} else {
|
|
23751
23682
|
try {
|
|
23752
23683
|
work = await dependencies.loadNavigatorWorkContext({
|
|
@@ -23759,7 +23690,7 @@ function createRoleRuntimeExtension(dependencies, deliveryRequestLimit) {
|
|
|
23759
23690
|
} catch (error) {
|
|
23760
23691
|
contextError = navigatorUnavailableError("context", error);
|
|
23761
23692
|
const fallbackSubjectKey = subjectPath(ctx.sessionManager.getSessionDir(), ctx.cwd);
|
|
23762
|
-
work = { subjectKey: fallbackSubjectKey,
|
|
23693
|
+
work = { subjectKey: fallbackSubjectKey, subjectProvenance: "placeholder" };
|
|
23763
23694
|
}
|
|
23764
23695
|
}
|
|
23765
23696
|
navigatorWorkContext = { ...work, ...contextError === void 0 ? {} : { contextError } };
|
|
@@ -23794,8 +23725,6 @@ function createRoleRuntimeExtension(dependencies, deliveryRequestLimit) {
|
|
|
23794
23725
|
role: entry.role,
|
|
23795
23726
|
phase: invocationPhase,
|
|
23796
23727
|
subjectKey: work.subjectKey,
|
|
23797
|
-
subject: work.subject,
|
|
23798
|
-
authority: work.authority,
|
|
23799
23728
|
invocationId,
|
|
23800
23729
|
deliveryRequestLimit: deliveryLimit,
|
|
23801
23730
|
...contextError === void 0 ? {} : { contextError },
|
|
@@ -23857,7 +23786,7 @@ function createRoleRuntimeDependencies(packageRoot) {
|
|
|
23857
23786
|
loadRoleSoul: loadRegisteredRoleSoul,
|
|
23858
23787
|
loadDoctorCase,
|
|
23859
23788
|
loadNotarySourceRun: loadNotarySourceRunLocator,
|
|
23860
|
-
loadMergerInput: async (path) => JSON.parse(await
|
|
23789
|
+
loadMergerInput: async (path) => JSON.parse(await readFile15(path, "utf8")),
|
|
23861
23790
|
loadNavigatorWorkContext: (options) => loadNavigatorWorkContext({
|
|
23862
23791
|
context: options.context,
|
|
23863
23792
|
role: options.role,
|
|
@@ -23868,8 +23797,6 @@ function createRoleRuntimeDependencies(packageRoot) {
|
|
|
23868
23797
|
role: options.role,
|
|
23869
23798
|
phase: options.phase,
|
|
23870
23799
|
subjectKey: options.subjectKey,
|
|
23871
|
-
subject: options.subject,
|
|
23872
|
-
authority: options.authority,
|
|
23873
23800
|
invocationId: options.invocationId,
|
|
23874
23801
|
createSession: navigatorSessionFactory,
|
|
23875
23802
|
...options.deliveryRequestLimit === void 0 ? {} : { deliveryRequestLimit: options.deliveryRequestLimit },
|
|
@@ -41,11 +41,6 @@ import {
|
|
|
41
41
|
import { sha256Hex } from "./sha256.js";
|
|
42
42
|
import { isRecord } from "./unknown-value.js";
|
|
43
43
|
const NAVIGATOR_EVENT_TYPE = "ak-navigator-attendance";
|
|
44
|
-
function resolveNavigatorAuthorityMaterial(roleInput, fileAuthority) {
|
|
45
|
-
if (roleInput !== void 0 && roleInput.trim() !== "") return roleInput;
|
|
46
|
-
if (fileAuthority !== void 0 && fileAuthority.trim() !== "") return fileAuthority;
|
|
47
|
-
return void 0;
|
|
48
|
-
}
|
|
49
44
|
const NAVIGATOR_TARGETS = PACKAGED_ROLE_REGISTRY.map(({ role, phases }) => ({ role, phases }));
|
|
50
45
|
const prepareSchema = navigatorAdviceBodySchema;
|
|
51
46
|
const INVOCATION_ENTRY = NAVIGATOR_INVOCATION_ENTRY;
|
|
@@ -124,8 +119,6 @@ function createNavigatorAttendance(options) {
|
|
|
124
119
|
let sessionReady;
|
|
125
120
|
let session;
|
|
126
121
|
let subjectKey = options.subjectKey;
|
|
127
|
-
let subject = options.subject;
|
|
128
|
-
let authority = options.authority;
|
|
129
122
|
let contextError = options.contextError;
|
|
130
123
|
let preparedAdvice;
|
|
131
124
|
const invocationPrincipal = options.invocationId ?? mintNavigatorInvocationId();
|
|
@@ -154,12 +147,6 @@ function createNavigatorAttendance(options) {
|
|
|
154
147
|
};
|
|
155
148
|
const loadMaterialsAndSession = async (invocationId) => {
|
|
156
149
|
if (contextError !== void 0) throw navigatorUnavailableError("context", contextError);
|
|
157
|
-
if (typeof authority !== "string" || authority.trim() === "") {
|
|
158
|
-
throw navigatorUnavailableError(
|
|
159
|
-
"context",
|
|
160
|
-
new Error("controlling authority content was not supplied as typed work context")
|
|
161
|
-
);
|
|
162
|
-
}
|
|
163
150
|
const modelPromise = (async () => {
|
|
164
151
|
try {
|
|
165
152
|
const resolved = await resolveNavigatorSeatSelection(options.context);
|
|
@@ -245,9 +232,7 @@ function createNavigatorAttendance(options) {
|
|
|
245
232
|
role: options.role,
|
|
246
233
|
phase: options.phase,
|
|
247
234
|
invocationId,
|
|
248
|
-
subjectKey
|
|
249
|
-
subject,
|
|
250
|
-
authority
|
|
235
|
+
subjectKey
|
|
251
236
|
});
|
|
252
237
|
try {
|
|
253
238
|
try {
|
|
@@ -324,8 +309,6 @@ function createNavigatorAttendance(options) {
|
|
|
324
309
|
closing2 = previous.dispose();
|
|
325
310
|
}
|
|
326
311
|
subjectKey = next.subjectKey;
|
|
327
|
-
subject = next.subject;
|
|
328
|
-
authority = next.authority;
|
|
329
312
|
contextError = next.contextError;
|
|
330
313
|
return closing2;
|
|
331
314
|
},
|
|
@@ -487,7 +470,6 @@ export {
|
|
|
487
470
|
parseNavigatorModelSetting,
|
|
488
471
|
readNavigatorModelSetting,
|
|
489
472
|
registerNavigatorModelCommand,
|
|
490
|
-
resolveNavigatorAuthorityMaterial,
|
|
491
473
|
resolveNavigatorSeatSelection,
|
|
492
474
|
subjectPath,
|
|
493
475
|
writeNavigatorModelSetting
|
|
@@ -1162,32 +1162,30 @@ export async function materializeCountersignInvocation(admitted, options) {
|
|
|
1162
1162
|
});
|
|
1163
1163
|
await writeRoleInvocationLedger({ ...admitted, sessionDirectory: placement.sessionDirectory, sessionFile: placement.sessionFile }, admitted.role, options.model);
|
|
1164
1164
|
}
|
|
1165
|
-
/**
|
|
1165
|
+
/**
|
|
1166
|
+
* Load the admitted section written at admission (Navigator work-context seam).
|
|
1167
|
+
* Missing / wrong-shape → undefined. Control-plane read faults propagate (#1187 F2).
|
|
1168
|
+
*/
|
|
1166
1169
|
export async function loadAdmittedJudgeRequest(runDirectory) {
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
if (record === undefined)
|
|
1170
|
-
return undefined;
|
|
1171
|
-
if (!packagedPublicInstructionSubject(record.role))
|
|
1172
|
-
return undefined;
|
|
1173
|
-
if (typeof record.instruction !== "string")
|
|
1174
|
-
return undefined;
|
|
1175
|
-
if (typeof record.instructionEmpty !== "boolean")
|
|
1176
|
-
return undefined;
|
|
1177
|
-
if (!Array.isArray(record.attachments))
|
|
1178
|
-
return undefined;
|
|
1179
|
-
const attachments = record.attachments
|
|
1180
|
-
.map((item) => normalizeAdmittedAttachment(item))
|
|
1181
|
-
.filter((item) => item !== undefined);
|
|
1182
|
-
return {
|
|
1183
|
-
instruction: record.instruction,
|
|
1184
|
-
instructionEmpty: record.instructionEmpty,
|
|
1185
|
-
attachments,
|
|
1186
|
-
};
|
|
1187
|
-
}
|
|
1188
|
-
catch {
|
|
1170
|
+
const record = readPageSync(runDirectory, "admitted");
|
|
1171
|
+
if (record === undefined)
|
|
1189
1172
|
return undefined;
|
|
1190
|
-
|
|
1173
|
+
if (!packagedPublicInstructionSubject(record.role))
|
|
1174
|
+
return undefined;
|
|
1175
|
+
if (typeof record.instruction !== "string")
|
|
1176
|
+
return undefined;
|
|
1177
|
+
if (typeof record.instructionEmpty !== "boolean")
|
|
1178
|
+
return undefined;
|
|
1179
|
+
if (!Array.isArray(record.attachments))
|
|
1180
|
+
return undefined;
|
|
1181
|
+
const attachments = record.attachments
|
|
1182
|
+
.map((item) => normalizeAdmittedAttachment(item))
|
|
1183
|
+
.filter((item) => item !== undefined);
|
|
1184
|
+
return {
|
|
1185
|
+
instruction: record.instruction,
|
|
1186
|
+
instructionEmpty: record.instructionEmpty,
|
|
1187
|
+
attachments,
|
|
1188
|
+
};
|
|
1191
1189
|
}
|
|
1192
1190
|
function parsePositivePrOption(raw) {
|
|
1193
1191
|
if (raw === undefined || raw.trim() === "")
|
|
@@ -13,10 +13,8 @@ import type { Message } from "@earendil-works/pi-ai";
|
|
|
13
13
|
|
|
14
14
|
import {
|
|
15
15
|
registerNavigatorModelCommand,
|
|
16
|
-
resolveNavigatorAuthorityMaterial,
|
|
17
16
|
} from "../src/navigator-attendance.ts";
|
|
18
17
|
import { loadNavigatorWorkContext as loadHostNeutralNavigatorWorkContext } from "../src/navigator-work-context.ts";
|
|
19
|
-
export { resolveNavigatorAuthorityMaterial };
|
|
20
18
|
import { JUDGE_OUTPUT_TOOL_NAME } from "../src/package-contracts/judge-output.ts";
|
|
21
19
|
import { readOAuthKeepaliveProviders } from "../src/oauth-keepalive.ts";
|
|
22
20
|
import {
|
package/package.json
CHANGED
|
@@ -1,13 +1,6 @@
|
|
|
1
|
-
##
|
|
1
|
+
## 备答
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
- **备答**:父衙门一开始即并行准备。自行判断当前进度——有票时读票卷宗里实际发生的角色运行,必要时看票面;不把过去建议或建议送达当作已经走过的站。按主衙门可能的结局 status 预写建议,经 `byStatus` 提交(键为 status 字面量,值为建议正文)。无状态分叉时可用单条 `prose`。
|
|
6
|
-
- **取用**:父衙门交卷后,代码只按实际 status 取对应原文,不再起模型轮次。没有对应建议则如实无建议。主衙门结束后最多再等十秒;到时停止等待,不扣押主结果。
|
|
7
|
-
|
|
8
|
-
## 宿主轴(与角色命令面)
|
|
9
|
-
|
|
10
|
-
调用与 host 解析见 `ak-role help`、`ak-role help navigator`;机构边界见 [ADR 0082](https://github.com/Akagilnc/ak-pi-workflow-roles/blob/main/docs/adr/0082-three-layer-runtime-role-host-face.md),席位解析见 [config 实现](../src/public-cli/config.ts)。
|
|
3
|
+
父衙门一开始即并行准备。有票时读票卷宗里实际发生的角色运行,必要时看票面;不读过去的建议。按主衙门可能的结局 status 预写建议,经 `byStatus` 提交(键为 status 字面量,值为建议正文)。无状态分叉时可用单条 `prose`。
|
|
11
4
|
|
|
12
5
|
## 常用交付线
|
|
13
6
|
|
|
@@ -32,12 +25,9 @@ collector(收齐 current-head 材料)
|
|
|
32
25
|
├─ 有问题 → 修内司 → 大理寺
|
|
33
26
|
└─ 收敛 → 调用者合并、关票
|
|
34
27
|
|
|
35
|
-
既往大理寺收敛不替代其后新一轮线上材料的裁决;缺失 reviewer 腿只是 degraded coverage,不改变 collector 后到大理寺的接力。
|
|
36
|
-
|
|
37
28
|
## 未完交棒(unfinished)
|
|
38
29
|
|
|
39
30
|
修内司 / 将作监 apply 以 unfinished 交棒时,工作仍未结清:
|
|
40
31
|
→ 续修(通常仍是同一 worker 的 apply),不要送大理寺
|
|
41
32
|
|
|
42
33
|
refused / partially_completed 是已结清结算,送大理寺审计仍合法。
|
|
43
|
-
unfinished 不是失败清理信号,也不豁免任何验收。
|
package/souls/navigator.md
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# Navigator Soul
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
按当前结算判断最低成本且安全的下一站:不跳必要站,不加多余站。只是建议,不授权、不执行。
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
当前 plan 阶段停用。
|
|
5
|
+
一句话,20 字以内。plan 阶段停用。
|
|
@@ -74,19 +74,6 @@ import { isRecord } from "./unknown-value.ts";
|
|
|
74
74
|
export const NAVIGATOR_EVENT_TYPE = "ak-navigator-attendance" as const;
|
|
75
75
|
export { NAVIGATOR_ROUTE_PLAYBOOK_FAILURE_ENTRY };
|
|
76
76
|
|
|
77
|
-
/**
|
|
78
|
-
* Role-input document bytes win verbatim over work-root file authority when non-empty.
|
|
79
|
-
* Absent or whitespace-only input yields to fileAuthority; neither remains undefined.
|
|
80
|
-
*/
|
|
81
|
-
export function resolveNavigatorAuthorityMaterial(
|
|
82
|
-
roleInput: string | undefined,
|
|
83
|
-
fileAuthority: string | undefined,
|
|
84
|
-
): string | undefined {
|
|
85
|
-
if (roleInput !== undefined && roleInput.trim() !== "") return roleInput;
|
|
86
|
-
if (fileAuthority !== undefined && fileAuthority.trim() !== "") return fileAuthority;
|
|
87
|
-
return undefined;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
77
|
/** Every public role is a lawful navigator route target (#675 — no nested-only seats). */
|
|
91
78
|
export const NAVIGATOR_TARGETS = PACKAGED_ROLE_REGISTRY
|
|
92
79
|
.map(({ role, phases }) => ({ role, phases }));
|
|
@@ -101,10 +88,9 @@ export type NavigatorSettlement =
|
|
|
101
88
|
|
|
102
89
|
export type NavigatorSubjectProvenance = "placeholder" | "role_input" | "user_prompt";
|
|
103
90
|
|
|
91
|
+
/** #1187: auto prepare identity only — no subject/authority material fields. */
|
|
104
92
|
export type NavigatorWorkContext = {
|
|
105
93
|
subjectKey: string;
|
|
106
|
-
subject: string;
|
|
107
|
-
authority: string;
|
|
108
94
|
subjectProvenance: NavigatorSubjectProvenance;
|
|
109
95
|
contextError?: unknown;
|
|
110
96
|
};
|
|
@@ -153,8 +139,6 @@ export type NavigatorAttendanceOptions = {
|
|
|
153
139
|
subjectKey: string;
|
|
154
140
|
createSession: NavigatorSessionFactory;
|
|
155
141
|
modelSettingPath?: string;
|
|
156
|
-
subject: string;
|
|
157
|
-
authority: string;
|
|
158
142
|
contextError?: unknown;
|
|
159
143
|
/** Exact principal owned by shared role lifecycle; attendance never overrides it. */
|
|
160
144
|
invocationId?: string;
|
|
@@ -277,8 +261,7 @@ export function createNavigatorAttendance(options: NavigatorAttendanceOptions) {
|
|
|
277
261
|
let sessionReady: Promise<NavigatorPreparationSession> | undefined;
|
|
278
262
|
let session: NavigatorPreparationSession | undefined;
|
|
279
263
|
let subjectKey = options.subjectKey;
|
|
280
|
-
|
|
281
|
-
let authority = options.authority;
|
|
264
|
+
// #1187: auto prepare is identity-only (role/phase/subjectKey).
|
|
282
265
|
let contextError = options.contextError;
|
|
283
266
|
/** Parallel-prepare result: status-keyed prose picked at settle (#1160). */
|
|
284
267
|
let preparedAdvice: PreparedNavigatorAdvice | undefined;
|
|
@@ -322,12 +305,8 @@ export function createNavigatorAttendance(options: NavigatorAttendanceOptions) {
|
|
|
322
305
|
*/
|
|
323
306
|
const loadMaterialsAndSession = async (invocationId: string): Promise<NavigatorPreparationSession> => {
|
|
324
307
|
if (contextError !== undefined) throw navigatorUnavailableError("context", contextError);
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
"context",
|
|
328
|
-
new Error("controlling authority content was not supplied as typed work context"),
|
|
329
|
-
);
|
|
330
|
-
}
|
|
308
|
+
// #1187: prepare runs from identity (role/phase/subjectKey). Parent dispatch
|
|
309
|
+
// and authority copies are not required materials for the auto prepare round.
|
|
331
310
|
const modelPromise = (async () => {
|
|
332
311
|
try {
|
|
333
312
|
const resolved = await resolveNavigatorSeatSelection(options.context);
|
|
@@ -413,16 +392,14 @@ export function createNavigatorAttendance(options: NavigatorAttendanceOptions) {
|
|
|
413
392
|
};
|
|
414
393
|
const activeSession = await loadMaterialsAndSession(invocationId);
|
|
415
394
|
// #1160: parallel prepare from parent start — model runs now; settle only picks.
|
|
416
|
-
//
|
|
417
|
-
//
|
|
395
|
+
// #1187: identity only. Parent dispatch / authority copies stay off this wire;
|
|
396
|
+
// navigator reads ticket and station records itself when needed.
|
|
418
397
|
const request = JSON.stringify({
|
|
419
398
|
kind: "prepare",
|
|
420
399
|
role: options.role,
|
|
421
400
|
phase: options.phase,
|
|
422
401
|
invocationId,
|
|
423
402
|
subjectKey,
|
|
424
|
-
subject,
|
|
425
|
-
authority,
|
|
426
403
|
});
|
|
427
404
|
try {
|
|
428
405
|
try {
|
|
@@ -520,8 +497,6 @@ export function createNavigatorAttendance(options: NavigatorAttendanceOptions) {
|
|
|
520
497
|
closing = previous.dispose();
|
|
521
498
|
}
|
|
522
499
|
subjectKey = next.subjectKey;
|
|
523
|
-
subject = next.subject;
|
|
524
|
-
authority = next.authority;
|
|
525
500
|
contextError = next.contextError;
|
|
526
501
|
return closing;
|
|
527
502
|
},
|
|
@@ -1,25 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Host-neutral Navigator work-context loader (#590).
|
|
2
|
+
* Host-neutral Navigator work-context loader (#590 / #1187).
|
|
3
|
+
* Auto prepare is identity-only: subjectKey + provenance. No parent dispatch,
|
|
4
|
+
* role-input bytes, or work-root authority files are loaded as materials.
|
|
3
5
|
* Flag/input resolution is supplied by the host; no ExtensionAPI dependency.
|
|
4
6
|
*/
|
|
5
|
-
import { readFile } from "node:fs/promises";
|
|
6
7
|
import { resolve } from "node:path";
|
|
7
8
|
|
|
8
9
|
import { sessionDirectoryOf } from "./role-run-placement.ts";
|
|
9
10
|
|
|
10
|
-
import { loadDoctorCase } from "./doctor-evidence.ts";
|
|
11
|
-
import { isEnoent } from "./unknown-value.ts";
|
|
12
11
|
import { runDirectoryFromHostContext, type HostContext } from "./host-contracts.ts";
|
|
13
12
|
import {
|
|
14
|
-
navigatorSubjectKey,
|
|
15
13
|
navigatorSubjectKeyForInput,
|
|
16
14
|
navigatorUnavailableError,
|
|
17
|
-
resolveNavigatorAuthorityMaterial,
|
|
18
15
|
subjectPath,
|
|
19
16
|
type NavigatorSubjectProvenance,
|
|
20
17
|
type NavigatorWorkContext,
|
|
21
18
|
} from "./navigator-attendance.ts";
|
|
22
|
-
import { loadNotarySourceRunLocator } from "./notary-source-run.ts";
|
|
23
19
|
import { packagedNavigatorSubject, packagedRoleInputFlag } from "./packaged-role-registry.ts";
|
|
24
20
|
import { loadAdmittedJudgeRequest } from "./public-cli/invocation.ts";
|
|
25
21
|
|
|
@@ -42,37 +38,26 @@ function navigatorInputReference(
|
|
|
42
38
|
|
|
43
39
|
/**
|
|
44
40
|
* Resolve typed Navigator work context from host flags and/or the public admitted request.
|
|
41
|
+
* Returns identity (subjectKey + provenance) only — auto prepare does not consume materials.
|
|
45
42
|
*/
|
|
46
43
|
export async function loadNavigatorWorkContext(
|
|
47
44
|
options: NavigatorWorkContextLoaderOptions,
|
|
48
45
|
): Promise<NavigatorWorkContext> {
|
|
49
46
|
const reference = navigatorInputReference(options.getFlag, options.role);
|
|
50
47
|
const subjectMode = packagedNavigatorSubject(options.role);
|
|
51
|
-
const input = reference === undefined || subjectMode === "case" || subjectMode === "source-run"
|
|
52
|
-
? undefined
|
|
53
|
-
: await readFile(reference, "utf8");
|
|
54
48
|
const subjectRoot = subjectPath(reference ?? options.context.sessionManager.getSessionDir(), options.context.cwd);
|
|
55
|
-
|
|
49
|
+
const subjectKey = reference === undefined
|
|
56
50
|
? subjectRoot
|
|
57
51
|
: navigatorSubjectKeyForInput(subjectRoot, reference, options.context.cwd);
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
if (subjectMode === "case" && reference !== undefined) {
|
|
61
|
-
const patient = await loadDoctorCase(reference);
|
|
62
|
-
subject = JSON.stringify({ identity: patient.identity, cost: patient.cost });
|
|
63
|
-
subjectProvenance = "role_input";
|
|
64
|
-
}
|
|
65
|
-
if (subjectMode === "source-run" && reference !== undefined) {
|
|
66
|
-
const locator = await loadNotarySourceRunLocator(reference);
|
|
67
|
-
subject = JSON.stringify({ sourceRun: locator });
|
|
68
|
-
subjectProvenance = "role_input";
|
|
69
|
-
}
|
|
70
|
-
// Public ak-role run: admitted request is the typed Navigator work-context source.
|
|
52
|
+
|
|
53
|
+
// Public ak-role run: admitted request decides empty vs concrete identity.
|
|
71
54
|
const publicRunDir = runDirectoryFromHostContext(options.context);
|
|
72
55
|
const currentSessionDir = options.context.sessionManager.getSessionDir();
|
|
73
56
|
const isBoundPublicRun = publicRunDir !== undefined
|
|
74
57
|
&& resolve(currentSessionDir) === resolve(sessionDirectoryOf(publicRunDir));
|
|
75
58
|
if (subjectMode === "public-instruction" && isBoundPublicRun) {
|
|
59
|
+
// Control-plane read faults keep their real cause inside context-error (#1187 F2).
|
|
60
|
+
// Only true absence / wrong-shape is undefined → generic missing message.
|
|
76
61
|
let admitted;
|
|
77
62
|
try {
|
|
78
63
|
admitted = await loadAdmittedJudgeRequest(publicRunDir);
|
|
@@ -86,48 +71,27 @@ export async function loadNavigatorWorkContext(
|
|
|
86
71
|
);
|
|
87
72
|
}
|
|
88
73
|
if (!admitted.instructionEmpty && admitted.instruction.trim() !== "") {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
74
|
+
// #1187: non-empty public admission starts parallel prepare by identity.
|
|
75
|
+
// Parent instruction remains the parent role's own dispatch; auto navigator
|
|
76
|
+
// does not receive that prose (or a duplicate authority copy) as material.
|
|
77
|
+
return {
|
|
78
|
+
subjectKey: subjectRoot,
|
|
79
|
+
subjectProvenance: "role_input",
|
|
80
|
+
};
|
|
94
81
|
}
|
|
95
82
|
return {
|
|
96
83
|
subjectKey: subjectRoot,
|
|
97
|
-
subject: `work subject: ${subjectRoot}`,
|
|
98
|
-
authority: "",
|
|
99
84
|
subjectProvenance: "placeholder",
|
|
100
85
|
};
|
|
101
86
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
resolve(workRoot, "authority.md"),
|
|
108
|
-
resolve(workRoot, "authority.txt"),
|
|
109
|
-
resolve(workRoot, "design-v2/owner-direction.md"),
|
|
110
|
-
];
|
|
111
|
-
let authorityMaterial: string | undefined;
|
|
112
|
-
for (const path of authorityFiles) {
|
|
113
|
-
try {
|
|
114
|
-
const content = await readFile(path, "utf8");
|
|
115
|
-
if (content.trim() !== "") {
|
|
116
|
-
authorityMaterial = content;
|
|
117
|
-
break;
|
|
118
|
-
}
|
|
119
|
-
} catch (error) {
|
|
120
|
-
if (!isEnoent(error)) throw error;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
const authority = resolveNavigatorAuthorityMaterial(input, authorityMaterial);
|
|
124
|
-
if (authority === undefined) {
|
|
125
|
-
return {
|
|
126
|
-
subjectKey: subjectRoot,
|
|
127
|
-
subject: `work subject: ${subjectRoot}`,
|
|
128
|
-
authority: "",
|
|
129
|
-
subjectProvenance: "placeholder",
|
|
130
|
-
};
|
|
87
|
+
|
|
88
|
+
// Concrete role-input path (file/case/source-run flag) is identity enough to start prepare.
|
|
89
|
+
// Navigator reads ticket and station records itself when needed — no material copy here.
|
|
90
|
+
if (reference !== undefined) {
|
|
91
|
+
return { subjectKey, subjectProvenance: "role_input" satisfies NavigatorSubjectProvenance };
|
|
131
92
|
}
|
|
132
|
-
return {
|
|
93
|
+
return {
|
|
94
|
+
subjectKey: subjectRoot,
|
|
95
|
+
subjectProvenance: "placeholder",
|
|
96
|
+
};
|
|
133
97
|
}
|
|
@@ -1937,7 +1937,10 @@ export async function materializeCountersignInvocation(
|
|
|
1937
1937
|
);
|
|
1938
1938
|
}
|
|
1939
1939
|
|
|
1940
|
-
/**
|
|
1940
|
+
/**
|
|
1941
|
+
* Load the admitted section written at admission (Navigator work-context seam).
|
|
1942
|
+
* Missing / wrong-shape → undefined. Control-plane read faults propagate (#1187 F2).
|
|
1943
|
+
*/
|
|
1941
1944
|
export async function loadAdmittedJudgeRequest(
|
|
1942
1945
|
runDirectory: string,
|
|
1943
1946
|
): Promise<{
|
|
@@ -1945,24 +1948,21 @@ export async function loadAdmittedJudgeRequest(
|
|
|
1945
1948
|
instructionEmpty: boolean;
|
|
1946
1949
|
attachments: readonly AdmittedAttachment[];
|
|
1947
1950
|
} | undefined> {
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
} catch {
|
|
1964
|
-
return undefined;
|
|
1965
|
-
}
|
|
1951
|
+
const record = readPageSync(runDirectory, "admitted");
|
|
1952
|
+
if (record === undefined) return undefined;
|
|
1953
|
+
if (!packagedPublicInstructionSubject(record.role)) return undefined;
|
|
1954
|
+
if (typeof record.instruction !== "string") return undefined;
|
|
1955
|
+
if (typeof record.instructionEmpty !== "boolean") return undefined;
|
|
1956
|
+
if (!Array.isArray(record.attachments)) return undefined;
|
|
1957
|
+
const attachments = record.attachments
|
|
1958
|
+
.map((item) => normalizeAdmittedAttachment(item))
|
|
1959
|
+
.filter((item): item is AdmittedAttachment => item !== undefined);
|
|
1960
|
+
return {
|
|
1961
|
+
instruction: record.instruction,
|
|
1962
|
+
instructionEmpty: record.instructionEmpty,
|
|
1963
|
+
attachments,
|
|
1964
|
+
};
|
|
1965
|
+
|
|
1966
1966
|
}
|
|
1967
1967
|
|
|
1968
1968
|
export type AdmitFixerInvocationOptions = {
|
|
@@ -58,8 +58,6 @@ export function createRoleRuntimeDependencies(packageRoot: string): RoleRuntimeD
|
|
|
58
58
|
role: options.role,
|
|
59
59
|
phase: options.phase,
|
|
60
60
|
subjectKey: options.subjectKey,
|
|
61
|
-
subject: options.subject,
|
|
62
|
-
authority: options.authority,
|
|
63
61
|
invocationId: options.invocationId,
|
|
64
62
|
createSession: navigatorSessionFactory,
|
|
65
63
|
...(options.deliveryRequestLimit === undefined ? {} : { deliveryRequestLimit: options.deliveryRequestLimit }),
|
package/src/role-runtime.ts
CHANGED
|
@@ -467,7 +467,7 @@ export type RoleRuntimeDependencies = {
|
|
|
467
467
|
loadNotarySourceRun?(path: string): Promise<import("./notary-contracts.ts").NotarySourceRunLocator>;
|
|
468
468
|
loadDoctorCase?(path: string): Promise<import("./doctor-contracts.ts").DoctorCase>;
|
|
469
469
|
loadMergerInput?(path: string): Promise<unknown>;
|
|
470
|
-
createNavigatorAttendance?(options: { context: HostContext; role: string; phase: NavigatorPhase; subjectKey: string;
|
|
470
|
+
createNavigatorAttendance?(options: { context: HostContext; role: string; phase: NavigatorPhase; subjectKey: string; contextError?: unknown; invocationId: string; deliveryRequestLimit?: number; onEvent: (event: import("./navigator-attendance.ts").NavigatorEvent, report: import("./navigator-attendance.ts").NavigatorReport) => void | Promise<void> }): NavigatorAttendanceDependency | Promise<NavigatorAttendanceDependency>;
|
|
471
471
|
loadNavigatorWorkContext?(options: { context: HostContext; role: string; phase: NavigatorPhase; getFlag?: (name: string) => unknown }): Promise<NavigatorWorkContext>;
|
|
472
472
|
activationClock?(): string;
|
|
473
473
|
activationTraceWriter?: (record: ActivationTraceRecord) => void | Promise<void>;
|
|
@@ -1185,22 +1185,15 @@ export function createRoleRuntimeExtension(
|
|
|
1185
1185
|
// Soft session_start placeholders (no materials yet) recover here; hard
|
|
1186
1186
|
// contextError from true loader failures stays poisoned and honest.
|
|
1187
1187
|
if (navigatorWorkContext.subjectProvenance === "placeholder") {
|
|
1188
|
-
// Navigator's own input bootstrap
|
|
1189
|
-
//
|
|
1190
|
-
//
|
|
1191
|
-
// nothing else has supplied a subject yet.
|
|
1188
|
+
// Navigator's own input bootstrap (#836): human prompt bytes key the
|
|
1189
|
+
// identity when nothing else has supplied a concrete subject yet.
|
|
1190
|
+
// Auto prepare stays identity-only — no subject/authority material copy.
|
|
1192
1191
|
const subject = prompt.trim();
|
|
1193
1192
|
if (subject !== "") {
|
|
1194
1193
|
const root = subjectPath(ctx.sessionManager.getSessionDir(), ctx.cwd);
|
|
1195
1194
|
const subjectProvenance = "user_prompt" satisfies NavigatorSubjectProvenance;
|
|
1196
|
-
const priorAuthority = navigatorWorkContext.authority;
|
|
1197
|
-
const authority = typeof priorAuthority === "string" && priorAuthority.trim() !== ""
|
|
1198
|
-
? priorAuthority
|
|
1199
|
-
: subject;
|
|
1200
1195
|
navigatorWorkContext = {
|
|
1201
1196
|
subjectKey: navigatorSubjectKey(root, subject, subjectProvenance),
|
|
1202
|
-
subject,
|
|
1203
|
-
authority,
|
|
1204
1197
|
subjectProvenance,
|
|
1205
1198
|
};
|
|
1206
1199
|
await navigatorAttendance.setWorkContext(navigatorWorkContext);
|
|
@@ -1712,7 +1705,7 @@ export function createRoleRuntimeExtension(
|
|
|
1712
1705
|
if (dependencies.loadNavigatorWorkContext === undefined) {
|
|
1713
1706
|
const fallbackSubjectKey = subjectPath(ctx.sessionManager.getSessionDir(), ctx.cwd);
|
|
1714
1707
|
contextError = new Error("Navigator work context loader is not configured");
|
|
1715
|
-
work = { subjectKey: fallbackSubjectKey,
|
|
1708
|
+
work = { subjectKey: fallbackSubjectKey, subjectProvenance: "placeholder" };
|
|
1716
1709
|
} else {
|
|
1717
1710
|
try {
|
|
1718
1711
|
work = await dependencies.loadNavigatorWorkContext({
|
|
@@ -1726,7 +1719,7 @@ export function createRoleRuntimeExtension(
|
|
|
1726
1719
|
// 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.
|
|
1727
1720
|
contextError = navigatorUnavailableError("context", error);
|
|
1728
1721
|
const fallbackSubjectKey = subjectPath(ctx.sessionManager.getSessionDir(), ctx.cwd);
|
|
1729
|
-
work = { subjectKey: fallbackSubjectKey,
|
|
1722
|
+
work = { subjectKey: fallbackSubjectKey, subjectProvenance: "placeholder" };
|
|
1730
1723
|
}
|
|
1731
1724
|
}
|
|
1732
1725
|
navigatorWorkContext = { ...work, ...(contextError === undefined ? {} : { contextError }) };
|
|
@@ -1765,8 +1758,6 @@ export function createRoleRuntimeExtension(
|
|
|
1765
1758
|
role: entry.role,
|
|
1766
1759
|
phase: invocationPhase,
|
|
1767
1760
|
subjectKey: work.subjectKey,
|
|
1768
|
-
subject: work.subject,
|
|
1769
|
-
authority: work.authority,
|
|
1770
1761
|
invocationId,
|
|
1771
1762
|
deliveryRequestLimit: deliveryLimit,
|
|
1772
1763
|
...(contextError === undefined ? {} : { contextError }),
|