@noodleseed/one 0.163.0 → 0.165.0
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/banner.d.ts +6 -0
- package/dist/banner.d.ts.map +1 -0
- package/dist/banner.js +29 -0
- package/dist/banner.js.map +1 -0
- package/dist/commands/project-setup.d.ts.map +1 -1
- package/dist/commands/project-setup.js +2 -0
- package/dist/commands/project-setup.js.map +1 -1
- package/dist/commands/solutions-coordination.d.ts +5 -0
- package/dist/commands/solutions-coordination.d.ts.map +1 -0
- package/dist/commands/solutions-coordination.js +94 -0
- package/dist/commands/solutions-coordination.js.map +1 -0
- package/dist/commands/solutions-ops.d.ts.map +1 -1
- package/dist/commands/solutions-ops.js +8 -4
- package/dist/commands/solutions-ops.js.map +1 -1
- package/dist/first-run.d.ts.map +1 -1
- package/dist/first-run.js +2 -0
- package/dist/first-run.js.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/curated/error-fixes.js +2 -0
- package/node_modules/@noodle-borg/agent-kit/dist/generated/example-files.js +3 -3
- package/node_modules/@noodle-borg/agent-kit/dist/generated/surface.js +2 -0
- package/node_modules/@noodle-borg/agent-kit/dist/index.d.ts +1 -0
- package/node_modules/@noodle-borg/agent-kit/dist/index.js +1 -0
- package/node_modules/@noodle-borg/agent-kit/dist/plugin-bootstrap-skill.js +10 -0
- package/node_modules/@noodle-borg/agent-kit/dist/skill-authoring-refs.js +4 -1
- package/node_modules/@noodle-borg/agent-kit/dist/welcome-wordmark.d.ts +3 -0
- package/node_modules/@noodle-borg/agent-kit/dist/welcome-wordmark.js +10 -0
- package/node_modules/@noodle-borg/agent-kit/package.json +1 -1
- package/node_modules/@noodle-borg/assistant-gateway/dist/embed-store.d.ts +4 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/in-memory-embed-store.d.ts +4 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/in-memory-embed-store.js +6 -2
- package/node_modules/@noodle-borg/assistant-gateway/package.json +1 -1
- package/node_modules/@noodle-borg/authoring/dist/config.d.ts +8 -2
- package/node_modules/@noodle-borg/authoring/dist/config.js +28 -1
- package/node_modules/@noodle-borg/authoring/dist/connectors.d.ts +37 -0
- package/node_modules/@noodle-borg/authoring/dist/connectors.js +4 -0
- package/node_modules/@noodle-borg/authoring/dist/index.d.ts +1 -1
- package/node_modules/@noodle-borg/authoring/dist/server.js +1 -0
- package/node_modules/@noodle-borg/cli-catalog/dist/catalog-data-solution-flags.js +83 -0
- package/node_modules/@noodle-borg/cli-catalog/dist/catalog-data-solutions.js +70 -92
- package/node_modules/@noodle-borg/compiler/dist/artifact/operation-ref.d.ts +2 -0
- package/node_modules/@noodle-borg/compiler/dist/artifact/version.d.ts +4 -1
- package/node_modules/@noodle-borg/compiler/dist/artifact/version.js +4 -1
- package/node_modules/@noodle-borg/compiler/dist/catalog/types.d.ts +7 -0
- package/node_modules/@noodle-borg/compiler/dist/errors.d.ts +1 -1
- package/node_modules/@noodle-borg/compiler/dist/fulfilment-emit.js +15 -2
- package/node_modules/@noodle-borg/compiler/dist/nested-operations.js +71 -0
- package/node_modules/@noodle-borg/compute/dist/code-connector.js +14 -2
- package/node_modules/@noodle-borg/compute/dist/deterministic-helpers.js +138 -0
- package/node_modules/@noodle-borg/compute/dist/quickjs-engine.js +48 -0
- package/node_modules/@noodle-borg/compute/dist/sandbox-eval.js +39 -5
- package/node_modules/@noodle-borg/compute/dist/worker-entry.js +7 -0
- package/node_modules/@noodle-borg/compute/dist/worker-pool.js +14 -3
- package/node_modules/@noodle-borg/connector-defs/dist/compile-http.js +31 -2
- package/node_modules/@noodle-borg/connector-defs/dist/compile.d.ts +1 -1
- package/node_modules/@noodle-borg/connector-defs/dist/compile.js +20 -0
- package/node_modules/@noodle-borg/connector-defs/dist/schema.d.ts +84 -0
- package/node_modules/@noodle-borg/connector-defs/dist/schema.js +44 -1
- package/node_modules/@noodle-borg/connector-http/dist/http-connector.d.ts +7 -0
- package/node_modules/@noodle-borg/connector-http/dist/http-connector.js +34 -6
- package/node_modules/@noodle-borg/connector-http/dist/http-response.d.ts +8 -1
- package/node_modules/@noodle-borg/connector-http/dist/http-response.js +19 -10
- package/node_modules/@noodle-borg/connector-http/dist/index.d.ts +1 -1
- package/node_modules/@noodle-borg/control-plane/dist/contracts.d.ts +2 -0
- package/node_modules/@noodle-borg/control-plane/dist/deploy-gates.js +1 -0
- package/node_modules/@noodle-borg/module/dist/contract.d.ts +2 -0
- package/node_modules/@noodle-borg/runtime/dist/connector/types.d.ts +7 -1
- package/node_modules/@noodle-borg/runtime/dist/connector-snapshot.js +8 -0
- package/node_modules/@noodle-borg/runtime/dist/execute.d.ts +2 -0
- package/node_modules/@noodle-borg/runtime/dist/index.d.ts +1 -0
- package/node_modules/@noodle-borg/runtime/dist/nested-operation-host.js +25 -0
- package/node_modules/@noodle-borg/runtime/dist/operation-coordination-execution.js +50 -0
- package/node_modules/@noodle-borg/runtime/dist/operation-coordination.d.ts +34 -0
- package/node_modules/@noodle-borg/runtime/dist/operation-evidence.d.ts +4 -0
- package/node_modules/@noodle-borg/runtime/dist/operation-execution.js +173 -94
- package/node_modules/@noodle-borg/service/dist/application-activity.js +152 -18
- package/node_modules/@noodle-borg/service/dist/application-runtime-target.js +15 -2
- package/node_modules/@noodle-borg/service/dist/business-information/definition-resolver.js +19 -0
- package/node_modules/@noodle-borg/service/dist/business-information/in-memory-store.js +1 -1
- package/node_modules/@noodle-borg/service/dist/business-information/managed-solution-blueprints.js +7 -0
- package/node_modules/@noodle-borg/service/dist/business-information/managed-solution-executable.js +11 -1
- package/node_modules/@noodle-borg/service/dist/business-information/model.js +2 -2
- package/node_modules/@noodle-borg/service/dist/business-information/portable.js +1 -1
- package/node_modules/@noodle-borg/service/dist/business-information/profiles.js +37 -1
- package/node_modules/@noodle-borg/service/dist/credential-binding-index.js +19 -1
- package/node_modules/@noodle-borg/service/dist/deployment-execution.js +1 -1
- package/node_modules/@noodle-borg/service/dist/operation-coordination.js +185 -0
- package/node_modules/@noodle-borg/service/dist/operation-evidence.js +3 -1
- package/node_modules/@noodle-borg/service/dist/routes/business-information-activity.js +48 -53
- package/node_modules/@noodle-borg/service/dist/routes/business-information-dispatch.js +2 -1
- package/node_modules/@noodle-borg/service/dist/routes/business-information-installation.js +51 -17
- package/node_modules/@noodle-borg/service/dist/routes/business-information-paths.js +6 -4
- package/node_modules/@noodle-borg/service/dist/routes/business-information-staff.js +4 -3
- package/node_modules/@noodle-borg/service/dist/routes/business-information.js +11 -6
- package/node_modules/@noodle-borg/service/dist/routes/control-plane.js +14 -1
- package/node_modules/@noodle-borg/service/dist/routes/deploy-public-embed.js +7 -2
- package/node_modules/@noodle-borg/service/dist/service.js +2 -1
- package/node_modules/@noodle-borg/service/dist/solution-installation-activation.js +58 -3
- package/node_modules/@noodle-borg/service/package.json +1 -1
- package/node_modules/@noodle-borg/wire-contracts/dist/business-information.d.ts +52 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/business-information.js +6 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/index.d.ts +1 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/index.js +1 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/operation-coordination.d.ts +59 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/operation-coordination.js +51 -0
- package/node_modules/@noodleseed/assistant/package.json +1 -1
- package/package.json +2 -2
|
@@ -99,6 +99,21 @@ declare const httpOperationSchema: z.ZodObject<{
|
|
|
99
99
|
"form-urlencoded": "form-urlencoded";
|
|
100
100
|
}>>;
|
|
101
101
|
response: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
102
|
+
responses: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
103
|
+
response: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
104
|
+
responseType: z.ZodOptional<z.ZodEnum<{
|
|
105
|
+
json: "json";
|
|
106
|
+
text: "text";
|
|
107
|
+
empty: "empty";
|
|
108
|
+
}>>;
|
|
109
|
+
evidence: z.ZodOptional<z.ZodObject<{
|
|
110
|
+
outcome: z.ZodEnum<{
|
|
111
|
+
unknown: "unknown";
|
|
112
|
+
rejected: "rejected";
|
|
113
|
+
}>;
|
|
114
|
+
reference: z.ZodOptional<z.ZodString>;
|
|
115
|
+
}, z.core.$strict>>;
|
|
116
|
+
}, z.core.$strict>>>;
|
|
102
117
|
evidence: z.ZodOptional<z.ZodObject<{
|
|
103
118
|
outcome: z.ZodString;
|
|
104
119
|
reference: z.ZodOptional<z.ZodString>;
|
|
@@ -340,6 +355,12 @@ declare const computeOperationSchema: z.ZodObject<{
|
|
|
340
355
|
maxHostCalls: z.ZodOptional<z.ZodNumber>;
|
|
341
356
|
}, z.core.$strict>>;
|
|
342
357
|
calls: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
358
|
+
coordination: z.ZodOptional<z.ZodObject<{
|
|
359
|
+
connectionId: z.ZodString;
|
|
360
|
+
namespace: z.ZodString;
|
|
361
|
+
key: z.ZodString;
|
|
362
|
+
reference: z.ZodString;
|
|
363
|
+
}, z.core.$strict>>;
|
|
343
364
|
credentials: z.ZodOptional<z.ZodObject<{
|
|
344
365
|
profiles: z.ZodArray<z.ZodString>;
|
|
345
366
|
scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -453,6 +474,21 @@ declare const httpConnectorDefSchema: z.ZodObject<{
|
|
|
453
474
|
"form-urlencoded": "form-urlencoded";
|
|
454
475
|
}>>;
|
|
455
476
|
response: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
477
|
+
responses: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
478
|
+
response: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
479
|
+
responseType: z.ZodOptional<z.ZodEnum<{
|
|
480
|
+
json: "json";
|
|
481
|
+
text: "text";
|
|
482
|
+
empty: "empty";
|
|
483
|
+
}>>;
|
|
484
|
+
evidence: z.ZodOptional<z.ZodObject<{
|
|
485
|
+
outcome: z.ZodEnum<{
|
|
486
|
+
unknown: "unknown";
|
|
487
|
+
rejected: "rejected";
|
|
488
|
+
}>;
|
|
489
|
+
reference: z.ZodOptional<z.ZodString>;
|
|
490
|
+
}, z.core.$strict>>;
|
|
491
|
+
}, z.core.$strict>>>;
|
|
456
492
|
evidence: z.ZodOptional<z.ZodObject<{
|
|
457
493
|
outcome: z.ZodString;
|
|
458
494
|
reference: z.ZodOptional<z.ZodString>;
|
|
@@ -796,6 +832,12 @@ declare const computeConnectorDefSchema: z.ZodObject<{
|
|
|
796
832
|
maxHostCalls: z.ZodOptional<z.ZodNumber>;
|
|
797
833
|
}, z.core.$strict>>;
|
|
798
834
|
calls: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
835
|
+
coordination: z.ZodOptional<z.ZodObject<{
|
|
836
|
+
connectionId: z.ZodString;
|
|
837
|
+
namespace: z.ZodString;
|
|
838
|
+
key: z.ZodString;
|
|
839
|
+
reference: z.ZodString;
|
|
840
|
+
}, z.core.$strict>>;
|
|
799
841
|
credentials: z.ZodOptional<z.ZodObject<{
|
|
800
842
|
profiles: z.ZodArray<z.ZodString>;
|
|
801
843
|
scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -927,6 +969,21 @@ declare const connectorDefSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
927
969
|
"form-urlencoded": "form-urlencoded";
|
|
928
970
|
}>>;
|
|
929
971
|
response: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
972
|
+
responses: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
973
|
+
response: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
974
|
+
responseType: z.ZodOptional<z.ZodEnum<{
|
|
975
|
+
json: "json";
|
|
976
|
+
text: "text";
|
|
977
|
+
empty: "empty";
|
|
978
|
+
}>>;
|
|
979
|
+
evidence: z.ZodOptional<z.ZodObject<{
|
|
980
|
+
outcome: z.ZodEnum<{
|
|
981
|
+
unknown: "unknown";
|
|
982
|
+
rejected: "rejected";
|
|
983
|
+
}>;
|
|
984
|
+
reference: z.ZodOptional<z.ZodString>;
|
|
985
|
+
}, z.core.$strict>>;
|
|
986
|
+
}, z.core.$strict>>>;
|
|
930
987
|
evidence: z.ZodOptional<z.ZodObject<{
|
|
931
988
|
outcome: z.ZodString;
|
|
932
989
|
reference: z.ZodOptional<z.ZodString>;
|
|
@@ -1266,6 +1323,12 @@ declare const connectorDefSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
1266
1323
|
maxHostCalls: z.ZodOptional<z.ZodNumber>;
|
|
1267
1324
|
}, z.core.$strict>>;
|
|
1268
1325
|
calls: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
1326
|
+
coordination: z.ZodOptional<z.ZodObject<{
|
|
1327
|
+
connectionId: z.ZodString;
|
|
1328
|
+
namespace: z.ZodString;
|
|
1329
|
+
key: z.ZodString;
|
|
1330
|
+
reference: z.ZodString;
|
|
1331
|
+
}, z.core.$strict>>;
|
|
1269
1332
|
credentials: z.ZodOptional<z.ZodObject<{
|
|
1270
1333
|
profiles: z.ZodArray<z.ZodString>;
|
|
1271
1334
|
scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -1394,6 +1457,21 @@ export declare const connectorFileSchema: z.ZodObject<{
|
|
|
1394
1457
|
"form-urlencoded": "form-urlencoded";
|
|
1395
1458
|
}>>;
|
|
1396
1459
|
response: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
1460
|
+
responses: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
1461
|
+
response: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
1462
|
+
responseType: z.ZodOptional<z.ZodEnum<{
|
|
1463
|
+
json: "json";
|
|
1464
|
+
text: "text";
|
|
1465
|
+
empty: "empty";
|
|
1466
|
+
}>>;
|
|
1467
|
+
evidence: z.ZodOptional<z.ZodObject<{
|
|
1468
|
+
outcome: z.ZodEnum<{
|
|
1469
|
+
unknown: "unknown";
|
|
1470
|
+
rejected: "rejected";
|
|
1471
|
+
}>;
|
|
1472
|
+
reference: z.ZodOptional<z.ZodString>;
|
|
1473
|
+
}, z.core.$strict>>;
|
|
1474
|
+
}, z.core.$strict>>>;
|
|
1397
1475
|
evidence: z.ZodOptional<z.ZodObject<{
|
|
1398
1476
|
outcome: z.ZodString;
|
|
1399
1477
|
reference: z.ZodOptional<z.ZodString>;
|
|
@@ -1733,6 +1811,12 @@ export declare const connectorFileSchema: z.ZodObject<{
|
|
|
1733
1811
|
maxHostCalls: z.ZodOptional<z.ZodNumber>;
|
|
1734
1812
|
}, z.core.$strict>>;
|
|
1735
1813
|
calls: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
1814
|
+
coordination: z.ZodOptional<z.ZodObject<{
|
|
1815
|
+
connectionId: z.ZodString;
|
|
1816
|
+
namespace: z.ZodString;
|
|
1817
|
+
key: z.ZodString;
|
|
1818
|
+
reference: z.ZodString;
|
|
1819
|
+
}, z.core.$strict>>;
|
|
1736
1820
|
credentials: z.ZodOptional<z.ZodObject<{
|
|
1737
1821
|
profiles: z.ZodArray<z.ZodString>;
|
|
1738
1822
|
scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -308,6 +308,25 @@ const httpOperationSchema = z
|
|
|
308
308
|
/** How to encode a non-GET request mapping. JSON remains the default. */
|
|
309
309
|
requestEncoding: z.enum(['json', 'form-urlencoded']).optional(),
|
|
310
310
|
response: exprMapSchema.optional(),
|
|
311
|
+
/** Explicit expected rejection outcomes. Authentication, redirects, rate limits and 5xx fail closed. */
|
|
312
|
+
responses: z
|
|
313
|
+
.record(z
|
|
314
|
+
.string()
|
|
315
|
+
.regex(/^4\d\d$/u)
|
|
316
|
+
.refine((status) => !['401', '403', '429'].includes(status)), z
|
|
317
|
+
.object({
|
|
318
|
+
response: exprMapSchema,
|
|
319
|
+
responseType: z.enum(['json', 'text', 'empty']).optional(),
|
|
320
|
+
evidence: z
|
|
321
|
+
.object({
|
|
322
|
+
outcome: z.enum(['rejected', 'unknown']),
|
|
323
|
+
reference: z.string().min(1).optional(),
|
|
324
|
+
})
|
|
325
|
+
.strict()
|
|
326
|
+
.optional(),
|
|
327
|
+
})
|
|
328
|
+
.strict())
|
|
329
|
+
.optional(),
|
|
311
330
|
/** Explicit provider evidence mapping; never infer completion from an HTTP status or tool name. */
|
|
312
331
|
evidence: z
|
|
313
332
|
.object({ outcome: z.string().min(1), reference: z.string().min(1).optional() })
|
|
@@ -339,6 +358,13 @@ const httpOperationSchema = z
|
|
|
339
358
|
})
|
|
340
359
|
.strict()
|
|
341
360
|
.superRefine((operation, ctx) => {
|
|
361
|
+
if (operation.responses !== undefined && operation.pagination !== undefined) {
|
|
362
|
+
ctx.addIssue({
|
|
363
|
+
code: z.ZodIssueCode.custom,
|
|
364
|
+
path: ['responses'],
|
|
365
|
+
message: 'HTTP response status mappings cannot be combined with pagination',
|
|
366
|
+
});
|
|
367
|
+
}
|
|
342
368
|
if (operation.requestEncoding !== 'form-urlencoded')
|
|
343
369
|
return;
|
|
344
370
|
if (operation.method === undefined || operation.method === 'GET') {
|
|
@@ -426,9 +452,26 @@ const computeOperationSchema = z
|
|
|
426
452
|
code: z.string().min(1),
|
|
427
453
|
limits: computeLimitsSchema.optional(),
|
|
428
454
|
calls: z.record(z.string(), z.string().min(1)).optional(),
|
|
455
|
+
coordination: z
|
|
456
|
+
.object({
|
|
457
|
+
connectionId: z.string().regex(/^[A-Za-z0-9_-]{1,128}$/),
|
|
458
|
+
namespace: z.string().regex(/^[A-Za-z0-9_-]{1,80}$/),
|
|
459
|
+
key: z.string().min(1).max(4096),
|
|
460
|
+
reference: z.string().min(1).max(4096),
|
|
461
|
+
})
|
|
462
|
+
.strict()
|
|
463
|
+
.optional(),
|
|
429
464
|
credentials: operationCredentialsSchema.optional(),
|
|
430
465
|
})
|
|
431
|
-
.strict()
|
|
466
|
+
.strict()
|
|
467
|
+
.superRefine((operation, ctx) => {
|
|
468
|
+
if (operation.coordination && operation.type !== 'action')
|
|
469
|
+
ctx.addIssue({
|
|
470
|
+
code: 'custom',
|
|
471
|
+
path: ['coordination'],
|
|
472
|
+
message: 'Coordination requires an action operation',
|
|
473
|
+
});
|
|
474
|
+
});
|
|
432
475
|
const managedVariableExpressionSchema = z
|
|
433
476
|
.string()
|
|
434
477
|
.regex(/^\$\{env\.[A-Za-z0-9_]+\}$/, 'must be an exact managed variable expression');
|
|
@@ -49,6 +49,12 @@ export interface HttpOperationFake {
|
|
|
49
49
|
readonly response?: unknown;
|
|
50
50
|
readonly pages?: readonly unknown[];
|
|
51
51
|
}
|
|
52
|
+
/** Explicit application outcomes for selected provider rejections, never transport/auth failures. */
|
|
53
|
+
export interface HttpStatusResponse {
|
|
54
|
+
readonly responseType?: 'json' | 'text' | 'empty';
|
|
55
|
+
readonly mapResponse: (body: unknown, args: Readonly<Record<string, unknown>>) => Record<string, unknown>;
|
|
56
|
+
readonly evidence?: (body: unknown) => OperationEvidence;
|
|
57
|
+
}
|
|
52
58
|
/**
|
|
53
59
|
* A single HTTP operation. `GET`, `POST`, `PUT`, `PATCH`, and `DELETE` are supported. The `path` template is
|
|
54
60
|
* filled from validated args
|
|
@@ -57,6 +63,7 @@ export interface HttpOperationFake {
|
|
|
57
63
|
* declared output fields.
|
|
58
64
|
*/
|
|
59
65
|
export interface HttpOperation {
|
|
66
|
+
readonly responses?: Readonly<Record<string, HttpStatusResponse>>;
|
|
60
67
|
readonly evidence?: (json: unknown) => OperationEvidence;
|
|
61
68
|
/** Compiler-derived requirement for mappings that consume the trusted operation identity. */
|
|
62
69
|
readonly requiresExecution?: boolean;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isCustomerEndpointRef, } from '@noodle-borg/compiler';
|
|
2
2
|
import { ConnectorInvocationError, } from '@noodle-borg/runtime';
|
|
3
3
|
import { customerRouteUnavailable, frozenCustomerEndpointRef, isWithinCustomerBase, resolveCustomerBase, sanitizedCustomerRouteError, } from './customer-route.js';
|
|
4
|
-
import { fetchResponseWithResilience } from './http-response.js';
|
|
4
|
+
import { fetchResponseWithResilience, } from './http-response.js';
|
|
5
5
|
import { applyProjection } from './projection.js';
|
|
6
6
|
import { requestPayload, setOwnedHeader } from './request-encoding.js';
|
|
7
7
|
import { assertPublicResolution, needsGuard } from './ssrf.js';
|
|
@@ -32,6 +32,8 @@ export class HttpConnector {
|
|
|
32
32
|
this.id = config.id;
|
|
33
33
|
this.version = config.version;
|
|
34
34
|
this.#config = config;
|
|
35
|
+
for (const operation of Object.values(config.operations))
|
|
36
|
+
validateStatusResponses(operation);
|
|
35
37
|
const customerRouted = isCustomerEndpointRef(config.baseUrl);
|
|
36
38
|
this.#customerBase = customerRouted ? frozenCustomerEndpointRef(config.baseUrl) : undefined;
|
|
37
39
|
const origins = customerRouted
|
|
@@ -115,9 +117,23 @@ export class HttpConnector {
|
|
|
115
117
|
...(call.signal === undefined ? {} : { signal: call.signal }),
|
|
116
118
|
...(payload !== undefined ? { body: payload } : {}),
|
|
117
119
|
};
|
|
118
|
-
const
|
|
119
|
-
? await this.#
|
|
120
|
-
:
|
|
120
|
+
const response = op.pagination === undefined
|
|
121
|
+
? await this.#fetchResponseWithResilience(url, op, init)
|
|
122
|
+
: {
|
|
123
|
+
status: 200,
|
|
124
|
+
body: await this.#fetchPaginatedJson(op, call.args, base, init, customerBase, allowed),
|
|
125
|
+
};
|
|
126
|
+
const json = response.body;
|
|
127
|
+
const statusResponse = op.responses?.[String(response.status)];
|
|
128
|
+
if (statusResponse !== undefined) {
|
|
129
|
+
// Do not inherit a successful-response mapping or completion evidence for a provider rejection.
|
|
130
|
+
const output = this.#mapOutput({ ...op, mapResponse: statusResponse.mapResponse }, json, call.args);
|
|
131
|
+
const evidence = statusResponse.evidence?.(json) ?? { outcome: 'unknown' };
|
|
132
|
+
call.reportOutcome?.(evidence.outcome === 'rejected' || evidence.outcome === 'unknown'
|
|
133
|
+
? evidence
|
|
134
|
+
: { outcome: 'unknown' });
|
|
135
|
+
return output;
|
|
136
|
+
}
|
|
121
137
|
if (op.evidence)
|
|
122
138
|
call.reportOutcome?.(op.evidence(json));
|
|
123
139
|
return this.#mapOutput(op, json, call.args);
|
|
@@ -218,7 +234,7 @@ export class HttpConnector {
|
|
|
218
234
|
return this.#collectPaginatedJson(op, args, async (_pageIndex, query) => {
|
|
219
235
|
const url = this.#buildUrl(op, args, base, query);
|
|
220
236
|
await this.#validateUrl(url, customerBase, allowed);
|
|
221
|
-
return this.#
|
|
237
|
+
return (await this.#fetchResponseWithResilience(url, op, init)).body;
|
|
222
238
|
});
|
|
223
239
|
}
|
|
224
240
|
#fakeJson(operation, op) {
|
|
@@ -301,7 +317,7 @@ export class HttpConnector {
|
|
|
301
317
|
}
|
|
302
318
|
return aggregate(pages, items, true, 'max_pages');
|
|
303
319
|
}
|
|
304
|
-
#
|
|
320
|
+
#fetchResponseWithResilience(url, op, init) {
|
|
305
321
|
return fetchResponseWithResilience(url, op, init, {
|
|
306
322
|
...(this.#config.maxBytes === undefined ? {} : { maxBytes: this.#config.maxBytes }),
|
|
307
323
|
...(this.#config.timeoutMs === undefined ? {} : { timeoutMs: this.#config.timeoutMs }),
|
|
@@ -309,6 +325,18 @@ export class HttpConnector {
|
|
|
309
325
|
});
|
|
310
326
|
}
|
|
311
327
|
}
|
|
328
|
+
function validateStatusResponses(operation) {
|
|
329
|
+
if (operation.responses === undefined)
|
|
330
|
+
return;
|
|
331
|
+
if (operation.pagination !== undefined)
|
|
332
|
+
throw new Error('HTTP response status mappings cannot be combined with pagination');
|
|
333
|
+
for (const [status, response] of Object.entries(operation.responses)) {
|
|
334
|
+
if (!/^4\d\d$/u.test(status) || ['401', '403', '429'].includes(status))
|
|
335
|
+
throw new Error('HTTP response status must be an explicit 4xx other than 401, 403, or 429');
|
|
336
|
+
if (typeof response.mapResponse !== 'function')
|
|
337
|
+
throw new Error('HTTP response status requires an explicit response mapping');
|
|
338
|
+
}
|
|
339
|
+
}
|
|
312
340
|
function isManagedOrigin(url, resolved) {
|
|
313
341
|
if (url.origin !== resolved || url.username !== '' || url.password !== '')
|
|
314
342
|
return false;
|
|
@@ -17,12 +17,19 @@ export interface ResponseOperation {
|
|
|
17
17
|
readonly retry?: HttpRetryPolicy;
|
|
18
18
|
};
|
|
19
19
|
readonly maxResponseBytes?: number;
|
|
20
|
+
readonly responses?: Readonly<Record<string, {
|
|
21
|
+
readonly responseType?: 'json' | 'text' | 'empty';
|
|
22
|
+
}>>;
|
|
23
|
+
}
|
|
24
|
+
export interface HttpResponse {
|
|
25
|
+
readonly status: number;
|
|
26
|
+
readonly body: unknown;
|
|
20
27
|
}
|
|
21
28
|
export interface ResponseFetchOptions {
|
|
22
29
|
readonly maxBytes?: number;
|
|
23
30
|
readonly timeoutMs?: number;
|
|
24
31
|
readonly lookup?: DnsLookup;
|
|
25
32
|
}
|
|
26
|
-
export declare function fetchResponseWithResilience(url: URL, op: ResponseOperation, init: RequestInit, options: ResponseFetchOptions): Promise<
|
|
33
|
+
export declare function fetchResponseWithResilience(url: URL, op: ResponseOperation, init: RequestInit, options: ResponseFetchOptions): Promise<HttpResponse>;
|
|
27
34
|
export {};
|
|
28
35
|
//# sourceMappingURL=http-response.d.ts.map
|
|
@@ -42,14 +42,23 @@ export async function fetchResponseWithResilience(url, op, init, options) {
|
|
|
42
42
|
retryable: false,
|
|
43
43
|
});
|
|
44
44
|
}
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
const declared = op.responses?.[String(response.status)];
|
|
46
|
+
const responseType = declared?.responseType ?? op.responseType;
|
|
47
|
+
const acceptedStatus = declared !== undefined;
|
|
48
|
+
if (responseType === 'text') {
|
|
49
|
+
return {
|
|
50
|
+
status: response.status,
|
|
51
|
+
body: await readResponseText(response, max, attempt, retry !== undefined, acceptedStatus),
|
|
52
|
+
};
|
|
47
53
|
}
|
|
48
|
-
if (
|
|
49
|
-
await readResponseText(response, max, attempt, retry !== undefined);
|
|
50
|
-
return {};
|
|
54
|
+
if (responseType === 'empty') {
|
|
55
|
+
await readResponseText(response, max, attempt, retry !== undefined, acceptedStatus);
|
|
56
|
+
return { status: response.status, body: {} };
|
|
51
57
|
}
|
|
52
|
-
return
|
|
58
|
+
return {
|
|
59
|
+
status: response.status,
|
|
60
|
+
body: await readJsonResponse(response, max, attempt, retry !== undefined, acceptedStatus),
|
|
61
|
+
};
|
|
53
62
|
}
|
|
54
63
|
catch (error) {
|
|
55
64
|
const normalized = normalizeAttemptError(error, attempt, retry, op.signature.type === 'read', signal.aborted);
|
|
@@ -112,8 +121,8 @@ async function readTextWithLimit(response, max) {
|
|
|
112
121
|
* guards shared by JSON and text response modes. Non-2xx responses and oversized bodies raise a
|
|
113
122
|
* `ConnectorInvocationError`; the raw decoded string is returned otherwise.
|
|
114
123
|
*/
|
|
115
|
-
async function readResponseText(response, max, attempt, hasRetryPolicy) {
|
|
116
|
-
if (!response.ok) {
|
|
124
|
+
async function readResponseText(response, max, attempt, hasRetryPolicy, acceptedStatus = false) {
|
|
125
|
+
if (!response.ok && !acceptedStatus) {
|
|
117
126
|
const category = categoryForStatus(response.status);
|
|
118
127
|
const retryAfterMs = response.status === 429 ? parseRetryAfterMs(response.headers.get('retry-after')) : undefined;
|
|
119
128
|
throw new ConnectorInvocationError(`backend responded ${response.status}`, {
|
|
@@ -149,8 +158,8 @@ async function readResponseText(response, max, attempt, hasRetryPolicy) {
|
|
|
149
158
|
throw error;
|
|
150
159
|
}
|
|
151
160
|
}
|
|
152
|
-
async function readJsonResponse(response, max, attempt, hasRetryPolicy) {
|
|
153
|
-
const text = await readResponseText(response, max, attempt, hasRetryPolicy);
|
|
161
|
+
async function readJsonResponse(response, max, attempt, hasRetryPolicy, acceptedStatus = false) {
|
|
162
|
+
const text = await readResponseText(response, max, attempt, hasRetryPolicy, acceptedStatus);
|
|
154
163
|
try {
|
|
155
164
|
return JSON.parse(text);
|
|
156
165
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { type HttpAuthScheme, HttpConnector, type HttpConnectorConfig, type HttpOperation, type HttpOperationFake, type HttpOperationPagination, type HttpPaginationAggregate, type HttpPaginationStopReason, } from './http-connector.js';
|
|
1
|
+
export { type HttpAuthScheme, HttpConnector, type HttpConnectorConfig, type HttpOperation, type HttpOperationFake, type HttpOperationPagination, type HttpPaginationAggregate, type HttpPaginationStopReason, type HttpStatusResponse, } from './http-connector.js';
|
|
2
2
|
export * from './mcp/index.js';
|
|
3
3
|
export type { HttpOperationProjection } from './projection.js';
|
|
4
4
|
export type { GuardedFetchOptions } from './ssrf.js';
|
|
@@ -92,6 +92,8 @@ export interface SignupAllowlistRecord {
|
|
|
92
92
|
}
|
|
93
93
|
/** Verified actor authorized to use the deployment and organization control plane. */
|
|
94
94
|
export interface ControlPlaneIdentity {
|
|
95
|
+
/** Server-produced provenance from the exact Google workload verifier; never request data. */
|
|
96
|
+
readonly authenticationKind?: 'google-workload';
|
|
95
97
|
readonly subject: string;
|
|
96
98
|
readonly email: string;
|
|
97
99
|
readonly identityIssuer?: string;
|
|
@@ -135,6 +135,7 @@ export class GoogleWorkloadControlPlaneGate {
|
|
|
135
135
|
identity: {
|
|
136
136
|
subject: identity.subject,
|
|
137
137
|
email,
|
|
138
|
+
authenticationKind: 'google-workload',
|
|
138
139
|
// Workload authority is bound only to the exact immutable Google subject. Email is profile data.
|
|
139
140
|
superAdmin: this.#admins.has(identity.subject.toLowerCase()),
|
|
140
141
|
},
|
|
@@ -53,6 +53,8 @@ export interface ControlPlaneAuthorizer {
|
|
|
53
53
|
authorize(req: IncomingMessage): Promise<ControlPlaneAuthResult> | ControlPlaneAuthResult;
|
|
54
54
|
}
|
|
55
55
|
export interface ControlPlaneIdentity {
|
|
56
|
+
/** Server-produced provenance from the exact Google workload verifier; never request data. */
|
|
57
|
+
readonly authenticationKind?: 'google-workload';
|
|
56
58
|
readonly subject: string;
|
|
57
59
|
readonly email: string;
|
|
58
60
|
readonly superAdmin: boolean;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { CredentialProfile, OperationSignature, ResolvedOperationRef } from '@noodle-borg/compiler';
|
|
2
2
|
import type { DownstreamCredential } from '../broker/types.js';
|
|
3
3
|
import type { CustomerConnectorRoute } from '../customer-routing.js';
|
|
4
|
+
import type { OperationCoordinationDeclaration, OperationCoordinationSnapshot } from '../operation-coordination.js';
|
|
4
5
|
import type { OperationEvidence } from '../operation-evidence.js';
|
|
5
6
|
/** Verified caller claims that may be threaded into first-party connector operations. */
|
|
6
7
|
export interface CallerIdentity {
|
|
@@ -74,7 +75,9 @@ export declare function connectorInvocationErrorMessage(value: unknown): string
|
|
|
74
75
|
* drift checks, policy, broker credentials, connector invocation, redaction, and output validation.
|
|
75
76
|
*/
|
|
76
77
|
export interface ConnectorCallHost {
|
|
77
|
-
callOperation(ref: ResolvedOperationRef, args: Readonly<Record<string, unknown>>, path: string
|
|
78
|
+
callOperation(ref: ResolvedOperationRef, args: Readonly<Record<string, unknown>>, path: string,
|
|
79
|
+
/** Internal inherited execution deadline; never a sandbox-controlled value. */
|
|
80
|
+
parentSignal?: AbortSignal): Promise<unknown>;
|
|
78
81
|
}
|
|
79
82
|
/** A single connector-operation invocation, fully resolved and credentialed by the runtime. */
|
|
80
83
|
export interface ConnectorCall {
|
|
@@ -85,6 +88,8 @@ export interface ConnectorCall {
|
|
|
85
88
|
}>;
|
|
86
89
|
/** Connector/application-classified evidence; never infer completion from a transport status alone. */
|
|
87
90
|
readonly reportOutcome?: (evidence: OperationEvidence) => void;
|
|
91
|
+
readonly coordination?: OperationCoordinationSnapshot;
|
|
92
|
+
readonly resolveCoordination?: () => Promise<void>;
|
|
88
93
|
/** Trusted request attribution for native public writes; never an argument or expression value. */
|
|
89
94
|
readonly publicAdmission?: {
|
|
90
95
|
readonly network: string;
|
|
@@ -130,6 +135,7 @@ export interface Connector {
|
|
|
130
135
|
signature(operation: string): OperationSignature | undefined;
|
|
131
136
|
/** Maximum action execution duration owned by this connector; excludes confirmation/model time. */
|
|
132
137
|
executionBoundMs?(operation: string): number | undefined;
|
|
138
|
+
coordination?(operation: string): OperationCoordinationDeclaration | undefined;
|
|
133
139
|
/** Invoke the operation. May reject; the runtime normalizes the failure (no secret leakage). */
|
|
134
140
|
invoke(call: ConnectorCall): Promise<unknown>;
|
|
135
141
|
}
|
|
@@ -22,6 +22,7 @@ export function withConnectorSnapshot(deps) {
|
|
|
22
22
|
}
|
|
23
23
|
const signatures = new Map();
|
|
24
24
|
const executionBounds = new Map();
|
|
25
|
+
const coordinations = new Map();
|
|
25
26
|
const snapshot = {
|
|
26
27
|
id: connector.id,
|
|
27
28
|
version: connector.version,
|
|
@@ -38,6 +39,13 @@ export function withConnectorSnapshot(deps) {
|
|
|
38
39
|
executionBounds.set(operation, connector.executionBoundMs?.(operation));
|
|
39
40
|
return executionBounds.get(operation);
|
|
40
41
|
},
|
|
42
|
+
coordination(operation) {
|
|
43
|
+
if (!coordinations.has(operation)) {
|
|
44
|
+
const live = connector.coordination?.(operation);
|
|
45
|
+
coordinations.set(operation, live === undefined ? undefined : deepFreeze(structuredClone(live)));
|
|
46
|
+
}
|
|
47
|
+
return coordinations.get(operation);
|
|
48
|
+
},
|
|
41
49
|
invoke(call) {
|
|
42
50
|
return connector.invoke(call);
|
|
43
51
|
},
|
|
@@ -4,6 +4,7 @@ import type { CallerIdentity, ConnectorRegistry, ExecutionTraceSink } from './co
|
|
|
4
4
|
import type { FrozenCustomerRoutes } from './customer-routing.js';
|
|
5
5
|
import { type EvalScope } from './eval/evaluate.js';
|
|
6
6
|
import type { InvocationContext } from './invocation-context.js';
|
|
7
|
+
import type { OperationCoordinationPort } from './operation-coordination.js';
|
|
7
8
|
import type { OperationEvidencePort } from './operation-evidence.js';
|
|
8
9
|
import type { PolicyGate } from './policy/types.js';
|
|
9
10
|
import type { ExecutionResult } from './result.js';
|
|
@@ -36,6 +37,7 @@ export interface ExecuteDeps {
|
|
|
36
37
|
/** Trusted adapter invocation/confirmation identity; never read from tool input or expression scope. */
|
|
37
38
|
readonly invocationId?: string;
|
|
38
39
|
readonly operationEvidence?: OperationEvidencePort;
|
|
40
|
+
readonly operationCoordination?: OperationCoordinationPort;
|
|
39
41
|
/** Hosting snapshot: operator configuration and original connected-account generations. */
|
|
40
42
|
readonly executionBinding?: {
|
|
41
43
|
readonly revision: string;
|
|
@@ -15,6 +15,7 @@ export { type ExecuteDeps, type ExecuteToolDeps, executePrompt, executeResource,
|
|
|
15
15
|
export { executeToolInteractive, resumeTool } from './interactive.js';
|
|
16
16
|
export type { InvocationContext, InvocationContextPreferenceSource, InvocationLocationContext, InvocationTemporalContext, } from './invocation-context.js';
|
|
17
17
|
export { type ManagedOriginResolutionResult, resolveManagedOrigins, } from './managed-origins.js';
|
|
18
|
+
export type { OperationCoordinationDeclaration, OperationCoordinationIntent, OperationCoordinationLease, OperationCoordinationPort, OperationCoordinationSnapshot, } from './operation-coordination.js';
|
|
18
19
|
export type { OperationEvidence, OperationEvidenceIntent, OperationEvidencePort, } from './operation-evidence.js';
|
|
19
20
|
export { AllowAllPolicy } from './policy/allow-all.js';
|
|
20
21
|
export type { PolicyContext, PolicyDecision, PolicyGate } from './policy/types.js';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ConnectorInvocationError } from './connector/types.js';
|
|
2
|
+
/** Bind only exact declared children, retaining the original host's execution/coordination identity. */
|
|
3
|
+
export function nestedOperationHost(ref, host, parentSignal) {
|
|
4
|
+
const calls = ref.calls;
|
|
5
|
+
if (calls === undefined && parentSignal === undefined)
|
|
6
|
+
return host;
|
|
7
|
+
// Legacy artifacts retain their declaration contract while inheriting the parent's deadline.
|
|
8
|
+
return {
|
|
9
|
+
callOperation(target, args, path) {
|
|
10
|
+
const declared = calls?.find((child) => child.connectorId === target.connectorId &&
|
|
11
|
+
child.connectorVersion === target.connectorVersion &&
|
|
12
|
+
child.operation === target.operation &&
|
|
13
|
+
child.signatureHash === target.signatureHash);
|
|
14
|
+
if (calls !== undefined && declared === undefined)
|
|
15
|
+
throw new ConnectorInvocationError('Undeclared nested connector operation', {
|
|
16
|
+
category: 'invalid_response',
|
|
17
|
+
retryable: false,
|
|
18
|
+
});
|
|
19
|
+
// Invoke as a method on the original host: WeakMap custody frames and private symbol state
|
|
20
|
+
// must never migrate to this projection. Caller-supplied binding metadata has no authority.
|
|
21
|
+
return host.callOperation(declared ?? target, args, path, parentSignal);
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=nested-operation-host.js.map
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { evaluateValue } from './eval/evaluate.js';
|
|
2
|
+
const frames = new WeakMap();
|
|
3
|
+
/** Parent evidence is runtime-owned. Child receipts remain durable but are not duplicate business rows. */
|
|
4
|
+
export function coordinatedParentId(host) {
|
|
5
|
+
return frames.get(host)?.at(-1)?.executionId;
|
|
6
|
+
}
|
|
7
|
+
/** Every nested action traverses this guard before credentials or provider I/O. */
|
|
8
|
+
export function admitCoordinatedAction(host) {
|
|
9
|
+
const frame = frames.get(host)?.at(-1);
|
|
10
|
+
if (!frame)
|
|
11
|
+
return true;
|
|
12
|
+
if (!frame.lease.acquired || frame.writeStarted)
|
|
13
|
+
return false;
|
|
14
|
+
frame.writeStarted = true;
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
export async function beginOperationCoordination(input) {
|
|
18
|
+
if (!input.deps.operationCoordination ||
|
|
19
|
+
!input.executionBoundMs ||
|
|
20
|
+
frames.get(input.host)?.length)
|
|
21
|
+
throw new Error('Coordination authority unavailable');
|
|
22
|
+
const scope = { args: input.args, env: input.env, execution: { id: input.executionId } };
|
|
23
|
+
const key = evaluateValue(input.declaration.key, scope);
|
|
24
|
+
const reference = evaluateValue(input.declaration.reference, scope);
|
|
25
|
+
if (typeof key !== 'string' || typeof reference !== 'string')
|
|
26
|
+
throw new Error('Coordination identity invalid');
|
|
27
|
+
const lease = await input.deps.operationCoordination.acquire({
|
|
28
|
+
id: input.executionId,
|
|
29
|
+
connectionId: input.declaration.connectionId,
|
|
30
|
+
namespace: input.declaration.namespace,
|
|
31
|
+
key,
|
|
32
|
+
reference,
|
|
33
|
+
executionBoundMs: input.executionBoundMs,
|
|
34
|
+
});
|
|
35
|
+
const stack = frames.get(input.host) ?? [];
|
|
36
|
+
const frame = { lease, executionId: input.executionId, writeStarted: false };
|
|
37
|
+
stack.push(frame);
|
|
38
|
+
frames.set(input.host, stack);
|
|
39
|
+
return {
|
|
40
|
+
lease,
|
|
41
|
+
didAdmitAction: () => frame.writeStarted,
|
|
42
|
+
dispose() {
|
|
43
|
+
if (stack.at(-1) === frame)
|
|
44
|
+
stack.pop();
|
|
45
|
+
if (stack.length === 0)
|
|
46
|
+
frames.delete(input.host);
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=operation-coordination-execution.js.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { ExprNode } from '@noodle-borg/compiler';
|
|
2
|
+
import type { OperationEvidence } from './operation-evidence.js';
|
|
3
|
+
/** Application-authored resource identity; values resolve before executing the guarded operation. */
|
|
4
|
+
export interface OperationCoordinationDeclaration {
|
|
5
|
+
readonly connectionId: string;
|
|
6
|
+
readonly namespace: string;
|
|
7
|
+
readonly key: ExprNode;
|
|
8
|
+
readonly reference: ExprNode;
|
|
9
|
+
}
|
|
10
|
+
export interface OperationCoordinationIntent {
|
|
11
|
+
readonly id: string;
|
|
12
|
+
readonly connectionId: string;
|
|
13
|
+
readonly namespace: string;
|
|
14
|
+
readonly key: string;
|
|
15
|
+
readonly reference: string;
|
|
16
|
+
readonly executionBoundMs: number;
|
|
17
|
+
}
|
|
18
|
+
export interface OperationCoordinationSnapshot {
|
|
19
|
+
readonly acquired: boolean;
|
|
20
|
+
readonly previous?: {
|
|
21
|
+
readonly reference: string;
|
|
22
|
+
readonly operationDigest: string;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/** A token-bound lease: resolving a prior uncertain effect never admits a write in this invocation. */
|
|
26
|
+
export interface OperationCoordinationLease extends OperationCoordinationSnapshot {
|
|
27
|
+
finish(evidence: OperationEvidence): Promise<void>;
|
|
28
|
+
resolvePrevious(): Promise<void>;
|
|
29
|
+
}
|
|
30
|
+
/** Production implementations share durable authority across service instances. */
|
|
31
|
+
export interface OperationCoordinationPort {
|
|
32
|
+
acquire(intent: OperationCoordinationIntent): Promise<OperationCoordinationLease>;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=operation-coordination.d.ts.map
|
|
@@ -9,6 +9,10 @@ export interface OperationEvidence {
|
|
|
9
9
|
}
|
|
10
10
|
export interface OperationEvidenceIntent {
|
|
11
11
|
readonly id: string;
|
|
12
|
+
/** Trusted coordinated-parent identity; never supplied by application arguments. */
|
|
13
|
+
readonly parentId?: string;
|
|
14
|
+
/** Coordination-selected connection for an outer compute action without a direct credential binding. */
|
|
15
|
+
readonly connectionId?: string;
|
|
12
16
|
readonly tool: string;
|
|
13
17
|
readonly operation: ResolvedOperationRef;
|
|
14
18
|
readonly arguments: Readonly<Record<string, unknown>>;
|