witnora 0.13.5 → 0.13.7
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/cli.js +2 -2
- package/dist/gateway.js +8 -3
- package/dist/internal/control-client/durable-action-worker.d.ts +14 -1
- package/dist/internal/control-client/durable-action-worker.d.ts.map +1 -1
- package/dist/internal/control-client/durable-action-worker.js +19 -0
- package/dist/runtime-sandbox-kit.js +221 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -39,7 +39,7 @@ import { runOnboard } from "./onboard.js";
|
|
|
39
39
|
import { inspectRepository } from "./onboard.js";
|
|
40
40
|
import { renderReleaseEvaluation, runReleaseEvaluation } from "./release-evaluation.js";
|
|
41
41
|
import { runPrivateCapabilityDiscovery } from "./private-discovery.js";
|
|
42
|
-
import { doctorCustomerGateway, initializeCustomerGateway, readManagedCustomerGatewayLogs, renderGatewayDoctor, renderManagedGatewayStatus, restartManagedCustomerGateway, runCustomerGateway, startManagedCustomerGateway, statusManagedCustomerGateway, stopManagedCustomerGateway, } from "./gateway.js";
|
|
42
|
+
import { doctorCustomerGateway, initializeCustomerGateway, isGatewayDoctorReady, readManagedCustomerGatewayLogs, renderGatewayDoctor, renderManagedGatewayStatus, restartManagedCustomerGateway, runCustomerGateway, startManagedCustomerGateway, statusManagedCustomerGateway, stopManagedCustomerGateway, } from "./gateway.js";
|
|
43
43
|
import { verifyEvidencePacketV02 } from "./evidence-v02.js";
|
|
44
44
|
process.on("uncaughtException", reportFatalError);
|
|
45
45
|
process.on("unhandledRejection", reportFatalError);
|
|
@@ -201,7 +201,7 @@ else if (command === "gateway") {
|
|
|
201
201
|
else if (action === "doctor") {
|
|
202
202
|
const result = await doctorCustomerGateway({ repository: readFlag("--repo") ?? process.cwd(), dir: readFlag("--dir") });
|
|
203
203
|
process.stdout.write(readBoolFlag("--json") ? `${JSON.stringify(result, null, 2)}\n` : renderGatewayDoctor(result));
|
|
204
|
-
if (result
|
|
204
|
+
if (!isGatewayDoctorReady(result))
|
|
205
205
|
process.exitCode = 1;
|
|
206
206
|
}
|
|
207
207
|
else if (action === "start") {
|
package/dist/gateway.js
CHANGED
|
@@ -131,7 +131,9 @@ export async function upgradeCustomerGatewayRuntime(options) {
|
|
|
131
131
|
const current = parseConfig(configRaw);
|
|
132
132
|
if (current.projectId !== options.authorization.projectId || current.server !== options.authorization.server)
|
|
133
133
|
throw new Error("Existing Gateway project/server binding does not match this authorized Runtime upgrade.");
|
|
134
|
-
|
|
134
|
+
const generatedClient = clientRaw === gatewayClient(current)
|
|
135
|
+
|| (!current.runtimeWorker && clientRaw === recordedGatewayClient(current));
|
|
136
|
+
if (!generatedClient || readmeRaw !== gatewayReadme(current))
|
|
135
137
|
throw new Error("Existing Gateway files differ from the Witnora-generated version; refusing to overwrite them.");
|
|
136
138
|
if (current.runtimeWorker && current.runtimeWorker.adapterId !== LOCAL_SANDBOX_ADAPTER_ID) {
|
|
137
139
|
throw new Error("Existing Gateway already has a different Runtime worker; preserve it and reconfigure in Advanced mode.");
|
|
@@ -632,7 +634,7 @@ export async function createConfiguredRuntimeActionWorker(input) {
|
|
|
632
634
|
const runtime = await adapterModule.createWitnoraRuntimeAdapter(adapterContext);
|
|
633
635
|
await inspectIsolatedOutcomeProbe(isolatedProbeConfig);
|
|
634
636
|
if (runtime.id !== workerConfig.adapterId || runtime.version !== workerConfig.adapterVersion || runtime.reconcileReadOnly !== true
|
|
635
|
-
|| typeof runtime.prepareClaim !== "function" || typeof runtime.execute !== "function" || typeof runtime.reconcile !== "function") {
|
|
637
|
+
|| typeof runtime.prepareClaim !== "function" || typeof runtime.execute !== "function" || typeof runtime.reconcile !== "function" || typeof runtime.submitEvidence !== "function") {
|
|
636
638
|
throw new Error("Runtime adapter does not match the exact configured id/version or read-only reconciliation contract.");
|
|
637
639
|
}
|
|
638
640
|
if (workerConfig.adapterId === LOCAL_SANDBOX_ADAPTER_ID && JSON.stringify(runtime.capabilities) !== JSON.stringify({
|
|
@@ -656,7 +658,7 @@ export async function createConfiguredRuntimeActionWorker(input) {
|
|
|
656
658
|
listActionReceipts: async (actionId) => (await primary(`actions/${encodeURIComponent(actionId)}/receipts`)).receipts ?? [],
|
|
657
659
|
claimExecutionGrant: (executionGrantId, claim, idempotencyKey) => claimHostedExecutionGrant(input.connection, requestFetch, executionGrantId, claim, idempotencyKey),
|
|
658
660
|
},
|
|
659
|
-
runtime: { reconcileReadOnly: true, prepareClaim: runtime.prepareClaim, execute: runtime.execute, reconcile: runtime.reconcile },
|
|
661
|
+
runtime: { reconcileReadOnly: true, prepareClaim: runtime.prepareClaim, execute: runtime.execute, reconcile: runtime.reconcile, submitEvidence: runtime.submitEvidence },
|
|
660
662
|
probe: {
|
|
661
663
|
id: workerConfig.probeId,
|
|
662
664
|
credentialHandle: workerConfig.probeTargetCredentialHandle,
|
|
@@ -914,6 +916,9 @@ export function renderGatewayDoctor(result) {
|
|
|
914
916
|
"",
|
|
915
917
|
].join("\n");
|
|
916
918
|
}
|
|
919
|
+
export function isGatewayDoctorReady(result) {
|
|
920
|
+
return result.overall === "READY_TO_RECORD" || result.overall === "READY_FOR_RUNTIME";
|
|
921
|
+
}
|
|
917
922
|
function parseConfig(raw) {
|
|
918
923
|
const value = JSON.parse(raw);
|
|
919
924
|
if (value.schemaVersion !== CONFIG_SCHEMA || !value.projectId || !value.server || !value.connectionName || !value.collectorId) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type DurableActionPhase = "TRACKED" | "WAITING_APPROVAL" | "DENIED" | "EXPIRED" | "BLOCKED" | "GRANT_ISSUED" | "EXECUTION_STARTED" | "UNKNOWN_RESULT" | "EXECUTED" | "PROBED" | "COMPLETED";
|
|
1
|
+
export type DurableActionPhase = "TRACKED" | "WAITING_APPROVAL" | "DENIED" | "EXPIRED" | "BLOCKED" | "GRANT_ISSUED" | "EXECUTION_STARTED" | "UNKNOWN_RESULT" | "EXECUTED" | "PROBED" | "EVIDENCE_SUBMITTED" | "COMPLETED";
|
|
2
2
|
export interface DurableWorkerProposal {
|
|
3
3
|
externalId: string;
|
|
4
4
|
actionType: string;
|
|
@@ -25,6 +25,9 @@ export interface DurableWorkerAction {
|
|
|
25
25
|
targetSystem: string;
|
|
26
26
|
expectedState?: Record<string, unknown>;
|
|
27
27
|
approvalExpiresAt?: string;
|
|
28
|
+
verificationSuccess?: boolean;
|
|
29
|
+
receiptId?: string;
|
|
30
|
+
receiptSignatureCount?: number;
|
|
28
31
|
assuranceContext?: {
|
|
29
32
|
executionIntent?: {
|
|
30
33
|
adapterId: string;
|
|
@@ -118,6 +121,8 @@ export interface DurableApprovedActionWorkerOptions {
|
|
|
118
121
|
verifyAction(actionId: string, input: Record<string, unknown>, idempotencyKey: string): Promise<{
|
|
119
122
|
status: string;
|
|
120
123
|
verificationSuccess?: boolean;
|
|
124
|
+
receiptId?: string;
|
|
125
|
+
receiptSignatureCount?: number;
|
|
121
126
|
}>;
|
|
122
127
|
listActionReceipts(actionId: string): Promise<Array<{
|
|
123
128
|
id: string;
|
|
@@ -147,6 +152,14 @@ export interface DurableApprovedActionWorkerOptions {
|
|
|
147
152
|
proposal: DurableWorkerProposal;
|
|
148
153
|
grant: DurableWorkerGrant;
|
|
149
154
|
}): Promise<DurableWorkerExecutionResult | undefined>;
|
|
155
|
+
submitEvidence(input: {
|
|
156
|
+
action: DurableWorkerAction;
|
|
157
|
+
proposal: DurableWorkerProposal;
|
|
158
|
+
grant: DurableWorkerGrant;
|
|
159
|
+
hostedReservation: DurableWorkerHostedReservation;
|
|
160
|
+
execution: DurableWorkerExecutionResult;
|
|
161
|
+
observation: DurableWorkerObservation;
|
|
162
|
+
}): Promise<void>;
|
|
150
163
|
};
|
|
151
164
|
probe: {
|
|
152
165
|
id: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"durable-action-worker.d.ts","sourceRoot":"","sources":["../../../../agentcert-sdk/src/durable-action-worker.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"durable-action-worker.d.ts","sourceRoot":"","sources":["../../../../agentcert-sdk/src/durable-action-worker.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,kBAAkB,GAC1B,SAAS,GACT,kBAAkB,GAClB,QAAQ,GACR,SAAS,GACT,SAAS,GACT,cAAc,GACd,mBAAmB,GACnB,gBAAgB,GAChB,UAAU,GACV,QAAQ,GACR,oBAAoB,GACpB,WAAW,CAAC;AAEhB,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,eAAe,EAAE;QACf,SAAS,EAAE,MAAM,CAAC;QAClB,wBAAwB,EAAE,MAAM,CAAC;QACjC,cAAc,EAAE,MAAM,EAAE,CAAC;QACzB,gBAAgB,EAAE,MAAM,CAAC;QACzB,eAAe,EAAE,MAAM,CAAC;QACxB,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC5C,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC1C,YAAY,EAAE,MAAM,CAAC;QACrB,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,kBAAkB,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,GAAG,kBAAkB,GAAG,eAAe,GAAG,UAAU,GAAG,MAAM,CAAC;IACzI,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,gBAAgB,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE;YACrC,SAAS,EAAE,MAAM,CAAC;YAClB,wBAAwB,EAAE,MAAM,CAAC;YACjC,cAAc,EAAE,MAAM,EAAE,CAAC;YACzB,gBAAgB,EAAE,MAAM,CAAC;YACzB,eAAe,EAAE,MAAM,CAAC;YACxB,wBAAwB,EAAE,MAAM,CAAC;YACjC,sBAAsB,EAAE,MAAM,CAAC;YAC/B,YAAY,EAAE,MAAM,CAAC;YACrB,gBAAgB,EAAE,MAAM,CAAC;SAC1B,CAAA;KAAE,CAAC;IACJ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IACrE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,4BAA4B;IAC3C,kBAAkB,EAAE,MAAM,CAAC;IAC3B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,8BAA8B;IAC7C,kBAAkB,EAAE,MAAM,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,wBAAwB;IACvC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,iBAAiB,EAAE,YAAY,GAAG,WAAW,GAAG,kBAAkB,GAAG,SAAS,GAAG,gBAAgB,GAAG,0BAA0B,CAAC;IAC/H,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,uBAAuB;IACtC,aAAa,EAAE,wCAAwC,CAAC;IACxD,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,kBAAkB,CAAC;IAC1B,QAAQ,EAAE,qBAAqB,CAAC;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,kBAAkB,CAAC;IAC3B,SAAS,CAAC,EAAE,4BAA4B,CAAC;IACzC,WAAW,CAAC,EAAE,wBAAwB,CAAC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,8BAA8B,CAAC;IACnD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,GAAG,SAAS,CAAC,CAAC;IACrE,IAAI,CAAC,UAAU,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,IAAI,IAAI,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAAC;IAC3C,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACvH;AAED,qBAAa,yBAA0B,YAAW,qBAAqB;IACrE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEvB,SAAS,EAAE,MAAM;IAEvB,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,GAAG,SAAS,CAAC;IAQpE,IAAI,CAAC,UAAU,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;IAYxD,IAAI,IAAI,OAAO,CAAC,uBAAuB,EAAE,CAAC;IAQ1C,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAmB3H,OAAO,CAAC,IAAI;IAIZ,OAAO,CAAC,SAAS;CAIlB;AAED,MAAM,WAAW,kCAAkC;IACjD,MAAM,EAAE;QACN,SAAS,EAAE,MAAM,CAAC;QAClB,cAAc,EAAE,MAAM,CAAC;QACvB,OAAO,EAAE,MAAM,CAAC;QAChB,qBAAqB,EAAE,MAAM,CAAC;QAC9B,iBAAiB,EAAE,MAAM,CAAC;QAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,KAAK,EAAE,qBAAqB,CAAC;IAC7B,MAAM,EAAE;QACN,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;QAC1D,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;QAC3H,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;YAAC,SAAS,CAAC,EAAE,MAAM,CAAC;YAAC,qBAAqB,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QACvM,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,OAAO,CAAC,EAAE;gBAAE,YAAY,CAAC,EAAE,OAAO,EAAE,CAAA;aAAE,CAAA;SAAE,CAAC,CAAC,CAAC;QAC7G,mBAAmB,CAAC,gBAAgB,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC;YAAE,QAAQ,EAAE,OAAO,CAAA;SAAE,CAAC,CAAC;KACvI,CAAC;IACF,OAAO,EAAE;QACP,iBAAiB,EAAE,IAAI,CAAC;QACxB,YAAY,CAAC,KAAK,EAAE;YAAE,MAAM,EAAE,mBAAmB,CAAC;YAAC,QAAQ,EAAE,qBAAqB,CAAC;YAAC,KAAK,EAAE,kBAAkB,CAAA;SAAE,GAAG,OAAO,CAAC,8BAA8B,CAAC,CAAC;QAC1J,OAAO,CAAC,KAAK,EAAE;YAAE,MAAM,EAAE,mBAAmB,CAAC;YAAC,QAAQ,EAAE,qBAAqB,CAAC;YAAC,KAAK,EAAE,kBAAkB,CAAC;YAAC,iBAAiB,EAAE,8BAA8B,CAAA;SAAE,GAAG,OAAO,CAAC,4BAA4B,CAAC,CAAC;QACtM,SAAS,CAAC,KAAK,EAAE;YAAE,MAAM,EAAE,mBAAmB,CAAC;YAAC,QAAQ,EAAE,qBAAqB,CAAC;YAAC,KAAK,EAAE,kBAAkB,CAAA;SAAE,GAAG,OAAO,CAAC,4BAA4B,GAAG,SAAS,CAAC,CAAC;QACjK,cAAc,CAAC,KAAK,EAAE;YAAE,MAAM,EAAE,mBAAmB,CAAC;YAAC,QAAQ,EAAE,qBAAqB,CAAC;YAAC,KAAK,EAAE,kBAAkB,CAAC;YAAC,iBAAiB,EAAE,8BAA8B,CAAC;YAAC,SAAS,EAAE,4BAA4B,CAAC;YAAC,WAAW,EAAE,wBAAwB,CAAA;SAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;KACtQ,CAAC;IACF,KAAK,EAAE;QACL,EAAE,EAAE,MAAM,CAAC;QACX,gBAAgB,EAAE,MAAM,CAAC;QACzB,QAAQ,EAAE,IAAI,CAAC;QACf,OAAO,CAAC,KAAK,EAAE;YAAE,MAAM,EAAE,mBAAmB,CAAC;YAAC,QAAQ,EAAE,qBAAqB,CAAC;YAAC,KAAK,EAAE,kBAAkB,CAAC;YAAC,SAAS,EAAE,4BAA4B,CAAA;SAAE,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAAC;KACzL,CAAC;IACF,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB;AAED,MAAM,WAAW,yBAAyB;IACxC,aAAa,EAAE,2CAA2C,CAAC;IAC3D,KAAK,EAAE,OAAO,CAAC;IACf,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,2BAA2B;IAQ1B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAPpC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAa;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuD;IAC9E,OAAO,CAAC,KAAK,CAAC,CAAiC;IAC/C,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,SAAS,CAAC,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgB;gBAEZ,OAAO,EAAE,kCAAkC;IAUlE,KAAK,CAAC,KAAK,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,qBAAqB,CAAA;KAAE,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAgB3G,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAOxD,KAAK,IAAI,IAAI;IAcb,IAAI,IAAI,IAAI;IAEN,MAAM,IAAI,OAAO,CAAC,yBAAyB,CAAC;YAapC,QAAQ;YAgIR,OAAO;CAMtB;AA2DD,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAY3F"}
|
|
@@ -160,6 +160,9 @@ export class DurableApprovedActionWorker {
|
|
|
160
160
|
if (!exactActionMatches(action, actionId, checkpoint.proposal, this.options.config.adapterId, this.options.config.adapterVersion)) {
|
|
161
161
|
return this.persist(checkpoint, "BLOCKED", { limitation: "Hosted action no longer matches the exact locally configured action, adapter, or build binding." });
|
|
162
162
|
}
|
|
163
|
+
if (action.status === "VERIFIED" && action.verificationSuccess === true && action.receiptId && (action.receiptSignatureCount ?? 0) > 0) {
|
|
164
|
+
return this.persist(checkpoint, "COMPLETED", { receiptId: action.receiptId, limitation: undefined });
|
|
165
|
+
}
|
|
163
166
|
if ((checkpoint.phase === "EXECUTION_STARTED" || checkpoint.phase === "UNKNOWN_RESULT") && checkpoint.grant) {
|
|
164
167
|
if (!exactGrantMatches(checkpoint.grant, actionId, checkpoint.proposal, this.options.config.runtimeIdentityId)) {
|
|
165
168
|
return this.persist(checkpoint, "BLOCKED", { limitation: "Hosted grant does not match the exact approved local action binding." });
|
|
@@ -261,6 +264,19 @@ export class DurableApprovedActionWorker {
|
|
|
261
264
|
throw new Error("Outcome observation did not come from the exact configured probe.");
|
|
262
265
|
checkpoint = await this.persist(checkpoint, "PROBED", { observation });
|
|
263
266
|
}
|
|
267
|
+
if (checkpoint.phase !== "EVIDENCE_SUBMITTED") {
|
|
268
|
+
if (!checkpoint.hostedReservation)
|
|
269
|
+
throw new Error("Durable execution evidence requires the bound Hosted reservation.");
|
|
270
|
+
await this.options.runtime.submitEvidence({
|
|
271
|
+
action,
|
|
272
|
+
proposal: checkpoint.proposal,
|
|
273
|
+
grant,
|
|
274
|
+
hostedReservation: checkpoint.hostedReservation,
|
|
275
|
+
execution: checkpoint.execution,
|
|
276
|
+
observation: checkpoint.observation,
|
|
277
|
+
});
|
|
278
|
+
checkpoint = await this.persist(checkpoint, "EVIDENCE_SUBMITTED");
|
|
279
|
+
}
|
|
264
280
|
const verified = await this.options.hosted.verifyAction(actionId, {
|
|
265
281
|
...checkpoint.observation,
|
|
266
282
|
executionGrantId: grant.id,
|
|
@@ -268,6 +284,9 @@ export class DurableApprovedActionWorker {
|
|
|
268
284
|
}, `durable-worker:verify:${actionId}:${checkpoint.execution.executionSessionId}`);
|
|
269
285
|
if (verified.status !== "VERIFIED" || verified.verificationSuccess !== true)
|
|
270
286
|
throw new Error("Hosted outcome verification did not establish the expected result.");
|
|
287
|
+
if (verified.receiptId && (verified.receiptSignatureCount ?? 0) > 0) {
|
|
288
|
+
return this.persist(checkpoint, "COMPLETED", { receiptId: verified.receiptId });
|
|
289
|
+
}
|
|
271
290
|
const receipts = await this.options.hosted.listActionReceipts(actionId);
|
|
272
291
|
const signed = receipts.find((item) => Array.isArray(item.receipt?.signatureSet) && item.receipt.signatureSet.length > 0);
|
|
273
292
|
if (!signed)
|
|
@@ -221,9 +221,230 @@ export function createWitnoraRuntimeAdapter(context) {
|
|
|
221
221
|
await persistExecution(context.storageDirectory, action.id, execution);
|
|
222
222
|
return execution;
|
|
223
223
|
},
|
|
224
|
+
async submitEvidence({ action, proposal, grant, hostedReservation, execution, observation }) {
|
|
225
|
+
const audit = await readCommittedAudit(reconcileCredential.handle, action.id, execution.executionSessionId);
|
|
226
|
+
const bundle = await loadOrCreateEvidenceBundle({
|
|
227
|
+
storageDirectory: context.storageDirectory,
|
|
228
|
+
action,
|
|
229
|
+
proposal,
|
|
230
|
+
grant,
|
|
231
|
+
hostedReservation,
|
|
232
|
+
execution,
|
|
233
|
+
observation,
|
|
234
|
+
audit,
|
|
235
|
+
runtime,
|
|
236
|
+
adapterId: context.adapterId,
|
|
237
|
+
adapterVersion: context.adapterVersion,
|
|
238
|
+
signingKeyHandle: signingKey.handle,
|
|
239
|
+
writeCredentialHandle: writeCredential.handle,
|
|
240
|
+
});
|
|
241
|
+
await context.hosted.request("execution-attempts/" + encodeURIComponent(execution.executionSessionId) + "/phase", {
|
|
242
|
+
method: "POST",
|
|
243
|
+
body: { executionSessionId: execution.executionSessionId, runtimeClaim: hostedReservation.claim, phase: "RECONCILED_SUCCESS", targetOperationId: execution.targetOperationId },
|
|
244
|
+
});
|
|
245
|
+
await context.hosted.request("execution-sessions/" + encodeURIComponent(execution.executionSessionId) + "/evidence", { method: "POST", body: bundle });
|
|
246
|
+
},
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
async function readCommittedAudit(handle, actionId, executionSessionId) {
|
|
251
|
+
const credential = await readSecretHandle(handle);
|
|
252
|
+
const response = await fetch("${sandboxOrigin}/audit/actions/" + encodeURIComponent(actionId) + "/sessions/" + encodeURIComponent(executionSessionId), { redirect: "error", headers: { "x-sandbox-audit-credential": credential } });
|
|
253
|
+
const audit = await response.json().catch(() => ({}));
|
|
254
|
+
if (!response.ok || audit.phase !== "COMMITTED" || audit.actionId !== actionId || audit.executionSessionId !== executionSessionId || typeof audit.transactionId !== "string") throw new Error("sandbox_evidence_audit_invalid");
|
|
255
|
+
return audit;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
async function loadOrCreateEvidenceBundle(input) {
|
|
259
|
+
const path = join(input.storageDirectory, "evidence-bundles", safeId(input.action.id) + ".json");
|
|
260
|
+
try { return JSON.parse(await readFile(path, "utf8")); }
|
|
261
|
+
catch (error) { if (error?.code !== "ENOENT") throw error; }
|
|
262
|
+
const bundle = await createEvidenceBundle(input);
|
|
263
|
+
await mkdir(dirname(path), { recursive: true });
|
|
264
|
+
const temporary = path + "." + randomUUID() + ".tmp";
|
|
265
|
+
await writeFile(temporary, JSON.stringify(bundle) + "\\n", { mode: 0o600 });
|
|
266
|
+
await rename(temporary, path);
|
|
267
|
+
return bundle;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
async function createEvidenceBundle(input) {
|
|
271
|
+
const grant = exactObject(input.grant?.grant, "grant");
|
|
272
|
+
const grantPayload = exactObject(grant.payload, "grant.payload");
|
|
273
|
+
const runtimeClaim = exactObject(input.hostedReservation.claim, "runtimeClaim");
|
|
274
|
+
const claimedAt = String(exactObject(runtimeClaim.payload, "runtimeClaim.payload").claimedAt);
|
|
275
|
+
const completedAt = new Date().toISOString();
|
|
276
|
+
const privateKeyPem = await readSecretHandle(input.signingKeyHandle);
|
|
277
|
+
const signRuntime = (payload) => {
|
|
278
|
+
const payloadSha256 = sha256(canonicalJson(payload));
|
|
279
|
+
return { payload, payloadSha256, signature: { algorithm: "Ed25519", keyId: input.runtime.keyId, signature: sign(null, Buffer.from(payloadSha256, "hex"), createPrivateKey(privateKeyPem)).toString("base64url") } };
|
|
280
|
+
};
|
|
281
|
+
const credentialLeaseId = randomUUID();
|
|
282
|
+
const eventChainGenesisHash = sha256(canonicalJson({ executionSessionId: input.execution.executionSessionId, executionGrantDigest: grant.payloadSha256, runtimeIdentityId: input.runtime.id }));
|
|
283
|
+
const executionSession = signRuntime({
|
|
284
|
+
protocolVersion: "agentcert.browser_enforcement.v0.2",
|
|
285
|
+
objectType: "ExecutionSessionAttestation",
|
|
286
|
+
signatureContext: "onegent.execution-session.v0.2",
|
|
287
|
+
executionSessionId: input.execution.executionSessionId,
|
|
288
|
+
executionGrantId: input.grant.id,
|
|
289
|
+
executionGrantDigest: grant.payloadSha256,
|
|
290
|
+
actionId: input.action.id,
|
|
291
|
+
actionIntentDigest: grantPayload.actionIntentDigest,
|
|
292
|
+
runtimeIdentityId: input.runtime.id,
|
|
293
|
+
runtimeKeyId: input.runtime.keyId,
|
|
294
|
+
adapterId: input.adapterId,
|
|
295
|
+
adapterVersion: input.adapterVersion,
|
|
296
|
+
browserContextIdDigest: sha256("durable-action:" + input.execution.executionSessionId),
|
|
297
|
+
credentialLeaseId,
|
|
298
|
+
credentialIsolationMode: "RUNTIME_INJECTED_CREDENTIAL",
|
|
299
|
+
targetAudience: grantPayload.targetAudience,
|
|
300
|
+
allowedOrigins: grantPayload.allowedOrigins,
|
|
301
|
+
startedAt: claimedAt,
|
|
302
|
+
sessionExpiresAt: grantPayload.expiresAt,
|
|
303
|
+
eventChainGenesisHash,
|
|
304
|
+
});
|
|
305
|
+
const events = [];
|
|
306
|
+
let previousEventHash = eventChainGenesisHash;
|
|
307
|
+
const append = (eventType, redactedPayload = {}) => {
|
|
308
|
+
const payload = {
|
|
309
|
+
protocolVersion: "agentcert.browser_enforcement.v0.2",
|
|
310
|
+
objectType: "ExecutionEvent",
|
|
311
|
+
signatureContext: "onegent.execution-event.v0.2",
|
|
312
|
+
eventId: randomUUID(),
|
|
313
|
+
actionId: input.action.id,
|
|
314
|
+
executionSessionId: input.execution.executionSessionId,
|
|
315
|
+
sequence: events.length + 1,
|
|
316
|
+
previousEventHash,
|
|
317
|
+
eventType,
|
|
318
|
+
sourceIdentityId: input.runtime.id,
|
|
319
|
+
sourceTimestamp: completedAt,
|
|
320
|
+
receivedTimestamp: completedAt,
|
|
321
|
+
payloadDigest: sha256(canonicalJson(redactedPayload)),
|
|
322
|
+
redactedPayload,
|
|
323
|
+
};
|
|
324
|
+
const signed = signRuntime(payload);
|
|
325
|
+
previousEventHash = signed.payloadSha256;
|
|
326
|
+
events.push(signed);
|
|
327
|
+
};
|
|
328
|
+
append("EXECUTION_GRANT_VERIFIED", { executionGrantDigest: grant.payloadSha256 });
|
|
329
|
+
append("EXECUTION_GRANT_CLAIMED", { executionGrantId: input.grant.id, claimDigest: runtimeClaim.payloadSha256 });
|
|
330
|
+
append("EXECUTION_SESSION_STARTED", { executionSessionDigest: executionSession.payloadSha256 });
|
|
331
|
+
append("CREDENTIAL_LEASE_ACTIVATED", { credentialLeaseId, isolationMode: "RUNTIME_INJECTED_CREDENTIAL" });
|
|
332
|
+
append("BROWSER_CONTEXT_CREATED", { browserContextIdDigest: executionSession.payload.browserContextIdDigest });
|
|
333
|
+
append("TARGET_NAVIGATION", { targetAudience: grantPayload.targetAudience, origin: grantPayload.allowedOrigins[0] });
|
|
334
|
+
append("AUTHORIZED_ACTION_PREPARED", { operation: grantPayload.allowedOperation, resource: grantPayload.allowedResource });
|
|
335
|
+
append("FINAL_PARAMETERS_VERIFIED", { parametersDigest: grantPayload.parametersDigest });
|
|
336
|
+
append("HIGH_RISK_SUBMISSION_STARTED", { actionId: input.action.id });
|
|
337
|
+
append("HIGH_RISK_SUBMISSION_COMPLETED", { targetSystem: input.action.targetSystem });
|
|
338
|
+
append("TARGET_RESPONSE_OBSERVED", { observedStateDigest: sha256(canonicalJson(input.execution.observedState ?? {})) });
|
|
339
|
+
append("OUTCOME_PROBE_STARTED", { probe: input.observation.observationSource });
|
|
340
|
+
append("OUTCOME_OBSERVED", { source: input.observation.observationSource, observedStateDigest: sha256(canonicalJson(input.observation.observedState)) });
|
|
341
|
+
append("CREDENTIAL_LEASE_REVOKED", { credentialLeaseId, revokedAt: completedAt, status: "REVOKED" });
|
|
342
|
+
const expectedState = input.action.expectedState ?? input.proposal.expectedState ?? {};
|
|
343
|
+
const outcomeResult = subsetMatches(expectedState, input.observation.observedState) ? "SATISFIED" : "NOT_SATISFIED";
|
|
344
|
+
const outcomeAttestation = signRuntime({
|
|
345
|
+
protocolVersion: "agentcert.browser_enforcement.v0.2",
|
|
346
|
+
objectType: "OutcomeAttestation",
|
|
347
|
+
signatureContext: "onegent.outcome-attestation.v0.2",
|
|
348
|
+
outcomeAttestationId: randomUUID(),
|
|
349
|
+
actionId: input.action.id,
|
|
350
|
+
executionSessionId: input.execution.executionSessionId,
|
|
351
|
+
executionGrantId: input.grant.id,
|
|
352
|
+
predicateId: "expected_state_subset",
|
|
353
|
+
predicateVersion: "1",
|
|
354
|
+
predicateDigest: grantPayload.outcomePredicateDigest,
|
|
355
|
+
expectedStateDigest: sha256(canonicalJson(expectedState)),
|
|
356
|
+
observedStateDigest: sha256(canonicalJson(input.observation.observedState)),
|
|
357
|
+
result: outcomeResult,
|
|
358
|
+
observationMethod: input.observation.observationMethod,
|
|
359
|
+
observationIndependence: "SEPARATE_READ_ONLY_PROBE",
|
|
360
|
+
observationSource: input.observation.observationSource,
|
|
361
|
+
sourceEvidenceDigest: sha256(canonicalJson(input.observation)),
|
|
362
|
+
evidenceReferences: ["target-audit:" + input.audit.transactionId],
|
|
363
|
+
collectorIdentityId: input.runtime.id,
|
|
364
|
+
collectorKeyId: input.runtime.keyId,
|
|
365
|
+
collectedAt: completedAt,
|
|
366
|
+
confidence: input.observation.confidence ?? 1,
|
|
367
|
+
limitations: ["The generated probe reads a separate localhost read credential; it is not an Independent Review."],
|
|
368
|
+
});
|
|
369
|
+
append("EXECUTION_SESSION_COMPLETED", { outcomeAttestationDigest: outcomeAttestation.payloadSha256 });
|
|
370
|
+
const credentialReferenceDigest = sha256(input.writeCredentialHandle);
|
|
371
|
+
const targetEvent = {
|
|
372
|
+
targetEventId: input.audit.transactionId,
|
|
373
|
+
actionId: input.action.id,
|
|
374
|
+
executionSessionId: input.execution.executionSessionId,
|
|
375
|
+
occurredAt: input.audit.at ?? completedAt,
|
|
376
|
+
operation: grantPayload.allowedOperation,
|
|
377
|
+
resource: grantPayload.allowedResource,
|
|
378
|
+
parametersDigest: grantPayload.parametersDigest,
|
|
379
|
+
credentialReferenceDigest,
|
|
380
|
+
};
|
|
381
|
+
const reconciliationReport = signRuntime({
|
|
382
|
+
protocolVersion: "agentcert.browser_enforcement.v0.2",
|
|
383
|
+
objectType: "ReconciliationReport",
|
|
384
|
+
signatureContext: "onegent.reconciliation-report.v0.2",
|
|
385
|
+
reconciliationReportId: randomUUID(),
|
|
386
|
+
tenantId: grantPayload.tenantId,
|
|
387
|
+
actionId: input.action.id,
|
|
388
|
+
executionSessionId: input.execution.executionSessionId,
|
|
389
|
+
targetSystem: grantPayload.targetAudience,
|
|
390
|
+
accountOrCredentialReferenceDigest: credentialReferenceDigest,
|
|
391
|
+
reconciliationWindowStart: claimedAt,
|
|
392
|
+
reconciliationWindowEnd: completedAt,
|
|
393
|
+
expectedActionIds: [input.action.id],
|
|
394
|
+
observedTargetEvents: [targetEvent],
|
|
395
|
+
matchedEvents: [input.audit.transactionId],
|
|
396
|
+
unmatchedTargetEvents: [],
|
|
397
|
+
unmatchedReceipts: [],
|
|
398
|
+
duplicateMatches: [],
|
|
399
|
+
result: "PASSED",
|
|
400
|
+
limitations: ["Reconciliation covers the dedicated localhost sandbox credential and this action only."],
|
|
401
|
+
collectorIdentityId: input.runtime.id,
|
|
402
|
+
collectedAt: completedAt,
|
|
403
|
+
});
|
|
404
|
+
const eventCheckpoint = signRuntime({
|
|
405
|
+
protocolVersion: "agentcert.browser_enforcement.v0.2",
|
|
406
|
+
objectType: "EventChainCheckpoint",
|
|
407
|
+
signatureContext: "onegent.event-checkpoint.v0.2",
|
|
408
|
+
actionId: input.action.id,
|
|
409
|
+
executionSessionId: input.execution.executionSessionId,
|
|
410
|
+
eventCount: events.length,
|
|
411
|
+
firstEventHash: events[0].payloadSha256,
|
|
412
|
+
finalEventHash: events.at(-1).payloadSha256,
|
|
413
|
+
completedAt,
|
|
414
|
+
});
|
|
415
|
+
return {
|
|
416
|
+
protocolVersion: "agentcert.browser_enforcement.v0.2",
|
|
417
|
+
executionGrant: grant,
|
|
418
|
+
grantStatus: "CONSUMED",
|
|
419
|
+
runtimeClaim,
|
|
420
|
+
executionSession,
|
|
421
|
+
credentialLease: {
|
|
422
|
+
credentialLeaseId,
|
|
423
|
+
tenantId: grantPayload.tenantId,
|
|
424
|
+
actionId: input.action.id,
|
|
425
|
+
executionSessionId: input.execution.executionSessionId,
|
|
426
|
+
providerType: "CUSTOMER_SECRET_PROVIDER",
|
|
427
|
+
providerReference: "opaque:" + credentialReferenceDigest,
|
|
428
|
+
targetAudience: grantPayload.targetAudience,
|
|
429
|
+
scopeDigest: sha256(canonicalJson({ allowedOrigins: grantPayload.allowedOrigins, operation: grantPayload.allowedOperation, resource: grantPayload.allowedResource })),
|
|
430
|
+
isolationMode: "RUNTIME_INJECTED_CREDENTIAL",
|
|
431
|
+
issuedAt: claimedAt,
|
|
432
|
+
expiresAt: grantPayload.expiresAt,
|
|
433
|
+
status: "REVOKED",
|
|
434
|
+
revokedAt: completedAt,
|
|
435
|
+
},
|
|
436
|
+
events,
|
|
437
|
+
eventCheckpoint,
|
|
438
|
+
outcomeAttestation,
|
|
439
|
+
reconciliationReport,
|
|
440
|
+
finalParametersDigest: grantPayload.parametersDigest,
|
|
441
|
+
detectedBypass: false,
|
|
442
|
+
execution: { method: "LOCAL_ADAPTER", status: "COMPLETED", targetSystem: input.action.targetSystem, observedState: input.execution.observedState },
|
|
224
443
|
};
|
|
225
444
|
}
|
|
226
445
|
|
|
446
|
+
function subsetMatches(expected, observed) { return Object.entries(expected).every(([key, value]) => canonicalJson(observed[key]) === canonicalJson(value)); }
|
|
447
|
+
|
|
227
448
|
function localhostTarget(proposal) {
|
|
228
449
|
if (proposal?.targetSystem !== "WitnoraLocalSandbox") throw new Error("sandbox_target_system_invalid");
|
|
229
450
|
const origins = proposal?.executionIntent?.allowedOrigins;
|