@zackbart/connecta 0.37.1 → 0.39.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.
Files changed (265) hide show
  1. package/CHANGELOG.md +94 -0
  2. package/README.md +5 -4
  3. package/bin/connecta.mjs +1 -39
  4. package/bin/version.mjs +1 -1
  5. package/dist/access-tokens.js +2 -4
  6. package/dist/agent-identity.js +1 -1
  7. package/dist/agent-routes.js +231 -0
  8. package/dist/auth/clerk-sdk/generated.js +2 -1
  9. package/dist/auth/downstream-oauth/consent.js +519 -0
  10. package/dist/auth/downstream-oauth/grant-store.js +439 -0
  11. package/dist/auth/downstream-oauth/refresh-coordinator.js +562 -0
  12. package/dist/auth/downstream-oauth/refresh-records.js +447 -0
  13. package/dist/auth/downstream-oauth/sdk-hooks.js +242 -0
  14. package/dist/auth/downstream-oauth.js +66 -2516
  15. package/dist/auth/downstream-revocation.js +1 -1
  16. package/dist/auth/native.js +27 -0
  17. package/dist/auth/oauth-grant.js +24 -0
  18. package/dist/auth/oauth-token-response.js +1 -1
  19. package/dist/auth/static-oauth.js +153 -131
  20. package/dist/auth/vercel-agent.js +2 -1
  21. package/dist/auth-elicitation.js +9 -3
  22. package/dist/authorization-handoff.js +11 -5
  23. package/dist/branding.d.ts +1 -15
  24. package/dist/branding.js +2 -2
  25. package/dist/bytes.js +42 -0
  26. package/dist/call-admission-context.js +2 -5
  27. package/dist/call-recovery.js +0 -3
  28. package/dist/catalog-cache.js +130 -43
  29. package/dist/catalog-fingerprint.js +2 -18
  30. package/dist/catalog-policy.js +18 -0
  31. package/dist/catalog-service.js +285 -48
  32. package/dist/catalog.js +18 -2
  33. package/dist/config-defaults.d.ts +1 -0
  34. package/dist/config-defaults.js +1 -0
  35. package/dist/config-schema.d.ts +1 -1
  36. package/dist/config-schema.js +6 -2
  37. package/dist/config.d.ts +57 -25
  38. package/dist/config.js +30 -77
  39. package/dist/connector-caller.d.ts +1 -1
  40. package/dist/connector-health.js +59 -0
  41. package/dist/connector-status.js +117 -0
  42. package/dist/connectors/api-connector.d.ts +7 -2
  43. package/dist/connectors/api-connector.js +11 -7
  44. package/dist/connectors/guarded-fetch.d.ts +0 -6
  45. package/dist/connectors/guarded-fetch.js +1 -11
  46. package/dist/connectors/negotiation-cache.js +22 -4
  47. package/dist/connectors/remote-mcp/call.js +164 -0
  48. package/dist/connectors/remote-mcp/catalog.js +278 -0
  49. package/dist/connectors/remote-mcp/config.js +263 -0
  50. package/dist/connectors/remote-mcp/connection.js +671 -0
  51. package/dist/connectors/remote-mcp/errors.js +488 -0
  52. package/dist/connectors/remote-mcp/oauth.js +469 -0
  53. package/dist/connectors/remote-mcp/resources.js +473 -0
  54. package/dist/connectors/remote-mcp/runtime.js +1 -0
  55. package/dist/connectors/remote-mcp/transport.js +544 -0
  56. package/dist/connectors/remote-mcp.js +61 -2898
  57. package/dist/connectors/resource-uri.js +0 -4
  58. package/dist/credential-contract.d.ts +23 -0
  59. package/dist/credential-reads.js +17 -0
  60. package/dist/credential-verification.js +53 -0
  61. package/dist/credentials.d.ts +7 -0
  62. package/dist/credentials.js +60 -25
  63. package/dist/d1.d.ts +0 -89
  64. package/dist/d1.js +0 -34
  65. package/dist/describe-config.d.ts +12 -2
  66. package/dist/describe-config.js +2 -0
  67. package/dist/discovery-health.js +199 -0
  68. package/dist/downstream-input.js +4 -2
  69. package/dist/errors.d.ts +55 -17
  70. package/dist/errors.js +95 -41
  71. package/dist/execute.js +172 -125
  72. package/dist/executor-result.js +5 -2
  73. package/dist/executors/quickjs-runtime.js +2 -25
  74. package/dist/executors/quickjs.js +1 -1
  75. package/dist/guest-functions.js +83 -0
  76. package/dist/guest-runtime.js +63 -20
  77. package/dist/guest-types.d.ts +24 -10
  78. package/dist/http/argument-problems.js +35 -0
  79. package/dist/http/client.js +1 -1
  80. package/dist/http/errors.js +7 -6
  81. package/dist/http/fields.js +192 -13
  82. package/dist/http/hatch-response.js +73 -0
  83. package/dist/http/hatch.js +88 -23
  84. package/dist/http/json-schema.js +1 -1
  85. package/dist/http/node-transport.js +0 -1
  86. package/dist/http/oauth.js +4 -3
  87. package/dist/http/paging.js +6 -9
  88. package/dist/http/provider.js +33 -5
  89. package/dist/http/safety.js +9 -1
  90. package/dist/http/services.js +1 -8
  91. package/dist/http/tools.js +45 -30
  92. package/dist/http/vendor.js +7 -7
  93. package/dist/identity.js +2 -6
  94. package/dist/index.d.ts +1 -1
  95. package/dist/index.js +9 -2
  96. package/dist/invocation-auth.js +2 -1
  97. package/dist/invocation.js +21 -6
  98. package/dist/membership.d.ts +13 -5
  99. package/dist/membership.js +34 -2
  100. package/dist/meta-tools.js +50 -35
  101. package/dist/native-recovery.js +4 -16
  102. package/dist/native-tools.js +6 -2
  103. package/dist/oauth-handoff.js +2 -2
  104. package/dist/oauth-sealing.js +10 -0
  105. package/dist/operation-vocabulary.js +136 -14
  106. package/dist/operator-record.d.ts +2 -2
  107. package/dist/operator-record.js +2 -49
  108. package/dist/operator-ui/contract.d.ts +12 -2
  109. package/dist/operator-ui/generated.js +3 -3
  110. package/dist/operator-ui/model.d.ts +22 -1
  111. package/dist/program-writes.js +3 -8
  112. package/dist/provider-call.js +0 -7
  113. package/dist/provider.d.ts +1 -1
  114. package/dist/providers/_shared/google/kit.js +1 -6
  115. package/dist/providers/_shared/google/service-account.js +1 -3
  116. package/dist/providers/_shared/google/workspace.d.ts +1 -1
  117. package/dist/providers/_shared/guide.js +3 -0
  118. package/dist/providers/_shared/json.js +12 -0
  119. package/dist/providers/_shared/rest/compact-index.js +1 -1
  120. package/dist/providers/_shared/rest/kit.js +1 -3
  121. package/dist/providers/_shared/rest/operation-index.js +49 -53
  122. package/dist/providers/_shared/rest/value-safety.js +106 -28
  123. package/dist/providers/breeze/api.js +9 -8
  124. package/dist/providers/breeze/index.js +4 -2
  125. package/dist/providers/breeze/skill.generated.js +1 -1
  126. package/dist/providers/breeze/tools.js +7 -7
  127. package/dist/providers/ccb/api.js +3 -7
  128. package/dist/providers/ccb/index.js +7 -1
  129. package/dist/providers/ccb/skill.generated.js +1 -1
  130. package/dist/providers/ccb/tools.js +1 -6
  131. package/dist/providers/cloudflare/api.js +10 -3
  132. package/dist/providers/cloudflare/index.js +2 -1
  133. package/dist/providers/cloudflare/safety.js +3 -3
  134. package/dist/providers/cloudflare/skill.generated.js +1 -1
  135. package/dist/providers/docs/lib/schemas.js +24 -22
  136. package/dist/providers/docs/safety.js +2 -0
  137. package/dist/providers/docs/skill.generated.js +1 -1
  138. package/dist/providers/docs/tools.js +4 -14
  139. package/dist/providers/drive/api.js +1 -0
  140. package/dist/providers/drive/lib/contracts.js +8 -5
  141. package/dist/providers/drive/skill.generated.js +1 -1
  142. package/dist/providers/drive/tools.js +23 -41
  143. package/dist/providers/forms/api.js +1 -0
  144. package/dist/providers/forms/skill.generated.js +1 -1
  145. package/dist/providers/forms/tools.js +11 -16
  146. package/dist/providers/github/api.js +1 -0
  147. package/dist/providers/github/lib/discovery.js +1 -1
  148. package/dist/providers/github/skill.generated.js +1 -1
  149. package/dist/providers/github/tools.js +61 -17
  150. package/dist/providers/gmail/lib/schemas.js +60 -50
  151. package/dist/providers/gmail/skill.generated.js +1 -1
  152. package/dist/providers/gmail/tools.js +12 -26
  153. package/dist/providers/granola/index.js +2 -0
  154. package/dist/providers/granola/skill.generated.js +1 -1
  155. package/dist/providers/overflow/api.js +8 -4
  156. package/dist/providers/overflow/index.js +2 -1
  157. package/dist/providers/overflow/skill.generated.js +1 -1
  158. package/dist/providers/overflow/tools.js +3 -7
  159. package/dist/providers/planning-center/api.js +5 -2
  160. package/dist/providers/planning-center/lib/constants.d.ts +1 -1
  161. package/dist/providers/planning-center/lib/json-api.js +1 -9
  162. package/dist/providers/planning-center/skill.generated.js +1 -1
  163. package/dist/providers/planning-center/tools.js +2 -1
  164. package/dist/providers/quickbooks/safety.js +80 -39
  165. package/dist/providers/quickbooks/skill.generated.js +1 -1
  166. package/dist/providers/sheets/api.js +1 -0
  167. package/dist/providers/sheets/skill.generated.js +1 -1
  168. package/dist/providers/sheets/tools.js +14 -23
  169. package/dist/providers/slides/skill.generated.js +1 -1
  170. package/dist/providers/slides/tools.js +19 -26
  171. package/dist/providers/stripe/index.js +2 -1
  172. package/dist/providers/stripe/safety.js +2 -2
  173. package/dist/providers/stripe/skill.generated.js +1 -1
  174. package/dist/providers/tithely/api.js +5 -8
  175. package/dist/providers/tithely/index.js +3 -2
  176. package/dist/providers/tithely/skill.generated.js +1 -1
  177. package/dist/providers/tithely/tools.js +7 -5
  178. package/dist/providers/vercel/api.js +2 -7
  179. package/dist/providers/vercel/lib/pin.js +1 -1
  180. package/dist/providers/vercel/safety.js +1 -1
  181. package/dist/providers/vercel/skill.generated.js +1 -1
  182. package/dist/providers/vercel/tools.js +6 -4
  183. package/dist/redaction-marker.js +2 -2
  184. package/dist/registry.d.ts +11 -5
  185. package/dist/registry.js +46 -20
  186. package/dist/request-principal.js +1 -1
  187. package/dist/request-state.js +2 -2
  188. package/dist/routes/access-tokens.js +1 -1
  189. package/dist/routes/activity-disclosure.js +1 -1
  190. package/dist/routes/connect.js +2 -2
  191. package/dist/routes/credentials.js +130 -61
  192. package/dist/routes/dispatch.js +5 -1
  193. package/dist/routes/mcp.js +34 -17
  194. package/dist/routes/oauth-management.js +1 -1
  195. package/dist/routes/operator.js +6 -5
  196. package/dist/routes/shared.d.ts +13 -8
  197. package/dist/routes/shared.js +15 -9
  198. package/dist/routes/ui-config.js +3 -3
  199. package/dist/routes/ui-data.js +126 -20
  200. package/dist/routes/ui.js +17 -1
  201. package/dist/runtime/call-admission.js +1 -1
  202. package/dist/runtime/call.js +8 -3
  203. package/dist/runtime/native-storage.js +9 -0
  204. package/dist/runtime/request-reads.js +182 -0
  205. package/dist/runtime/request-scope.js +16 -0
  206. package/dist/runtime/settlement.js +1 -1
  207. package/dist/runtime/shared-read.js +2 -15
  208. package/dist/runtime/storage.js +12 -0
  209. package/dist/sent-secrets.d.ts +1 -2
  210. package/dist/sent-secrets.js +3 -8
  211. package/dist/server.js +4 -4
  212. package/dist/skills.js +44 -54
  213. package/dist/sqlite.d.ts +0 -19
  214. package/dist/sqlite.js +2 -83
  215. package/dist/storage/keys.js +69 -128
  216. package/dist/storage/memory.js +8 -2
  217. package/dist/storage/sql-native.js +27 -101
  218. package/dist/storage/sql.d.ts +1 -24
  219. package/dist/storage/sql.js +13 -14
  220. package/dist/storage-digest.js +32 -0
  221. package/dist/timeout.js +8 -0
  222. package/dist/tool-error.js +4 -0
  223. package/dist/types.d.ts +33 -0
  224. package/dist/url-safety.js +0 -4
  225. package/dist/usage-guide.js +18 -37
  226. package/dist/validate.d.ts +3 -0
  227. package/dist/validate.js +220 -158
  228. package/dist/version.d.ts +1 -1
  229. package/dist/version.js +1 -1
  230. package/dist/worker.js +1 -1
  231. package/dist/write-outcome.js +0 -3
  232. package/documentation/README.md +19 -55
  233. package/documentation/architecture.md +436 -515
  234. package/documentation/auth.md +229 -88
  235. package/documentation/code-mode.md +201 -94
  236. package/documentation/deploying.md +25 -43
  237. package/documentation/integrating.md +18 -19
  238. package/documentation/meta-tools.md +225 -51
  239. package/documentation/migration-0.33.md +10 -6
  240. package/documentation/migration-0.34.md +5 -5
  241. package/documentation/migration-retired-layouts.md +74 -0
  242. package/documentation/operator-tests.md +20 -120
  243. package/documentation/operator-ui.md +108 -16
  244. package/documentation/pool-membership-upgrade.md +44 -0
  245. package/documentation/provider-auth-migration.md +4 -10
  246. package/documentation/provider-migration-0.29.md +4 -15
  247. package/documentation/providers.md +105 -0
  248. package/examples/worker/AGENTS.md +14 -16
  249. package/examples/worker/README.md +24 -118
  250. package/examples/worker/src/connecta.config.ts +1 -0
  251. package/guides/connecting-agents.md +9 -31
  252. package/guides/how-it-works.md +6 -4
  253. package/guides/safety-and-trust.md +4 -1
  254. package/package.json +19 -19
  255. package/templates/node/AGENTS.md +13 -12
  256. package/templates/node/README.md +9 -26
  257. package/templates/node/package.json +1 -1
  258. package/templates/node/src/connecta.config.ts +1 -0
  259. package/dist/auth/oauth-v2-migration.js +0 -135
  260. package/dist/provider-call-facts.d.ts +0 -115
  261. package/dist/provider-call.d.ts +0 -112
  262. package/dist/storage/d1-copy.js +0 -255
  263. package/dist/storage/sql-schema.d.ts +0 -6
  264. package/examples/worker/kv-to-d1.wrangler.jsonc +0 -26
  265. package/examples/worker/scripts/copy-kv-to-d1.mjs +0 -162
@@ -113,7 +113,13 @@ Connecta passes exactly one provider, named `connecta`. An executor must:
113
113
 
114
114
  1. **Expose each provider as a guest global** whose properties are its `fns`,
115
115
  called with the program's arguments and awaited. Connecta supplies `search`,
116
- `describe`, `call`, `read`, `result`, `skill`, and `emit`.
116
+ `describe`, `call`, `read`, `result`, `skill`, and `emit`; the prelude also
117
+ binds the guest's `skills` alias to `skill`. Connecta also supplies
118
+ `unawaited`, which the built-in prelude calls at most once, after a failed
119
+ program read a result field off an unawaited call. It spends no host call;
120
+ the host admits one notice per run and ends the run with `budget_exceeded`
121
+ on any further call, so a bridge that exposes it directly gains no
122
+ uncounted round trips.
117
123
  2. **Evaluate `prelude` after the provider globals exist and before the
118
124
  program.** It is trusted host code that installs the immutable namespace
119
125
  and waits for emission acknowledgements. Capture runner intrinsics first;
@@ -196,13 +202,16 @@ is preserved; no JavaScript identifier conversion takes place.
196
202
 
197
203
  **A2.** Connectors create no guest globals, so an id resembling a JavaScript
198
204
  builtin, or one that would collide after sanitization, stays usable through its
199
- canonical address. The bounded connector inventory in the tool description shows
200
- canonical ids with bounded configured titles when present. Clauses A3–A5
205
+ canonical address. The bounded connector inventory in the tool description names
206
+ every connector by canonical id, adding a bounded configured title only when it
207
+ says more than the id, and each guide's fetch call (see
208
+ [meta-tools](./meta-tools.md#discovery-context)). Clauses A3–A5
201
209
  belonged to shortcut dispatch and stay retired; nothing reuses those ids.
202
210
 
203
211
  ## The surface
204
212
 
205
- Seven functions: `search`, `describe`, `call`, `read`, `result`, `skill`, and `emit`.
213
+ Seven functions: `search`, `describe`, `call`, `read`, `result`, `skill`, and `emit`,
214
+ plus `skills`, an undeclared alias bound to the same host function as `skill`.
206
215
  All return awaitable values; emission also works without `await`. The namespace
207
216
  has no inherited members. Unknown properties are undefined, and calling them
208
217
  fails as a guest `TypeError`. The host also dispatches only own members of `fns`.
@@ -217,7 +226,7 @@ const page = await connecta.search({
217
226
  limit: 8, // 1–100, default 8
218
227
  offset: 0,
219
228
  fullDescriptions: false,
220
- includeSchemas: "json", // default; or "compact" / "typescript"
229
+ includeSchemas: "typescript", // default; or "json" / "compact"
221
230
  includeSchemaKeys: true, // default true in code mode
222
231
  });
223
232
  ```
@@ -234,18 +243,26 @@ query browses; non-empty input with no ASCII lexical terms returns no tools plus
234
243
  bounded no-match analysis in `queryAnalysis`; mixed input searches with its
235
244
  ASCII terms.
236
245
 
237
- Each entry carries `address`, `name`, the configured `connectorTitle` when
238
- present (normalized whitespace, at most 120 UTF-8 bytes), and — when requested —
239
- `description`, `inputSchema`, `outputSchema`, and `annotations`. An entry whose
240
- connector carries a usage guide also carries `guide` (the skill name) and a
241
- bounded `guideSummary`, requested or not. An output shape learned under `S9`
246
+ The first page may also carry `readyCalls`: complete operation reads to pass
247
+ unchanged as `connecta.call(entry.address, entry.args)`
248
+ ([fully determined operations](./meta-tools.md#discovery-context) only).
249
+
250
+ Each entry carries `address`, `name`, and — when requested — `description`,
251
+ the rendered schemas, and `annotations`. The page's `connectors` map holds each
252
+ row's connector facts once, keyed by the id before the address's first dot: the
253
+ configured `title` when present (normalized whitespace, at most 120 UTF-8
254
+ bytes), and `guide` (the skill name) with a bounded `guideSummary` when the
255
+ connector carries a usage guide, requested or not. An output shape learned under `S9`
242
256
  also carries `outputSchemaSource: "observed"`; provider declarations carry no
243
257
  source marker.
244
258
 
245
- Programs default to `includeSchemas: "json"`: `inputSchema` and available
246
- `outputSchema` are JSON Schema values, labeled `schemaFormat: "json"`.
247
- Explicit `includeSchemas: "compact"` returns strings labeled
248
- `schemaFormat: "text"`; TypeScript signatures carry the same text label.
259
+ Programs default to `includeSchemas: "typescript"`: each row carries one
260
+ `signature` string for its input and available output, labeled
261
+ `schemaFormat: "text"`, with `inputKeys`, `requiredInputKeys`, and `outputKeys`
262
+ for code to check. A signature is about half the bytes of the JSON rows.
263
+ Explicit `includeSchemas: "json"` returns `inputSchema` and available
264
+ `outputSchema` as JSON Schema values, labeled `schemaFormat: "json"`, and
265
+ `includeSchemas: "compact"` returns compact strings labeled `schemaFormat: "text"`.
249
266
  Compact shapes omit property prose and put required fields first, under these
250
267
  bounds:
251
268
 
@@ -349,8 +366,14 @@ says so inside its `Promise<…>`.
349
366
  ### connecta.call
350
367
 
351
368
  The published `GuestApi` type describes the supplied global for editors.
352
- The executable usage guide checks its API notation against those declarations;
353
- programs still use plain JavaScript.
369
+ The `execute_code` description declares a compact subset of it inline: argument
370
+ shapes that match what `GuestApi` accepts, result fields it returns, and no
371
+ others. Authored emit blocks are the exact variants `M1` accepts;
372
+ forwarded blocks are the native variants from `result.content`. It also
373
+ states that search and describe return objects rather than arrays, that a call
374
+ result over 1 MiB returns a paged handle, and that every function except `emit`
375
+ spends a host call (`M7`). `GuestApi`'s `emit` takes no paged handle, which the
376
+ host refuses. Programs still use plain JavaScript.
354
377
 
355
378
  ```js
356
379
  const { data: run, format } = await connecta.call("ci.get_run", { runId: 42 });
@@ -409,11 +432,17 @@ mismatches, revoked access, and old entries without bindings are `not_found`, as
409
432
  are unknown or expired ids; a storage failure is `unavailable`. IDs are random UUIDs.
410
433
  The `get_result` meta-tool is removed.
411
434
 
412
- `await connecta.skill(name)` resolves the same URI or compatibility name as
413
- top-level `skills`, within the admitted connector view. It reads the registry
414
- behind native `skills/get` and `resources/read`, including opted-in downstream
415
- skills. It returns
416
- `{ name, format: "text", text }`; an unknown name is `not_found`.
435
+ `await connecta.skill(name)` resolves the same URI, compatibility name, or bare
436
+ connector id as top-level `skills`, within the admitted connector view; built-in
437
+ names stay reserved (see
438
+ [meta-tools](./meta-tools.md#connector-guides-and-skills)). It reads the
439
+ registry behind native `skills/get` and `resources/read`, including opted-in
440
+ downstream skills. It returns
441
+ `{ name, format: "text", text }`; an unknown name is `not_found`. It also
442
+ accepts the top-level tool's `{ name }` object, and `connecta.skills` is an
443
+ undeclared alias of `connecta.skill` with the same host-call accounting, because
444
+ models copy the `skills` tool's shape into programs. Any other argument is
445
+ `invalid_args`, with a message naming `connecta.skill("usage")`.
417
446
 
418
447
  ### Parallel calls
419
448
 
@@ -622,8 +651,20 @@ when empty. An empty string reports `program_error` with
622
651
  **E6.** A guest `TypeError`, `ReferenceError`, syntax error, invented API, or
623
652
  program-authored throw is `program_error`. `details.name` is a bounded engine
624
653
  error name; `details.line` is the source line when the runtime supplies one,
625
- otherwise null. Fixed hints repair imports/require/filesystem access, shadowed
626
- `connecta`, and invented globals such as `callTool`.
654
+ otherwise null. `message` is `Program <name>: <engine message>`, naming the
655
+ error once even when an executor reports a prefixed message. Fixed hints repair
656
+ imports/require/filesystem access, shadowed `connecta`, invented globals such
657
+ as `callTool`, and a missing `await`. Detection is at runtime, never from
658
+ source: the Promise each `connecta.*` call except `emit` returns has
659
+ non-enumerable getters for result fields (`data`, `format`, `content`, `tools`,
660
+ `catalogErrors`, `total`, `text`, `resultId`, `hasMore`, `nextOffset`). Reading
661
+ one before `await`, as in `connecta.call(...).data` or
662
+ `const { tools } = connecta.search(...)`, returns undefined as before and sets
663
+ a per-run flag. When that program then fails, the prelude reports the flag
664
+ through the uncounted `unawaited` host function before the failure crosses,
665
+ and the hint is `connecta.* returns a Promise; await it`. Awaiting, `then`,
666
+ `Promise.all`, and `Promise.allSettled` never read those fields. Hints are
667
+ fixed text; no program source, field name, or value enters them.
627
668
 
628
669
  An unchanged uncaught host error retains its classification through Error
629
670
  identity. A new error containing its message is a new program error. Copied
@@ -657,13 +698,14 @@ past the deployment's result cap. A clipped address still identifies the mistake
657
698
  by its position; a short one is exact and untagged.
658
699
 
659
700
  **E8.** A remote MCP tool whose advertised schema rejects the call fails before
660
- provider dispatch with `invalid_args`, carrying bounded, value-free
661
- `{ path, code, expected }` findings and the same scoped
662
- `function: "connecta.search"` recovery every other in-program miss gets. A
663
- declared property reports the schema keyword that failed, never the validator's
664
- duplicate `additionalProperties` branch; a truly undeclared property still
665
- reports `additionalProperties`. Unsupported schemas pass through; unrecognized
666
- provider prose remains `connector_call_failed`.
701
+ provider dispatch with `invalid_args`, carrying every bounded
702
+ `{ path, expected, received? }` finding, one corrected `example` when it can be
703
+ built, and the same scoped `function: "connecta.search"` recovery every other
704
+ in-program miss gets ([argument recovery](./meta-tools.md#argument-recovery)).
705
+ A declared property reports the constraint that failed, never the validator's
706
+ duplicate `additionalProperties` branch; a truly undeclared property reports
707
+ the accepted keys. Unsupported schemas pass through; unrecognized provider
708
+ prose remains `connector_call_failed`.
667
709
 
668
710
  ## Results and projection
669
711
 
@@ -673,11 +715,26 @@ fields. Program-authored projection saved bytes; host heuristics could drop
673
715
  deliberately returned fields. Helpers need [#222](https://github.com/zackbart/connecta/issues/222)
674
716
  evidence that programs fail to project.
675
717
 
676
- **R2.** The boundary is 24,000 serialized characters (~6k tokens), shared with
677
- emitted text. An oversized return is stashed as compact JSON through the same
718
+ **R2.** The boundary is `execute.maxResultChars` serialized characters, shared
719
+ with emitted text: 24,000 (~6k tokens) by default, configurable from 4,000 to
720
+ 1,000,000. Raise it when agents need large results whole and the model's
721
+ context can afford them, since every paging round trip costs a model step.
722
+ The response carries a return twice (text content and `structuredContent`),
723
+ and Connecta has no response-size limit of its own, so the client's limits
724
+ apply; `admission.requests.maxBodyBytes` bounds request bodies only. Claude Code,
725
+ for one, passes at most 50,000 characters of text and can reject a larger result
726
+ with no content (see [truncated direct-call results](./meta-tools.md#truncated-direct-call-results)),
727
+ so keep the cap below what every client of the deployment accepts. Redaction scans the whole envelope once, so its cost grows with the cap.
728
+ The cap does not change stash paging: pages still obey the stashed call's
729
+ `maxResultBytes` and the 32 KiB bridge ceiling.
730
+ An oversized return is stashed as compact JSON through the same
678
731
  result store as direct calls. The returned notice carries `truncated`, `resultId`,
679
732
  `totalBytes`, `hint`, `nextOffset: 0`, and an executable `nextAction` that pages
680
- with `connecta.result`. It also retains `totalChars` and a bounded `preview`.
733
+ with `connecta.result`. Its page size is `floor((maxResultChars - 1024) / 6)`
734
+ bytes, so a page fits the next program's return even when every byte escapes to
735
+ six characters (3,829 bytes by default), at most the stashed call's
736
+ `maxResultBytes` and the 32 KiB bridge ceiling; direct-call notices use the same
737
+ size. It also retains `totalChars` and a bounded `preview`.
681
738
  The recovery action and hint precede the preview, so clients that spill results
682
739
  after the first 2,000 characters retain the handle and the instruction.
683
740
  Small returns pass through unchanged; Connecta does not select fields.
@@ -790,8 +847,8 @@ a successful result, appended to `content` after the JSON envelope, which gains
790
847
  response (`R6`). `structuredContent` stays the envelope alone — emission is
791
848
  presentation, not a second data channel.
792
849
 
793
- **M3.** Text emission shares `R2`'s 24,000 serialized-character cap, less 512
794
- characters reserved for the envelope (23,488 for emitted text). Its
850
+ **M3.** Text emission shares `R2`'s `execute.maxResultChars` cap, less 512
851
+ characters reserved for the envelope (23,488 for emitted text by default). Its
795
852
  serialized block size reduces the return budget, and oversized text fails with
796
853
  `result_too_large`. Image/audio blocks use the separate transport budget and
797
854
  reach the model as real MCP media content, including when `emit` is not awaited.
@@ -881,7 +938,11 @@ operations when a pending storage response arrives. An in-process caller receive
881
938
 
882
939
  Programs and direct calls use the same invocation deadline and stages. A call's
883
940
  `timeoutMs` wins, then `calls.defaultTimeoutMs`, then `execute.hostCallTimeoutMs`
884
- (default 15,000). A guest may request a longer individual call, but the sandbox
941
+ (default 15,000). `connecta.result`, `connecta.skill` and `connecta.read` always
942
+ use `execute.hostCallTimeoutMs`. The `execute_code` description advertises the
943
+ `connecta.call` default as `<n>s/host call`, or, when `calls.defaultTimeoutMs`
944
+ differs, both deadlines, for example `25s/call (15s result/skill/read)`.
945
+ A guest may request a longer individual call, but the sandbox
885
946
  and request ceilings still bound the whole run. Timeout details are agent-facing;
886
947
  operator records retain only checked classifications and numeric facts.
887
948
  Result processing, including stash reservation, uses the same remaining call
@@ -913,17 +974,17 @@ deadline past the ceiling means raising the ceiling too.
913
974
  **L4.** Per-execution bounds that are contract, identical in both executors
914
975
  because connecta enforces them above the sandbox:
915
976
 
916
- | Bound | Value |
917
- | --------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
918
- | Host calls per execution, shared by every guest call except `emit` | 20 by default, `execute.maxHostCalls` |
919
- | Writes per run on a writable endpoint, on top of the host calls they also spend (`W10`) | 10 by default, `execute.maxWrites` |
920
- | Deadline per host call | 15 s, `execute.hostCallTimeoutMs`; one deadline covers catalog resolution, admission, the connector call, and result processing |
921
- | Discovery page | ≤ 100 tools, ≤ 256,000 serialized bytes |
922
- | `describe` addresses | ≤ 100 |
923
- | `describe` nearby suggestions | ≤ 3 canonical addresses per failed entry |
924
- | Caller text echoed by `describe` recovery | ≤ 512 UTF-8 bytes per field, plus `…` |
925
- | Result | 24,000 serialized characters |
926
- | Logs presented to the model | 4,000 characters |
977
+ | Bound | Value |
978
+ | ---------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
979
+ | Host calls per execution, shared by every guest call except `emit` and the single `unawaited` notice | 20 by default, `execute.maxHostCalls` |
980
+ | Writes per run on a writable endpoint, on top of the host calls they also spend (`W10`) | 10 by default, `execute.maxWrites` |
981
+ | Deadline per host call | `connecta.call`: its `timeoutMs`, else `calls.defaultTimeoutMs`, else `execute.hostCallTimeoutMs` (15 s); `result`, `skill` and `read`: `execute.hostCallTimeoutMs`. One deadline covers catalog resolution, admission, the connector call, and result processing |
982
+ | Discovery page | ≤ 100 tools, ≤ 256,000 serialized bytes |
983
+ | `describe` addresses | ≤ 100 |
984
+ | `describe` nearby suggestions | ≤ 3 canonical addresses per failed entry |
985
+ | Caller text echoed by `describe` recovery | ≤ 512 UTF-8 bytes per field, plus `…` |
986
+ | Result | 24,000 serialized characters by default, `execute.maxResultChars` (4,000–1,000,000) |
987
+ | Logs presented to the model | 4,000 characters |
927
988
 
928
989
  For any tool whose output declares `page`, continue while `page.hasMore` is true.
929
990
  When approaching the program's host-call limit, return `page.nextCursor` before
@@ -1285,51 +1346,97 @@ and on the Worker adapter with a real Miniflare Loader in `test/guest-api-contra
1285
1346
  Titles name clauses; executor-independent clauses run in both arms.
1286
1347
  `test/codemode-compat.test.ts` pins upstream shape compatibility, minified upstream
1287
1348
  rejection, and branded adapter acceptance across module copies.
1288
-
1289
- | Clauses | Test |
1290
- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1291
- | `P1`, `P5` | both guest-contract executors (TypeScript syntax, trailing terminators, wrapper recovery), `test/program-source.test.ts` (which semicolons and wrappers are recovered), `test/quickjs-executor.node.test.ts` (`normalizeCode`) |
1292
- | `P2`, `X5` | `test/guest-api-contract.test.ts` (Dynamic globals plus loader-only filesystem, HTTP, environment, egress, DNS, and local `data:` boundaries), `test/guest-api-contract-quickjs.node.test.ts` (exact absent globals and blocked imports), `test/quickjs-child-stderr.node.test.ts` (a child-process environment holding only `TZ=UTC`), `test/deployment-shapes.node.test.ts` (loader-only Worker construction) |
1293
- | `P3`, `X9` | `test/guest-api-contract.test.ts`, `test/execute.test.ts` |
1294
- | `P4` | `test/guest-api-contract.test.ts` (no cross-run leakage), `test/execute.test.ts` (one catalog load per connector per execution) |
1295
- | `A1`, `A2` | `test/guest-api-contract.test.ts`, `test/execute.test.ts` (canonical addressing), `test/server.test.ts` (bounded live connector inventory) |
1296
- | `S1`, `S1a`, `S2` | `test/guest-api-contract.test.ts` (flat page, connector guides, schema keys, unfiltered browse), `test/execute.test.ts` (guide pagination/partial/no-match behavior and `$ref`/`allOf`), `test/meta-tools-search.test.ts` (mixed complete/partial ranking, stable pagination, the two safety classes), `test/typescript-signatures.test.ts` (the TypeScript format over provider and pathological schemas, search/describe parity, observed labeling), `test/typescript-signatures-parse.node.test.ts` (every rendering parses) |
1297
- | `S3` | `test/guest-api-contract.test.ts` (typed uncaught bound), `test/execute.test.ts` (count limits, fan-out bound) |
1298
- | `S4` | both guest-contract executors (ordered mixed describe results with unknown-address, unknown-tool suggestion, and catalog-failure details), `test/meta-tools-search.test.ts` (top-level routing, no-suggestion, catalog-failure, and hostile-input bounds) |
1299
- | `S5`, `S6` | `test/guest-api-contract.test.ts`, `test/execute.test.ts` (`unwrapMcpResult`, fail-closed annotations, activity parity) |
1300
- | `S7` | `test/guest-api-contract.test.ts`, `test/execute.test.ts` (parallel calls and shared admission) |
1301
- | `S8`, `E1`, `X11` | both guest-contract executors (caught call, discovery, utility, removed-function, and forgery cases; typed promise rejections), `test/quickjs-executor.node.test.ts` (oversized messages, private transport, forged outcomes) |
1302
- | `S9` | `test/result-shapes.test.ts` (value exclusion, bounds, merging, LRU and time expiry, runtime isolation, read-only admission, declared precedence, definition invalidation, unwrapped MCP results, discovery provenance, copy isolation, failure isolation) |
1303
- | `S10` | `test/resource-read.test.ts` (qualified routing, whole-connector grants, personal credentials, redaction, admission, timeout, cancellation and downstream MCP reads), both guest-contract executors (successful resource reads and caught/uncaught typed failures) |
1304
- | `E2`, `E8` | `test/guest-api-contract.test.ts` (code → `retryable`, caught, parallel, and uncaught validation recovery, a conflict's bounded `current`), `test/meta-tools-call.test.ts` (direct, destructive, provider fallback), `test/validate.test.ts` (bounded payload-free findings), `test/errors.test.ts` |
1305
- | `E3`, `E4` | `test/guest-api-contract.test.ts`, `test/execute.test.ts` (`auth_required`, destructive reroute), `test/identity-write-journey.node.test.ts` (read-only refusals before validation or dispatch, actual QuickJS) |
1306
- | `E5` | `test/guest-api-contract.test.ts` (execution-failure channel, in-flight `cancelled`), `test/execute.test.ts` (admission), `test/executor-admission.test.ts`, `test/quickjs-executor.node.test.ts` (mid-run shutdown) |
1307
- | `E6`, `X8` | `test/guest-api-contract.test.ts` (unknown and inherited members, retained error identities), `test/quickjs-executor.node.test.ts` |
1308
- | `E7` | `test/guest-api-contract.test.ts` (refusals about a `503`-named connector), `test/errors.test.ts` |
1309
- | `R1`, `R2`, `R3`, `R4` | `test/guest-api-contract.test.ts` and `test/guest-api-contract-quickjs.node.test.ts` (small pass-through, shared return paging and unavailable fallback, no repeated writes, live authority), `test/program-result-cases.ts` (reconstruction, redaction, notice survives a 2,000-character spill) |
1310
- | `M6`, `M9` | verdicts; `R2`'s guard, `M1`'s strict typing, and `M2`'s collect-then-deliver are their enforcement |
1311
- | `R5` | `test/guest-api-contract.test.ts`, `test/quickjs-log-limits.node.test.ts` |
1312
- | `R6`–`R8` | `test/guest-api-contract.test.ts` (normal result keys), `test/execute.test.ts` (opt-in operation aggregates, failure paths, payload exclusion) |
1313
- | `Y1`, `Y2`, `Y3` | `test/guest-api-contract.test.ts` (one attempt per call, retryable flags by code) |
1314
- | `Y4` | `test/meta-tools-call.test.ts`, `test/call-admission.test.ts` (one attempt, retry hints, caller reissue) |
1315
- | `L1`, `L2` | `test/guest-api-contract.test.ts` (in-flight call fails `cancelled`), `test/execute.test.ts` (cancels outstanding host calls, discovery included, and refuses discovery after the run; a cancelled wedged executor, or one whose `acquire()` ignores the signal, returns promptly and releases its lease) |
1316
- | `L3`, `X1` | `test/guest-api-contract.test.ts` (short-deadline executors), `test/execute.test.ts` (the watchdog ends a never-settling executor, frees the default pool, spares a slow run, and falls back from an unusable value) |
1317
- | `L4`, `L8` | `test/guest-api-contract.test.ts`, `test/execute.test.ts` (shared discovery/call budgets and terminal catch-and-continue loops and queued-write cancellation on both executors), `test/worker-budget-response.node.test.ts` (native handle disposal and admission recovery across completed HTTP responses) |
1318
- | `L5`, `L7`, `X2` | `test/quickjs-executor.node.test.ts` (CPU, heap), `test/execute.test.ts` and `test/executor-admission.test.ts` (bounded admission and queue), `test/executor-requests.test.ts` (queued handoffs and refusal shape across separate workerd requests), `test/request-context.node.test.ts` (queued and QuickJS host-call request context) |
1319
- | `L6`, `X10` | `test/guest-api-contract-quickjs.node.test.ts` and `test/guest-api-contract.test.ts` (whole oversized reads and one-write pageable handles), `test/sqlite-storage.node.test.ts` and `test/kv-to-d1.test.ts` (SQL stash and native D1 fault probes), `test/quickjs-executor.node.test.ts` (bridge and IPC bounds for arguments and result; the address in the over-bound message), `test/quickjs-child-stderr.node.test.ts` (outer reply serialization failure settles the call) |
1320
- | `V1`–`V4` | `test/guest-api-contract.test.ts` (dispatched calls, every refusal class including an address no connector owns, the friction each derives, no event for the execution itself), `test/activity.test.ts` (the shared code → friction table, the identity clamp, the one-attempt floor), `test/browser/operator-ui.spec.ts` (identity changes), `test/sql-storage-contract.ts`, run by `test/sqlite-storage.node.test.ts` (historical activity rows still round-trip) |
1321
- | `V5`, `W9` | `test/program-writes.test.ts` (unawaited program drain, failed-program accounting), `test/identity-write-journey.node.test.ts` (committed ambiguity, reconciliation and physical writes), `test/invocation-pipeline.test.ts` (the gate after validation, an unrecorded refusal) |
1322
- | `W10`, `W12` | `test/identity-write-journey.node.test.ts` (real HTTP/MCP and QuickJS: write budget, read-only discovery and refusal, named guide, pool inheritance/reopening and connector policy), `test/program-writes.test.ts` (construction refusals and classification drift), `test/operator-ui-model.test.ts`, `test/browser/operator-ui.spec.ts` (the badge) |
1323
- | `M1` | `test/guest-api-contract.test.ts` (invalid emits throw catchably, accept nothing), `test/execute-emit.test.ts` (rejected shapes, bounded native snapshots, paging before metadata traversal, and cyclic presentation refusal) |
1324
- | `M2`, `M3` | `test/guest-api-contract.test.ts` (delivery order, truncated return plus delivered blocks), `test/execute-emit.test.ts` (envelope, `structuredContent`, byte-for-byte no-emit path) |
1325
- | `M4` | `test/guest-api-contract.test.ts` (discard is visible), `test/execute-emit.test.ts` (structured and plain paths), `test/quickjs-executor.node.test.ts` (mid-run shutdown) |
1326
- | `M5`, `M7` | `test/execute-emit.test.ts` (both budgets fail the crossing block; host-call budget untouched) |
1327
- | `M8` | two arms passing one case table, `test/codemode-compat.test.ts` |
1328
- | `M10` | `test/execute-emit.test.ts` (aggregate present, numbers only, absent when nothing emitted) |
1329
- | `X4` | `test/guest-api-contract.test.ts` (string logs only), `test/quickjs-executor.node.test.ts` (logs before cancellation), `test/quickjs-child-stderr.node.test.ts` (crash, shutdown, deadline, IPC failure, bounded parent retention), `test/quickjs-log-limits.node.test.ts` (unchanged successful logs) |
1330
- | `X3`, `X6` | `test/quickjs-executor.node.test.ts` (cancels a running child, never-settling await), `test/execute.test.ts` (a wedged executor stops being awaited) |
1331
- | `X7` | `P3`'s tests; the Workers superset is deliberately unused |
1332
-
1333
- The surface itself is checked by `test/server.test.ts` (the exact six-tool list),
1334
- `test/code-first-surface.test.ts` (construction, executor, removed tools, copy, and size),
1349
+ `test/package-surface.node.test.ts` compiles the description's compact guest
1350
+ declaration against `GuestApi`, checks arguments in both directions, and rejects
1351
+ invented, mistyped, and missing members and authored blocks the host refuses.
1352
+
1353
+ | Clauses | Test |
1354
+ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1355
+ | `P1`, `P5` | both guest-contract executors (TypeScript syntax, trailing terminators, wrapper recovery), `test/program-source.test.ts` (which semicolons and wrappers are recovered), `test/quickjs-executor.node.test.ts` (`normalizeCode`) |
1356
+ | `P2`, `X5` | `test/guest-api-contract.test.ts` (Dynamic globals plus loader-only filesystem, HTTP, environment, egress, DNS, and local `data:` boundaries), `test/guest-api-contract-quickjs.node.test.ts` (exact absent globals and blocked imports), `test/deployment-shapes.node.test.ts` (loader-only Worker construction) |
1357
+ | `P3`, `X9` | `test/guest-api-contract.test.ts`, `test/execute.test.ts` |
1358
+ | `P4` | `test/guest-api-contract.test.ts` (no cross-run leakage), `test/execute.test.ts` (one catalog load per connector per execution) |
1359
+ | `A1`, `A2` | `test/guest-api-contract.test.ts`, `test/execute.test.ts` (canonical addressing), `test/server.test.ts` (bounded live connector inventory) |
1360
+ | `S1`, `S1a`, `S2` | `test/guest-api-contract.test.ts` (flat page, connector guides, schema keys, unfiltered browse), `test/execute.test.ts` (guide pagination/partial/no-match behavior and `$ref`/`allOf`), `test/meta-tools-search.test.ts` (mixed complete/partial ranking, stable pagination, the two safety classes), `test/typescript-signatures.test.ts` (the TypeScript format over provider and pathological schemas, search/describe parity, observed labeling) |
1361
+ | `S3` | `test/guest-api-contract.test.ts` (typed uncaught bound), `test/execute.test.ts` (count limits, fan-out bound) |
1362
+ | `S4` | both guest-contract executors (ordered mixed describe results with unknown-address, unknown-tool suggestion, and catalog-failure details), `test/meta-tools-search.test.ts` (top-level routing, no-suggestion, catalog-failure, and hostile-input bounds) |
1363
+ | `S5`, `S6` | `test/guest-api-contract.test.ts`, `test/execute.test.ts` (`unwrapMcpResult`, fail-closed annotations, activity parity) |
1364
+ | `S7` | `test/guest-api-contract.test.ts`, `test/execute.test.ts` (parallel calls and shared admission) |
1365
+ | `S8`, `E1`, `X11` | both guest-contract executors (caught call, discovery, utility, removed-function, and forgery cases; typed promise rejections), `test/quickjs-executor.node.test.ts` (oversized messages, private transport, forged outcomes) |
1366
+ | `S9` | `test/result-shapes.test.ts` (value exclusion, bounds, merging, LRU and time expiry, runtime isolation, read-only admission, declared precedence, definition invalidation, unwrapped MCP results, discovery provenance, copy isolation, failure isolation) |
1367
+ | `S10` | `test/resource-read.test.ts` (qualified routing, whole-connector grants, personal credentials, redaction, admission, timeout, cancellation and downstream MCP reads), both guest-contract executors (successful resource reads and caught/uncaught typed failures) |
1368
+ | `E2`, `E8` | `test/guest-api-contract.test.ts` (code → `retryable`, caught, parallel, and uncaught validation recovery, a conflict's bounded `current`), `test/meta-tools-call.test.ts` (direct, destructive, provider fallback), `test/validate.test.ts` (bounded payload-free findings), `test/errors.test.ts` |
1369
+ | `E3`, `E4` | `test/guest-api-contract.test.ts`, `test/execute.test.ts` (`auth_required`, destructive reroute), `test/identity-write-journey.node.test.ts` (read-only refusals before validation or dispatch, actual QuickJS) |
1370
+ | `E5` | `test/guest-api-contract.test.ts` (execution-failure channel, in-flight `cancelled`), `test/execute.test.ts` (admission), `test/executor-admission.test.ts`, `test/quickjs-executor.node.test.ts` (mid-run shutdown) |
1371
+ | `E6`, `X8` | `test/guest-api-contract.test.ts` (unknown and inherited members, retained error identities), `test/quickjs-executor.node.test.ts` |
1372
+ | `E7` | `test/guest-api-contract.test.ts` (refusals about a `503`-named connector), `test/errors.test.ts` |
1373
+ | `R1`, `R2`, `R3`, `R4` | `test/guest-api-contract.test.ts` and `test/guest-api-contract-quickjs.node.test.ts` (small pass-through, shared return paging and unavailable fallback, no repeated writes, live authority), `test/program-result-cases.ts` (reconstruction, redaction, notice survives a 2,000-character spill) |
1374
+ | `M6`, `M9` | verdicts; `R2`'s guard, `M1`'s strict typing, and `M2`'s collect-then-deliver are their enforcement |
1375
+ | `R5` | `test/guest-api-contract.test.ts` |
1376
+ | `R6`–`R8` | `test/guest-api-contract.test.ts` (normal result keys), `test/execute.test.ts` (opt-in operation aggregates, failure paths, payload exclusion) |
1377
+ | `Y1`, `Y2`, `Y3` | `test/guest-api-contract.test.ts` (one attempt per call, retryable flags by code) |
1378
+ | `Y4` | `test/meta-tools-call.test.ts`, `test/call-admission.test.ts` (one attempt, retry hints, caller reissue) |
1379
+ | `L1`, `L2` | `test/guest-api-contract.test.ts` (in-flight call fails `cancelled`), `test/execute.test.ts` (cancels outstanding host calls, discovery included, and refuses discovery after the run; a cancelled wedged executor, or one whose `acquire()` ignores the signal, returns promptly and releases its lease) |
1380
+ | `L3`, `X1` | `test/guest-api-contract.test.ts` (short-deadline executors), `test/execute.test.ts` (the watchdog ends a never-settling executor, frees the default pool, spares a slow run, and falls back from an unusable value) |
1381
+ | `L4`, `L8` | `test/guest-api-contract.test.ts`, `test/execute.test.ts` (shared discovery/call budgets and terminal catch-and-continue loops and queued-write cancellation on both executors) |
1382
+ | `L5`, `L7`, `X2` | `test/quickjs-executor.node.test.ts` (CPU, heap), `test/execute.test.ts` and `test/executor-admission.test.ts` (bounded admission and queue), `test/executor-requests.test.ts` (queued handoffs and refusal shape across separate workerd requests), `test/request-context.node.test.ts` (queued and QuickJS host-call request context) |
1383
+ | `L6`, `X10` | `test/guest-api-contract-quickjs.node.test.ts` and `test/guest-api-contract.test.ts` (whole oversized reads and one-write pageable handles), `test/sqlite-storage.node.test.ts` and `test/storage-sql-d1.test.ts` (SQL stash and native D1 fault probes), `test/quickjs-executor.node.test.ts` (bridge and IPC bounds for arguments and result; the address in the over-bound message) |
1384
+ | `V1`–`V4` | `test/guest-api-contract.test.ts` (dispatched calls, every refusal class including an address no connector owns, the friction each derives, no event for the execution itself), `test/activity.test.ts` (the shared code → friction table, the identity clamp, the one-attempt floor), `test/browser/operator-ui.spec.ts` (identity changes), `test/sql-storage-contract.ts`, run by `test/sqlite-storage.node.test.ts` (historical activity rows still round-trip) |
1385
+ | `V5`, `W9` | `test/program-writes.test.ts` (unawaited program drain, failed-program accounting), `test/identity-write-journey.node.test.ts` (committed ambiguity, reconciliation and physical writes), `test/invocation-pipeline.test.ts` (the gate after validation, an unrecorded refusal) |
1386
+ | `W10`, `W12` | `test/identity-write-journey.node.test.ts` (real HTTP/MCP and QuickJS: write budget, read-only discovery and refusal, named guide, pool inheritance/reopening and connector policy), `test/program-writes.test.ts` (construction refusals and classification drift), `test/browser/operator-ui.spec.ts` (the badge) |
1387
+ | `M1` | `test/guest-api-contract.test.ts` (invalid emits throw catchably, accept nothing), `test/execute-emit.test.ts` (rejected shapes, bounded native snapshots, paging before metadata traversal, and cyclic presentation refusal) |
1388
+ | `M2`, `M3` | `test/guest-api-contract.test.ts` (delivery order, truncated return plus delivered blocks), `test/execute-emit.test.ts` (envelope, `structuredContent`, byte-for-byte no-emit path) |
1389
+ | `M4` | `test/guest-api-contract.test.ts` (discard is visible), `test/execute-emit.test.ts` (structured and plain paths), `test/quickjs-executor.node.test.ts` (mid-run shutdown) |
1390
+ | `M5`, `M7` | `test/execute-emit.test.ts` (both budgets fail the crossing block; host-call budget untouched) |
1391
+ | `M8` | two arms passing one case table, `test/codemode-compat.test.ts` |
1392
+ | `M10` | `test/execute-emit.test.ts` (aggregate present, numbers only, absent when nothing emitted) |
1393
+ | `X4` | `test/guest-api-contract.test.ts` (string logs only), `test/quickjs-executor.node.test.ts` (logs before cancellation) |
1394
+ | `X3`, `X6` | `test/quickjs-executor.node.test.ts` (cancels a running child, never-settling await), `test/execute.test.ts` (a wedged executor stops being awaited) |
1395
+ | `X7` | `P3`'s tests; the Workers superset is deliberately unused |
1396
+
1397
+ The surface itself is checked by `test/server.test.ts` (the exact six-tool list)
1335
1398
  and `test/program-writes.test.ts` (deployment policy and classification construction refusals).
1399
+
1400
+ ### Adding a guest function
1401
+
1402
+ `src/guest-functions.ts` lists every `connecta.<name>` function once, as
1403
+ guest-safe data with no host code or imports. The guest runtime builds the
1404
+ frozen namespace from it, so the runtime source stays one self-contained string
1405
+ that QuickJS and the Worker executor evaluate unchanged. `execute.ts` admits
1406
+ each bridge call by the entry's budget class and binds it by name to a host
1407
+ implementation, and the `execute_code` description joins each entry's compact
1408
+ declaration and names the functions that spend no host call.
1409
+
1410
+ | Function | Budget | Purpose |
1411
+ | ----------- | ---------- | -------------------------------------------------------------------------- |
1412
+ | `search` | `hostCall` | Searches the catalog and returns one flat page of `{ tools }`. |
1413
+ | `describe` | `hostCall` | Describes exact addresses, one entry per address in order. |
1414
+ | `call` | `hostCall` | Calls one tool and inlines transfer pages and native content. |
1415
+ | `read` | `hostCall` | Reads one advertised resource URI. |
1416
+ | `result` | `hostCall` | Pages a retained result by page or UTF-8 byte offset. |
1417
+ | `skill` | `hostCall` | Fetches a skill's text by exact name. |
1418
+ | `emit` | `emission` | Forwards a content block to the client; needs no await. |
1419
+ | `unawaited` | `once` | Tells the host a failed program read a result field off an unawaited call. |
1420
+
1421
+ A `hostCall` function spends one host call on entry (`L4`, `M7`) and returns a
1422
+ Promise whose result fields mark an unawaited read. The runtime wraps
1423
+ `provider.<name>`, or its own local of that name when the entry is `wrapped`,
1424
+ as `call` is. An `emission` function spends none, is bounded by the emission
1425
+ collector and an attempt cap, and returns a tracked thenable. A `once`
1426
+ function accepts one call per run, ends the run on a second, and is called only
1427
+ by the runtime, never from the namespace.
1428
+
1429
+ To add a function:
1430
+
1431
+ 1. Add its entry to `GUEST_FUNCTIONS`: name, budget class, compact
1432
+ declaration and a one-line JSDoc purpose. A `wrapped` function also needs a
1433
+ guest-side local of the same name in `guestInitializer`.
1434
+ 2. Add the member to `GuestApi` in `src/guest-types.ts`. The package-surface
1435
+ declaration test fails until the compact declaration and `GuestApi` agree.
1436
+ 3. Bind its host implementation in `sandboxProvider`'s `operations` in
1437
+ `src/execute.ts`. Typecheck fails while a registry entry has no binding.
1438
+ 4. Add behavior cases to `test/guest-contract-cases.ts`, which run on both
1439
+ executors. The namespace-membership and missing-await cases cover the new
1440
+ entry without edits.
1441
+ 5. Document its clause in this guide and add its row to the table above; the
1442
+ package-surface test compares the table with the registry.