@zackbart/connecta 0.39.0 → 0.41.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/CHANGELOG.md +115 -0
- package/bin/connecta.mjs +4 -8
- package/bin/version.mjs +1 -1
- package/dist/access-tokens.js +6 -4
- package/dist/activity.d.ts +30 -4
- package/dist/activity.js +28 -2
- package/dist/agent-observation.js +24 -2
- package/dist/agent-routes.js +4 -41
- package/dist/auth/clerk.d.ts +6 -1
- package/dist/auth/clerk.js +16 -0
- package/dist/auth/cloudflare-access.js +49 -7
- package/dist/auth/downstream-oauth/consent.js +79 -29
- package/dist/auth/downstream-oauth/grant-store.js +58 -7
- package/dist/auth/downstream-oauth/refresh-records.js +6 -5
- package/dist/auth/downstream-oauth.js +12 -4
- package/dist/auth/native.js +10 -0
- package/dist/auth/oauth-request-not-sent.js +4 -0
- package/dist/auth/static-oauth.js +51 -21
- package/dist/catalog-cache.js +151 -37
- package/dist/catalog-freshness.js +13 -0
- package/dist/catalog-service.js +39 -12
- package/dist/catalog.js +103 -38
- package/dist/config.d.ts +10 -4
- package/dist/config.js +30 -7
- package/dist/connectors/remote-mcp/call.js +1 -1
- package/dist/connectors/remote-mcp/connection.js +52 -7
- package/dist/connectors/remote-mcp/oauth.js +6 -2
- package/dist/connectors/remote-mcp/resources.js +5 -2
- package/dist/connectors/remote-mcp/transport.js +37 -8
- package/dist/connectors/remote-mcp.js +8 -5
- package/dist/credential-contract.d.ts +3 -1
- package/dist/describe-config.d.ts +1 -0
- package/dist/describe-config.js +1 -0
- package/dist/downstream-input.js +11 -2
- package/dist/errors.d.ts +8 -1
- package/dist/errors.js +2 -0
- package/dist/execute.js +20 -7
- package/dist/executor-result.js +1 -1
- package/dist/executors/quickjs-child.js +1 -1
- package/dist/executors/quickjs-runtime.js +1 -1
- package/dist/executors/quickjs.js +1 -1
- package/dist/guarded-transport.js +2 -0
- package/dist/http/client.js +7 -0
- package/dist/http/hatch.js +2 -0
- package/dist/http/node-transport.js +110 -4
- package/dist/http/oauth.js +17 -6
- package/dist/index.js +10 -21
- package/dist/invocation-failure.js +28 -0
- package/dist/invocation.js +77 -35
- package/dist/membership.d.ts +1 -1
- package/dist/meta-tools.js +58 -36
- package/dist/module-contracts.d.ts +3 -1
- package/dist/native-tools.js +12 -5
- package/dist/node.d.ts +7 -0
- package/dist/node.js +82 -3
- package/dist/operation-activity.js +103 -0
- package/dist/operator-record.d.ts +8 -0
- package/dist/operator-record.js +15 -0
- package/dist/operator-ui/generated.js +2 -2
- package/dist/provider-call-facts.js +6 -2
- package/dist/provider.d.ts +1 -1
- package/dist/providers/_shared/google/workspace.d.ts +1 -1
- package/dist/providers/breeze/index.js +1 -1
- package/dist/providers/ccb/index.js +1 -1
- package/dist/providers/cloudflare/index.js +1 -1
- package/dist/providers/docs/index.js +1 -1
- package/dist/providers/drive/index.js +1 -1
- package/dist/providers/forms/index.js +1 -1
- package/dist/providers/github/index.js +1 -1
- package/dist/providers/gmail/index.js +1 -1
- package/dist/providers/granola/index.js +1 -1
- package/dist/providers/overflow/index.js +1 -1
- package/dist/providers/planning-center/index.js +1 -1
- package/dist/providers/planning-center/lib/constants.d.ts +1 -1
- package/dist/providers/quickbooks/api.js +28 -25
- package/dist/providers/quickbooks/index.js +1 -1
- package/dist/providers/quickbooks/lib/writes.js +55 -0
- package/dist/providers/quickbooks/safety.js +17 -5
- package/dist/providers/quickbooks/skill.generated.js +1 -1
- package/dist/providers/sheets/index.js +1 -1
- package/dist/providers/slides/index.js +1 -1
- package/dist/providers/stripe/index.js +2 -2
- package/dist/providers/tithely/index.js +1 -1
- package/dist/providers/vercel/api.js +1 -0
- package/dist/registry.js +16 -4
- package/dist/resource-read.js +21 -2
- package/dist/route-names.js +44 -0
- package/dist/routes/activity-context.js +1 -0
- package/dist/routes/activity-disclosure.js +26 -4
- package/dist/routes/activity.js +2 -1
- package/dist/routes/mcp.js +32 -13
- package/dist/routes/ui-config.js +1 -1
- package/dist/routes/ui-data.js +3 -2
- package/dist/runtime/native-storage.js +15 -0
- package/dist/runtime/request-reads.js +87 -10
- package/dist/runtime/request-scope.js +2 -1
- package/dist/skill-origin.js +16 -0
- package/dist/skills.js +132 -43
- package/dist/storage/d1-driver.js +33 -5
- package/dist/storage/keys.js +7 -1
- package/dist/storage/sql-native.js +85 -3
- package/dist/storage/sql.js +6 -0
- package/dist/timing-trace.js +84 -0
- package/dist/types.d.ts +5 -0
- package/dist/url-safety.js +38 -20
- package/dist/utility-recovery.js +33 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/worker.js +33 -8
- package/documentation/architecture.md +83 -2
- package/documentation/auth.md +132 -37
- package/documentation/code-mode.md +61 -46
- package/documentation/deploying.md +25 -1
- package/documentation/integrating.md +2 -2
- package/documentation/meta-tools.md +134 -15
- package/documentation/operating.md +86 -1
- package/documentation/operator-ui.md +51 -2
- package/documentation/providers.md +16 -14
- package/package.json +10 -8
- package/templates/node/package.json +1 -1
package/dist/url-safety.js
CHANGED
|
@@ -13,11 +13,11 @@
|
|
|
13
13
|
* legacy IPv4 spelling (`2130706433`, `0x7f.1`, `0177.0.0.1`) into dotted
|
|
14
14
|
* decimal and every IPv6 literal into compressed hex, so one canonical form is
|
|
15
15
|
* all this module reads. It never resolves a name: that needs DNS, which the
|
|
16
|
-
* Workers-safe core cannot do
|
|
17
|
-
*
|
|
16
|
+
* Workers-safe core cannot do. The owned Node transport additionally resolves
|
|
17
|
+
* and pins learned destinations at connect time. Pure Web API, no `node:` import.
|
|
18
18
|
*/
|
|
19
19
|
function classifyIpv4(octets) {
|
|
20
|
-
const [a = 0, b = 0] = octets;
|
|
20
|
+
const [a = 0, b = 0, c = 0] = octets;
|
|
21
21
|
if (a === 127)
|
|
22
22
|
return "loopback";
|
|
23
23
|
if (a === 0 ||
|
|
@@ -25,7 +25,14 @@ function classifyIpv4(octets) {
|
|
|
25
25
|
(a === 172 && b >= 16 && b <= 31) ||
|
|
26
26
|
(a === 192 && b === 168) ||
|
|
27
27
|
(a === 169 && b === 254) ||
|
|
28
|
-
(a === 100 && b >= 64 && b <= 127)
|
|
28
|
+
(a === 100 && b >= 64 && b <= 127) ||
|
|
29
|
+
(a === 192 && b === 0 && (c === 0 || c === 2)) || // IETF protocol, documentation
|
|
30
|
+
(a === 192 && b === 88 && c === 99) || // 6to4 relay anycast
|
|
31
|
+
(a === 198 && (b === 18 || b === 19)) || // benchmarking
|
|
32
|
+
(a === 198 && b === 51 && c === 100) || // documentation
|
|
33
|
+
(a === 203 && b === 0 && c === 113) || // documentation
|
|
34
|
+
a >= 224 // multicast, reserved, broadcast
|
|
35
|
+
) {
|
|
29
36
|
return "private";
|
|
30
37
|
}
|
|
31
38
|
return "public";
|
|
@@ -61,24 +68,35 @@ function ipv6Pieces(host) {
|
|
|
61
68
|
return [...head, ...Array.from({ length: missing }, () => 0), ...tail];
|
|
62
69
|
}
|
|
63
70
|
function classifyIpv6(pieces) {
|
|
64
|
-
const [
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
+
const [p0 = 0, p1 = 0, p2 = 0, p3 = 0, p4 = 0, p5 = 0, p6 = 0, p7 = 0] = pieces;
|
|
72
|
+
const v4 = (high, low) => classifyIpv4([high >> 8, high & 0xff, low >> 8, low & 0xff]);
|
|
73
|
+
// A transitional form reaches, at most, the IPv4 address it carries. Only a
|
|
74
|
+
// mapped address can reach this host, so only it stays `loopback`; every
|
|
75
|
+
// other non-public carrier is `private`, keeping it out of a loopback
|
|
76
|
+
// connector's learned URLs.
|
|
77
|
+
const carried = (high, low) => (v4(high, low) === "public" ? "public" : "private");
|
|
78
|
+
const zeros = p0 === 0 && p1 === 0 && p2 === 0 && p3 === 0;
|
|
79
|
+
if (zeros && p4 === 0) {
|
|
80
|
+
if (p5 === 0xffff)
|
|
81
|
+
return v4(p6, p7); // ::ffff:a.b.c.d mapped
|
|
82
|
+
if (p5 === 0) {
|
|
83
|
+
if (p6 === 0 && p7 === 1)
|
|
84
|
+
return "loopback"; // ::1
|
|
85
|
+
return carried(p6, p7); // :: and ::a.b.c.d compatible
|
|
86
|
+
}
|
|
71
87
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
88
|
+
if (zeros && p4 === 0xffff && p5 === 0)
|
|
89
|
+
return carried(p6, p7); // ::ffff:0:a.b.c.d translated
|
|
90
|
+
if (p0 === 0x64 && p1 === 0xff9b && p2 === 0 && p3 === 0 && p4 === 0 && p5 === 0)
|
|
91
|
+
return carried(p6, p7); // NAT64
|
|
92
|
+
if (p0 === 0x2002)
|
|
93
|
+
return carried(p1, p2); // 6to4
|
|
94
|
+
// Global unicast is 2000::/3. Outside it: unique-local, link-local,
|
|
95
|
+
// site-local, multicast, local-use NAT64, reserved. Inside it, special-purpose
|
|
96
|
+
// 2001::/23 and documentation 2001:db8::/32 and 3fff::/20 are not destinations.
|
|
97
|
+
if ((p0 & 0xe000) !== 0x2000 || (p0 === 0x2001 && (p1 < 0x200 || p1 === 0xdb8)) || (p0 === 0x3fff && p1 < 0x1000)) {
|
|
98
|
+
return "private";
|
|
77
99
|
}
|
|
78
|
-
if ((first & 0xfe00) === 0xfc00)
|
|
79
|
-
return "private"; // fc00::/7
|
|
80
|
-
if ((first & 0xffc0) === 0xfe80)
|
|
81
|
-
return "private"; // fe80::/10
|
|
82
100
|
return "public";
|
|
83
101
|
}
|
|
84
102
|
/**
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/** Actions outside the tool namespace never invent a route on a serving surface. */
|
|
2
|
+
export function utilityRecovery(code, message, retryable = false) {
|
|
3
|
+
return {
|
|
4
|
+
code,
|
|
5
|
+
message,
|
|
6
|
+
retryable,
|
|
7
|
+
nextAction: {
|
|
8
|
+
action: ["unsupported_capability", "input_required_unsupported", "invalid_args"].includes(code)
|
|
9
|
+
? "inspect_capabilities"
|
|
10
|
+
: code === "not_found"
|
|
11
|
+
? "recover_result"
|
|
12
|
+
: "contact_operator",
|
|
13
|
+
purpose: ["unsupported_capability", "input_required_unsupported", "invalid_args"].includes(code)
|
|
14
|
+
? "Inspect the supported utility input and client capabilities before a fresh call. Never repeat a write whose outcome is unknown."
|
|
15
|
+
: code === "not_found"
|
|
16
|
+
? "Use a retained result handle if available. Otherwise report the missing output; never repeat a write to recover output."
|
|
17
|
+
: "Ask the operator to restore availability. Retry reads only after recovery; reconcile any write whose outcome is unknown.",
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/** Missing skill names need local discovery, never service restoration or result recovery. */
|
|
22
|
+
export function skillLookupRecovery(message) {
|
|
23
|
+
return {
|
|
24
|
+
code: "not_found",
|
|
25
|
+
message,
|
|
26
|
+
retryable: false,
|
|
27
|
+
nextAction: {
|
|
28
|
+
tool: "skills",
|
|
29
|
+
arguments: {},
|
|
30
|
+
purpose: "List available skills, then fetch an exact name from that list.",
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const CONNECTA_VERSION = "0.
|
|
1
|
+
export declare const CONNECTA_VERSION = "0.41.0";
|
package/dist/version.js
CHANGED
package/dist/worker.js
CHANGED
|
@@ -99,6 +99,20 @@ export function workerExecutor(options) {
|
|
|
99
99
|
// The SDK prepares its source/dispatchers against this inert loader.
|
|
100
100
|
// Actual Loader and RPC acquisition belongs to the native program below.
|
|
101
101
|
let prepared;
|
|
102
|
+
// Upstream 0.5.5+ answers every host call that settles after its
|
|
103
|
+
// evaluate() with a late-call error. Its inert evaluate stays pending
|
|
104
|
+
// until the native evaluation ends, so the SDK's gate stays open for the
|
|
105
|
+
// whole run and closes once the run is over or the lease is released.
|
|
106
|
+
let evaluating;
|
|
107
|
+
const evaluated = new Promise((resolve) => {
|
|
108
|
+
evaluating = resolve;
|
|
109
|
+
});
|
|
110
|
+
let settleUpstream;
|
|
111
|
+
const endUpstream = () => {
|
|
112
|
+
const settle = settleUpstream;
|
|
113
|
+
settleUpstream = undefined;
|
|
114
|
+
settle?.();
|
|
115
|
+
};
|
|
102
116
|
const dispose = (resource) => Effect.sync(() => {
|
|
103
117
|
try {
|
|
104
118
|
const method = Reflect.get(resource, Symbol.dispose);
|
|
@@ -309,7 +323,10 @@ const {
|
|
|
309
323
|
getEntrypoint: () => ({
|
|
310
324
|
evaluate: (...evaluateArgs) => {
|
|
311
325
|
acquisition.args = evaluateArgs;
|
|
312
|
-
return Promise
|
|
326
|
+
return new Promise((resolve) => {
|
|
327
|
+
settleUpstream = () => resolve({ result: undefined });
|
|
328
|
+
evaluating?.();
|
|
329
|
+
});
|
|
313
330
|
},
|
|
314
331
|
}),
|
|
315
332
|
};
|
|
@@ -342,15 +359,21 @@ const {
|
|
|
342
359
|
const started = Date.now();
|
|
343
360
|
const operation = Effect.gen(function* () {
|
|
344
361
|
const setup = yield* Effect.tryPromise({
|
|
345
|
-
try: () =>
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
362
|
+
try: () => {
|
|
363
|
+
const upstream = new DynamicWorkerExecutor({
|
|
364
|
+
loader,
|
|
365
|
+
...(options.timeout !== undefined ? { timeout: options.timeout } : {}),
|
|
366
|
+
}).execute(code, detached);
|
|
367
|
+
// The SDK's own result, which settles only after endUpstream(),
|
|
368
|
+
// carries nothing; the native evaluation below owns the outcome.
|
|
369
|
+
upstream.catch(() => undefined);
|
|
370
|
+
return Promise.race([upstream, evaluated.then(() => undefined)]);
|
|
371
|
+
},
|
|
349
372
|
catch: (error) => error,
|
|
350
373
|
});
|
|
351
374
|
// Provider validation can return before the SDK reaches its loader.
|
|
352
|
-
if (!prepared)
|
|
353
|
-
return setup;
|
|
375
|
+
if (setup !== undefined || !prepared)
|
|
376
|
+
return setup ?? { result: undefined };
|
|
354
377
|
const load = prepared.load;
|
|
355
378
|
const args = prepared.args;
|
|
356
379
|
const open = () => Effect.suspend(() => released || resources.state._tag === "Closed"
|
|
@@ -369,7 +392,7 @@ const {
|
|
|
369
392
|
try: () => Reflect.apply(Reflect.get(entrypoint, "evaluate"), entrypoint, args ?? []),
|
|
370
393
|
catch: (error) => error,
|
|
371
394
|
});
|
|
372
|
-
}).pipe(Scope.provide(resources));
|
|
395
|
+
}).pipe(Scope.provide(resources), Effect.ensuring(Effect.sync(endUpstream)));
|
|
373
396
|
const result = yield* evaluation;
|
|
374
397
|
const outcome = result;
|
|
375
398
|
if (outcome.failure) {
|
|
@@ -407,6 +430,7 @@ const {
|
|
|
407
430
|
}));
|
|
408
431
|
}).pipe(Effect.raceFirst(Deferred.await(stopped)), Effect.catchDefect((error) => Effect.fail(error)), Effect.ensuring(Effect.sync(() => {
|
|
409
432
|
runEnded = true;
|
|
433
|
+
endUpstream();
|
|
410
434
|
hostProviders = undefined;
|
|
411
435
|
prepared = undefined;
|
|
412
436
|
hostFailures.clear();
|
|
@@ -420,6 +444,7 @@ const {
|
|
|
420
444
|
if (released)
|
|
421
445
|
return;
|
|
422
446
|
released = true;
|
|
447
|
+
endUpstream();
|
|
423
448
|
hostProviders = undefined;
|
|
424
449
|
prepared = undefined;
|
|
425
450
|
hostFailures.clear();
|
|
@@ -340,7 +340,7 @@ without storage reads, decryption or hashing. Catalog invalidation (including
|
|
|
340
340
|
operator refresh and OAuth connect/disconnect/restart) advances a counter for the
|
|
341
341
|
registry's cache store; built-in vault set/clear advances a counter for that vault.
|
|
342
342
|
These weakly held counters contain no catalogs, credentials or caller identity;
|
|
343
|
-
catalogs and derived views remain request-local. A moved fence replaces the
|
|
343
|
+
registry catalogs and derived views remain request-local. A moved fence replaces the
|
|
344
344
|
retained read and its search views, and prevents joining an older registry flight.
|
|
345
345
|
Changes made through another process/isolate or directly in storage need not be
|
|
346
346
|
observed mid-request; the next request uses the durable generation and auth checks.
|
|
@@ -619,6 +619,18 @@ Only complete, intake-redacted tools/list, resources/list and
|
|
|
619
619
|
resources/templates/list successes are stored. Resource payloads are not cached. SDK default
|
|
620
620
|
in-memory caching is replaced, so raw catalogs never enter it.
|
|
621
621
|
|
|
622
|
+
A warm isolate retains at most four validated stored JSON catalogs, with a
|
|
623
|
+
combined accounting budget of 8 MiB (twice serialized input bytes, key bytes and
|
|
624
|
+
64 bytes per object property/array slot; larger entries bypass reuse).
|
|
625
|
+
These deeply frozen facts contain no request context, transport, signal,
|
|
626
|
+
callback or promise, and require neither weak references nor cleanup timers.
|
|
627
|
+
Reuse follows the same manifest TTL checks, complete chunk reads, recomputed
|
|
628
|
+
SHA-256 fingerprint and fresh generation/credential acceptance fence as a cold
|
|
629
|
+
read. Its key binds the stored entry, current private owner/deployment partition
|
|
630
|
+
(even for public entries), and chunk fingerprint. Request-specific credential
|
|
631
|
+
redaction and TTL intake still run every time. Eviction affects performance
|
|
632
|
+
only; SQL remains authoritative.
|
|
633
|
+
|
|
622
634
|
Stored catalog and negotiation keys use deployment-keyed partitions. A remote
|
|
623
635
|
connector's whole cache configuration and negotiation input enter a stored key
|
|
624
636
|
only through HMAC-SHA-256 (`src/storage-digest.ts`) under a key that never
|
|
@@ -643,6 +655,28 @@ refresh baselines within 48 hours, verdicts within six hours), so each remote
|
|
|
643
655
|
connector's partitions refill once after the upgrade with one handshake and
|
|
644
656
|
listing.
|
|
645
657
|
|
|
658
|
+
Warm remote resolution batches the negotiation verdict and locating generation
|
|
659
|
+
when their physical keys share an observed SQL store. Private and public
|
|
660
|
+
manifest probes share a `getMany` statement; their normal precedence and public
|
|
661
|
+
scope check still apply. These batches contain only reads. Catalog addresses
|
|
662
|
+
use the listing's pinned OAuth identity and locating generation; they authorize
|
|
663
|
+
nothing. After chunk verification, acceptance re-reads the OAuth identity and
|
|
664
|
+
generation separately and refuses a changed epoch or token digest. The invocation
|
|
665
|
+
gate checks disconnect first, then reads tokens separately to refuse absent
|
|
666
|
+
credentials and observe current expiry and the invalidation fingerprint. Token
|
|
667
|
+
removal, expiry, scope and replacement can change without advancing the epoch;
|
|
668
|
+
epoch fences alone cannot protect these values. The SDK's later token read may
|
|
669
|
+
return no tokens and omit Authorization, so it does not replace invocation's
|
|
670
|
+
token-presence refusal. The transport also refuses tokenless MCP requests on
|
|
671
|
+
passive OAuth paths, regardless of provider history; an explicit authorization
|
|
672
|
+
start may probe for the SDK's challenge. A refused tool send binds its private
|
|
673
|
+
failure provenance to the undispatched physical request. Invocation accepts it
|
|
674
|
+
only for the owning boundary and whole logical call; error fields, copied
|
|
675
|
+
connectors, and refusals after a send cannot supply that proof.
|
|
676
|
+
Connection reuse and SDK dispatch retain their fresh
|
|
677
|
+
epoch or token reads; no credential read is prefetched.
|
|
678
|
+
Stores with replaced methods or separate backing stores retain individual reads.
|
|
679
|
+
|
|
646
680
|
A remote connector's `listTools` without a live connection in its request
|
|
647
681
|
reads this cache before connecting. It derives the same partition a connect
|
|
648
682
|
binds (the admitted principal, the caller's credential digest, or the owner's
|
|
@@ -1008,7 +1042,15 @@ run of K = 8 consecutive UTF-16 units of a registered form of a value at least K
|
|
|
1008
1042
|
long, in the raw text or any JSON-decoded layer; text cut where the cut can end
|
|
1009
1043
|
inside a form loses that unfinished tail, however short.** Runs formed from
|
|
1010
1044
|
placeholder text and kept text or numbers are covered too; the placeholder
|
|
1011
|
-
itself is reserved replacement text.
|
|
1045
|
+
itself is reserved replacement text. The guarantee excludes an occurrence made
|
|
1046
|
+
entirely of reserved replacement text, including a run across the seam between
|
|
1047
|
+
adjacent markers, whether or not the registered form contains a complete
|
|
1048
|
+
`[redacted]`. For example, register `secretsecret` and `ted][red`, then redact
|
|
1049
|
+
`["secretsecret", "secretsecret"]`: the returned leaves may be
|
|
1050
|
+
`["[redacted]", "[redacted]"]`. Their joined projection spells the second
|
|
1051
|
+
registered value using only reserved replacement text; no original secret
|
|
1052
|
+
units survive. An occurrence that includes retained original text stays covered.
|
|
1053
|
+
Registered forms are
|
|
1012
1054
|
the raw value, its URL/form encodings (either percent hex case), base64 and
|
|
1013
1055
|
base64url, and the `Bearer `/`token ` framings. The framing words are public, so
|
|
1014
1056
|
no indexed run starts inside them; a run reaching K units of the value is
|
|
@@ -3738,6 +3780,16 @@ change. All 88 declarations still exclude Effect and have complete references.
|
|
|
3738
3780
|
|
|
3739
3781
|
### Native remote MCP programs (contributor)
|
|
3740
3782
|
|
|
3783
|
+
Legacy session termination may read a token before rotation and send its DELETE
|
|
3784
|
+
on the wire after rotation. This is accepted only for bounded, headers-only
|
|
3785
|
+
termination of the old session, never for application traffic (`tools/call`,
|
|
3786
|
+
`tools/list`, or other RPCs). Connection scope close retains the same cleanup
|
|
3787
|
+
completion after revocation; later connector close joins it so the runtime's
|
|
3788
|
+
deferred hook (Workers `waitUntil`) owns the bounded tail. Abandoned leases from
|
|
3789
|
+
rotation and failed connects, and authorization exchange transports, retain their
|
|
3790
|
+
cleanup in that same request state. Termination and local close keep their
|
|
3791
|
+
existing one-second budgets; the caller-facing close window remains 100 ms.
|
|
3792
|
+
|
|
3741
3793
|
Remote MCP connection joins, credential and epoch checks, catalog intake,
|
|
3742
3794
|
negotiation, calls, resources, Skills, auth and status compose native programs.
|
|
3743
3795
|
`connectors/remote-mcp.ts` keeps the published options, the redirect guard and
|
|
@@ -3884,3 +3936,32 @@ cache. Exact authored names and complete authored matches precede API pointers;
|
|
|
3884
3936
|
ordinary result limits, offsets, catalog failure disclosure and byte bounds apply.
|
|
3885
3937
|
The published discovery contract states compilation, query and cache bounds.
|
|
3886
3938
|
No request identity, signal, credential or promise enters a vocabulary cache.
|
|
3939
|
+
|
|
3940
|
+
SQL catalog locating snapshots derive at most two manifest candidates from the
|
|
3941
|
+
stored generation alongside negotiation and generation rows. These candidates
|
|
3942
|
+
are request-local hints with exact config, owner and credential partitions.
|
|
3943
|
+
Complete chunk verification and a separate later primary generation and identity
|
|
3944
|
+
fence decide acceptance. OAuth invocation and dispatch reads stay separate.
|
|
3945
|
+
|
|
3946
|
+
SQL result stashes write at most 64 trailing rows per awaited transaction, with one
|
|
3947
|
+
expiry sweep per batch. Header publication follows confirmed trailing writes in a
|
|
3948
|
+
separate transaction; uncertain writes retain their ledger charge until expiry.
|
|
3949
|
+
Custom storage keeps sequential writes.
|
|
3950
|
+
|
|
3951
|
+
Admission observation sampling retains at most 256 scalar deadlines per live
|
|
3952
|
+
physical storage identity in an isolate. Only a recent valid stored timestamp
|
|
3953
|
+
or confirmed CAS populates it, for at most one minute. This telemetry cache
|
|
3954
|
+
never answers token admission; every request still checks current credentials.
|
|
3955
|
+
|
|
3956
|
+
### Lexical token reuse (contributor)
|
|
3957
|
+
|
|
3958
|
+
Search may retain four complete accepted catalog token indexes, bounded by an
|
|
3959
|
+
8 MiB estimate including key text, token strings, postings and structural slots.
|
|
3960
|
+
Identity includes complete served content (including schemas, classification and
|
|
3961
|
+
order), connector, physical store, owner partition/revisions and the downstream catalog
|
|
3962
|
+
generation observed by the current successful listing. The generation marker
|
|
3963
|
+
is request-local primitive evidence; it grants no cache acceptance or authority. Only immutable
|
|
3964
|
+
strings and numeric positions cross requests. Search views map positions to the
|
|
3965
|
+
current request's definitions after owner visibility, classification, redaction
|
|
3966
|
+
and endpoint restrictions; no query results are retained. Partial failed
|
|
3967
|
+
catalogs cannot enter this cache. Eviction changes cost only, never results.
|