@akagilnc/pi-workflow-roles 0.1.5245 → 0.1.5252
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 +24 -55
- package/dist/headless-host/production-host.js +24 -55
- package/dist/navigator-invocation-identity.js +0 -57
- package/dist/public-cli/main.js +5 -52
- package/dist/public-cli/settlement.js +10 -59
- package/package.json +1 -1
- package/src/navigator-invocation-identity.ts +4 -121
- package/src/public-cli/settlement.ts +8 -75
- package/src/role-runtime.ts +23 -5
|
@@ -10894,11 +10894,6 @@ async function appendRunAttemptHistory(source, outcome) {
|
|
|
10894
10894
|
} catch {
|
|
10895
10895
|
}
|
|
10896
10896
|
}
|
|
10897
|
-
function navigatorAttendanceCorrelatedWithBoundMarker(details, attendanceIndex, terminalIndex, marker) {
|
|
10898
|
-
if (attendanceIndex <= terminalIndex) return false;
|
|
10899
|
-
if (details.invocationId !== marker.invocationId) return false;
|
|
10900
|
-
return true;
|
|
10901
|
-
}
|
|
10902
10897
|
function parseNavigatorAttendanceDetails(details) {
|
|
10903
10898
|
const disposition = details.disposition;
|
|
10904
10899
|
const advisoryDiagnostic = typeof details.routePlaybookReadFailure === "string" ? { advisoryDiagnostic: details.routePlaybookReadFailure } : {};
|
|
@@ -11049,54 +11044,12 @@ function extractNavigatorAttendanceFact(entries) {
|
|
|
11049
11044
|
reason: "Navigator attendance has no durable packaged role terminal"
|
|
11050
11045
|
};
|
|
11051
11046
|
}
|
|
11052
|
-
let
|
|
11053
|
-
for (let i = terminal.index - 1; i >= 0; i -= 1) {
|
|
11047
|
+
for (let i = terminal.index; i < entries.length; i += 1) {
|
|
11054
11048
|
const entry = entries[i];
|
|
11055
|
-
if (entry?.type
|
|
11056
|
-
|
|
11057
|
-
|
|
11058
|
-
|
|
11059
|
-
}
|
|
11060
|
-
if (markerIndex < 0) {
|
|
11061
|
-
return {
|
|
11062
|
-
disposition: "unavailable",
|
|
11063
|
-
source: "unknown",
|
|
11064
|
-
reason: "Navigator attendance is uncorrelated with session invocation facts"
|
|
11065
|
-
};
|
|
11066
|
-
}
|
|
11067
|
-
const marker = parseInvocationMarkerIdentity(entries[markerIndex]?.data);
|
|
11068
|
-
if (marker === void 0) {
|
|
11069
|
-
return {
|
|
11070
|
-
disposition: "unavailable",
|
|
11071
|
-
source: "unknown",
|
|
11072
|
-
reason: "Navigator attendance is uncorrelated with session invocation facts"
|
|
11073
|
-
};
|
|
11074
|
-
}
|
|
11075
|
-
for (let i = entries.length - 1; i >= 0; i -= 1) {
|
|
11076
|
-
const entry = entries[i];
|
|
11077
|
-
if (entry?.type === "custom_message" && entry.customType === "ak-navigator-attendance") {
|
|
11078
|
-
const details = entry.message?.details ?? entry.details;
|
|
11079
|
-
if (!isRecord10(details)) {
|
|
11080
|
-
return {
|
|
11081
|
-
disposition: "unavailable",
|
|
11082
|
-
source: "unknown",
|
|
11083
|
-
reason: "Navigator attendance is unparseable"
|
|
11084
|
-
};
|
|
11085
|
-
}
|
|
11086
|
-
if (!navigatorAttendanceCorrelatedWithBoundMarker(
|
|
11087
|
-
details,
|
|
11088
|
-
i,
|
|
11089
|
-
terminal.index,
|
|
11090
|
-
marker
|
|
11091
|
-
)) {
|
|
11092
|
-
return {
|
|
11093
|
-
disposition: "unavailable",
|
|
11094
|
-
source: "unknown",
|
|
11095
|
-
reason: "Navigator attendance is uncorrelated with session invocation facts"
|
|
11096
|
-
};
|
|
11097
|
-
}
|
|
11098
|
-
return parseNavigatorAttendanceDetails(details);
|
|
11099
|
-
}
|
|
11049
|
+
if (entry?.type !== "custom" || entry.customType !== "ak-role-submission-closure") continue;
|
|
11050
|
+
const details = isRecord10(entry.data) ? entry.data.navigator : void 0;
|
|
11051
|
+
if (!isRecord10(details)) break;
|
|
11052
|
+
return parseNavigatorAttendanceDetails(details);
|
|
11100
11053
|
}
|
|
11101
11054
|
return {
|
|
11102
11055
|
disposition: "unavailable",
|
|
@@ -24028,8 +23981,15 @@ async function projectClosedSubmissionLifecycle(closed, context, phase, recordAc
|
|
|
24028
23981
|
isError: false,
|
|
24029
23982
|
details: closed.accepted
|
|
24030
23983
|
};
|
|
24031
|
-
|
|
24032
|
-
|
|
23984
|
+
let navigator;
|
|
23985
|
+
try {
|
|
23986
|
+
navigator = await settle(publicNavigatorSettlement(closed.role, phase, closure));
|
|
23987
|
+
} finally {
|
|
23988
|
+
context.sessionManager.appendCustomEntry?.("ak-role-submission-closure", {
|
|
23989
|
+
...closure,
|
|
23990
|
+
...navigator === void 0 ? {} : { navigator }
|
|
23991
|
+
});
|
|
23992
|
+
}
|
|
24033
23993
|
}
|
|
24034
23994
|
function createFiledOfficerRuntime(roleHost, spec, dependencies) {
|
|
24035
23995
|
let soul;
|
|
@@ -24388,6 +24348,8 @@ function createRoleRuntimeExtension(dependencies) {
|
|
|
24388
24348
|
let activeReviewerParent;
|
|
24389
24349
|
let navigatorAttendance;
|
|
24390
24350
|
let pendingNavigatorPresentation;
|
|
24351
|
+
let navigatorActivation = 0;
|
|
24352
|
+
let navigatorDeliveryClosed = false;
|
|
24391
24353
|
let pendingNavigatorSettlement;
|
|
24392
24354
|
let navigatorWorkContext;
|
|
24393
24355
|
let navigatorSessionParent;
|
|
@@ -24440,6 +24402,7 @@ function createRoleRuntimeExtension(dependencies) {
|
|
|
24440
24402
|
void settlePromise.catch(() => void 0);
|
|
24441
24403
|
const raced = await raceNavigatorGrace(settlePromise, NAVIGATOR_POST_ROLE_GRACE_MS);
|
|
24442
24404
|
if (raced.status !== "timeout") return;
|
|
24405
|
+
navigatorDeliveryClosed = true;
|
|
24443
24406
|
if (pendingNavigatorPresentation === void 0) {
|
|
24444
24407
|
const report = {
|
|
24445
24408
|
disposition: "unavailable",
|
|
@@ -24464,6 +24427,7 @@ function createRoleRuntimeExtension(dependencies) {
|
|
|
24464
24427
|
})();
|
|
24465
24428
|
pendingNavigatorSettlement = pending;
|
|
24466
24429
|
await pending;
|
|
24430
|
+
return pendingNavigatorPresentation?.event;
|
|
24467
24431
|
};
|
|
24468
24432
|
projectClosedSubmission = async (closed, context) => projectClosedSubmissionLifecycle(
|
|
24469
24433
|
closed,
|
|
@@ -24943,6 +24907,8 @@ function createRoleRuntimeExtension(dependencies) {
|
|
|
24943
24907
|
receiptDelivery = createReceiptDeliveryPolicy();
|
|
24944
24908
|
noReceiptRecorded = false;
|
|
24945
24909
|
pendingNavigatorPresentation = void 0;
|
|
24910
|
+
navigatorActivation += 1;
|
|
24911
|
+
navigatorDeliveryClosed = false;
|
|
24946
24912
|
pendingNavigatorSettlement = void 0;
|
|
24947
24913
|
pendingInfrastructureFailures.clear();
|
|
24948
24914
|
pendingSubmissionNonPassByToolCallId.clear();
|
|
@@ -25038,6 +25004,7 @@ function createRoleRuntimeExtension(dependencies) {
|
|
|
25038
25004
|
} catch {
|
|
25039
25005
|
}
|
|
25040
25006
|
}
|
|
25007
|
+
const activation = navigatorActivation;
|
|
25041
25008
|
navigatorAttendance = await dependencies.createNavigatorAttendance({
|
|
25042
25009
|
context: ctx,
|
|
25043
25010
|
role: entry.role,
|
|
@@ -25048,7 +25015,9 @@ function createRoleRuntimeExtension(dependencies) {
|
|
|
25048
25015
|
invocationId,
|
|
25049
25016
|
...contextError === void 0 ? {} : { contextError },
|
|
25050
25017
|
onEvent: (navigatorEvent, report) => {
|
|
25051
|
-
|
|
25018
|
+
if (activation === navigatorActivation && !navigatorDeliveryClosed) {
|
|
25019
|
+
pendingNavigatorPresentation = { event: navigatorEvent, report };
|
|
25020
|
+
}
|
|
25052
25021
|
}
|
|
25053
25022
|
});
|
|
25054
25023
|
if (navigatorWorkContext.contextError === void 0 && navigatorWorkContext.subjectProvenance !== "placeholder") {
|
|
@@ -11314,11 +11314,6 @@ async function appendRunAttemptHistory(source, outcome) {
|
|
|
11314
11314
|
} catch {
|
|
11315
11315
|
}
|
|
11316
11316
|
}
|
|
11317
|
-
function navigatorAttendanceCorrelatedWithBoundMarker(details, attendanceIndex, terminalIndex, marker) {
|
|
11318
|
-
if (attendanceIndex <= terminalIndex) return false;
|
|
11319
|
-
if (details.invocationId !== marker.invocationId) return false;
|
|
11320
|
-
return true;
|
|
11321
|
-
}
|
|
11322
11317
|
function parseNavigatorAttendanceDetails(details) {
|
|
11323
11318
|
const disposition = details.disposition;
|
|
11324
11319
|
const advisoryDiagnostic = typeof details.routePlaybookReadFailure === "string" ? { advisoryDiagnostic: details.routePlaybookReadFailure } : {};
|
|
@@ -11469,54 +11464,12 @@ function extractNavigatorAttendanceFact(entries) {
|
|
|
11469
11464
|
reason: "Navigator attendance has no durable packaged role terminal"
|
|
11470
11465
|
};
|
|
11471
11466
|
}
|
|
11472
|
-
let
|
|
11473
|
-
for (let i = terminal.index - 1; i >= 0; i -= 1) {
|
|
11467
|
+
for (let i = terminal.index; i < entries.length; i += 1) {
|
|
11474
11468
|
const entry = entries[i];
|
|
11475
|
-
if (entry?.type
|
|
11476
|
-
|
|
11477
|
-
|
|
11478
|
-
|
|
11479
|
-
}
|
|
11480
|
-
if (markerIndex < 0) {
|
|
11481
|
-
return {
|
|
11482
|
-
disposition: "unavailable",
|
|
11483
|
-
source: "unknown",
|
|
11484
|
-
reason: "Navigator attendance is uncorrelated with session invocation facts"
|
|
11485
|
-
};
|
|
11486
|
-
}
|
|
11487
|
-
const marker = parseInvocationMarkerIdentity(entries[markerIndex]?.data);
|
|
11488
|
-
if (marker === void 0) {
|
|
11489
|
-
return {
|
|
11490
|
-
disposition: "unavailable",
|
|
11491
|
-
source: "unknown",
|
|
11492
|
-
reason: "Navigator attendance is uncorrelated with session invocation facts"
|
|
11493
|
-
};
|
|
11494
|
-
}
|
|
11495
|
-
for (let i = entries.length - 1; i >= 0; i -= 1) {
|
|
11496
|
-
const entry = entries[i];
|
|
11497
|
-
if (entry?.type === "custom_message" && entry.customType === "ak-navigator-attendance") {
|
|
11498
|
-
const details = entry.message?.details ?? entry.details;
|
|
11499
|
-
if (!isRecord10(details)) {
|
|
11500
|
-
return {
|
|
11501
|
-
disposition: "unavailable",
|
|
11502
|
-
source: "unknown",
|
|
11503
|
-
reason: "Navigator attendance is unparseable"
|
|
11504
|
-
};
|
|
11505
|
-
}
|
|
11506
|
-
if (!navigatorAttendanceCorrelatedWithBoundMarker(
|
|
11507
|
-
details,
|
|
11508
|
-
i,
|
|
11509
|
-
terminal.index,
|
|
11510
|
-
marker
|
|
11511
|
-
)) {
|
|
11512
|
-
return {
|
|
11513
|
-
disposition: "unavailable",
|
|
11514
|
-
source: "unknown",
|
|
11515
|
-
reason: "Navigator attendance is uncorrelated with session invocation facts"
|
|
11516
|
-
};
|
|
11517
|
-
}
|
|
11518
|
-
return parseNavigatorAttendanceDetails(details);
|
|
11519
|
-
}
|
|
11469
|
+
if (entry?.type !== "custom" || entry.customType !== "ak-role-submission-closure") continue;
|
|
11470
|
+
const details = isRecord10(entry.data) ? entry.data.navigator : void 0;
|
|
11471
|
+
if (!isRecord10(details)) break;
|
|
11472
|
+
return parseNavigatorAttendanceDetails(details);
|
|
11520
11473
|
}
|
|
11521
11474
|
return {
|
|
11522
11475
|
disposition: "unavailable",
|
|
@@ -24121,8 +24074,15 @@ async function projectClosedSubmissionLifecycle(closed, context, phase, recordAc
|
|
|
24121
24074
|
isError: false,
|
|
24122
24075
|
details: closed.accepted
|
|
24123
24076
|
};
|
|
24124
|
-
|
|
24125
|
-
|
|
24077
|
+
let navigator;
|
|
24078
|
+
try {
|
|
24079
|
+
navigator = await settle(publicNavigatorSettlement(closed.role, phase, closure));
|
|
24080
|
+
} finally {
|
|
24081
|
+
context.sessionManager.appendCustomEntry?.("ak-role-submission-closure", {
|
|
24082
|
+
...closure,
|
|
24083
|
+
...navigator === void 0 ? {} : { navigator }
|
|
24084
|
+
});
|
|
24085
|
+
}
|
|
24126
24086
|
}
|
|
24127
24087
|
function createFiledOfficerRuntime(roleHost, spec, dependencies) {
|
|
24128
24088
|
let soul;
|
|
@@ -24481,6 +24441,8 @@ function createRoleRuntimeExtension(dependencies) {
|
|
|
24481
24441
|
let activeReviewerParent;
|
|
24482
24442
|
let navigatorAttendance;
|
|
24483
24443
|
let pendingNavigatorPresentation;
|
|
24444
|
+
let navigatorActivation = 0;
|
|
24445
|
+
let navigatorDeliveryClosed = false;
|
|
24484
24446
|
let pendingNavigatorSettlement;
|
|
24485
24447
|
let navigatorWorkContext;
|
|
24486
24448
|
let navigatorSessionParent;
|
|
@@ -24533,6 +24495,7 @@ function createRoleRuntimeExtension(dependencies) {
|
|
|
24533
24495
|
void settlePromise.catch(() => void 0);
|
|
24534
24496
|
const raced = await raceNavigatorGrace(settlePromise, NAVIGATOR_POST_ROLE_GRACE_MS);
|
|
24535
24497
|
if (raced.status !== "timeout") return;
|
|
24498
|
+
navigatorDeliveryClosed = true;
|
|
24536
24499
|
if (pendingNavigatorPresentation === void 0) {
|
|
24537
24500
|
const report = {
|
|
24538
24501
|
disposition: "unavailable",
|
|
@@ -24557,6 +24520,7 @@ function createRoleRuntimeExtension(dependencies) {
|
|
|
24557
24520
|
})();
|
|
24558
24521
|
pendingNavigatorSettlement = pending;
|
|
24559
24522
|
await pending;
|
|
24523
|
+
return pendingNavigatorPresentation?.event;
|
|
24560
24524
|
};
|
|
24561
24525
|
projectClosedSubmission = async (closed, context) => projectClosedSubmissionLifecycle(
|
|
24562
24526
|
closed,
|
|
@@ -25036,6 +25000,8 @@ function createRoleRuntimeExtension(dependencies) {
|
|
|
25036
25000
|
receiptDelivery = createReceiptDeliveryPolicy();
|
|
25037
25001
|
noReceiptRecorded = false;
|
|
25038
25002
|
pendingNavigatorPresentation = void 0;
|
|
25003
|
+
navigatorActivation += 1;
|
|
25004
|
+
navigatorDeliveryClosed = false;
|
|
25039
25005
|
pendingNavigatorSettlement = void 0;
|
|
25040
25006
|
pendingInfrastructureFailures.clear();
|
|
25041
25007
|
pendingSubmissionNonPassByToolCallId.clear();
|
|
@@ -25131,6 +25097,7 @@ function createRoleRuntimeExtension(dependencies) {
|
|
|
25131
25097
|
} catch {
|
|
25132
25098
|
}
|
|
25133
25099
|
}
|
|
25100
|
+
const activation = navigatorActivation;
|
|
25134
25101
|
navigatorAttendance = await dependencies.createNavigatorAttendance({
|
|
25135
25102
|
context: ctx,
|
|
25136
25103
|
role: entry.role,
|
|
@@ -25141,7 +25108,9 @@ function createRoleRuntimeExtension(dependencies) {
|
|
|
25141
25108
|
invocationId,
|
|
25142
25109
|
...contextError === void 0 ? {} : { contextError },
|
|
25143
25110
|
onEvent: (navigatorEvent, report) => {
|
|
25144
|
-
|
|
25111
|
+
if (activation === navigatorActivation && !navigatorDeliveryClosed) {
|
|
25112
|
+
pendingNavigatorPresentation = { event: navigatorEvent, report };
|
|
25113
|
+
}
|
|
25145
25114
|
}
|
|
25146
25115
|
});
|
|
25147
25116
|
if (navigatorWorkContext.contextError === void 0 && navigatorWorkContext.subjectProvenance !== "placeholder") {
|
|
@@ -146,47 +146,6 @@ function findLatestDurablePackagedRoleTerminal(entries) {
|
|
|
146
146
|
}
|
|
147
147
|
return void 0;
|
|
148
148
|
}
|
|
149
|
-
function bindCurrentDurableTerminalToMarker(entries) {
|
|
150
|
-
const terminal = findLatestDurablePackagedRoleTerminal(entries);
|
|
151
|
-
if (terminal === void 0) return { kind: "absent" };
|
|
152
|
-
let markerIndex = -1;
|
|
153
|
-
for (let i = terminal.index - 1; i >= 0; i -= 1) {
|
|
154
|
-
if (isInvocationMarkerEntry(entries[i])) {
|
|
155
|
-
markerIndex = i;
|
|
156
|
-
break;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
if (markerIndex < 0) {
|
|
160
|
-
return { kind: "unbound", terminal };
|
|
161
|
-
}
|
|
162
|
-
const marker = parseInvocationMarkerIdentity(entries[markerIndex]?.data);
|
|
163
|
-
if (marker === void 0) {
|
|
164
|
-
return { kind: "unbound", terminal };
|
|
165
|
-
}
|
|
166
|
-
let windowEnd = entries.length;
|
|
167
|
-
for (let i = markerIndex + 1; i < entries.length; i += 1) {
|
|
168
|
-
if (isInvocationMarkerEntry(entries[i])) {
|
|
169
|
-
windowEnd = i;
|
|
170
|
-
break;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
let durableCount = 0;
|
|
174
|
-
for (let i = markerIndex + 1; i < windowEnd; i += 1) {
|
|
175
|
-
if (durableTerminalAt(entries, i) !== void 0) durableCount += 1;
|
|
176
|
-
}
|
|
177
|
-
if (durableCount !== 1) return { kind: "ambiguous" };
|
|
178
|
-
if (terminal.index <= markerIndex || terminal.index >= windowEnd) {
|
|
179
|
-
return { kind: "ambiguous" };
|
|
180
|
-
}
|
|
181
|
-
return {
|
|
182
|
-
kind: "bound",
|
|
183
|
-
terminal,
|
|
184
|
-
marker: { ...marker, index: markerIndex }
|
|
185
|
-
};
|
|
186
|
-
}
|
|
187
|
-
function isReceiptSettlementBindingClear(entries) {
|
|
188
|
-
return bindCurrentDurableTerminalToMarker(entries).kind !== "ambiguous";
|
|
189
|
-
}
|
|
190
149
|
function resolveLifecycleInvocationPrincipal(entries, expected) {
|
|
191
150
|
const markerIndex = latestInvocationMarkerIndex(entries);
|
|
192
151
|
if (markerIndex < 0) {
|
|
@@ -206,35 +165,19 @@ function resolveLifecycleInvocationPrincipal(entries, expected) {
|
|
|
206
165
|
}
|
|
207
166
|
return { invocationId: marker.invocationId, resume: true };
|
|
208
167
|
}
|
|
209
|
-
function currentInvocationPrincipalFromSession(entries, beforeIndex = entries.length) {
|
|
210
|
-
return currentInvocationMarkerFromSession(entries, beforeIndex)?.invocationId;
|
|
211
|
-
}
|
|
212
|
-
function currentInvocationMarkerFromSession(entries, beforeIndex = entries.length) {
|
|
213
|
-
const limit = Math.min(Math.max(beforeIndex, 0), entries.length);
|
|
214
|
-
for (let i = limit - 1; i >= 0; i -= 1) {
|
|
215
|
-
const entry = entries[i];
|
|
216
|
-
if (!isInvocationMarkerEntry(entry)) continue;
|
|
217
|
-
return parseInvocationMarkerIdentity(entry?.data);
|
|
218
|
-
}
|
|
219
|
-
return void 0;
|
|
220
|
-
}
|
|
221
168
|
export {
|
|
222
169
|
NAVIGATOR_INFRASTRUCTURE_FAILURE_EVIDENCE_KEYS,
|
|
223
170
|
NAVIGATOR_INFRASTRUCTURE_FAILURE_KIND,
|
|
224
171
|
NAVIGATOR_INVOCATION_ENTRY,
|
|
225
172
|
NAVIGATOR_ROUTE_PLAYBOOK_FAILURE_ENTRY,
|
|
226
|
-
bindCurrentDurableTerminalToMarker,
|
|
227
173
|
buildNavigatorInfrastructureFailureFact,
|
|
228
174
|
classifyPackagedRoleTerminalResult,
|
|
229
|
-
currentInvocationMarkerFromSession,
|
|
230
|
-
currentInvocationPrincipalFromSession,
|
|
231
175
|
extractInfrastructureFailureEvidence,
|
|
232
176
|
findLatestDurablePackagedRoleTerminal,
|
|
233
177
|
hasNavigatorInfrastructureFailureBase,
|
|
234
178
|
isAcceptedPackagedRoleTerminalResult,
|
|
235
179
|
isDurablePackagedRoleTerminalResult,
|
|
236
180
|
isNavigatorInfrastructureFailureFact,
|
|
237
|
-
isReceiptSettlementBindingClear,
|
|
238
181
|
markerMatchesExpectedIdentity,
|
|
239
182
|
mintNavigatorInvocationId,
|
|
240
183
|
parseInvocationMarkerIdentity,
|
package/dist/public-cli/main.js
CHANGED
|
@@ -23840,11 +23840,6 @@ async function appendRunAttemptHistory(source, outcome) {
|
|
|
23840
23840
|
} catch {
|
|
23841
23841
|
}
|
|
23842
23842
|
}
|
|
23843
|
-
function navigatorAttendanceCorrelatedWithBoundMarker(details, attendanceIndex, terminalIndex, marker) {
|
|
23844
|
-
if (attendanceIndex <= terminalIndex) return false;
|
|
23845
|
-
if (details.invocationId !== marker.invocationId) return false;
|
|
23846
|
-
return true;
|
|
23847
|
-
}
|
|
23848
23843
|
function parseNavigatorAttendanceDetails(details) {
|
|
23849
23844
|
const disposition = details.disposition;
|
|
23850
23845
|
const advisoryDiagnostic = typeof details.routePlaybookReadFailure === "string" ? { advisoryDiagnostic: details.routePlaybookReadFailure } : {};
|
|
@@ -23995,54 +23990,12 @@ function extractNavigatorAttendanceFact(entries) {
|
|
|
23995
23990
|
reason: "Navigator attendance has no durable packaged role terminal"
|
|
23996
23991
|
};
|
|
23997
23992
|
}
|
|
23998
|
-
let
|
|
23999
|
-
for (let i = terminal.index - 1; i >= 0; i -= 1) {
|
|
24000
|
-
const entry = entries[i];
|
|
24001
|
-
if (entry?.type === "custom" && entry.customType === NAVIGATOR_INVOCATION_ENTRY) {
|
|
24002
|
-
markerIndex = i;
|
|
24003
|
-
break;
|
|
24004
|
-
}
|
|
24005
|
-
}
|
|
24006
|
-
if (markerIndex < 0) {
|
|
24007
|
-
return {
|
|
24008
|
-
disposition: "unavailable",
|
|
24009
|
-
source: "unknown",
|
|
24010
|
-
reason: "Navigator attendance is uncorrelated with session invocation facts"
|
|
24011
|
-
};
|
|
24012
|
-
}
|
|
24013
|
-
const marker = parseInvocationMarkerIdentity(entries[markerIndex]?.data);
|
|
24014
|
-
if (marker === void 0) {
|
|
24015
|
-
return {
|
|
24016
|
-
disposition: "unavailable",
|
|
24017
|
-
source: "unknown",
|
|
24018
|
-
reason: "Navigator attendance is uncorrelated with session invocation facts"
|
|
24019
|
-
};
|
|
24020
|
-
}
|
|
24021
|
-
for (let i = entries.length - 1; i >= 0; i -= 1) {
|
|
23993
|
+
for (let i = terminal.index; i < entries.length; i += 1) {
|
|
24022
23994
|
const entry = entries[i];
|
|
24023
|
-
if (entry?.type
|
|
24024
|
-
|
|
24025
|
-
|
|
24026
|
-
|
|
24027
|
-
disposition: "unavailable",
|
|
24028
|
-
source: "unknown",
|
|
24029
|
-
reason: "Navigator attendance is unparseable"
|
|
24030
|
-
};
|
|
24031
|
-
}
|
|
24032
|
-
if (!navigatorAttendanceCorrelatedWithBoundMarker(
|
|
24033
|
-
details,
|
|
24034
|
-
i,
|
|
24035
|
-
terminal.index,
|
|
24036
|
-
marker
|
|
24037
|
-
)) {
|
|
24038
|
-
return {
|
|
24039
|
-
disposition: "unavailable",
|
|
24040
|
-
source: "unknown",
|
|
24041
|
-
reason: "Navigator attendance is uncorrelated with session invocation facts"
|
|
24042
|
-
};
|
|
24043
|
-
}
|
|
24044
|
-
return parseNavigatorAttendanceDetails(details);
|
|
24045
|
-
}
|
|
23995
|
+
if (entry?.type !== "custom" || entry.customType !== "ak-role-submission-closure") continue;
|
|
23996
|
+
const details = isRecord8(entry.data) ? entry.data.navigator : void 0;
|
|
23997
|
+
if (!isRecord8(details)) break;
|
|
23998
|
+
return parseNavigatorAttendanceDetails(details);
|
|
24046
23999
|
}
|
|
24047
24000
|
return {
|
|
24048
24001
|
disposition: "unavailable",
|
|
@@ -26,7 +26,7 @@ import { DOCTOR_CANDIDATE_ENTRY_TYPE } from "../dossier-resolution.js";
|
|
|
26
26
|
import { REVIEWER_OUTPUT_TOOL_NAME, } from "../package-contracts/reviewer-output.js";
|
|
27
27
|
import { packagedAuditToolName, packagedDurableOfficerEntry, packagedRoleAcceptedOutputTool, packagedRoleMetadata, packagedSkipsGateOnInfrastructureStage, } from "../packaged-role-registry.js";
|
|
28
28
|
import { SECRETARIAT_COUNTERSIGN_TERMINAL_FACT_KEY, SECRETARIAT_GATE_OFFICER_ENTRY_TYPE, } from "../secretariat-contracts.js";
|
|
29
|
-
import { classifyPackagedRoleTerminalResult, findLatestDurablePackagedRoleTerminal, hasNavigatorInfrastructureFailureBase, isAcceptedPackagedRoleTerminalResult,
|
|
29
|
+
import { classifyPackagedRoleTerminalResult, findLatestDurablePackagedRoleTerminal, hasNavigatorInfrastructureFailureBase, isAcceptedPackagedRoleTerminalResult, NAVIGATOR_ROUTE_PLAYBOOK_FAILURE_ENTRY, } from "../navigator-invocation-identity.js";
|
|
30
30
|
import { NO_RECEIPT_LIFECYCLE_ENTRY_TYPE, RECEIPT_DELIVERY_TURN_LIMIT, noReceiptLifecycleFacts, parseNoReceiptLifecycleFacts, } from "../receipt-delivery-policy.js";
|
|
31
31
|
import { roleRunArtifactsDirectory } from "../role-run-placement.js";
|
|
32
32
|
import { rewriteRunDirectoryPathValue } from "../role-run-relocation.js";
|
|
@@ -1353,19 +1353,6 @@ export async function appendRunAttemptHistory(source, outcome) {
|
|
|
1353
1353
|
}
|
|
1354
1354
|
catch { }
|
|
1355
1355
|
}
|
|
1356
|
-
/**
|
|
1357
|
-
* Minimal attendance provenance against the bound marker (ADR 0043).
|
|
1358
|
-
* Keep only invocationId + post-terminal ordering. Runtime-self-produced
|
|
1359
|
-
* role/phase/subject/version are not re-reconciled here (ADR 0042).
|
|
1360
|
-
*/
|
|
1361
|
-
function navigatorAttendanceCorrelatedWithBoundMarker(details, attendanceIndex, terminalIndex, marker) {
|
|
1362
|
-
if (attendanceIndex <= terminalIndex)
|
|
1363
|
-
return false;
|
|
1364
|
-
// Exact current invocation token is the bound marker principal.
|
|
1365
|
-
if (details.invocationId !== marker.invocationId)
|
|
1366
|
-
return false;
|
|
1367
|
-
return true;
|
|
1368
|
-
}
|
|
1369
1356
|
function parseNavigatorAttendanceDetails(details) {
|
|
1370
1357
|
const disposition = details.disposition;
|
|
1371
1358
|
const advisoryDiagnostic = typeof details.routePlaybookReadFailure === "string"
|
|
@@ -1586,10 +1573,9 @@ export function extractNavigatorFact(entries) {
|
|
|
1586
1573
|
return message === undefined ? fact : { ...fact, advisoryDiagnostic: message };
|
|
1587
1574
|
}
|
|
1588
1575
|
function extractNavigatorAttendanceFact(entries) {
|
|
1589
|
-
// Affirmative attendance only. Missing /
|
|
1590
|
-
//
|
|
1591
|
-
//
|
|
1592
|
-
// receipt settlement (isReceiptSettlementBindingClear), not attendance extraction.
|
|
1576
|
+
// Affirmative attendance only. Missing / unparseable is never no-advice.
|
|
1577
|
+
// The shared lifecycle places the settled event on this submission's closure;
|
|
1578
|
+
// an unrelated attendance message cannot supply another call's result.
|
|
1593
1579
|
const terminal = findLatestDurablePackagedRoleTerminal(entries);
|
|
1594
1580
|
if (terminal === undefined) {
|
|
1595
1581
|
return {
|
|
@@ -1598,49 +1584,14 @@ function extractNavigatorAttendanceFact(entries) {
|
|
|
1598
1584
|
reason: "Navigator attendance has no durable packaged role terminal",
|
|
1599
1585
|
};
|
|
1600
1586
|
}
|
|
1601
|
-
let
|
|
1602
|
-
for (let i = terminal.index - 1; i >= 0; i -= 1) {
|
|
1587
|
+
for (let i = terminal.index; i < entries.length; i += 1) {
|
|
1603
1588
|
const entry = entries[i];
|
|
1604
|
-
if (entry?.type
|
|
1605
|
-
|
|
1589
|
+
if (entry?.type !== "custom" || entry.customType !== "ak-role-submission-closure")
|
|
1590
|
+
continue;
|
|
1591
|
+
const details = isRecord(entry.data) ? entry.data.navigator : undefined;
|
|
1592
|
+
if (!isRecord(details))
|
|
1606
1593
|
break;
|
|
1607
|
-
|
|
1608
|
-
}
|
|
1609
|
-
if (markerIndex < 0) {
|
|
1610
|
-
return {
|
|
1611
|
-
disposition: "unavailable",
|
|
1612
|
-
source: "unknown",
|
|
1613
|
-
reason: "Navigator attendance is uncorrelated with session invocation facts",
|
|
1614
|
-
};
|
|
1615
|
-
}
|
|
1616
|
-
const marker = parseInvocationMarkerIdentity(entries[markerIndex]?.data);
|
|
1617
|
-
if (marker === undefined) {
|
|
1618
|
-
return {
|
|
1619
|
-
disposition: "unavailable",
|
|
1620
|
-
source: "unknown",
|
|
1621
|
-
reason: "Navigator attendance is uncorrelated with session invocation facts",
|
|
1622
|
-
};
|
|
1623
|
-
}
|
|
1624
|
-
for (let i = entries.length - 1; i >= 0; i -= 1) {
|
|
1625
|
-
const entry = entries[i];
|
|
1626
|
-
if (entry?.type === "custom_message" && entry.customType === "ak-navigator-attendance") {
|
|
1627
|
-
const details = entry.message?.details ?? entry.details;
|
|
1628
|
-
if (!isRecord(details)) {
|
|
1629
|
-
return {
|
|
1630
|
-
disposition: "unavailable",
|
|
1631
|
-
source: "unknown",
|
|
1632
|
-
reason: "Navigator attendance is unparseable",
|
|
1633
|
-
};
|
|
1634
|
-
}
|
|
1635
|
-
if (!navigatorAttendanceCorrelatedWithBoundMarker(details, i, terminal.index, marker)) {
|
|
1636
|
-
return {
|
|
1637
|
-
disposition: "unavailable",
|
|
1638
|
-
source: "unknown",
|
|
1639
|
-
reason: "Navigator attendance is uncorrelated with session invocation facts",
|
|
1640
|
-
};
|
|
1641
|
-
}
|
|
1642
|
-
return parseNavigatorAttendanceDetails(details);
|
|
1643
|
-
}
|
|
1594
|
+
return parseNavigatorAttendanceDetails(details);
|
|
1644
1595
|
}
|
|
1645
1596
|
// Absence is not successful no-advice — require affirmative typed attendance.
|
|
1646
1597
|
return {
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Exact current-invocation principal for
|
|
2
|
+
* Exact current-invocation principal for shared role lifecycle (#1087).
|
|
3
3
|
* Shared role lifecycle owns one opaque uuidv7 per Role invocation and persists
|
|
4
4
|
* it on the role session via Pi's guaranteed `pi.appendEntry` boundary.
|
|
5
5
|
*
|
|
@@ -7,21 +7,14 @@
|
|
|
7
7
|
* unfinished exact-session resume reuses the latest valid marker only when its
|
|
8
8
|
* role/phase/subjectKey still match the expected identity; a packaged role
|
|
9
9
|
* terminal completing that marker starts the next invocation (fresh mint).
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* self-shape, markers after the terminal, or stale older markers behind a
|
|
13
|
-
* malformed nearest. Non-UUIDv7 principals are never accepted.
|
|
10
|
+
* Public settlement does not re-correlate attendance against this principal
|
|
11
|
+
* (ADR 0042); lifecycle dispose/grace owns call-boundary isolation (ADR 0084).
|
|
14
12
|
*
|
|
15
13
|
* One shared typed terminal classifier owns durable completion for lifecycle,
|
|
16
14
|
* publicNavigatorSettlement, and every public CLI Receipt extractor:
|
|
17
15
|
* - accepted/human: isError exactly false and no infrastructure-failure fact
|
|
18
16
|
* - infrastructure: isError exactly true plus base kind/source/reasonCode identity
|
|
19
17
|
* - retryable/missing/nonboolean/contradictory/malformed: nonterminal
|
|
20
|
-
*
|
|
21
|
-
* One truth table also owns marker↔terminal cardinality:
|
|
22
|
-
* - a marker binds exactly one durable packaged role terminal
|
|
23
|
-
* - multiple durable terminals after the same marker → ambiguous / fail-closed
|
|
24
|
-
* - marker role/phase/subjectKey must match the terminal + independent expected
|
|
25
18
|
*/
|
|
26
19
|
|
|
27
20
|
import { LEGACY_REVIEW_OUTPUT_ROLES, PACKAGED_ROLE_REGISTRY } from "./packaged-role-registry.ts";
|
|
@@ -147,7 +140,7 @@ export type InvocationMarkerIdentity = {
|
|
|
147
140
|
readonly subjectKey: string;
|
|
148
141
|
};
|
|
149
142
|
|
|
150
|
-
/** Independently admitted / registry / cwd expected identity for resume
|
|
143
|
+
/** Independently admitted / registry / cwd expected identity for lifecycle resume. */
|
|
151
144
|
export type ExpectedInvocationIdentity = {
|
|
152
145
|
readonly role: string;
|
|
153
146
|
readonly phase?: InvocationPhase;
|
|
@@ -342,83 +335,6 @@ export function findLatestDurablePackagedRoleTerminal(
|
|
|
342
335
|
return undefined;
|
|
343
336
|
}
|
|
344
337
|
|
|
345
|
-
/**
|
|
346
|
-
* Truth-table binding of the current durable packaged role terminal to its
|
|
347
|
-
* owning invocation marker. Singleton cardinality: multiple durable terminals
|
|
348
|
-
* after the same marker are ambiguous and fail closed.
|
|
349
|
-
*/
|
|
350
|
-
export type DurableTerminalMarkerBinding =
|
|
351
|
-
| {
|
|
352
|
-
readonly kind: "bound";
|
|
353
|
-
readonly terminal: DurablePackagedRoleTerminalRef;
|
|
354
|
-
readonly marker: InvocationMarkerIdentity & { readonly index: number };
|
|
355
|
-
}
|
|
356
|
-
| {
|
|
357
|
-
readonly kind: "unbound";
|
|
358
|
-
readonly terminal: DurablePackagedRoleTerminalRef;
|
|
359
|
-
}
|
|
360
|
-
| { readonly kind: "absent" }
|
|
361
|
-
| { readonly kind: "ambiguous" };
|
|
362
|
-
|
|
363
|
-
export function bindCurrentDurableTerminalToMarker(
|
|
364
|
-
entries: readonly NavigatorInvocationEntryLike[],
|
|
365
|
-
): DurableTerminalMarkerBinding {
|
|
366
|
-
const terminal = findLatestDurablePackagedRoleTerminal(entries);
|
|
367
|
-
if (terminal === undefined) return { kind: "absent" };
|
|
368
|
-
|
|
369
|
-
let markerIndex = -1;
|
|
370
|
-
for (let i = terminal.index - 1; i >= 0; i -= 1) {
|
|
371
|
-
if (isInvocationMarkerEntry(entries[i])) {
|
|
372
|
-
markerIndex = i;
|
|
373
|
-
break;
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
if (markerIndex < 0) {
|
|
377
|
-
return { kind: "unbound", terminal };
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
const marker = parseInvocationMarkerIdentity(entries[markerIndex]?.data);
|
|
381
|
-
if (marker === undefined) {
|
|
382
|
-
// Malformed nearest marker: no stale fallback; terminal exists but is unbound.
|
|
383
|
-
return { kind: "unbound", terminal };
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
let windowEnd = entries.length;
|
|
387
|
-
for (let i = markerIndex + 1; i < entries.length; i += 1) {
|
|
388
|
-
if (isInvocationMarkerEntry(entries[i])) {
|
|
389
|
-
windowEnd = i;
|
|
390
|
-
break;
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
let durableCount = 0;
|
|
395
|
-
for (let i = markerIndex + 1; i < windowEnd; i += 1) {
|
|
396
|
-
if (durableTerminalAt(entries, i) !== undefined) durableCount += 1;
|
|
397
|
-
}
|
|
398
|
-
if (durableCount !== 1) return { kind: "ambiguous" };
|
|
399
|
-
// Current terminal must be the singleton inside this marker window.
|
|
400
|
-
if (terminal.index <= markerIndex || terminal.index >= windowEnd) {
|
|
401
|
-
return { kind: "ambiguous" };
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
return {
|
|
405
|
-
kind: "bound",
|
|
406
|
-
terminal,
|
|
407
|
-
marker: { ...marker, index: markerIndex },
|
|
408
|
-
};
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
/**
|
|
412
|
-
* Whether public Receipt settlement may proceed for the current durable terminal.
|
|
413
|
-
* Only ambiguous multi-terminal bindings fail closed; attendance mismatch does not
|
|
414
|
-
* pollute an otherwise legal single Receipt.
|
|
415
|
-
*/
|
|
416
|
-
export function isReceiptSettlementBindingClear(
|
|
417
|
-
entries: readonly NavigatorInvocationEntryLike[],
|
|
418
|
-
): boolean {
|
|
419
|
-
return bindCurrentDurableTerminalToMarker(entries).kind !== "ambiguous";
|
|
420
|
-
}
|
|
421
|
-
|
|
422
338
|
export type LifecycleInvocationPrincipal = {
|
|
423
339
|
readonly invocationId: string;
|
|
424
340
|
/** True when the principal is already on the admitted session (resume; do not re-append). */
|
|
@@ -463,36 +379,3 @@ export function resolveLifecycleInvocationPrincipal(
|
|
|
463
379
|
|
|
464
380
|
return { invocationId: marker.invocationId, resume: true };
|
|
465
381
|
}
|
|
466
|
-
|
|
467
|
-
/**
|
|
468
|
-
* Exact current invocation principal already present on the role session.
|
|
469
|
-
* `beforeIndex` is the current packaged role terminal index: only the nearest
|
|
470
|
-
* marker strictly before that bound is applicable. A malformed nearest marker
|
|
471
|
-
* fails closed (undefined) — never falls back to a stale older valid marker.
|
|
472
|
-
* Markers at/after the terminal (future prepare/event) are never considered.
|
|
473
|
-
* Non-UUIDv7 values are rejected.
|
|
474
|
-
*/
|
|
475
|
-
export function currentInvocationPrincipalFromSession(
|
|
476
|
-
entries: readonly NavigatorInvocationEntryLike[],
|
|
477
|
-
beforeIndex: number = entries.length,
|
|
478
|
-
): string | undefined {
|
|
479
|
-
return currentInvocationMarkerFromSession(entries, beforeIndex)?.invocationId;
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
/**
|
|
483
|
-
* Full marker identity nearest before `beforeIndex` (current durable terminal).
|
|
484
|
-
* Malformed nearest fails closed — no stale older fallback.
|
|
485
|
-
*/
|
|
486
|
-
export function currentInvocationMarkerFromSession(
|
|
487
|
-
entries: readonly NavigatorInvocationEntryLike[],
|
|
488
|
-
beforeIndex: number = entries.length,
|
|
489
|
-
): InvocationMarkerIdentity | undefined {
|
|
490
|
-
const limit = Math.min(Math.max(beforeIndex, 0), entries.length);
|
|
491
|
-
for (let i = limit - 1; i >= 0; i -= 1) {
|
|
492
|
-
const entry = entries[i];
|
|
493
|
-
if (!isInvocationMarkerEntry(entry)) continue;
|
|
494
|
-
// Nearest marker only — parse full identity or fail closed.
|
|
495
|
-
return parseInvocationMarkerIdentity(entry?.data);
|
|
496
|
-
}
|
|
497
|
-
return undefined;
|
|
498
|
-
}
|
|
@@ -88,11 +88,7 @@ import {
|
|
|
88
88
|
findLatestDurablePackagedRoleTerminal,
|
|
89
89
|
hasNavigatorInfrastructureFailureBase,
|
|
90
90
|
isAcceptedPackagedRoleTerminalResult,
|
|
91
|
-
isReceiptSettlementBindingClear,
|
|
92
|
-
NAVIGATOR_INVOCATION_ENTRY,
|
|
93
91
|
NAVIGATOR_ROUTE_PLAYBOOK_FAILURE_ENTRY,
|
|
94
|
-
parseInvocationMarkerIdentity,
|
|
95
|
-
type InvocationMarkerIdentity,
|
|
96
92
|
} from "../navigator-invocation-identity.ts";
|
|
97
93
|
import {
|
|
98
94
|
NO_RECEIPT_LIFECYCLE_ENTRY_TYPE,
|
|
@@ -1921,23 +1917,6 @@ export async function appendRunAttemptHistory(
|
|
|
1921
1917
|
} catch {}
|
|
1922
1918
|
}
|
|
1923
1919
|
|
|
1924
|
-
/**
|
|
1925
|
-
* Minimal attendance provenance against the bound marker (ADR 0043).
|
|
1926
|
-
* Keep only invocationId + post-terminal ordering. Runtime-self-produced
|
|
1927
|
-
* role/phase/subject/version are not re-reconciled here (ADR 0042).
|
|
1928
|
-
*/
|
|
1929
|
-
function navigatorAttendanceCorrelatedWithBoundMarker(
|
|
1930
|
-
details: Record<string, unknown>,
|
|
1931
|
-
attendanceIndex: number,
|
|
1932
|
-
terminalIndex: number,
|
|
1933
|
-
marker: InvocationMarkerIdentity,
|
|
1934
|
-
): boolean {
|
|
1935
|
-
if (attendanceIndex <= terminalIndex) return false;
|
|
1936
|
-
// Exact current invocation token is the bound marker principal.
|
|
1937
|
-
if (details.invocationId !== marker.invocationId) return false;
|
|
1938
|
-
return true;
|
|
1939
|
-
}
|
|
1940
|
-
|
|
1941
1920
|
function parseNavigatorAttendanceDetails(
|
|
1942
1921
|
details: Record<string, unknown>,
|
|
1943
1922
|
): TerminalNavigatorFact {
|
|
@@ -2216,10 +2195,9 @@ export function extractNavigatorFact(
|
|
|
2216
2195
|
function extractNavigatorAttendanceFact(
|
|
2217
2196
|
entries: readonly SessionEntry[],
|
|
2218
2197
|
): TerminalNavigatorFact {
|
|
2219
|
-
// Affirmative attendance only. Missing /
|
|
2220
|
-
//
|
|
2221
|
-
//
|
|
2222
|
-
// receipt settlement (isReceiptSettlementBindingClear), not attendance extraction.
|
|
2198
|
+
// Affirmative attendance only. Missing / unparseable is never no-advice.
|
|
2199
|
+
// The shared lifecycle places the settled event on this submission's closure;
|
|
2200
|
+
// an unrelated attendance message cannot supply another call's result.
|
|
2223
2201
|
const terminal = findLatestDurablePackagedRoleTerminal(entries);
|
|
2224
2202
|
if (terminal === undefined) {
|
|
2225
2203
|
return {
|
|
@@ -2229,57 +2207,12 @@ function extractNavigatorAttendanceFact(
|
|
|
2229
2207
|
};
|
|
2230
2208
|
}
|
|
2231
2209
|
|
|
2232
|
-
let
|
|
2233
|
-
for (let i = terminal.index - 1; i >= 0; i -= 1) {
|
|
2234
|
-
const entry = entries[i];
|
|
2235
|
-
if (entry?.type === "custom" && entry.customType === NAVIGATOR_INVOCATION_ENTRY) {
|
|
2236
|
-
markerIndex = i;
|
|
2237
|
-
break;
|
|
2238
|
-
}
|
|
2239
|
-
}
|
|
2240
|
-
if (markerIndex < 0) {
|
|
2241
|
-
return {
|
|
2242
|
-
disposition: "unavailable",
|
|
2243
|
-
source: "unknown",
|
|
2244
|
-
reason: "Navigator attendance is uncorrelated with session invocation facts",
|
|
2245
|
-
};
|
|
2246
|
-
}
|
|
2247
|
-
const marker = parseInvocationMarkerIdentity(entries[markerIndex]?.data);
|
|
2248
|
-
if (marker === undefined) {
|
|
2249
|
-
return {
|
|
2250
|
-
disposition: "unavailable",
|
|
2251
|
-
source: "unknown",
|
|
2252
|
-
reason: "Navigator attendance is uncorrelated with session invocation facts",
|
|
2253
|
-
};
|
|
2254
|
-
}
|
|
2255
|
-
|
|
2256
|
-
for (let i = entries.length - 1; i >= 0; i -= 1) {
|
|
2210
|
+
for (let i = terminal.index; i < entries.length; i += 1) {
|
|
2257
2211
|
const entry = entries[i];
|
|
2258
|
-
if (entry?.type
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
disposition: "unavailable",
|
|
2263
|
-
source: "unknown",
|
|
2264
|
-
reason: "Navigator attendance is unparseable",
|
|
2265
|
-
};
|
|
2266
|
-
}
|
|
2267
|
-
if (
|
|
2268
|
-
!navigatorAttendanceCorrelatedWithBoundMarker(
|
|
2269
|
-
details,
|
|
2270
|
-
i,
|
|
2271
|
-
terminal.index,
|
|
2272
|
-
marker,
|
|
2273
|
-
)
|
|
2274
|
-
) {
|
|
2275
|
-
return {
|
|
2276
|
-
disposition: "unavailable",
|
|
2277
|
-
source: "unknown",
|
|
2278
|
-
reason: "Navigator attendance is uncorrelated with session invocation facts",
|
|
2279
|
-
};
|
|
2280
|
-
}
|
|
2281
|
-
return parseNavigatorAttendanceDetails(details);
|
|
2282
|
-
}
|
|
2212
|
+
if (entry?.type !== "custom" || entry.customType !== "ak-role-submission-closure") continue;
|
|
2213
|
+
const details = isRecord(entry.data) ? entry.data.navigator : undefined;
|
|
2214
|
+
if (!isRecord(details)) break;
|
|
2215
|
+
return parseNavigatorAttendanceDetails(details);
|
|
2283
2216
|
}
|
|
2284
2217
|
// Absence is not successful no-advice — require affirmative typed attendance.
|
|
2285
2218
|
return {
|
package/src/role-runtime.ts
CHANGED
|
@@ -523,7 +523,7 @@ export async function projectClosedSubmissionLifecycle(
|
|
|
523
523
|
context: HostContext,
|
|
524
524
|
phase: NavigatorPhase,
|
|
525
525
|
recordAccepted: () => void,
|
|
526
|
-
settle: (settlement: NavigatorSettlement | undefined) => Promise<
|
|
526
|
+
settle: (settlement: NavigatorSettlement | undefined) => Promise<NavigatorEvent | undefined>,
|
|
527
527
|
): Promise<void> {
|
|
528
528
|
recordAccepted();
|
|
529
529
|
const closure = {
|
|
@@ -531,8 +531,17 @@ export async function projectClosedSubmissionLifecycle(
|
|
|
531
531
|
isError: false,
|
|
532
532
|
details: closed.accepted,
|
|
533
533
|
};
|
|
534
|
-
|
|
535
|
-
|
|
534
|
+
let navigator: NavigatorEvent | undefined;
|
|
535
|
+
try {
|
|
536
|
+
navigator = await settle(publicNavigatorSettlement(closed.role, phase, closure));
|
|
537
|
+
} finally {
|
|
538
|
+
// A Navigator failure cannot erase an already accepted role closure.
|
|
539
|
+
// Missing attendance remains a typed unavailable at public settlement.
|
|
540
|
+
context.sessionManager.appendCustomEntry?.("ak-role-submission-closure", {
|
|
541
|
+
...closure,
|
|
542
|
+
...(navigator === undefined ? {} : { navigator }),
|
|
543
|
+
});
|
|
544
|
+
}
|
|
536
545
|
}
|
|
537
546
|
|
|
538
547
|
/**
|
|
@@ -1032,6 +1041,8 @@ export function createRoleRuntimeExtension(
|
|
|
1032
1041
|
let navigatorAttendance: NavigatorAttendanceDependency | undefined;
|
|
1033
1042
|
// #351: session-lifecycle owner for periodic OAuth refresh (orthogonal to role admission).
|
|
1034
1043
|
let pendingNavigatorPresentation: { event: import("./navigator-attendance.ts").NavigatorEvent; report: import("./navigator-attendance.ts").NavigatorReport } | undefined;
|
|
1044
|
+
let navigatorActivation = 0;
|
|
1045
|
+
let navigatorDeliveryClosed = false;
|
|
1035
1046
|
let pendingNavigatorSettlement: Promise<void> | undefined;
|
|
1036
1047
|
let navigatorWorkContext: NavigatorWorkContext | undefined;
|
|
1037
1048
|
let navigatorSessionParent: string | undefined;
|
|
@@ -1085,7 +1096,7 @@ export function createRoleRuntimeExtension(
|
|
|
1085
1096
|
}
|
|
1086
1097
|
void Promise.resolve(pending).then(undefined, recordDisposeFailure);
|
|
1087
1098
|
};
|
|
1088
|
-
const settleNavigatorProjection = async (settlement: NavigatorSettlement | undefined) => {
|
|
1099
|
+
const settleNavigatorProjection = async (settlement: NavigatorSettlement | undefined): Promise<NavigatorEvent | undefined> => {
|
|
1089
1100
|
const attendance = navigatorAttendance;
|
|
1090
1101
|
if (settlement === undefined || attendance === undefined) return;
|
|
1091
1102
|
const workContext = navigatorWorkContext;
|
|
@@ -1099,6 +1110,7 @@ export function createRoleRuntimeExtension(
|
|
|
1099
1110
|
void settlePromise.catch(() => undefined);
|
|
1100
1111
|
const raced = await raceNavigatorGrace(settlePromise, NAVIGATOR_POST_ROLE_GRACE_MS);
|
|
1101
1112
|
if (raced.status !== "timeout") return;
|
|
1113
|
+
navigatorDeliveryClosed = true;
|
|
1102
1114
|
if (pendingNavigatorPresentation === undefined) {
|
|
1103
1115
|
const report: NavigatorReport = {
|
|
1104
1116
|
disposition: "unavailable",
|
|
@@ -1124,6 +1136,7 @@ export function createRoleRuntimeExtension(
|
|
|
1124
1136
|
})();
|
|
1125
1137
|
pendingNavigatorSettlement = pending;
|
|
1126
1138
|
await pending;
|
|
1139
|
+
return pendingNavigatorPresentation?.event;
|
|
1127
1140
|
};
|
|
1128
1141
|
projectClosedSubmission = async (closed, context) => projectClosedSubmissionLifecycle(
|
|
1129
1142
|
closed,
|
|
@@ -1695,6 +1708,8 @@ export function createRoleRuntimeExtension(
|
|
|
1695
1708
|
receiptDelivery = createReceiptDeliveryPolicy();
|
|
1696
1709
|
noReceiptRecorded = false;
|
|
1697
1710
|
pendingNavigatorPresentation = undefined;
|
|
1711
|
+
navigatorActivation += 1;
|
|
1712
|
+
navigatorDeliveryClosed = false;
|
|
1698
1713
|
pendingNavigatorSettlement = undefined;
|
|
1699
1714
|
pendingInfrastructureFailures.clear();
|
|
1700
1715
|
pendingSubmissionNonPassByToolCallId.clear();
|
|
@@ -1811,6 +1826,7 @@ export function createRoleRuntimeExtension(
|
|
|
1811
1826
|
});
|
|
1812
1827
|
} catch {}
|
|
1813
1828
|
}
|
|
1829
|
+
const activation = navigatorActivation;
|
|
1814
1830
|
navigatorAttendance = await dependencies.createNavigatorAttendance({
|
|
1815
1831
|
context: ctx,
|
|
1816
1832
|
role: entry.role,
|
|
@@ -1821,7 +1837,9 @@ export function createRoleRuntimeExtension(
|
|
|
1821
1837
|
invocationId,
|
|
1822
1838
|
...(contextError === undefined ? {} : { contextError }),
|
|
1823
1839
|
onEvent: (navigatorEvent, report) => {
|
|
1824
|
-
|
|
1840
|
+
if (activation === navigatorActivation && !navigatorDeliveryClosed) {
|
|
1841
|
+
pendingNavigatorPresentation = { event: navigatorEvent, report };
|
|
1842
|
+
}
|
|
1825
1843
|
},
|
|
1826
1844
|
});
|
|
1827
1845
|
// Concrete work context starts standby attendance (record only, no model).
|