@zackbart/connecta 0.18.3 → 0.20.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 (76) hide show
  1. package/CHANGELOG.md +131 -4
  2. package/dist/apps-shell.d.ts +10 -12
  3. package/dist/apps-shell.js +29 -220
  4. package/dist/catalog-service.d.ts +16 -13
  5. package/dist/catalog-service.js +106 -115
  6. package/dist/catalog.js +29 -46
  7. package/dist/connector-scope.js +2 -7
  8. package/dist/connectors/api.d.ts +4 -16
  9. package/dist/connectors/api.js +19 -46
  10. package/dist/connectors/guarded-fetch.d.ts +9 -23
  11. package/dist/connectors/guarded-fetch.js +38 -76
  12. package/dist/connectors/remote-mcp.js +36 -79
  13. package/dist/errors.d.ts +6 -27
  14. package/dist/errors.js +8 -5
  15. package/dist/execute.d.ts +23 -28
  16. package/dist/execute.js +101 -257
  17. package/dist/executor-result.d.ts +1 -0
  18. package/dist/executor-result.js +4 -11
  19. package/dist/executors/quickjs-child.js +1 -3
  20. package/dist/executors/quickjs-runtime.js +1 -3
  21. package/dist/executors/quickjs.js +1 -3
  22. package/dist/index.js +134 -123
  23. package/dist/invocation.d.ts +1 -1
  24. package/dist/invocation.js +113 -183
  25. package/dist/meta-tools.d.ts +15 -29
  26. package/dist/meta-tools.js +41 -582
  27. package/dist/operator-ui/generated.d.ts +2 -2
  28. package/dist/providers/cloudflare.d.ts +2 -18
  29. package/dist/providers/cloudflare.js +1460 -2451
  30. package/dist/providers/linear.d.ts +4 -41
  31. package/dist/providers/linear.js +8 -39
  32. package/dist/providers/mixpanel.d.ts +3 -25
  33. package/dist/providers/mixpanel.js +7 -22
  34. package/dist/providers/notion.d.ts +1 -15
  35. package/dist/providers/notion.js +44 -173
  36. package/dist/providers/revenuecat.d.ts +4 -57
  37. package/dist/providers/revenuecat.js +10 -93
  38. package/dist/providers/stripe.d.ts +1 -12
  39. package/dist/providers/stripe.js +7 -45
  40. package/dist/registry.d.ts +9 -34
  41. package/dist/registry.js +9 -103
  42. package/dist/routes/mcp.js +1 -1
  43. package/dist/routes/oauth.js +3 -3
  44. package/dist/routes/shared.d.ts +15 -15
  45. package/dist/routes/shared.js +1 -3
  46. package/dist/skills.d.ts +1 -1
  47. package/dist/skills.js +5 -5
  48. package/dist/timeout.d.ts +8 -7
  49. package/dist/timeout.js +47 -38
  50. package/dist/types.d.ts +3 -3
  51. package/dist/ui.d.ts +1 -25
  52. package/dist/ui.js +18 -45
  53. package/dist/version.d.ts +1 -1
  54. package/dist/version.js +1 -1
  55. package/documentation/call-admission.md +1 -1
  56. package/documentation/cloudflare.md +1 -1
  57. package/documentation/code-mode.md +25 -25
  58. package/documentation/connectors.md +24 -1
  59. package/documentation/linear.md +1 -1
  60. package/documentation/meta-tools.md +4 -30
  61. package/documentation/mixpanel.md +1 -1
  62. package/documentation/notion.md +1 -1
  63. package/documentation/operations.md +29 -25
  64. package/documentation/provider-conventions.md +4 -5
  65. package/documentation/revenuecat.md +1 -1
  66. package/documentation/stripe.md +1 -1
  67. package/documentation/upgrading.md +43 -8
  68. package/ethos.md +75 -121
  69. package/package.json +3 -4
  70. package/templates/node/package.json +1 -1
  71. package/documentation/code-first-exploration.md +0 -292
  72. package/documentation/mcp-2026-07-28.md +0 -46
  73. package/documentation/mcp-ui-design.md +0 -382
  74. package/documentation/program-ui-read-calls.md +0 -213
  75. package/documentation/provider-audit.md +0 -198
  76. package/documentation/rich-output-design.md +0 -211
@@ -160,6 +160,29 @@ is that machinery extracted once ([#341](https://github.com/zackbart/connecta/is
160
160
  one `guardedFetch({ provider, baseUrl, headers, maxResponseBytes, authenticate })`
161
161
  factory returning the transport a connector sends every request through.
162
162
 
163
+ ```ts
164
+ const send = guardedFetch({
165
+ provider: "Billing",
166
+ baseUrl: "https://billing.internal.example/v1",
167
+ maxResponseBytes: 4 * 1024 * 1024,
168
+ headers: { Accept: "application/json" },
169
+ authenticate: async (ctx) => {
170
+ const token = await ctx.credential?.get();
171
+ if (!token) throw new ConnectorCallError("auth_required", "...");
172
+ return { Authorization: `Bearer ${token}` };
173
+ },
174
+ });
175
+
176
+ const invoice = await send(
177
+ { method: "GET", path: `/invoices/${id}` },
178
+ ctx,
179
+ (response) => {
180
+ if (!response.ok) throw billingFailure(response.status);
181
+ return response.json();
182
+ },
183
+ );
184
+ ```
185
+
163
186
  What it owns is mechanical and provider-independent:
164
187
 
165
188
  - **Confinement.** A request path is provider-relative, carries no query or
@@ -212,7 +235,7 @@ supplies the third caller that would settle it.
212
235
  ## MCP version skew
213
236
 
214
237
  Connecta deliberately sits between protocol generations
215
- ([full revision inventory](./mcp-2026-07-28.md)):
238
+ ([full revision inventory](https://github.com/zackbart/connecta/blob/main/records/mcp-2026-07-28.md)):
216
239
 
217
240
  - **Inbound:** `/mcp` serves both the 2026-07-28 revision and legacy 2025
218
241
  clients. Modern clients negotiate with `server/discover` and do not send
@@ -179,4 +179,4 @@ settings at construction.
179
179
  This connection is audited against
180
180
  [the provider conventions](./provider-conventions.md). Its verdict per
181
181
  convention, including every recorded exception, is the Linear section of
182
- [the provider audit](./provider-audit.md).
182
+ [the provider audit](https://github.com/zackbart/connecta/blob/main/records/provider-audit.md).
@@ -192,36 +192,10 @@ offsets and totals refer to that exact compact text.
192
192
  A `call_tool` truncation notice carries both the historical `resultId` and an
193
193
  exact `nextAction: { tool: "get_result", arguments: { id, offset: 0 } }`. The
194
194
  handle is therefore
195
- directly actionable without copying an identifier out of prose; re-calling with
196
- `fields` remains the smaller alternative when projection is possible. Program results and oversized discovery responses carry no such
197
- route — paging a program's return value is a refused shape, because a program
198
- can shrink anything before it returns.
199
-
200
- `fields` keeps its historical flat `{ "<path>": value }` result when every
201
- requested dot-path resolves. Dot notation traverses objects; append `[]` to an
202
- array field before continuing, as in `results[].id`. Empty arrays resolve to
203
- empty arrays. An exact downstream
204
- `$connecta` field is always escaped under `data`. If any path misses—or that
205
- reserved name is selected—the result carries matches under `data` and reserves `$connecta` for a
206
- `type: "field_projection"` recovery record naming each `unmatchedFields`
207
- entry. A path that resolves for only some array elements stays in `data` and
208
- appears in `partialFields`; its unresolved positions serialize as `null`, while
209
- the recovery record distinguishes them from genuine downstream nulls. A path
210
- that misses every element appears in `unmatchedFields` and is omitted from
211
- `data`. Both lists scale with requested paths, never with array length. When a
212
- miss matches a declared array path except for `[]`, the record also carries the
213
- traversal hint. The discriminator means downstream fields
214
- named `data`, `projection`,
215
- or `$connecta` remain ordinary values nested under `data`, never apparent
216
- metadata. A declared output schema contributes a bounded `availableFields`
217
- list and a `schemaCoverage` verdict. Only a completely analyzed, closed schema
218
- can label paths `invalidFields`; open, patterned, tuple, unresolvable, cyclic,
219
- `$ref`-sibling, or traversal-limited shapes stay `partial`. Traversal bounds
220
- depth, nodes, path count, individual path characters/bytes, and cumulative path
221
- characters/bytes before sorting or rendering. Without a schema, Connecta
222
- reports only observed misses and does not pretend it knows the complete runtime
223
- shape. API values and JSON-parseable downstream MCP text blocks follow the same
224
- rule.
195
+ directly actionable without copying an identifier out of prose. Program results
196
+ and oversized discovery responses carry no such route — paging a program's
197
+ return value is a refused shape, because a program can shrink anything before
198
+ it returns.
225
199
 
226
200
  ## Lexical discovery
227
201
 
@@ -145,4 +145,4 @@ either way and still needs restrained use.
145
145
  This connection is audited against
146
146
  [the provider conventions](./provider-conventions.md). Its verdict per
147
147
  convention, including every recorded exception, is the Mixpanel section of
148
- [the provider audit](./provider-audit.md).
148
+ [the provider audit](https://github.com/zackbart/connecta/blob/main/records/provider-audit.md).
@@ -268,4 +268,4 @@ from this connection, not hidden behind a generic call.
268
268
  This connection is audited against
269
269
  [the provider conventions](./provider-conventions.md). Its verdict per
270
270
  convention, including every recorded exception, is the Notion section of
271
- [the provider audit](./provider-audit.md).
271
+ [the provider audit](https://github.com/zackbart/connecta/blob/main/records/provider-audit.md).
@@ -96,14 +96,14 @@ optional.
96
96
  | `admission.requests?` | 16 active / 32 queued / 5 s / 1 s | global FIFO `/mcp` capacity, taken before auth ([request admission](./request-admission.md)) |
97
97
  | `admission.code?` | 2 active / 8 queued / 5 s / 1 s | fallback pool for an executor that owns no `acquire()`; ignored with a warning when it does |
98
98
 
99
- Options removed in earlier releases throw with their migration named rather
100
- than falling back to a default: `toolkits`
101
- ([#178](https://github.com/zackbart/connecta/issues/178)), `credentials.health`
102
- ([#179](https://github.com/zackbart/connecta/issues/179)), `surface` and
103
- `calls.maxBatchResultBytes`
104
- ([#273](https://github.com/zackbart/connecta/issues/273)), and the flat v0.6
105
- paths. Silently ignoring a removed option is how a deployment ends up running a
106
- policy its config file says it has.
99
+ An unknown own option throws before construction does deployment work. The
100
+ check covers the top level, every configuration group, admission pools,
101
+ branding icons, and server icons; the error names the rejected path without
102
+ copying its value. Removed options such as `toolkits`, `credentials.health`,
103
+ `surface`, `calls.maxBatchResultBytes`, and the flat v0.6 paths now take that
104
+ same path. The [upgrade guide](./upgrading.md#removed-options-that-throw) keeps
105
+ their historical mappings. Silently ignoring either a typo or a removed option
106
+ is how a deployment runs a policy its config file does not describe.
107
107
 
108
108
  ### Deployment as a release unit
109
109
 
@@ -150,7 +150,7 @@ are in it and that no unshippable path leaked in — including any
150
150
  Cloudflare-named connector or storage path (`connectors/cloudflare`,
151
151
  `storage/cloudflare`) anywhere in the artifact, `dist/` and `examples/` alike —
152
152
  derives the shipped guide list from which guides still carry a stub marker,
153
- hands the packed path list to `scripts/check-packed-links.mjs`, and then runs
153
+ hands the packed path list to `check-doc-links --packed`, and then runs
154
154
  `connecta init` and builds and runs the generated deployment's own container.
155
155
 
156
156
  That last step enforces the packed-link policy, which is one sentence: **every
@@ -224,39 +224,43 @@ in.
224
224
  | `catalog.test.ts` | lexical ranking and the compact schema renderer — `const`, `allOf` beside siblings, `$ref`, the depth limit, per-schema caching, and 2020-12 keyword compatibility |
225
225
  | `clerk.test.ts` | protected-resource metadata, the browser sign-in config, OAuth and session tokens, cached best-effort activity labels with their caps, the hand-applied `azp` rejection, and the `allowedDomains` allowlist including every lookalike that must not be repaired into a match |
226
226
  | `cloudflare-provider.test.ts` | `cloudflare()` construction, tool surface, request building, projections, typed failures, and credential test |
227
- | `cloudflare-registry.test.ts` | the same provider inside a real deployment: discovery including compact page bounds, addressing, and admission through the registry |
228
227
  | `code-first-surface.test.ts` | the seven-tool surface itself — an executor required, every removed option and top-level tool refused, compact always-loaded routing pinned below 1,000 characters, complete on-demand usage served, and `connecta.ui` findable before connector search |
229
228
  | `codemode-compat.test.ts` | the `Executor` seam staying structurally compatible with `@cloudflare/codemode`'s `DynamicWorkerExecutor`, enforced by `tsc` |
230
- | `config.test.ts` | the grouped `ConnectaConfig` boundary — each group forwarding to its internals, malformed admission bounds failing construction, and one complete migration error for legacy own-properties |
229
+ | `config.test.ts` | the grouped `ConnectaConfig` boundary — each group forwarding to its internals, malformed admission bounds failing construction, and unknown own-properties rejected by their complete path before construction does work |
231
230
  | `credentials.test.ts` | the pure stored-shape classifier (containment, not equality) and the AES-GCM vault: round-trip, ciphertext bound to its connector id, named field sets, masked metadata, wrong-key rejection, deletion, coexistence with OAuth keys |
232
231
  | `d1-activity-example.test.ts` | the Worker example's deployment-owned D1 activity store: actor namespace round-trip, payload-free friction reconstructed from the persisted code, and agreement with the package's friction table |
233
232
  | `downstream-oauth.test.ts` | `KvOAuthProvider` round-trips and races, `auth_required` versus `error`, `startAuth`/`finishAuth`, callback refusal equality, bounded diagnostics, and HTML escaping |
234
233
  | `errors.test.ts` | `ConnectorCallError` codes, retryable defaults and overrides, `retryAfterMs` round-trip, typed-over-heuristic classification, `AbortError` as a retryable timeout, and framing errors |
235
234
  | `execute.test.ts` | the code-mode host bridge: identifier sanitization, MCP-result unwrapping, sandbox provider construction, authenticated thrown-failure framing, fail-closed filtering of destructive and unannotated tools, MCP/code-mode invocation parity, and payload-free describe diagnostics |
236
235
  | `execute-emit.test.ts` | `connecta.emit` (M1–M10) — block validation, budgets, the provider, delivery after the result envelope on success only, and the defaults |
237
- | `execute-ui.test.ts` | `connecta.ui` (U1–U9) — validation, multiplicity and budget, the provider, `_meta` delivery, and the Apps shell |
236
+ | `execute-ui.test.ts` | display-only `connecta.ui` (U1–U13) — one-string validation, multiplicity and budget, the provider, `_meta` delivery, shell isolation, and the absence of a payload-to-host call path |
238
237
  | `executor-admission.test.ts` | the portable bounded FIFO both pools use: active and queue ceilings, stable retryable overload, queue timeout, cancellation removal, idempotent release, shutdown |
239
238
  | `guarded-fetch.test.ts` | the guarded transport — construction, request building, destination confinement, and response handling |
240
239
  | `guest-api-contract.test.ts` | the shared guest contract on the Dynamic Worker, including caught call, typed inline describe recovery, discovery, utility, batch, and budget failure codes; plus the real authority boundary — local `data:` fetch, denied egress, unresolved DNS, empty environment paths, unavailable filesystem/HTTP builtins, and present runtime globals |
241
- | `linear-provider.test.ts` / `linear-registry.test.ts` | the Linear proxy's construction, classification, and guide; then the same connector inside a real deployment |
242
- | `meta-tools.test.ts` | the registry-backed meta-tools: bounded discovery with page and address maxima, compact descriptions and the complete on-demand usage skill, compact and JSON schemas with constraints, typed describe recovery and suggestions, structured errors, connector-guide selection and summary bounds, stored-credential drift, catalog health, field projection, truncation and `get_result`, per-connector result bounds, probe timeouts, and unavailable or unknown browse recovery |
243
- | `mixpanel-provider.test.ts` / `mixpanel-registry.test.ts` | the Mixpanel proxy, its conditional-input guide and complete reviewed schema-digest manifest, then the same connector inside a real deployment |
244
- | `notion-provider.test.ts` / `notion-registry.test.ts` | Notion's deliberate tool surface, including declined expanded page inputs, request construction, lean projections, both pagination conventions, error mapping, and writes; then the connector in a real deployment |
240
+ | `linear-provider.test.ts` | the Linear proxy's construction, classification, and guide |
241
+ | `meta-tools-call.test.ts` | registry-backed calls: structured errors, truncation and `get_result`, per-connector result bounds, JSON representation failures, MCP content bounds, and offset alignment |
242
+ | `meta-tools-search.test.ts` | registry-backed discovery: bounded search with page and address maxima, compact and JSON schemas with constraints, typed describe recovery and suggestions, and structured-result compatibility |
243
+ | `meta-tools.test.ts` | the remaining registry-backed meta-tools: the complete on-demand usage skill, connector-guide selection and summary bounds, stored-credential drift, catalog health, authorization, probe timeouts, and unavailable or unknown browse recovery |
244
+ | `mixpanel-provider.test.ts` | the Mixpanel proxy, its conditional-input guide and complete reviewed schema-digest manifest |
245
+ | `notion-provider.test.ts` | Notion's deliberate tool surface, including declined expanded page inputs, request construction, lean projections, both pagination conventions, error mapping, and writes |
245
246
  | `operator-boundary.test.ts` | the operator row of the decisions table, after every mutation route: authentication material managed without moving a declared structure, and the one honest exception — a credential write making a remote catalog appear, which is discovery arriving, not an operator editing the deployment |
246
247
  | `operator-store.test.ts` | `src/operator-ui/app/store.ts` against a fake browser: the Clerk listener, `gate()`, the generation fence, and the request path |
247
248
  | `provider-conventions.test.ts` | the conventions a test can hold: hand-written providers refusing schemas they cannot enforce (H5), their compact discovery schemas staying complete (H7), Cloudflare stating its second pagination convention in the schema (H10), and Notion saying it has no escape hatch (H14) |
248
- | `registry.test.ts` | construction and id validation, startup warnings, address resolution, catalog TTL/persistence/completeness, agent-only stale-while-revalidate with cross-request single-flight shared with blocking reads in both start orders, owned teardown, invalidation/fingerprint guards, blocking diagnostics, and broken-connector isolation |
249
+ | `provider-registry.test.ts` | all six maintained providers inside real deployments: boot, description, address, catalog, storage, credential, admission, and activity isolation; plus provider-specific discovery and guide contracts |
250
+ | `registry.test.ts` | construction and id validation, startup warnings, address resolution, version 2 catalog TTL/persistence/completeness, agent-only stale-while-revalidate with cross-request single-flight shared with blocking reads in both start orders, owned teardown, invalidation/fingerprint guards, blocking diagnostics, and broken-connector isolation |
249
251
  | `remote-mcp.test.ts` | `remoteMcp()` against an in-process server through the `_transportFactory` seam: passthrough, downstream `isError`, Workers-safe output-schema validation, request-scoped client reuse and at-most-once scope close; plus the real transport's manual redirect policy, destination guard, credential containment, and downstream session termination |
250
- | `remote-mcp-credential.test.ts` | `remoteMcp()` drawing a static key from `/credentials`: the declared slot and its refusal of named fields and bad header names, header framing (bearer, bare, and the two `Basic` forms) observed on the wire, an empty slot failing as `auth_required` rather than reaching the downstream, a value carrying a control character refused before framing and absent from every surface — `call_tool`, `status`, the Test result, `lastError`, and the thrown error — rotation replacing the cached client and a connect already in flight while a wiped value fails the next call, the Test action's catalog probe and scope close, the cleartext-destination warning, and the vault and `authorize_connector` handoff end to end |
252
+ | `remote-mcp-credential.test.ts` | `remoteMcp()` drawing a static key from `/credentials`: the declared slot and its refusal of named fields and bad header names, header framing (bearer, bare, and the two `Basic` forms) observed on the wire, an empty slot failing as `auth_required` rather than reaching the downstream, a value carrying a control character refused before framing and absent from every surface — `call_tool`, `status`, the Test result, the payload-free activity event, and the thrown error — rotation replacing the cached client and a connect already in flight while a wiped value fails the next call, the Test action's catalog probe and scope close, the cleartext-destination warning, and the vault and `authorize_connector` handoff end to end |
251
253
  | `remote-mcp-pagination.test.ts` | the `tools/list` cursor chain in both directions — exact cursor handoff, first-wins dedup, a failed later page rejecting rather than returning its prefix, the runaway backstops, the tool-metadata re-prime across pages, and paginated catalogs reaching the discovery path |
252
254
  | `request-admission.test.ts` | `/mcp` bounded before auth, the stable 503 and `Retry-After`, health and operator responsiveness under saturation, payload-free counters, queued cancellation, shutdown rejection while active work drains, and the separate fallback code pool |
253
255
  | `result-shapes.test.ts` | passive output-shape learning: value-free bounded inference, merging, 256-entry LRU eviction, 24-hour expiry, runtime isolation, read-only admission, declared-schema precedence, definition-change invalidation, discovery provenance, and failure isolation |
254
- | `revenuecat-provider.test.ts` / `revenuecat-registry.test.ts` | the RevenueCat proxy's per-project key scoping and account-wide OAuth guides, its purpose-bearing summary, the argued borderline verdicts in its digest-free manifest, and the deliberately unclassified `render-paywall-screenshot`; then two project-scoped keys as two connectors in a real deployment |
255
- | `server.test.ts` | end-to-end `/mcp` (401 → compact initialize instructions → seven compact definitions with bounded connector inventory → complete usage skill → `call_tool`), conditional guide pointers, open routes, Clerk `.well-known` metadata without network, code mode, and deferred catalog reads through both discovery surfaces |
256
+ | `revenuecat-provider.test.ts` | the RevenueCat proxy's per-project key scoping and account-wide OAuth guides, its purpose-bearing summary, the argued borderline verdicts in its digest-free manifest, and the deliberately unclassified `render-paywall-screenshot` |
257
+ | `server.test.ts` | end-to-end `/mcp` (401 → compact initialize instructions → seven compact definitions with bounded connector inventory and exact model-only Apps metadata → complete usage skill → `call_tool`), conditional guide pointers, open routes, Clerk `.well-known` metadata without network, code mode, and deferred catalog reads through both discovery surfaces |
256
258
  | `server-route-contracts.test.ts` | the route contracts `server.ts` must keep byte-identical: every built-in answered ahead of connector routes inside the security wrapper, open data-free shells with framing denied, per-route auth and same-origin requirements with exact 401/403/405 bodies, and OAuth `verifyState`-before-`finishAuth` ordering |
257
259
  | `startup-warnings.test.ts` | every construction-time `logger.warn` and, as importantly, the conditions that must *not* trigger one: open mode with a credential or OAuth connector, `publicUrl` unset beside OAuth, dropped branding and `uiAuth` URLs, a missing `verifyState`, a credential test-hook mismatch, and an unusable `calls.maxResultBytes` |
258
- | `stripe-provider.test.ts` / `stripe-registry.test.ts` | the Stripe proxy's mixed-mode OAuth and fixed-mode header contracts, admission, exact account selectors, and no-guess rule; then fixed credentials in a real deployment |
259
- | `ui.test.ts` | the server shell and `/ui/*` routes and the app's pure state rules from `view.ts` filtering, page routing and capability states, credential management, gated `/ui/data` with broken-connector isolation and registry-owned catalog-observation containment, and the URL safety gates |
260
+ | `stripe-provider.test.ts` | the Stripe proxy's mixed-mode OAuth and fixed-mode header contracts, admission, exact account selectors, and no-guess rule |
261
+ | `operator-view.test.ts` | the app's pure state rules from `view.ts`: filtering, page routing, capability states, activity summaries, drift display, and identity reset |
262
+ | `ui-credentials.test.ts` | credential-management routes: save, test, delete, validation, authentication, same-origin checks, and multi-field credential shapes |
263
+ | `ui.test.ts` | the server shell and remaining `/ui/*` routes: gated `/ui/data` with broken-connector isolation and registry-owned catalog-observation containment, plus the URL safety gates |
260
264
  | `validate.test.ts` | `validateToolInput()` — a returned (not thrown) `invalid_args` naming the path, `additionalProperties: false` enforcement, per-schema validator caching, and an unusable schema passed through with one warning |
261
265
 
262
266
  ### Node-bound (`NODE_ONLY_SUITES`)
@@ -282,15 +286,15 @@ justification for *not* re-running it in workerd, so "it was easier" is not one.
282
286
  | `quickjs-log-limits.test.ts` | bounded `console.*` capture — per-entry cut, cumulative character and transport budgets, escape-heavy floods preserving the guest result | runs the Node QuickJS child-process executor |
283
287
  | `suite-partition.test.ts` | this partition, including itself: every `*.test.ts` in exactly one list, stale entries and empty reasons refused | walks the test directory to guard the partition |
284
288
  | `template-file-activity.test.ts` | the Node template's own activity store — persistence across restart, torn-line repair, newest-first paging, and compaction past the slack window | runs it against real files |
285
- | `upgrade-guide.test.ts` | the [upgrade guide](./upgrading.md)'s claims about somebody else's deployment — the generated file inventory, the seven tool names doctor demands, version boundaries that actually shipped, a bump target that is this release, and the three places a reader finds it | reads the guide, the template tree, and the CLI with Node filesystem APIs |
286
- | `version.test.ts` | `CONNECTA_VERSION` matching `package.json` | reads `package.json` with Node filesystem APIs |
289
+ | `upgrade-guide.test.ts` | the [upgrade guide](./upgrading.md)'s claims about somebody else's deployment — the generated file inventory, the seven tool names doctor demands, version boundaries that actually shipped, the exact newest boundary and generation B endpoint matching this release, a bump target that is this release, and the three places a reader finds it | reads the guide, the template tree, and the CLI with Node filesystem APIs |
290
+ | `version.test.ts` | `CONNECTA_VERSION` matching `package.json` and the Node template's exact dependency pin | reads both package manifests with Node filesystem APIs |
287
291
 
288
292
  ### Outside `npm run check`
289
293
 
290
294
  | Suite | Covers |
291
295
  | --- | --- |
292
296
  | `browser/operator-ui.spec.ts` | the operator wiring in a real browser: Clerk loader order across its version redirect and a real load failure, the shell staying open until authentication, credential and access-token and OAuth flows end to end, drift shown without naming a tool, and every failure and empty state |
293
- | `browser/program-ui.spec.ts` | the Apps shell in a real browser: a bound view merging fixed and declared arguments and correlating concurrent reads, and the one-string payload receiving no read bridge ([program UI read calls](./program-ui-read-calls.md)) |
297
+ | `browser/program-ui.spec.ts` | the display-only Apps shell in a real browser: local payload JavaScript runs, `connecta` stays absent, and forged payload messages never become host tool calls |
294
298
 
295
299
  **The `_transportFactory` seam.** `RemoteMcpOptions._transportFactory` is
296
300
  internal, not public API: when set, `remoteMcp()` uses that `Transport` instead
@@ -183,10 +183,9 @@ tokens.
183
183
 
184
184
  ### H8 — Every tool declares an `outputSchema`
185
185
 
186
- Declared outputs are what produce `outputKeys` and the `fields` projection's
187
- `availableFields`, and they let a program reduce a result without first
188
- fetching one to look at. Connecta measured *declared* output schemas at 0 of 30
189
- tools on one real deployment and 3 of 30 on another
186
+ Declared outputs produce `outputKeys` and let a program reduce a result without
187
+ first fetching one to look at. Connecta measured *declared* output schemas at 0
188
+ of 30 tools on one real deployment and 3 of 30 on another
190
189
  ([#282](https://github.com/zackbart/connecta/issues/282)) — nearly every tool an
191
190
  agent meets is a shape it can only learn by calling. A maintained provider has
192
191
  no excuse to join that majority.
@@ -651,7 +650,7 @@ runs this document against each of the six providers and returns a verdict per
651
650
  convention: **meets**, **misses** (with the fix), or **not applicable** (with
652
651
  the reason). A convention is never quietly skipped, and an accepted miss is
653
652
  recorded as a provider-specific exception with its argument, not left blank.
654
- Its six reports live in [provider-audit.md](./provider-audit.md), and the
653
+ Its six reports live in [provider-audit.md](https://github.com/zackbart/connecta/blob/main/records/provider-audit.md), and the
655
654
  mechanically checkable half of the hand-written bar runs on every test run in
656
655
  [`test/provider-conventions.test.ts`](https://github.com/zackbart/connecta/blob/main/test/provider-conventions.test.ts) —
657
656
  so a convention that was met once stays met, or fails loudly.
@@ -298,4 +298,4 @@ still needs restrained use.
298
298
  This connection is audited against
299
299
  [the provider conventions](./provider-conventions.md). Its verdict per
300
300
  convention is the RevenueCat section of
301
- [the provider audit](./provider-audit.md).
301
+ [the provider audit](https://github.com/zackbart/connecta/blob/main/records/provider-audit.md).
@@ -251,4 +251,4 @@ about rather than read:
251
251
  This connection is audited against
252
252
  [the provider conventions](./provider-conventions.md). Its verdict per
253
253
  convention, including every recorded exception, is the Stripe section of
254
- [the provider audit](./provider-audit.md).
254
+ [the provider audit](https://github.com/zackbart/connecta/blob/main/records/provider-audit.md).
@@ -57,7 +57,7 @@ exist so far:
57
57
  | --- | --- | --- |
58
58
  | **pre-template** | before 0.10.2 | no `connecta init` existed; hand-written, or copied from the retired `examples/node` |
59
59
  | **A** | 0.10.2 – 0.15.1 | `.env.example`, `.gitignore`, `AGENTS.md`, `CLAUDE.md`, `README.md`, `package.json`, `src/index.ts`, `tsconfig.json` |
60
- | **B** | 0.16.0 – 0.18.3 | adds `.dockerignore`, `Dockerfile`, `docker-compose.yml`, and `src/file-activity.ts`; `src/index.ts` grows the four commented operator blocks; `.env.example` ships `CONNECTA_TOKEN=` empty |
60
+ | **B** | 0.16.0 – 0.20.0 | adds `.dockerignore`, `Dockerfile`, `docker-compose.yml`, and `src/file-activity.ts`; `src/index.ts` grows the four commented operator blocks; `.env.example` ships `CONNECTA_TOKEN=` empty |
61
61
 
62
62
  Generation A is a decade in template years and identifying it precisely does
63
63
  not matter, because you are about to reconstruct it exactly rather than guess
@@ -106,7 +106,7 @@ know what to preserve, once to know what to re-verify at the end.
106
106
  ### Bump the pin and install
107
107
 
108
108
  ```sh
109
- npm pkg set dependencies.@zackbart/connecta=0.18.3
109
+ npm pkg set dependencies.@zackbart/connecta=0.20.0
110
110
  npm install
111
111
  ```
112
112
 
@@ -130,7 +130,7 @@ Generate the *current* template beside the base you already made, into the same
130
130
  `$SCRATCH`:
131
131
 
132
132
  ```sh
133
- (cd "$SCRATCH" && npx @zackbart/connecta@0.18.3 init current)
133
+ (cd "$SCRATCH" && npx @zackbart/connecta@0.20.0 init current)
134
134
  ```
135
135
 
136
136
  You now have a three-way merge with a real base: `$SCRATCH/base` is what this
@@ -186,7 +186,7 @@ A deployment older than 0.10.2 has no base to diff against. Do not try to
186
186
  manufacture one. Instead:
187
187
 
188
188
  1. `SCRATCH=$(mktemp -d)`, then
189
- `(cd "$SCRATCH" && npx @zackbart/connecta@0.18.3 init current)` — there is no
189
+ `(cd "$SCRATCH" && npx @zackbart/connecta@0.20.0 init current)` — there is no
190
190
  `base` leg here, only the current template to read from.
191
191
  2. Copy `$SCRATCH/current` into the deployment file by file, **skipping
192
192
  `src/index.ts`**.
@@ -207,6 +207,39 @@ first, so cross them bottom-up: start at the oldest one still above this
207
207
  deployment's pin and work back up the page, because each boundary assumes the
208
208
  older ones are already done.
209
209
 
210
+ ### 0.19.0 → 0.20.0
211
+
212
+ Three intake paths become deliberately strict. None changes storage, the two
213
+ deployment shapes, or the exact seven-tool MCP surface.
214
+
215
+ - `createConnecta` now rejects every unknown own configuration property by its
216
+ complete path. Remove typos and options retired before 0.19, including the
217
+ top-level `toolkits`, `credentialHealth`, `surface`, and `maxResultBytes`,
218
+ plus `credentials.health` and `calls.maxBatchResultBytes`. Connector, auth,
219
+ storage, activity-store, logger, deployment-metadata, and executor
220
+ implementations remain open objects; their implementation-specific fields
221
+ are not configuration typos.
222
+ - `call_tool` and `call_destructive_tool` no longer accept `fields`. Put
223
+ projection in one `execute_code` program. For a legitimate oversized direct
224
+ read, call without `fields` and follow the returned `get_result` action; that
225
+ paging path remains part of the seven-tool surface.
226
+ - `connecta.ui` accepts one HTML string and is display-only. Remove its second
227
+ read-binding argument and any page calls to `connecta.read`. Fetch and shape
228
+ data in the program before rendering, then return the same compact summary
229
+ the view initially displays. Views cannot call any Connecta tool.
230
+
231
+ The Node template layout remains generation B. Reconcile it as usual after the
232
+ version bump; no new deployment file or environment variable is required.
233
+
234
+ ### 0.18.3 → 0.19.0
235
+
236
+ Nothing changes for a deployment. Bump the version and reconcile the template
237
+ as usual; no configuration, storage, runtime, or model-facing boundary moved.
238
+ The release deletes unreachable compatibility code and consolidates source and
239
+ tests behind the same public behavior. Six design records also moved out of the
240
+ npm package and now live only at their GitHub URLs. They were maintainer history,
241
+ not deployment documentation.
242
+
210
243
  ### 0.18.2 → 0.18.3
211
244
 
212
245
  Nothing throws for an existing deployment, and the version bump alone crosses
@@ -442,9 +475,11 @@ built-in routes miss, so it can add a route and never shadow one
442
475
 
443
476
  ### Removed options that throw
444
477
 
445
- These fail at construction with their migration named rather than falling back
446
- to a default, because silently ignoring a removed option is how a deployment
447
- ends up running a policy its config file says it has:
478
+ These fail at construction rather than falling back to a default, because
479
+ silently ignoring a removed option is how a deployment runs a policy its config
480
+ file says it has. Releases through 0.19 name the migration in the error. Version
481
+ 0.20's strict configuration boundary names the unknown path; this table remains
482
+ the migration map:
448
483
 
449
484
  | Option | Removed in | Do |
450
485
  | --- | --- | --- |
@@ -452,7 +487,7 @@ ends up running a policy its config file says it has:
452
487
  | `credentials.health`, `credentialHealth` | 0.8.1 (#179) | delete; credentials fail at use |
453
488
  | `surface` | 0.11.0 (#273) | delete; there is one seven-tool surface |
454
489
  | `calls.maxBatchResultBytes` | 0.11.0 (#273) | delete; program batching is bounded by `execute_code`'s own limits |
455
- | flat v0.6 config paths | 0.7.0 | move into their groups — one complete migration error lists them ([operations](./operations.md#configuration)) |
490
+ | flat v0.6 config paths | 0.7.0 | move into their groups ([operations](./operations.md#configuration)) |
456
491
 
457
492
  ## Verify
458
493