@zackbart/connecta 0.18.3 → 0.19.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 (69) hide show
  1. package/CHANGELOG.md +73 -4
  2. package/dist/catalog-service.d.ts +16 -13
  3. package/dist/catalog-service.js +106 -115
  4. package/dist/catalog.js +29 -46
  5. package/dist/connector-scope.js +2 -7
  6. package/dist/connectors/api.d.ts +4 -16
  7. package/dist/connectors/api.js +19 -46
  8. package/dist/connectors/guarded-fetch.d.ts +9 -23
  9. package/dist/connectors/guarded-fetch.js +38 -76
  10. package/dist/connectors/remote-mcp.js +36 -79
  11. package/dist/errors.d.ts +6 -27
  12. package/dist/errors.js +8 -5
  13. package/dist/execute.d.ts +24 -22
  14. package/dist/execute.js +98 -145
  15. package/dist/executor-result.d.ts +1 -0
  16. package/dist/executor-result.js +4 -11
  17. package/dist/executors/quickjs-child.js +1 -3
  18. package/dist/executors/quickjs-runtime.js +1 -3
  19. package/dist/executors/quickjs.js +1 -3
  20. package/dist/index.js +27 -57
  21. package/dist/invocation.js +113 -183
  22. package/dist/meta-tools.d.ts +15 -28
  23. package/dist/meta-tools.js +33 -89
  24. package/dist/providers/cloudflare.d.ts +2 -18
  25. package/dist/providers/cloudflare.js +1460 -2451
  26. package/dist/providers/linear.d.ts +4 -41
  27. package/dist/providers/linear.js +8 -39
  28. package/dist/providers/mixpanel.d.ts +3 -25
  29. package/dist/providers/mixpanel.js +7 -22
  30. package/dist/providers/notion.d.ts +1 -15
  31. package/dist/providers/notion.js +44 -173
  32. package/dist/providers/revenuecat.d.ts +4 -57
  33. package/dist/providers/revenuecat.js +10 -93
  34. package/dist/providers/stripe.d.ts +1 -12
  35. package/dist/providers/stripe.js +7 -45
  36. package/dist/registry.d.ts +9 -34
  37. package/dist/registry.js +9 -103
  38. package/dist/routes/mcp.js +1 -1
  39. package/dist/routes/oauth.js +3 -3
  40. package/dist/routes/shared.d.ts +15 -15
  41. package/dist/routes/shared.js +1 -3
  42. package/dist/timeout.d.ts +8 -7
  43. package/dist/timeout.js +47 -38
  44. package/dist/types.d.ts +3 -3
  45. package/dist/ui.d.ts +1 -25
  46. package/dist/ui.js +18 -45
  47. package/dist/version.d.ts +1 -1
  48. package/dist/version.js +1 -1
  49. package/documentation/call-admission.md +1 -1
  50. package/documentation/cloudflare.md +1 -1
  51. package/documentation/code-mode.md +7 -7
  52. package/documentation/connectors.md +24 -1
  53. package/documentation/linear.md +1 -1
  54. package/documentation/mixpanel.md +1 -1
  55. package/documentation/notion.md +1 -1
  56. package/documentation/operations.md +18 -14
  57. package/documentation/provider-conventions.md +1 -1
  58. package/documentation/revenuecat.md +1 -1
  59. package/documentation/stripe.md +1 -1
  60. package/documentation/upgrading.md +13 -4
  61. package/ethos.md +75 -121
  62. package/package.json +3 -4
  63. package/templates/node/package.json +1 -1
  64. package/documentation/code-first-exploration.md +0 -292
  65. package/documentation/mcp-2026-07-28.md +0 -46
  66. package/documentation/mcp-ui-design.md +0 -382
  67. package/documentation/program-ui-read-calls.md +0 -213
  68. package/documentation/provider-audit.md +0 -198
  69. package/documentation/rich-output-design.md +0 -211
@@ -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,7 +224,6 @@ 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
229
  | `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 |
@@ -238,25 +237,30 @@ in.
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, field projection, 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 |
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` |
255
257
  | `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
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 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](https://github.com/zackbart/connecta/blob/main/records/program-ui-read-calls.md)) |
294
298
 
295
299
  **The `_transportFactory` seam.** `RemoteMcpOptions._transportFactory` is
296
300
  internal, not public API: when set, `remoteMcp()` uses that `Transport` instead
@@ -651,7 +651,7 @@ runs this document against each of the six providers and returns a verdict per
651
651
  convention: **meets**, **misses** (with the fix), or **not applicable** (with
652
652
  the reason). A convention is never quietly skipped, and an accepted miss is
653
653
  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
654
+ Its six reports live in [provider-audit.md](https://github.com/zackbart/connecta/blob/main/records/provider-audit.md), and the
655
655
  mechanically checkable half of the hand-written bar runs on every test run in
656
656
  [`test/provider-conventions.test.ts`](https://github.com/zackbart/connecta/blob/main/test/provider-conventions.test.ts) —
657
657
  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.19.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.19.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.19.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.19.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,15 @@ 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.18.3 → 0.19.0
211
+
212
+ Nothing changes for a deployment. Bump the version and reconcile the template
213
+ as usual; no configuration, storage, runtime, or model-facing boundary moved.
214
+ The release deletes unreachable compatibility code and consolidates source and
215
+ tests behind the same public behavior. Six design records also moved out of the
216
+ npm package and now live only at their GitHub URLs. They were maintainer history,
217
+ not deployment documentation.
218
+
210
219
  ### 0.18.2 → 0.18.3
211
220
 
212
221
  Nothing throws for an existing deployment, and the version bump alone crosses
package/ethos.md CHANGED
@@ -1,149 +1,103 @@
1
1
  # connecta — ethos
2
2
 
3
3
  What connecta is, what it refuses to be, and the invariants every change must
4
- preserve. This file is deliberately terse. When a proposed change contradicts a
5
- line here, either the change is wrong or this file needs amending — in that
6
- order, and amending it is a design decision, not a drive-by edit.
4
+ preserve. Deliberately terse: when a change contradicts a line here, either the
5
+ change is wrong or this file needs amending — in that order, and amending it is
6
+ a design decision, not a drive-by edit.
7
7
 
8
8
  ## What this is
9
9
 
10
- - **One MCP endpoint, one programmable surface.** Every integration you've
11
- deliberately chosen sits behind a capability catalog that agents reach by
12
- writing ordinary JavaScript, ringed by a few explicit tools for the
13
- boundaries code must not cross, and for the jobs a program is the wrong
14
- shape for.
10
+ - **One MCP endpoint, one programmable surface.** Every integration you chose
11
+ sits behind a capability catalog that agents reach by writing JavaScript,
12
+ ringed by a few explicit tools for the boundaries code must not cross.
15
13
  - **A deployment is a small config-as-code file.** Changing what agents can
16
- reach is an edit and a redeploy. One deployment, one tenant, one audience
17
- more audiences means more deployments.
18
- - **Curated when available, open when not.** Prefer an explicitly imported
19
- prebuilt connection when Connecta maintains one: it carries the provider's
20
- known-good endpoint, authentication defaults, tool ergonomics, and concise
21
- usage guidance. `remoteMcp()` and `api()` remain equal, first-class
22
- primitives for custom and unsupported integrations. Every path produces the
23
- same `Connector`: same addresses, same catalog, same safety rules.
14
+ reach is an edit and a redeploy. One deployment, one tenant, one audience.
15
+ - **Curated when available, open when not.** Prefer a maintained prebuilt
16
+ connection; `remoteMcp()` and `api()` stay first-class for everything else.
17
+ Every path yields the same `Connector` with the same rules.
24
18
  - **Seven tools, an executor required.** The primary surface is a program, so
25
- every deployment runs an executor a Dynamic Worker on Cloudflare, QuickJS
26
- behind its optional-peer subpath on Node and one without refuses to boot
27
- ([#273](https://github.com/zackbart/connecta/issues/273)). Every meta-tool
28
- earns its keep: the default answer to "agents need X" is the program
29
- surface, and a capability has to be shown inexpressible through it before
30
- it earns a top-level tool
31
- ([#224](https://github.com/zackbart/connecta/issues/224)). Packaging is
32
- unchanged: required describes the deployment, never the dependencies.
33
- - **Safe by default.** Only tools explicitly annotated read-only are callable
34
- without crossing the destructive boundary — directly or from generated code;
35
- everything else goes through `call_destructive_tool`, where the MCP host can
36
- put the question to a human. Approval is the host's job; connecta makes the
37
- question visible.
38
- - **One fetch-native core, two runtimes.** The same code runs unchanged on
39
- Cloudflare Workers and in Node — a Worker or a Docker stack, your pick. Web
40
- APIs only in the core; Node touches live behind explicit subpaths.
19
+ every deployment runs an executor and one without refuses to boot. A
20
+ capability earns a top-level tool only by being inexpressible as a program.
21
+ - **Safe by default.** Only tools explicitly annotated read-only run without
22
+ crossing `call_destructive_tool`, where the host can ask a human. Approval is
23
+ the host's job; connecta makes the question visible.
24
+ - **One fetch-native core, two runtimes.** Web APIs only in the core; Node
25
+ touches live behind explicit subpaths. Cloudflare Worker or Docker, your pick.
41
26
  - **Observable, actionable only over authentication material.** Operator pages
42
- show connector status, masked credentials, and payload-free activity and
43
- they act: rotate a credential, issue or revoke an access token, run a
44
- downstream OAuth flow. Declared capability is what they cannot touch.
27
+ show status and payload-free activity and may rotate credentials, issue
28
+ tokens, and run OAuth. Declared capability they cannot touch.
45
29
 
46
30
  ## What this isn't
47
31
 
48
- - **Not a platform.** No runtime connector registration, no admin UI that
49
- changes declared capability, no policy engine, no approvals, no pauses.
50
- - **Not a schema ingester.** No OpenAPI or GraphQL → tools. Generated tool
51
- sprawl is the disease the meta-tools treat, not a feature to add.
52
- - **Not multi-tenant.** No Connecta account model, per-user credential store, or org hierarchy; credentials, storage, admission, and health stay connector-scoped.
53
- Provider-owned sessions may expose provider-native account scope only through live schemas. Metadata never proves account identity; Connecta never invents or normalizes selectors, and ambiguity stops.
54
- - **Not stateful.** No protocol sessions, no server push. Scope resolves per
55
- request which is also where the MCP spec itself has now arrived.
56
- - **Not a nanny.** Credentials fail loudly at use; connecta never probes one.
57
- - **Not a promise to strangers — yet.** Built for its author's deployments
58
- first, published openly. Breaking changes are cheap and the version number
59
- signals change, not stability.
32
+ - **Not a platform.** No runtime registration, admin-editable capability,
33
+ policy engine, approvals, or pauses.
34
+ - **Not a schema ingester.** No OpenAPI or GraphQL → tools.
35
+ - **Not multi-tenant.** No account model or per-user credential store; scope
36
+ stays connector-level, and ambiguity stops rather than guesses.
37
+ - **Not stateful.** No protocol sessions, no server push; scope resolves per
38
+ request.
39
+ - **Not a nanny.** Credentials fail loudly at use; nothing probes one.
40
+ - **Not a promise to strangers yet.** Breaking changes are cheap; the version
41
+ number signals change, not stability.
60
42
 
61
43
  ## Decisions
62
44
 
63
- The record of shapes considered and refused. Proposing one again is allowed;
64
- proposing one without a new argument is not.
45
+ Shapes considered and turned down. Proposing one again without a new argument
46
+ is not allowed. Accepted designs live in their subsystem guide and the
47
+ CHANGELOG, not here.
65
48
 
66
49
  | Decision | Verdict | Why |
67
50
  | --- | --- | --- |
68
- | OpenAPI / GraphQL ingestion | refused | generated tools are the disease; hand-write `api()` |
69
- | Multi-tenancy / account model | refused | one deployment per tenant; deploy again instead |
51
+ | OpenAPI / GraphQL ingestion | refused | the disease is a tool nobody chose — a document authored it; hand-written literals, even through a shared factory, are still authorship |
52
+ | Multi-tenancy / account model | refused | one deployment per tenant; deploy again |
70
53
  | Policy engine, approvals, pauses | refused | the host asks the human; connecta only annotates |
71
54
  | Runtime connector registration | refused | config-as-code is the security model |
72
- | Prebuilt connections as the preferred authoring path | accepted | an a-la-carte provider constructor, imported and constructed in the deployment file, encodes maintained defaults for providers connecta actually uses — preferred *when maintained*, with no promise of one per provider; it returns exactly one ordinary `Connector` with no extra privileges — never a bundle, a group, a preset, or a registry — its tools are hand-written or proxied from a downstream MCP catalog, never generated from a schema document; its vetted annotations classify what the downstream leaves unannotated and otherwise preserve explicit annotations, with one fail-closed exception: a release-reviewed destructive classification outranks a contradictory downstream `readOnlyHint: true`, because Connecta has independently established that the tool mutates existing state; `remoteMcp()` and `api()` stay first-class ([#297](https://github.com/zackbart/connecta/issues/297), [#315](https://github.com/zackbart/connecta/issues/315)) |
73
- | Guarded raw REST escape hatches in a prebuilt connection | accepted | a large, fast-moving provider cannot be honestly represented by a small frozen list: a GET-only tool may expose provider-relative reads, while JSON mutations and explicit-content uploads stay separate and always cross the destructive boundary; the connector owns authentication, rate limits, error mapping, URL confinement, and safe method classification, while the provider token remains the capability boundary — this is not schema ingestion, runtime connector registration, or permission widening |
74
- | Expanded Notion page create/update options | refused | the maintained writes own explicit parents, authored content, property replacement, and reversible trash; workspace-private creation, placement, richer media, coordination locks, asynchronous templates, and irreversible child erasure are different ownership, ordering, file, coordination, or deletion workflows, not missing fields — keep the approval names honest and use a custom `api()` connector when a deployment needs one ([#408](https://github.com/zackbart/connecta/issues/408), [#409](https://github.com/zackbart/connecta/issues/409)) |
75
- | Hosted-provider drift detection during catalog refreshes | accepted | a vetted classification is a claim about somebody else's catalog, and an allowlist nobody can tell is stale is an allowlist that is wrong — so each maintained hosted-MCP proxy ships the tool names, classifications, and (once a release records them) schemas it reviewed, and compares them against the live listing *inside* a catalog refresh the deployment already asked for; the boundary is the piggyback itself, which is what keeps this from being proactive credential liveness wearing a new hat ([#179](https://github.com/zackbart/connecta/issues/179)): no scheduled job, no background request, no credential probe, and not one byte of network traffic that would not have happened anyway; what it produces is four counts — unclassified additions, names no longer served, explicit annotation conflicts, schema changes — on connector status, `connecta doctor`, and one payload-free activity event with nowhere to put a tool name or a schema; the two read surfaces answer for the runtime that served the refresh, because the observation is isolate-local and only the activity event is durable, and unknown tools already fail closed, so drift costs approval round trips and stale guidance rather than capability ([#343](https://github.com/zackbart/connecta/issues/343)) |
76
- | Provider registry / integration marketplace | refused | prebuilt connections are imports, not listings; discovery happens in documentation, never at runtime ([#297](https://github.com/zackbart/connecta/issues/297)) |
55
+ | Provider registry / marketplace | refused | prebuilt connections are imports; discovery happens in docs ([#297](https://github.com/zackbart/connecta/issues/297)) |
56
+ | Expanded Notion page create/update options | refused | different workflows, not missing fields; use `api()` ([#408](https://github.com/zackbart/connecta/issues/408)) |
77
57
  | Protocol sessions & server push | refused | stateless per request |
78
- | Resources & prompts aggregation | refused | tools only; connecta's own Apps shell is the one `resources/read` carve-out ([#266](https://github.com/zackbart/connecta/issues/266)) |
58
+ | Resources & prompts aggregation | refused | tools only; the Apps shell is the one `resources/read` carve-out ([#266](https://github.com/zackbart/connecta/issues/266)) |
79
59
  | Elicitation passthrough | refused | no route through a stateless aggregator |
80
60
  | Repository formatter | refused | style is authored, not enforced |
81
- | Toolkits (scoped views) | removed | never earned its keep; deploy per audience ([#178](https://github.com/zackbart/connecta/issues/178)) |
61
+ | Host-side projection of program results | refused | a program projects; a heuristic drops fields invisibly ([#223](https://github.com/zackbart/connecta/issues/223)) |
62
+ | `get_result` paging for program results | refused | paging rewards the unprojected return code mode exists to remove ([#223](https://github.com/zackbart/connecta/issues/223)) |
63
+ | Native Tasks for oversized results | refused | tasks solve duration, `get_result` solves size ([#176](https://github.com/zackbart/connecta/issues/176)) |
64
+ | Widening the `Executor` result contract | refused | `{ result, error?, logs? }` is the `@cloudflare/codemode` parity guarantee ([#267](https://github.com/zackbart/connecta/issues/267)) |
65
+ | Erasable TypeScript in `execute_code` | refused | 24 MB dependency in the core, no measured agent benefit ([#419](https://github.com/zackbart/connecta/issues/419)) |
66
+ | Guest-minted `resource` / `resource_link` blocks | refused | a program can never mint a URI a client may dereference ([#266](https://github.com/zackbart/connecta/issues/266)) |
67
+ | Provenance tracking for emitted content | refused | everything a program emits is program output ([#267](https://github.com/zackbart/connecta/issues/267)) |
68
+ | Result sampling on the catalog surface | refused | sampling is execution and cannot ride a catalog read ([#282](https://github.com/zackbart/connecta/issues/282)) |
69
+ | Legacy embedded `UIResource` delivery | refused | superseded upstream, rendered by no client we face ([#266](https://github.com/zackbart/connecta/issues/266)) |
70
+ | Effect as the core effect system | refused | −4% of the core for +75 KB gzip and a second async paradigm; re-measure at v4 stable ([#470](https://github.com/zackbart/connecta/issues/470)) |
71
+ | Shared bounded queue under both admission controllers | refused | built and measured −17 lines for a hook-parameterised abstraction ([#453](https://github.com/zackbart/connecta/issues/453)) |
72
+ | Toolkits (scoped views) | removed | deploy per audience ([#178](https://github.com/zackbart/connecta/issues/178)) |
82
73
  | Proactive credential liveness | removed | fail-at-use is enough ([#179](https://github.com/zackbart/connecta/issues/179)) |
83
- | Agent credential recovery | accepted | one `auth_required` route through `authorize_connector`; only an operator handles secrets ([#192](https://github.com/zackbart/connecta/issues/192)) |
84
- | Operator-issued MCP access tokens | accepted | named, revocable authentication gives header-capable clients a small alternative to OAuth; tokens identify callers but never scope tools or become operator credentials |
85
- | Operator boundary reworded: authentication material, never declared capability | accepted | supersedes "observable, never administrable", which had stopped describing the surface: operator routes already rotate credentials, issue and revoke access tokens, and drive downstream OAuth, each under its own accepted row, and the owner has decided the surface stays actionable — so the boundary now says what is actually true, that operator routes may manage authentication material for capabilities declared in deployment configuration and may not change the connector set, the declared tool catalog or annotations, requested OAuth scopes, admission policy, authorization rules, or caller tool scope; the claim is deliberately about *declared* capability, and twice so, because replacing an API token with a broader-scoped one widens downstream reach and no browser page can honestly promise otherwise, and because a remote MCP server's catalog is discovered rather than declared — connecta declares the connector, its credential slot, and its admission policy, while the tools that server serves are its own answer, so storing a credential or finishing an OAuth flow can legitimately take an `mcp()` connector from no tools to N, which is discovery arriving, not an operator editing the deployment ([#338](https://github.com/zackbart/connecta/issues/338)) |
86
- | Structured result surface | accepted | canonical `structuredContent` plus complete compact `content`; summary-only text is gated on host-forwarding evidence ([#191](https://github.com/zackbart/connecta/issues/191)) |
87
- | Code mode (`execute_code`) | accepted | the primary read, discovery, and composition surface: smaller serialized definitions, far smaller results once composition and projection happen before the model sees them, and a cold-start model that read the interface without help ([exploration](./documentation/code-first-exploration.md), [#224](https://github.com/zackbart/connecta/issues/224)) |
88
- | Code-first as the default; the eval gate retired | accepted | owner decision, 2026-07-30: one operator, no deploy-time flip; [`eval/code-first-gate`](https://github.com/zackbart/connecta/blob/main/eval/code-first-gate/README.md) survives as measurement, but nothing waits on its verdict ([#222](https://github.com/zackbart/connecta/issues/222), [#224](https://github.com/zackbart/connecta/issues/224)) |
89
- | Always-loaded routing, on-demand execution detail | accepted | every conversation pays for MCP instructions and seven serialized definitions, so they carry only route selection, the fail-closed boundary, and the minimum guest syntax; selection detail, examples, runtime differences, and repair live in the existing byte-identical `usage` skill, fetched at most once per task — no new skill surface or deployment option ([#418](https://github.com/zackbart/connecta/issues/418)) |
90
- | Surface consolidation to seven tools | accepted | `list_connectors`, `describe_tools`, and `batch_call` fold into the program surface, deleting the routing choice between direct calls, batches, discovery, and execution; `call_tool` stays because a simple call is not cheaper through code ([#224](https://github.com/zackbart/connecta/issues/224)) |
91
- | Classic (executor-free) surface | removed | supersedes its provisional retention under [#224](https://github.com/zackbart/connecta/issues/224) — an executor is mandatory, and a deployment without one refuses to boot rather than serving a fallback shape ([#273](https://github.com/zackbart/connecta/issues/273)) |
92
- | Connector shortcut namespaces in programs | accepted | sugar over canonical addressing, kept but frozen — every expansion invents a collision class `<connectorId>.<toolName>` already solved ([#223](https://github.com/zackbart/connecta/issues/223)) |
93
- | Automatic host-side projection of program results | refused | the measured win was program-authored projection; a host heuristic drops fields a program chose to return and is invisible in the transcript ([#223](https://github.com/zackbart/connecta/issues/223)) |
94
- | Caller-visible execution diagnostics | accepted | optional request-local timing and size aggregates make catalog, connector, and executor costs distinguishable without persisting payloads, adding a tool, or charging normal responses context ([#247](https://github.com/zackbart/connecta/issues/247)) |
95
- | `get_result` paging for program results | refused | paging rewards the unprojected return code mode exists to remove; a program can shrink anything ([#223](https://github.com/zackbart/connecta/issues/223)) |
96
- | Stabilized workflows (programs → versioned scripts/skills) | gated | earns a surface only once real traffic shows programs that actually recur ([#225](https://github.com/zackbart/connecta/issues/225)) |
97
- | Semantic tool search | gated | keyword search has not been shown to be the thing failing; earns its way in through [#222](https://github.com/zackbart/connecta/issues/222)'s harness ([#27](https://github.com/zackbart/connecta/issues/27)) |
98
- | Per-result lexical query coverage | removed | verbose, indexed, and trailing shapes did not earn their response-token cost: the coverage-off arm beat the verbose wire, the first compact wire regressed efficiency, and the trailing wire failed its precommitted 30-run clean-route gate (13/30 vs 9/30, +13.3 pp, Fisher p=0.422); preserve the mixed complete/partial ranking from [#326](https://github.com/zackbart/connecta/issues/326), but do not revive serialized coverage without new causal evidence ([#322](https://github.com/zackbart/connecta/issues/322), [#323](https://github.com/zackbart/connecta/issues/323)) |
99
- | MRTR / `input_required` passthrough | gated | statelessly relayable via `requestState`, but no host or downstream emits it yet; fails loudly until adoption evidence ([#176](https://github.com/zackbart/connecta/issues/176)) |
100
- | Native Tasks for oversized results | refused | tasks solve duration, `get_result` solves size; paging on a polling extension adds round trips for nothing ([#176](https://github.com/zackbart/connecta/issues/176)) |
101
- | Downstream `ttlMs` cache hints | gated | fixed TTL + fingerprint is battle-tested and catalog reads are ~3 ms; earns its way in with refresh-churn evidence ([#176](https://github.com/zackbart/connecta/issues/176)) |
102
- | Inbound-demand catalog stale-while-revalidate | accepted | an agent-facing catalog read may return a complete, fingerprint-verified entry inside its configured stale window and move the refresh that same read demanded onto the runtime's existing deferred-work channel; this originates no timer, schedule, warmup, or credential probe, and operator status remains blocking — one refresh per connector is shared across agent and operator requests, a deferred owner uses a fresh bounded signal and connector scope and closes that scope, and invalidation is rechecked before stale publication, so no request-bound capability survives and no partial or pre-invalidation catalog gains authority ([#396](https://github.com/zackbart/connecta/issues/396)) |
103
- | Rich program output (`connecta.emit`) | accepted | one host-collected emission channel: programs emit strictly validated text/image/audio blocks, delivered after the result envelope on success only; budgets fail loudly at the emit call ([design record](./documentation/rich-output-design.md), [#267](https://github.com/zackbart/connecta/issues/267)) |
104
- | Result-channel widening of the `Executor` contract | refused | `ExecuteResult` stays `{ result, error?, logs? }` — structural compatibility with `@cloudflare/codemode` is the parity guarantee; emission rides the provider bridge instead ([#267](https://github.com/zackbart/connecta/issues/267)) |
105
- | Erasable TypeScript in `execute_code` | refused | a location-preserving prototype accepted annotations, return types, assertions, aliases, interfaces, and erased generics at ~8.3 µs median transform cost, but `ts-blank-space` drags a 23.68 MB installed TypeScript dependency into the fetch-native core and no runnable agent arm established a first-run or repair benefit; the plain-JavaScript contract stands until new measured model evidence earns that package and parity cost ([evidence](https://github.com/zackbart/connecta/blob/main/eval/current-version/results/issue-419-evidence.md), [#419](https://github.com/zackbart/connecta/issues/419)) |
106
- | Guest-emitted `resource` / `resource_link` blocks | refused | a program can never mint a URI a client may dereference, and the carve-out this row waited on does not need one: `connecta.ui` takes HTML content, and the only `ui://` URI is connecta's build-time shell ([design record](./documentation/mcp-ui-design.md), [#266](https://github.com/zackbart/connecta/issues/266), [#267](https://github.com/zackbart/connecta/issues/267)) |
107
- | Provenance tracking for emitted content | refused | everything a program emits is program output; handles or attribution labels are capability-shaped machinery that changes no client's trust posture ([#267](https://github.com/zackbart/connecta/issues/267)) |
108
- | Program-generated UI (`connecta.ui` + the Apps shell) | accepted | one MCP Apps view per successful run: the program supplies HTML only, delivered in result `_meta`, which hosts keep out of model context, and rendered by connecta's static shell inside the host's sandboxed frame ([design record](./documentation/mcp-ui-design.md), [#266](https://github.com/zackbart/connecta/issues/266)) |
109
- | Serving connecta's own UI template via `resources/read` | accepted | a narrow carve-out from the resources-aggregation refusal, not a reversal of it: one static build-time shell at one URI, an empty `resources/list`, nothing downstream ever listed or aggregated ([#266](https://github.com/zackbart/connecta/issues/266)) |
110
- | Downstream MCP Apps template passthrough | gated | proxying downstream `resources/read` earns its way in when a downstream connector actually ships an Apps template ([#266](https://github.com/zackbart/connecta/issues/266)) |
111
- | View-initiated read calls from program UI | accepted | named bindings materially improve refresh, cursor pagination, and drill-down without persistence or a new tool; the trusted shell delegates only to the existing fail-closed `call_tool`, and the one-string UI remains display-only ([evidence](./documentation/program-ui-read-calls.md), [#287](https://github.com/zackbart/connecta/issues/287), [#289](https://github.com/zackbart/connecta/issues/289)) |
112
- | View-initiated mutation calls from program UI | gated | live-read utility says nothing about write consent: a click is not approval, stale/replayed effects need a host-tested story, and the ordinary destructive path keeps the action in the transcript ([#287](https://github.com/zackbart/connecta/issues/287)) |
113
- | Result sampling on the catalog surface (`sample` / `dryRun`) | refused | sampling is execution and cannot ride a catalog read; most tools carry required arguments no sampler can invent, and undeclared `outputSchema` (measured 0/30 and 3/30 on real deployments) is a real gap that is not a sampleable one — a program that checks the shape before rendering already hands back the first record inside the run it was going to make anyway, at zero new surface ([#282](https://github.com/zackbart/connecta/issues/282)) |
114
- | Passive observed output schemas | accepted | the sampling refusal stands: discovery originates no call and invents no arguments; instead, a successful explicitly read-only call whose provider declared no `outputSchema` records field names and broad JSON types only, under strict depth, breadth, property-name, node, and byte bounds, then merges that open optional-field shape in a 256-entry process-local cache for 24 hours; property names may be user-authored, search and describe label the shape `outputSchemaSource: "observed"`, a materially changed tool definition cannot inherit it, a provider declaration always wins, and no argument, scalar value, raw result, code, credential, or error is retained; this is new evidence rather than a rewrite of #282's facts: Blacksmith measured a value-free warm shape cache cutting one Linear code-mode task from 116.6 s / $1.91 to 56.6 s / $1.06, while live Connecta catalogs measured 246/378 missing on BePresent and 0/90 missing on OneMany ([study](https://www.blacksmith.sh/blog/code-smith-code-mode), [#442](https://github.com/zackbart/connecta/issues/442)) |
115
- | Legacy embedded `UIResource` delivery | refused | superseded upstream and rendered by none of the clients connecta faces; per-request minted URIs also fight the caching the Apps spec assumes ([#266](https://github.com/zackbart/connecta/issues/266)) |
74
+ | Classic (executor-free) surface | removed | an executor is mandatory ([#273](https://github.com/zackbart/connecta/issues/273)) |
75
+ | Per-result lexical query coverage | removed | did not earn its response bytes in a precommitted gate ([#323](https://github.com/zackbart/connecta/issues/323)) |
76
+ | Stabilized workflows | gated | needs programs that actually recur ([#225](https://github.com/zackbart/connecta/issues/225)) |
77
+ | Semantic tool search | gated | keyword search has not been shown to fail ([#27](https://github.com/zackbart/connecta/issues/27)) |
78
+ | MRTR / `input_required` passthrough | gated | relayable statelessly; no host or downstream emits it yet ([#176](https://github.com/zackbart/connecta/issues/176)) |
79
+ | Downstream `ttlMs` cache hints | gated | needs refresh-churn evidence ([#206](https://github.com/zackbart/connecta/issues/206)) |
80
+ | Downstream MCP Apps template passthrough | gated | needs a downstream that ships one ([#266](https://github.com/zackbart/connecta/issues/266)) |
81
+ | View-initiated mutation calls from program UI | gated | a click is not approval ([#287](https://github.com/zackbart/connecta/issues/287)) |
82
+
116
83
  ## Invariants
117
84
 
118
- One line each; the enforcing tests live beside the subsystem documentation. Breaking one is not a bug fix — it is a design change wearing a disguise.
85
+ One line each; the enforcing tests live beside the subsystem documentation.
86
+ Breaking one is a design change wearing a disguise.
119
87
 
120
- - **Fail-closed read-only.** A missing, false, or contradictory annotation
121
- never gets the benefit of the doubt.
122
- - **Generated code cannot mint capabilities.** Admission, credentials, and
123
- read-only classification are enforced below the sandbox; nothing a program
124
- does widens what it can reach.
125
- - **Only explicitly read-only work runs inside the sandbox.** Unannotated,
126
- write-capable, and destructive tools cross `call_destructive_tool`, where the
127
- host can ask a human.
128
- - **Nothing request-bound survives a request.** No transport, stream, abort
129
- state, or later-awaited promise outlives the request that made it.
130
- - **A downstream catalog is complete or it is a failure.** A partial catalog
131
- is never cached, persisted, or served as if it were small.
132
- - **Activity is payload-free by construction.** The event type has nowhere to
133
- put arguments, results, code, or raw error text.
134
- - **An observed shape is never a declaration.** It contains field names and broad JSON types only, remains open and optional, is labeled on discovery, and disappears behind any provider-declared output schema.
135
- - **Credentials never leave the host.** Encrypted at rest, readable only by
136
- the owning connector, never rendered by any surface.
137
- - **Import-graph purity.** Nothing reachable from the root entry imports a
138
- `node:` builtin.
139
- - **The published surface is a boundary.** Heavyweight or platform-bound code
140
- goes behind an optional-peer subpath, never into core.
141
- - **Operator routes manage authentication material, never declared
142
- capability.** Authenticating a declared capability is allowed; the connector
143
- set, declared catalog and annotations, OAuth scopes, admission, authorization
144
- rules, and caller tool scope take a config edit. A downstream catalog is
145
- discovered, not declared — remote MCP tools appear when its credential does.
146
- - **Structural mistakes throw at construction.** A deployment that boots into
147
- the wrong shape is worse than one that refuses to boot.
88
+ - **Fail-closed read-only.** A missing, false, or contradictory annotation never gets the benefit of the doubt.
89
+ - **Generated code cannot mint capabilities.** Admission, credentials, and classification are enforced below the sandbox.
90
+ - **Only explicitly read-only work runs inside the sandbox.** Everything else crosses `call_destructive_tool`.
91
+ - **Nothing request-bound survives a request.** No transport, stream, signal, or awaited promise outlives it.
92
+ - **A downstream catalog is complete or it is a failure.** A partial catalog is never cached, persisted, or served.
93
+ - **Activity is payload-free by construction.** The event type has nowhere to put arguments, results, code, or raw errors.
94
+ - **An observed shape is never a declaration.** Names and broad types only, labeled, and gone behind any declared schema.
95
+ - **Credentials never leave the host.** Encrypted at rest, readable only by the owning connector, rendered by nothing.
96
+ - **Import-graph purity.** Nothing reachable from the root entry imports a `node:` builtin.
97
+ - **The published surface is a boundary.** Heavyweight or platform-bound code goes behind an optional-peer subpath.
98
+ - **Operator routes manage authentication material, never declared capability.** A downstream catalog is discovered, not declared.
99
+ - **Structural mistakes throw at construction.** Booting into the wrong shape is worse than not booting.
148
100
 
149
- Connecta began as a radical simplification of [executor](https://github.com/UsefulSoftwareCo/executor); the table above is the record of that simplification holding.
101
+ Connecta began as a radical simplification of
102
+ [executor](https://github.com/UsefulSoftwareCo/executor); this file is the
103
+ record of that simplification holding.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zackbart/connecta",
3
- "version": "0.18.3",
3
+ "version": "0.19.0",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "description": "One MCP to rule them all — a single MCP endpoint aggregating many downstream connectors behind a code-first surface of seven meta-tools.",
@@ -105,12 +105,11 @@
105
105
  "check:examples": "tsc -p tsconfig.template.node.json && tsc -p tsconfig.examples.worker.json",
106
106
  "check:security": "npm audit --omit=dev --audit-level=moderate",
107
107
  "check:package": "node scripts/check-package.mjs",
108
- "load:admission": "npm run build && node scripts/admission-load.mjs",
108
+ "load:admission": "npm run build && node eval/admission-load.mjs",
109
109
  "drift:check": "tsx scripts/drift-check.mjs",
110
110
  "check": "npm run check:docs && npm run check:operator-ui && npm run check:lint && npm run check:unused && npm run typecheck && npm run test && npm run build && npm run check:examples",
111
111
  "release:check": "npm run check && npm run check:security && npm run check:package",
112
- "prepack": "npm run check",
113
- "prepublishOnly": "npm run check:security"
112
+ "prepack": "npm run check"
114
113
  },
115
114
  "dependencies": {
116
115
  "@cfworker/json-schema": "^4.1.1",
@@ -15,7 +15,7 @@
15
15
  "typecheck": "tsc --noEmit"
16
16
  },
17
17
  "dependencies": {
18
- "@zackbart/connecta": "0.18.3",
18
+ "@zackbart/connecta": "0.19.0",
19
19
  "quickjs-emscripten": "0.32.0"
20
20
  },
21
21
  "devDependencies": {