@akagilnc/pi-workflow-roles 0.1.4239 → 0.1.4259
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/dist/acp-host/production-host.js +547 -221
- package/dist/engine-detour-tool.js +64 -5
- package/dist/engine-detour-usage.js +285 -0
- package/dist/headless-host/production-host.js +557 -231
- package/dist/pi/role-turn-host.js +10 -0
- package/dist/public-cli/main.js +433 -202
- package/dist/public-cli/post-admission.js +72 -43
- package/dist/public-cli/settlement.js +80 -24
- package/dist/public-cli/turn-request.js +3 -0
- package/package.json +1 -1
- package/src/engine-detour-tool.ts +106 -8
- package/src/engine-detour-usage.ts +373 -0
- package/src/host-contracts.ts +12 -1
- package/src/pi/adapter.ts +6 -0
- package/src/pi/role-turn-host.ts +6 -0
- package/src/public-cli/post-admission.ts +91 -49
- package/src/public-cli/settlement.ts +148 -23
- package/src/public-cli/turn-request.ts +5 -0
- package/src/role-envelope.ts +2 -0
|
@@ -51,6 +51,14 @@ import {
|
|
|
51
51
|
COLLECTOR_WAIT_TOOL,
|
|
52
52
|
} from "../collector-ledger.ts";
|
|
53
53
|
import { ENGINE_DETOUR_TOOL_NAME } from "../engine-detour.ts";
|
|
54
|
+
import {
|
|
55
|
+
projectEngineDetourToolUsageForPublicTerminal,
|
|
56
|
+
readEngineDetourToolUsage,
|
|
57
|
+
readInvocationEngineMounted,
|
|
58
|
+
runDirectoryFromSessionDirectory,
|
|
59
|
+
sessionFileFromSessionDirectory,
|
|
60
|
+
withEngineDetourToolUsageFact,
|
|
61
|
+
} from "../engine-detour-usage.ts";
|
|
54
62
|
import {
|
|
55
63
|
JUDGE_OUTPUT_TOOL_NAME,
|
|
56
64
|
type JudgeVerdict,
|
|
@@ -158,6 +166,8 @@ function sealedLedgerHome(admitted: Pick<AdmittedRoleInvocation, "runDirectory">
|
|
|
158
166
|
*/
|
|
159
167
|
export type SettlementCourtScope = {
|
|
160
168
|
readonly courtAttemptId?: string;
|
|
169
|
+
/** Public-invocation scope from the shared Host envelope (#537). */
|
|
170
|
+
readonly invocationScopeId?: string;
|
|
161
171
|
};
|
|
162
172
|
|
|
163
173
|
function ledgerReadScope(
|
|
@@ -300,6 +310,7 @@ export async function attachRecordedSubmissions<T extends TerminalResult>(
|
|
|
300
310
|
export async function settleHostEndedNoReceipt(
|
|
301
311
|
admitted: AdmittedRoleInvocation,
|
|
302
312
|
authority: DurablePrincipalAuthority,
|
|
313
|
+
scope?: SettlementCourtScope,
|
|
303
314
|
): Promise<TerminalResult> {
|
|
304
315
|
const facts = noReceiptLifecycleFacts({
|
|
305
316
|
terminalToolCalled: false,
|
|
@@ -323,6 +334,7 @@ export async function settleHostEndedNoReceipt(
|
|
|
323
334
|
runId: admitted.runId,
|
|
324
335
|
},
|
|
325
336
|
coordinates.sessionDirectory,
|
|
337
|
+
detourGateContext(admitted, scope),
|
|
326
338
|
);
|
|
327
339
|
}
|
|
328
340
|
|
|
@@ -2187,11 +2199,86 @@ export async function extractGateFactFromSessionDirectory(
|
|
|
2187
2199
|
* or swallowed); callers that already hold a controlled failure still surface the
|
|
2188
2200
|
* JSONL/session cause rather than pretend the gate was absent.
|
|
2189
2201
|
*/
|
|
2202
|
+
/**
|
|
2203
|
+
* #537: project this-invocation ak_engine_detour usage onto decisiveFacts.
|
|
2204
|
+
* Absent when engine is not mounted; callCount 0 when mounted with zero calls.
|
|
2205
|
+
* Never mutates role payloads (ADR 0003 / 0042 / 0052).
|
|
2206
|
+
* Scope is the public-invocation id bound once per ak-role call — never
|
|
2207
|
+
* courtAttemptId and never Pi session.jsonl toolResult join. Session damage
|
|
2208
|
+
* therefore cannot replace an already-formed roleOutcome (no_receipt / failure).
|
|
2209
|
+
*/
|
|
2210
|
+
async function attachEngineDetourToolUsage<
|
|
2211
|
+
T extends { roleOutcome: TerminalRoleOutcome; resume?: TerminalResume },
|
|
2212
|
+
>(
|
|
2213
|
+
base: T,
|
|
2214
|
+
sessionDirectory: string,
|
|
2215
|
+
gateContext: {
|
|
2216
|
+
readonly runDirectory?: string;
|
|
2217
|
+
readonly courtAttemptId?: string;
|
|
2218
|
+
readonly invocationScopeId?: string;
|
|
2219
|
+
} = {},
|
|
2220
|
+
): Promise<T> {
|
|
2221
|
+
const runDirectory =
|
|
2222
|
+
typeof gateContext.runDirectory === "string" && gateContext.runDirectory.length > 0
|
|
2223
|
+
? gateContext.runDirectory
|
|
2224
|
+
: runDirectoryFromSessionDirectory(sessionDirectory);
|
|
2225
|
+
const engineMounted = await readInvocationEngineMounted(runDirectory);
|
|
2226
|
+
if (!engineMounted) return base;
|
|
2227
|
+
|
|
2228
|
+
// Public-invocation scope from the shared Host envelope (settlement scope), never
|
|
2229
|
+
// courtAttemptId and never a detour sidecar file.
|
|
2230
|
+
const invocationScopeId =
|
|
2231
|
+
typeof gateContext.invocationScopeId === "string" &&
|
|
2232
|
+
gateContext.invocationScopeId.length > 0
|
|
2233
|
+
? gateContext.invocationScopeId
|
|
2234
|
+
: undefined;
|
|
2235
|
+
|
|
2236
|
+
const sessionFile = sessionFileFromSessionDirectory(sessionDirectory);
|
|
2237
|
+
const usage = await readEngineDetourToolUsage({
|
|
2238
|
+
sessionParent: sessionFile,
|
|
2239
|
+
engineMounted: true,
|
|
2240
|
+
...(invocationScopeId === undefined ? {} : { invocationScopeId }),
|
|
2241
|
+
cwd: runDirectory,
|
|
2242
|
+
});
|
|
2243
|
+
const projected =
|
|
2244
|
+
usage === undefined
|
|
2245
|
+
? undefined
|
|
2246
|
+
: projectEngineDetourToolUsageForPublicTerminal(usage, {
|
|
2247
|
+
// Resumable Terminal: run ID only in resume.command — relative openable path.
|
|
2248
|
+
discloseRecordFile: base.resume === undefined,
|
|
2249
|
+
});
|
|
2250
|
+
return {
|
|
2251
|
+
...base,
|
|
2252
|
+
roleOutcome: withEngineDetourToolUsageFact(base.roleOutcome, projected),
|
|
2253
|
+
};
|
|
2254
|
+
}
|
|
2255
|
+
|
|
2256
|
+
/** Gate + detour projection context from admitted run + settlement scope. */
|
|
2257
|
+
function detourGateContext(
|
|
2258
|
+
admitted: { readonly runDirectory: string },
|
|
2259
|
+
scope?: SettlementCourtScope,
|
|
2260
|
+
): {
|
|
2261
|
+
readonly runDirectory: string;
|
|
2262
|
+
readonly courtAttemptId?: string;
|
|
2263
|
+
readonly invocationScopeId?: string;
|
|
2264
|
+
} {
|
|
2265
|
+
return {
|
|
2266
|
+
runDirectory: admitted.runDirectory,
|
|
2267
|
+
...(scope?.courtAttemptId === undefined || scope.courtAttemptId.length === 0
|
|
2268
|
+
? {}
|
|
2269
|
+
: { courtAttemptId: scope.courtAttemptId }),
|
|
2270
|
+
...(scope?.invocationScopeId === undefined || scope.invocationScopeId.length === 0
|
|
2271
|
+
? {}
|
|
2272
|
+
: { invocationScopeId: scope.invocationScopeId }),
|
|
2273
|
+
};
|
|
2274
|
+
}
|
|
2275
|
+
|
|
2190
2276
|
async function withOptionalGateProjection<
|
|
2191
2277
|
T extends {
|
|
2192
2278
|
roleOutcome: TerminalRoleOutcome;
|
|
2193
2279
|
navigator: TerminalNavigatorFact;
|
|
2194
2280
|
artifacts: readonly TerminalArtifactRef[];
|
|
2281
|
+
resume?: TerminalResume;
|
|
2195
2282
|
},
|
|
2196
2283
|
>(
|
|
2197
2284
|
base: T,
|
|
@@ -2199,6 +2286,8 @@ async function withOptionalGateProjection<
|
|
|
2199
2286
|
gateContext: {
|
|
2200
2287
|
readonly runDirectory?: string;
|
|
2201
2288
|
readonly parentSessionFile?: string;
|
|
2289
|
+
readonly courtAttemptId?: string;
|
|
2290
|
+
readonly invocationScopeId?: string;
|
|
2202
2291
|
} = {},
|
|
2203
2292
|
): Promise<T & { gate?: TerminalGateFact }> {
|
|
2204
2293
|
// A gate transport failure is already represented by typed evidence and has no
|
|
@@ -2207,19 +2296,23 @@ async function withOptionalGateProjection<
|
|
|
2207
2296
|
const secondaryEvidence = base.roleOutcome.kind === "failure"
|
|
2208
2297
|
? base.roleOutcome.decisiveFacts.secondaryEvidence
|
|
2209
2298
|
: undefined;
|
|
2210
|
-
|
|
2299
|
+
const skipGate =
|
|
2211
2300
|
isRecord(secondaryEvidence)
|
|
2212
2301
|
&& secondaryEvidence.kind === "role_infrastructure_failure"
|
|
2213
2302
|
&& (
|
|
2214
2303
|
secondaryEvidence.stage === "gatekeeper"
|
|
2215
2304
|
|| secondaryEvidence.stage === "inspector"
|
|
2216
2305
|
|| secondaryEvidence.stage === "notary"
|
|
2217
|
-
)
|
|
2218
|
-
|
|
2306
|
+
);
|
|
2307
|
+
|
|
2308
|
+
let next: T & { gate?: TerminalGateFact } = base;
|
|
2309
|
+
if (!skipGate) {
|
|
2310
|
+
// Defaults live solely in extractGateFactFromSessionDirectory — do not re-derive.
|
|
2311
|
+
const gate = await extractGateFactFromSessionDirectory(sessionDirectory, gateContext);
|
|
2312
|
+
if (gate !== undefined) next = { ...base, gate };
|
|
2313
|
+
}
|
|
2219
2314
|
|
|
2220
|
-
|
|
2221
|
-
const gate = await extractGateFactFromSessionDirectory(sessionDirectory, gateContext);
|
|
2222
|
-
return gate === undefined ? base : { ...base, gate };
|
|
2315
|
+
return attachEngineDetourToolUsage(next, sessionDirectory, gateContext);
|
|
2223
2316
|
}
|
|
2224
2317
|
|
|
2225
2318
|
export function extractNavigatorFact(
|
|
@@ -2508,6 +2601,7 @@ async function settleLawfulJudgeTerminalResult(
|
|
|
2508
2601
|
runId: admitted.runId,
|
|
2509
2602
|
},
|
|
2510
2603
|
coordinates.sessionDirectory,
|
|
2604
|
+
detourGateContext(admitted, scope),
|
|
2511
2605
|
);
|
|
2512
2606
|
}
|
|
2513
2607
|
|
|
@@ -2575,6 +2669,7 @@ async function settleLawfulCoderTerminalResult(
|
|
|
2575
2669
|
runId: admitted.runId,
|
|
2576
2670
|
},
|
|
2577
2671
|
coordinates.sessionDirectory,
|
|
2672
|
+
detourGateContext(admitted, scope),
|
|
2578
2673
|
);
|
|
2579
2674
|
}
|
|
2580
2675
|
|
|
@@ -2751,6 +2846,7 @@ async function settleLawfulFixerTerminalResult(
|
|
|
2751
2846
|
runId: admitted.runId,
|
|
2752
2847
|
},
|
|
2753
2848
|
sessionDirectory,
|
|
2849
|
+
detourGateContext(admitted, scope),
|
|
2754
2850
|
);
|
|
2755
2851
|
}
|
|
2756
2852
|
|
|
@@ -2848,11 +2944,16 @@ async function settleLawfulCollectorTerminalResult(
|
|
|
2848
2944
|
if (residual === undefined) continue;
|
|
2849
2945
|
const candidate = residual.candidate;
|
|
2850
2946
|
const details = isRecord(candidate) ? candidate : { candidate };
|
|
2851
|
-
const failed = await settleFailureTerminalResult(
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2947
|
+
const failed = await settleFailureTerminalResult(
|
|
2948
|
+
admitted,
|
|
2949
|
+
{
|
|
2950
|
+
cause: "output",
|
|
2951
|
+
diagnostic: residual.diagnostic,
|
|
2952
|
+
details,
|
|
2953
|
+
},
|
|
2954
|
+
authority,
|
|
2955
|
+
scope ?? {},
|
|
2956
|
+
);
|
|
2856
2957
|
return attachRecordedSubmissions(admitted, failed, scope);
|
|
2857
2958
|
}
|
|
2858
2959
|
return undefined;
|
|
@@ -2874,6 +2975,7 @@ async function settleLawfulCollectorTerminalResult(
|
|
|
2874
2975
|
runId: admitted.runId,
|
|
2875
2976
|
},
|
|
2876
2977
|
sessionDirectory,
|
|
2978
|
+
detourGateContext(admitted, scope),
|
|
2877
2979
|
),
|
|
2878
2980
|
scope,
|
|
2879
2981
|
);
|
|
@@ -3025,6 +3127,7 @@ async function settleLawfulDoctorTerminalResult(
|
|
|
3025
3127
|
runId: admitted.runId,
|
|
3026
3128
|
},
|
|
3027
3129
|
sessionDirectory,
|
|
3130
|
+
detourGateContext(admitted, scope),
|
|
3028
3131
|
);
|
|
3029
3132
|
}
|
|
3030
3133
|
const roleOutcome = sealed;
|
|
@@ -3048,6 +3151,7 @@ async function settleLawfulDoctorTerminalResult(
|
|
|
3048
3151
|
runId: admitted.runId,
|
|
3049
3152
|
},
|
|
3050
3153
|
sessionDirectory,
|
|
3154
|
+
detourGateContext(admitted, scope),
|
|
3051
3155
|
);
|
|
3052
3156
|
}
|
|
3053
3157
|
|
|
@@ -3137,11 +3241,16 @@ async function settleLawfulSeatAcceptedTerminalResult(
|
|
|
3137
3241
|
const details = isRecord(residual.candidate)
|
|
3138
3242
|
? residual.candidate
|
|
3139
3243
|
: { candidate: residual.candidate };
|
|
3140
|
-
const failed = await settleFailureTerminalResult(
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3244
|
+
const failed = await settleFailureTerminalResult(
|
|
3245
|
+
admitted,
|
|
3246
|
+
{
|
|
3247
|
+
cause: "output",
|
|
3248
|
+
diagnostic: residual.diagnostic,
|
|
3249
|
+
details,
|
|
3250
|
+
},
|
|
3251
|
+
authority,
|
|
3252
|
+
scope ?? {},
|
|
3253
|
+
);
|
|
3145
3254
|
return withSubmissions(failed, submissions);
|
|
3146
3255
|
}
|
|
3147
3256
|
}
|
|
@@ -3157,6 +3266,7 @@ async function settleLawfulSeatAcceptedTerminalResult(
|
|
|
3157
3266
|
runId: admitted.runId,
|
|
3158
3267
|
},
|
|
3159
3268
|
sessionDirectory,
|
|
3269
|
+
detourGateContext(admitted, scope),
|
|
3160
3270
|
),
|
|
3161
3271
|
submissions,
|
|
3162
3272
|
);
|
|
@@ -3172,6 +3282,7 @@ async function settleLawfulSeatAcceptedTerminalResult(
|
|
|
3172
3282
|
runId: admitted.runId,
|
|
3173
3283
|
},
|
|
3174
3284
|
sessionDirectory,
|
|
3285
|
+
detourGateContext(admitted, scope),
|
|
3175
3286
|
),
|
|
3176
3287
|
submissions,
|
|
3177
3288
|
);
|
|
@@ -3568,6 +3679,7 @@ async function settleLawfulReviewerTerminalResult(
|
|
|
3568
3679
|
runId: admitted.runId,
|
|
3569
3680
|
},
|
|
3570
3681
|
sessionDirectory,
|
|
3682
|
+
detourGateContext(admitted, scope),
|
|
3571
3683
|
);
|
|
3572
3684
|
}
|
|
3573
3685
|
|
|
@@ -3720,11 +3832,16 @@ async function settleLawfulMergerTerminalResult(
|
|
|
3720
3832
|
if (residual === undefined) continue;
|
|
3721
3833
|
const candidate = residual.candidate;
|
|
3722
3834
|
const details = isRecord(candidate) ? candidate : { candidate };
|
|
3723
|
-
const failed = await settleFailureTerminalResult(
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
|
|
3835
|
+
const failed = await settleFailureTerminalResult(
|
|
3836
|
+
admitted,
|
|
3837
|
+
{
|
|
3838
|
+
cause: "output",
|
|
3839
|
+
diagnostic: residual.diagnostic,
|
|
3840
|
+
details,
|
|
3841
|
+
},
|
|
3842
|
+
authority,
|
|
3843
|
+
scope ?? {},
|
|
3844
|
+
);
|
|
3728
3845
|
return attachRecordedSubmissions(admitted, failed, scope);
|
|
3729
3846
|
}
|
|
3730
3847
|
return undefined;
|
|
@@ -3753,6 +3870,7 @@ async function settleLawfulMergerTerminalResult(
|
|
|
3753
3870
|
runId: admitted.runId,
|
|
3754
3871
|
},
|
|
3755
3872
|
sessionDirectory,
|
|
3873
|
+
detourGateContext(admitted, scope),
|
|
3756
3874
|
),
|
|
3757
3875
|
scope,
|
|
3758
3876
|
);
|
|
@@ -4018,7 +4136,9 @@ export async function settleFailureTerminalResult(
|
|
|
4018
4136
|
admitted: AdmittedRoleInvocation,
|
|
4019
4137
|
failure: ControlledFailure,
|
|
4020
4138
|
authority: DurablePrincipalAuthority,
|
|
4021
|
-
options:
|
|
4139
|
+
options: SettlementCourtScope & {
|
|
4140
|
+
readonly resume?: TerminalResume;
|
|
4141
|
+
} = {},
|
|
4022
4142
|
): Promise<TerminalResult> {
|
|
4023
4143
|
const coordinates = coordinatesFromAdmitted(authority, admitted);
|
|
4024
4144
|
const { sessionDirectory, sessionFile } = coordinates;
|
|
@@ -4061,6 +4181,7 @@ export async function settleFailureTerminalResult(
|
|
|
4061
4181
|
runId: admitted.runId,
|
|
4062
4182
|
},
|
|
4063
4183
|
sessionDirectory,
|
|
4184
|
+
detourGateContext(admitted, options),
|
|
4064
4185
|
);
|
|
4065
4186
|
}
|
|
4066
4187
|
} catch { /* malformed lifecycle bytes remain the existing nonzero output failure */ }
|
|
@@ -4104,6 +4225,7 @@ export async function settleFailureTerminalResult(
|
|
|
4104
4225
|
resume: options.resume,
|
|
4105
4226
|
},
|
|
4106
4227
|
sessionDirectory,
|
|
4228
|
+
detourGateContext(admitted, options),
|
|
4107
4229
|
);
|
|
4108
4230
|
}
|
|
4109
4231
|
const roleOutcome: TerminalRoleOutcome = {
|
|
@@ -4122,6 +4244,7 @@ export async function settleFailureTerminalResult(
|
|
|
4122
4244
|
runId: admitted.runId,
|
|
4123
4245
|
},
|
|
4124
4246
|
sessionDirectory,
|
|
4247
|
+
detourGateContext(admitted, options),
|
|
4125
4248
|
);
|
|
4126
4249
|
}
|
|
4127
4250
|
|
|
@@ -4130,7 +4253,9 @@ export async function settleJudgeFailureTerminalResult(
|
|
|
4130
4253
|
admitted: AdmittedJudgeInvocation,
|
|
4131
4254
|
failure: ControlledFailure,
|
|
4132
4255
|
authority: DurablePrincipalAuthority,
|
|
4133
|
-
options:
|
|
4256
|
+
options: SettlementCourtScope & {
|
|
4257
|
+
readonly resume?: TerminalResume;
|
|
4258
|
+
} = {},
|
|
4134
4259
|
): Promise<TerminalResult> {
|
|
4135
4260
|
return settleFailureTerminalResult(admitted, failure, authority, options);
|
|
4136
4261
|
}
|
|
@@ -34,6 +34,8 @@ export type RoleTurnRequestProjectionOptions = {
|
|
|
34
34
|
continuation: RoleTurnRequest["continuation"];
|
|
35
35
|
/** #833 resume-with-message court attempt. */
|
|
36
36
|
courtAttemptId?: string;
|
|
37
|
+
/** #537 public-invocation scope (one ak-role call). */
|
|
38
|
+
invocationScopeId?: string;
|
|
37
39
|
/** Station child role run (#840): omit automatic navigator attendance. */
|
|
38
40
|
stationChild?: boolean;
|
|
39
41
|
};
|
|
@@ -79,6 +81,9 @@ export function projectRoleTurnRequest(
|
|
|
79
81
|
...(options.courtAttemptId === undefined || options.courtAttemptId.length === 0
|
|
80
82
|
? {}
|
|
81
83
|
: { courtAttemptId: options.courtAttemptId }),
|
|
84
|
+
...(options.invocationScopeId === undefined || options.invocationScopeId.length === 0
|
|
85
|
+
? {}
|
|
86
|
+
: { invocationScopeId: options.invocationScopeId }),
|
|
82
87
|
...(options.stationChild === undefined ? {} : { stationChild: options.stationChild }),
|
|
83
88
|
};
|
|
84
89
|
}
|
package/src/role-envelope.ts
CHANGED
|
@@ -175,6 +175,8 @@ export async function prepareRoleEnvelope(options: {
|
|
|
175
175
|
model: request.model === undefined ? undefined : { provider: request.model.provider },
|
|
176
176
|
runDirectory: request.runDirectory,
|
|
177
177
|
...(request.courtAttemptId === undefined ? {} : { courtAttemptId: request.courtAttemptId }),
|
|
178
|
+
...(request.invocationScopeId === undefined ? {} : { invocationScopeId: request.invocationScopeId }),
|
|
179
|
+
...(request.host === undefined || request.host.trim() === "" ? {} : { host: request.host.trim() }),
|
|
178
180
|
sessionManager: {
|
|
179
181
|
getLeafEntry: () => sessionEntries.at(-1) as ReturnType<HostContext["sessionManager"]["getLeafEntry"]>,
|
|
180
182
|
getLeafId: () => runId,
|