@zackbart/connecta 0.31.0 → 0.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +97 -0
- package/README.md +30 -20
- package/bin/connecta.mjs +25 -6
- package/bin/version.mjs +1 -1
- package/dist/access-tokens.d.ts +167 -23
- package/dist/access-tokens.js +676 -140
- package/dist/agent-identity.js +47 -0
- package/dist/auth/cloudflare-access.js +13 -5
- package/dist/auth-elicitation.js +1 -1
- package/dist/call-admission-context.js +15 -0
- package/dist/call-admission.js +30 -43
- package/dist/call-recovery.js +6 -2
- package/dist/catalog-service.js +7 -2
- package/dist/config-value-sources.js +14 -9
- package/dist/config.d.ts +58 -78
- package/dist/config.js +143 -47
- package/dist/connector-access.d.ts +4 -33
- package/dist/connector-access.js +15 -99
- package/dist/connector-caller.d.ts +7 -1
- package/dist/connector-caller.js +3 -2
- package/dist/connectors/api-connector.d.ts +27 -4
- package/dist/connectors/api-connector.js +2 -0
- package/dist/connectors/guarded-fetch.d.ts +9 -0
- package/dist/connectors/guarded-fetch.js +7 -0
- package/dist/connectors/remote-mcp.js +2 -0
- package/dist/describe-config.d.ts +32 -7
- package/dist/describe-config.js +9 -18
- package/dist/errors.d.ts +1 -1
- package/dist/errors.js +1 -0
- package/dist/execute.js +16 -14
- package/dist/index.d.ts +4 -3
- package/dist/index.js +30 -10
- package/dist/invocation.js +12 -7
- package/dist/membership.d.ts +51 -0
- package/dist/membership.js +121 -0
- package/dist/meta-tools.js +17 -19
- package/dist/module-contracts.d.ts +23 -6
- package/dist/operator-record.d.ts +2 -2
- package/dist/operator-record.js +2 -2
- package/dist/operator-ui/agents.d.ts +74 -0
- package/dist/operator-ui/agents.js +104 -0
- package/dist/operator-ui/contract.d.ts +151 -29
- package/dist/operator-ui/endpoints.js +192 -0
- package/dist/operator-ui/fix-prompts.js +4 -4
- package/dist/operator-ui/generated.js +5 -4
- package/dist/operator-ui/member-page.js +112 -0
- package/dist/operator-ui/model.d.ts +15 -7
- package/dist/operator-ui/view.d.ts +84 -19
- package/dist/operator-ui/view.js +83 -21
- package/dist/page-styles.js +1 -1
- package/dist/program-writes.js +2 -2
- package/dist/provider.d.ts +63 -11
- package/dist/provider.js +46 -7
- package/dist/providers/_shared/google/workspace.d.ts +53 -16
- package/dist/providers/_shared/google/workspace.js +31 -9
- package/dist/providers/_shared/rest/tools.js +2 -2
- package/dist/providers/_shared/rest/value-safety.d.ts +50 -0
- package/dist/providers/_shared/rest/value-safety.js +699 -7
- package/dist/providers/breeze/skill.generated.js +2 -2
- package/dist/providers/ccb/index.js +1 -1
- package/dist/providers/cloudflare/index.js +3 -3
- package/dist/providers/cloudflare/rest.js +25 -3
- package/dist/providers/cloudflare/skill.generated.js +2 -2
- package/dist/providers/cloudflare/value-safety.js +32 -0
- package/dist/providers/docs/index.d.ts +1 -1
- package/dist/providers/docs/index.js +5 -5
- package/dist/providers/docs/skill.generated.js +2 -2
- package/dist/providers/drive/index.d.ts +1 -1
- package/dist/providers/drive/index.js +4 -4
- package/dist/providers/drive/skill.generated.js +2 -2
- package/dist/providers/forms/index.d.ts +1 -1
- package/dist/providers/forms/index.js +5 -5
- package/dist/providers/forms/skill.generated.js +2 -2
- package/dist/providers/github/skill.generated.js +2 -2
- package/dist/providers/gmail/index.d.ts +1 -1
- package/dist/providers/gmail/index.js +279 -26
- package/dist/providers/gmail/skill.generated.js +2 -2
- package/dist/providers/linear/index.js +1 -1
- package/dist/providers/mixpanel/index.d.ts +27 -12
- package/dist/providers/mixpanel/index.js +58 -6
- package/dist/providers/mixpanel/operations.js +20 -0
- package/dist/providers/mixpanel/rest.js +603 -0
- package/dist/providers/mixpanel/skill.generated.js +3 -2
- package/dist/providers/mixpanel/value-safety.js +16 -0
- package/dist/providers/notion/index.d.ts +7 -0
- package/dist/providers/notion/index.js +116 -11
- package/dist/providers/notion/rest.js +183 -24
- package/dist/providers/notion/skill.generated.js +4 -4
- package/dist/providers/notion/value-safety.js +30 -5
- package/dist/providers/overflow/index.js +1 -1
- package/dist/providers/planning-center/index.d.ts +27 -0
- package/dist/providers/planning-center/index.js +287 -25
- package/dist/providers/planning-center/skill.generated.js +24 -4
- package/dist/providers/sheets/index.d.ts +4 -1
- package/dist/providers/sheets/index.js +9 -6
- package/dist/providers/sheets/skill.generated.js +2 -2
- package/dist/providers/slides/index.d.ts +1 -1
- package/dist/providers/slides/index.js +6 -6
- package/dist/providers/slides/skill.generated.js +2 -2
- package/dist/providers/stripe/rest.js +9 -2
- package/dist/providers/stripe/skill.generated.js +2 -2
- package/dist/providers/stripe/value-safety.js +22 -0
- package/dist/providers/vercel/index.js +2 -2
- package/dist/providers/vercel/rest.js +20 -2
- package/dist/providers/vercel/skill.generated.js +2 -2
- package/dist/providers/vercel/value-safety.js +22 -0
- package/dist/providers/wispr-flow/index.d.ts +14 -0
- package/dist/providers/wispr-flow/index.js +117 -0
- package/dist/providers/wispr-flow/skill.generated.js +8 -0
- package/dist/registry.d.ts +2 -3
- package/dist/registry.js +8 -9
- package/dist/routes/access-tokens.js +82 -75
- package/dist/routes/activity-disclosure.js +17 -18
- package/dist/routes/activity.js +34 -54
- package/dist/routes/actor-labels.js +33 -4
- package/dist/routes/agent-path.js +43 -0
- package/dist/routes/connect.js +16 -12
- package/dist/routes/credentials.js +16 -40
- package/dist/routes/mcp.js +155 -85
- package/dist/routes/oauth-management.js +11 -5
- package/dist/routes/oauth.js +3 -9
- package/dist/routes/operator.js +25 -17
- package/dist/routes/shared.d.ts +60 -20
- package/dist/routes/shared.js +187 -96
- package/dist/routes/ui-config.js +437 -97
- package/dist/routes/ui-data.js +2 -2
- package/dist/routes/ui.js +9 -16
- package/dist/runtime/call-admission.js +9 -0
- package/dist/server.js +8 -0
- package/dist/skills.js +5 -4
- package/dist/storage/keys.js +9 -1
- package/dist/tool-safety.js +13 -5
- package/dist/types.d.ts +12 -1
- package/dist/ui.d.ts +2 -2
- package/dist/ui.js +17 -15
- package/dist/usage-guide.js +3 -3
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/workspace-address.js +9 -0
- package/dist/workspace-subject.js +23 -0
- package/documentation/README.md +46 -22
- package/documentation/architecture.md +378 -58
- package/documentation/auth.md +806 -215
- package/documentation/code-mode.md +93 -81
- package/documentation/deploying.md +128 -26
- package/documentation/integrating.md +145 -22
- package/documentation/meta-tools.md +58 -46
- package/documentation/migration-0.33.md +344 -0
- package/documentation/operating.md +14 -9
- package/documentation/operator-tests.md +117 -31
- package/documentation/operator-ui.md +326 -55
- package/documentation/provider-auth-migration.md +42 -27
- package/documentation/provider-migration-0.29.md +3 -3
- package/examples/worker/AGENTS.md +35 -8
- package/examples/worker/README.md +92 -53
- package/examples/worker/src/connecta.config.ts +41 -20
- package/examples/worker/wrangler.jsonc +3 -0
- package/package.json +7 -2
- package/templates/node/.env.example +3 -0
- package/templates/node/AGENTS.md +33 -10
- package/templates/node/Dockerfile +2 -2
- package/templates/node/README.md +71 -44
- package/templates/node/docker-compose.yml +3 -2
- package/templates/node/package.json +4 -3
- package/templates/node/src/adopt-token.ts +23 -0
- package/templates/node/src/connecta.config.ts +33 -12
- package/templates/node/src/rotate-token.ts +17 -0
- package/dist/tool-safety.d.ts +0 -9
- package/templates/node/src/provision-token.ts +0 -17
|
@@ -48,7 +48,7 @@ QuickJS subpath:
|
|
|
48
48
|
import { createConnecta } from "@zackbart/connecta";
|
|
49
49
|
import { quickJsExecutor } from "@zackbart/connecta/quickjs";
|
|
50
50
|
|
|
51
|
-
createConnecta({ executor: quickJsExecutor() /* connectors, auth, storage… */ });
|
|
51
|
+
createConnecta({ executor: quickJsExecutor(), readOnly: false /* connectors, auth, storage… */ });
|
|
52
52
|
```
|
|
53
53
|
|
|
54
54
|
`quickJsExecutor()` runs each program in a disposable child process, with CPU,
|
|
@@ -61,7 +61,7 @@ On Workers the Worker Loader is the sandbox; Dynamic Workers require the Paid pl
|
|
|
61
61
|
```ts
|
|
62
62
|
import { workerExecutor } from "@zackbart/connecta/worker";
|
|
63
63
|
|
|
64
|
-
createConnecta({ executor: workerExecutor({ loader: env.LOADER }) });
|
|
64
|
+
createConnecta({ executor: workerExecutor({ loader: env.LOADER }), readOnly: false /* … */ });
|
|
65
65
|
```
|
|
66
66
|
|
|
67
67
|
The adapter uses only `loader` and an optional `timeout`. Its admission defaults
|
|
@@ -80,7 +80,7 @@ and cleanup at budget exhaustion, cancellation, and deadlines; the wrapper only
|
|
|
80
80
|
|
|
81
81
|
## What an executor must implement
|
|
82
82
|
|
|
83
|
-
The Promise provider/result seam
|
|
83
|
+
The Promise provider/result seam is declared in the installed `dist/types.d.ts`. Custom implementations
|
|
84
84
|
also need the lifecycle wrapper above; structural compatibility alone is insufficient.
|
|
85
85
|
|
|
86
86
|
```ts
|
|
@@ -283,7 +283,10 @@ signature is byte-identical to the one `search_tools` returns.
|
|
|
283
283
|
integration is ambiguous. `safety: "readOnly"` selects stored read verdicts;
|
|
284
284
|
`"approvalRequired"` selects stored write verdicts; omitted or `"all"` selects
|
|
285
285
|
both. Search and describe rows carry `classification`. These filters grant no
|
|
286
|
-
authority and change no
|
|
286
|
+
authority and change no call admission decision. On a read-only endpoint,
|
|
287
|
+
search and describe omit write tools (`W12`): a write is absent from every
|
|
288
|
+
filter, and describing one is `unknown_tool`. `connecta.skill` guides are not
|
|
289
|
+
filtered and may name such a write; calling it is still refused.
|
|
287
290
|
|
|
288
291
|
**S2.** A requested object schema carries `inputKeys`, `requiredInputKeys`
|
|
289
292
|
(declared properties only), and `outputKeys`: the names the rendered schema
|
|
@@ -394,10 +397,10 @@ and a 32 KiB bridge ceiling. `page` is zero-based and mutually exclusive with
|
|
|
394
397
|
are at least four bytes wide and align both edges to UTF-8 boundaries.
|
|
395
398
|
Follow `nextOffset`, reassemble inside the program, and return a reduced value.
|
|
396
399
|
Before returning a page, the host rechecks current authentication, connector/tool
|
|
397
|
-
grants, pool membership, and endpoint
|
|
398
|
-
tool classification. A read-only endpoint cannot page a
|
|
399
|
-
|
|
400
|
-
|
|
400
|
+
grants, pool membership, and whether the endpoint is read-only against both the
|
|
401
|
+
original and current tool classification. A read-only endpoint cannot page a
|
|
402
|
+
write result; it never runs a write, so any write result it is asked for came
|
|
403
|
+
from a writable endpoint. Binding
|
|
401
404
|
mismatches, revoked access, and old entries without bindings are `not_found`, as
|
|
402
405
|
are unknown or expired ids; a storage failure is `unavailable`. IDs are random UUIDs.
|
|
403
406
|
The `get_result` meta-tool is removed.
|
|
@@ -477,10 +480,10 @@ Connecta passes an admitted decoded URI as an opaque MCP `resources/read`
|
|
|
477
480
|
argument to the configured endpoint. It never fetches that
|
|
478
481
|
URI or creates a connector from it.
|
|
479
482
|
|
|
480
|
-
Resources are protocol reads
|
|
481
|
-
requires
|
|
482
|
-
|
|
483
|
-
resources. An absent, hidden, tool-restricted or resource-incapable connector
|
|
483
|
+
Resources are protocol reads on read-only and writable endpoints alike. A read
|
|
484
|
+
requires the whole connector on the endpoint: plain `/mcp`, or a pool whose
|
|
485
|
+
`tools` list the connector id. A pool listing only exact `connector.tool`
|
|
486
|
+
addresses authorizes no resources. An absent, hidden, tool-restricted or resource-incapable connector
|
|
484
487
|
fails with `unknown_address`. The URI and extra arguments cannot select a
|
|
485
488
|
different credential owner or downstream subject. Personal credentials come
|
|
486
489
|
from the admitted principal, just as they do for tool calls.
|
|
@@ -553,27 +556,27 @@ URL-elicitation hosts retain their existing flow.
|
|
|
553
556
|
may do. A provider maps each downstream failure to the code that tells the
|
|
554
557
|
caller what to do next, and never invents a cause it was not told.
|
|
555
558
|
|
|
556
|
-
| Code
|
|
557
|
-
|
|
|
558
|
-
| `unknown_address`
|
|
559
|
-
| `unknown_tool`
|
|
560
|
-
| `
|
|
561
|
-
| `auth_required`
|
|
562
|
-
| `invalid_args`
|
|
563
|
-
| `not_found`
|
|
564
|
-
| `conflict`
|
|
565
|
-
| `input_required_unsupported`
|
|
566
|
-
| `rate_limited`
|
|
567
|
-
| `unavailable`
|
|
568
|
-
| `timeout`
|
|
569
|
-
| `program_error`
|
|
570
|
-
| `cancelled`
|
|
571
|
-
| `connector_call_failed`
|
|
572
|
-
| `catalog_lookup_failed`
|
|
573
|
-
| `result_processing_failed`
|
|
574
|
-
| `result_too_large`
|
|
575
|
-
| `budget_exceeded`
|
|
576
|
-
| `write_outcome_unknown`
|
|
559
|
+
| Code | Raised when | `retryable` |
|
|
560
|
+
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
|
|
561
|
+
| `unknown_address` | no visible connector owns the tool address or grants the resource reader | false |
|
|
562
|
+
| `unknown_tool` | the connector has no such tool | false |
|
|
563
|
+
| `read_only_endpoint` | a program on a read-only endpoint attempted a write (`E4`) | false |
|
|
564
|
+
| `auth_required` | the credential is missing, expired, or rejected | false |
|
|
565
|
+
| `invalid_args` | arguments or discovery bounds were rejected | false |
|
|
566
|
+
| `not_found` | the downstream answered and the resource is not there — the one code that says skip this id rather than stop, raised only where the provider tells absence from a permission gap | false |
|
|
567
|
+
| `conflict` | the write named a base version someone else already moved past; nothing changed. `details.current` says where things stand (at most 20 whole-number entries) — re-read, reapply, retry with that base | false |
|
|
568
|
+
| `input_required_unsupported` | a downstream asked for input; use `nextAction` for the equivalent direct call | false |
|
|
569
|
+
| `rate_limited` | the downstream reported a rate limit | true |
|
|
570
|
+
| `unavailable` | the downstream is down or unreachable; optional sanitized `details.host` and `details.code` describe the transport failure without paths, queries, credentials, or provider prose | true |
|
|
571
|
+
| `timeout` | a call or sandbox deadline expired; details name operation, stage, elapsedMs, and deadlineMs | per operation |
|
|
572
|
+
| `program_error` | guest JavaScript failed; `details.name`, `line`, and a fixed repair hint describe it | false |
|
|
573
|
+
| `cancelled` | the run ended while this call was in flight (`E5`) | false |
|
|
574
|
+
| `connector_call_failed` | anything else the connector threw | per message |
|
|
575
|
+
| `catalog_lookup_failed` | the connector's catalog could not be loaded | per cause |
|
|
576
|
+
| `result_processing_failed` | the result could not be prepared | per message |
|
|
577
|
+
| `result_too_large` | a discovery response exceeded its byte bound | false |
|
|
578
|
+
| `budget_exceeded` | the run exhausted a host-call, write, or emitted-output budget | false |
|
|
579
|
+
| `write_outcome_unknown` | a program write was sent and no answer came back; it is never sent again (`W9`) | false |
|
|
577
580
|
|
|
578
581
|
**E3.** `auth_required` carries the same recovery envelope as `call_tool`:
|
|
579
582
|
`connector`, `operation`, `recovery` (`oauth`, `operator_config`, or
|
|
@@ -581,16 +584,13 @@ caller what to do next, and never invents a cause it was not told.
|
|
|
581
584
|
sentence. A program cannot recover credentials — only an operator can — so stop
|
|
582
585
|
and let the failure reach the model.
|
|
583
586
|
|
|
584
|
-
**E4.** A tool classified as a write never runs
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
call is the approval, and the only one: generated code can neither mint the
|
|
592
|
-
capability nor approve its own write, and the model's short `reason` grants no
|
|
593
|
-
authority and never goes downstream.
|
|
587
|
+
**E4.** A tool classified as a write never runs on a read-only endpoint
|
|
588
|
+
(`W12`). A program's call is refused with `read_only_endpoint` before
|
|
589
|
+
validation and before anything is sent. The refusal carries no `nextAction` and
|
|
590
|
+
echoes no arguments: no route on that endpoint writes, so the program reports
|
|
591
|
+
it rather than retrying. Generated code can neither mint the capability nor
|
|
592
|
+
change the endpoint; on a writable endpoint, approval of the program as a write
|
|
593
|
+
belongs to the client.
|
|
594
594
|
|
|
595
595
|
**E5.** Failures of the _execution_, not of a call, never appear inside the
|
|
596
596
|
guest: admission rejection (`executor_overloaded`, retryable, with
|
|
@@ -631,7 +631,7 @@ Program diagnostic fields are bounded before transport, including escaped text;
|
|
|
631
631
|
a large custom error name cannot turn a failure into a truncated success.
|
|
632
632
|
|
|
633
633
|
**E7.** `retryable` for `unknown_address`, `unknown_tool`, and
|
|
634
|
-
`
|
|
634
|
+
`read_only_endpoint` is pinned false, never inferred from an
|
|
635
635
|
address containing `503`, `429`, or `temporar`. The first two carry
|
|
636
636
|
`nextAction: { function: "connecta.search", arguments: { query, connector?, includeSchemas: "compact" } }`
|
|
637
637
|
— scoped discovery keyed to the surface the caller has, since a program cannot
|
|
@@ -686,7 +686,7 @@ Caught call failures retain that connector visibility when catalog loading or
|
|
|
686
686
|
tool resolution fails. Recovery messages listing configured connectors or
|
|
687
687
|
local guides retain visibility of those contributors too.
|
|
688
688
|
Each page rechecks current auth,
|
|
689
|
-
grants, pool membership, and
|
|
689
|
+
grants, pool membership, and the endpoint's `readOnly`. Reading a stash inside a program carries
|
|
690
690
|
its dependencies forward to any new return stash. The page cap is the smallest
|
|
691
691
|
of the deployment cap and contributing connectors' effective `maxResultBytes`.
|
|
692
692
|
Read-only endpoints cannot page write results. A UUID is a handle, never a grant.
|
|
@@ -737,9 +737,6 @@ and nonzero pad bits are rejected before collection. Size budgets still apply.
|
|
|
737
737
|
MCP-native output a return value cannot carry: base64 is not projectable, so a
|
|
738
738
|
block that fits the inline call limit (`S5`, `L6`) can use the separate
|
|
739
739
|
emission transport budget instead of the `R2` return guard.
|
|
740
|
-
The earlier alternatives are in [decision history](https://github.com/zackbart/connecta/blob/main/decisions/0001-ethos-verdict-table.md)
|
|
741
|
-
([#267](https://github.com/zackbart/connecta/issues/267),
|
|
742
|
-
[#270](https://github.com/zackbart/connecta/issues/270)).
|
|
743
740
|
|
|
744
741
|
**M1.** `connecta.emit(result)` accepts a rich result from this program's
|
|
745
742
|
`connecta.call` and forwards its original native content blocks, including
|
|
@@ -861,7 +858,7 @@ Programs and direct calls use the same invocation deadline and stages. A call's
|
|
|
861
858
|
`timeoutMs` wins, then `calls.defaultTimeoutMs`, then `execute.hostCallTimeoutMs`
|
|
862
859
|
(default 15,000). A guest may request a longer individual call, but the sandbox
|
|
863
860
|
and request ceilings still bound the whole run. Timeout details are agent-facing;
|
|
864
|
-
|
|
861
|
+
operator records retain only checked classifications and numeric facts.
|
|
865
862
|
A dispatched write timeout becomes `write_outcome_unknown` and retains its
|
|
866
863
|
deadline details even when the program catches the failure. The final program
|
|
867
864
|
error includes the first timeout in `details`; multiple write timeouts also
|
|
@@ -882,17 +879,17 @@ deadline past the ceiling means raising the ceiling too.
|
|
|
882
879
|
**L4.** Per-execution bounds that are contract, identical in both executors
|
|
883
880
|
because connecta enforces them above the sandbox:
|
|
884
881
|
|
|
885
|
-
| Bound
|
|
886
|
-
|
|
|
887
|
-
| Host calls per execution, shared by `search`, `describe`, `call`, and `read`
|
|
888
|
-
|
|
|
889
|
-
| Deadline per host call
|
|
890
|
-
| Discovery page
|
|
891
|
-
| `describe` addresses
|
|
892
|
-
| `describe` nearby suggestions
|
|
893
|
-
| Caller text echoed by `describe` recovery
|
|
894
|
-
| Result
|
|
895
|
-
| Logs presented to the model
|
|
882
|
+
| Bound | Value |
|
|
883
|
+
| --------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
|
|
884
|
+
| Host calls per execution, shared by `search`, `describe`, `call`, and `read` | 20 by default, `execute.maxHostCalls` |
|
|
885
|
+
| Writes per run on a writable endpoint, on top of the host calls they also spend (`W10`) | 10 by default, `execute.maxWrites` |
|
|
886
|
+
| Deadline per host call | 15 s, `execute.hostCallTimeoutMs`; one deadline covers catalog resolution, admission, and the connector call |
|
|
887
|
+
| Discovery page | ≤ 100 tools, ≤ 256,000 serialized bytes |
|
|
888
|
+
| `describe` addresses | ≤ 100 |
|
|
889
|
+
| `describe` nearby suggestions | ≤ 3 canonical addresses per failed entry |
|
|
890
|
+
| Caller text echoed by `describe` recovery | ≤ 512 UTF-8 bytes per field, plus `…` |
|
|
891
|
+
| Result | 24,000 serialized characters |
|
|
892
|
+
| Logs presented to the model | 4,000 characters |
|
|
896
893
|
|
|
897
894
|
Every `call`, `read`, `search`, and `describe` spends one host call on entry, before
|
|
898
895
|
resolution, validation, or dispatch. Catching a local refusal refunds nothing.
|
|
@@ -901,7 +898,7 @@ The first call beyond the budget ends the host run with one non-retryable
|
|
|
901
898
|
`try/catch` cannot swallow it. Later host access, including `emit`, stops; pending
|
|
902
899
|
replies are withheld. The refusal reaches no connector, returns no partial result,
|
|
903
900
|
and discards accepted emits (`M4`). Calls still resolving or awaiting admission
|
|
904
|
-
are cancelled, including
|
|
901
|
+
are cancelled, including writes past their gate. Dispatched writes
|
|
905
902
|
drain under `W9`; unknown outcomes retain precedence. The lease then releases:
|
|
906
903
|
QuickJS terminates its child, and the Worker adapter disposes RPC and loader
|
|
907
904
|
handles independently of the guest deadline. Workers guest computation may
|
|
@@ -1003,22 +1000,22 @@ payload-free _by construction_ means the event has nowhere to put a payload.
|
|
|
1003
1000
|
distinctive output is the program source — exactly what a payload-free history
|
|
1004
1001
|
must never keep.
|
|
1005
1002
|
|
|
1006
|
-
**V5.** A
|
|
1003
|
+
**V5.** A write a program issues after it has already returned is not
|
|
1007
1004
|
sent and records nothing: it was never an attempt (`W9`).
|
|
1008
1005
|
|
|
1009
1006
|
## Writes
|
|
1010
1007
|
|
|
1011
|
-
|
|
1012
|
-
`
|
|
1013
|
-
|
|
1014
|
-
|
|
1008
|
+
Whether an endpoint writes belongs to deployment code. Every deployment sets
|
|
1009
|
+
`readOnly` for `/mcp` explicitly; construction fails without it. Each named pool inherits
|
|
1010
|
+
the deployment's `readOnly` unless it sets its own, in either direction. The
|
|
1011
|
+
client owns approval; Connecta answers one question per endpoint: can it write.
|
|
1015
1012
|
|
|
1016
1013
|
```ts
|
|
1017
1014
|
createConnecta({
|
|
1018
1015
|
connectors, executor,
|
|
1019
|
-
|
|
1016
|
+
readOnly: false, // required: false writes, true refuses every write call
|
|
1020
1017
|
pools: {
|
|
1021
|
-
|
|
1018
|
+
reporting: { tools: ["posthog"], readOnly: true, members: analysts },
|
|
1022
1019
|
},
|
|
1023
1020
|
classification: {
|
|
1024
1021
|
posthog: { exec: "read" }, // only for a deployment with a read-only exec contract
|
|
@@ -1027,6 +1024,9 @@ createConnecta({
|
|
|
1027
1024
|
});
|
|
1028
1025
|
```
|
|
1029
1026
|
|
|
1027
|
+
The removed `trust` option, on the deployment or a pool, fails construction
|
|
1028
|
+
with a message naming `readOnly`.
|
|
1029
|
+
|
|
1030
1030
|
The registry computes one `classifyTool` verdict on each request-scoped
|
|
1031
1031
|
published catalog entry. It caches and persists only raw downstream facts.
|
|
1032
1032
|
Every caller consumes that stored verdict. Config cannot classify an individual
|
|
@@ -1044,7 +1044,7 @@ fail construction; unknown remote tool keys fail publication of the whole
|
|
|
1044
1044
|
catalog. Overrides are exact tool names, including names containing dots.
|
|
1045
1045
|
They are never inferred from descriptions or arguments.
|
|
1046
1046
|
|
|
1047
|
-
**W9.** Programs
|
|
1047
|
+
**W9.** Programs on a writable endpoint may write. A dispatched write is awaited even
|
|
1048
1048
|
if the program does not await it, bounded by its host-call deadline. A write
|
|
1049
1049
|
that reaches accounting after the program settles is not sent. An unanswered
|
|
1050
1050
|
write makes the run fail `write_outcome_unknown` with
|
|
@@ -1054,7 +1054,7 @@ write is automatically retried, including an ambiguous timeout. A downstream
|
|
|
1054
1054
|
refusal or a tool's `isError` can establish failure; a timeout or an unanswered
|
|
1055
1055
|
transport failure leaves the outcome unknown.
|
|
1056
1056
|
|
|
1057
|
-
**W10.** `execute.maxWrites`, default 10, bounds
|
|
1057
|
+
**W10.** `execute.maxWrites`, default 10, bounds a program's writes in
|
|
1058
1058
|
addition to the host-call budget. It is checked after argument validation and
|
|
1059
1059
|
before admission, so an over-budget write spends no permit.
|
|
1060
1060
|
|
|
@@ -1067,14 +1067,20 @@ reconciliation. Any new call must use the original arguments when its echo is
|
|
|
1067
1067
|
partial or absent. A returned `writes` count cannot make a run safe to repeat.
|
|
1068
1068
|
See [argument echo rules](./meta-tools.md#echo-budgets) for supported schema shapes.
|
|
1069
1069
|
|
|
1070
|
-
**W12.**
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
`
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1070
|
+
**W12.** Writable endpoints annotate `execute_code` as a write
|
|
1071
|
+
(`readOnlyHint: false, destructiveHint: true`) and permit program writes and
|
|
1072
|
+
`call_destructive_tool`; `call_tool` still accepts only reads and refuses a write
|
|
1073
|
+
with `destructive_tool_requires_approval`. Read-only endpoints annotate
|
|
1074
|
+
`execute_code` as read-only (`readOnlyHint: true, destructiveHint: false`),
|
|
1075
|
+
omit write tools from `search_tools`, `connecta.search`, and
|
|
1076
|
+
`connecta.describe`, and refuse every write call through `call_tool`,
|
|
1077
|
+
`call_destructive_tool`, and programs with `read_only_endpoint` before
|
|
1078
|
+
validation or dispatch. Guides and skills are documentation and may still name
|
|
1079
|
+
those tools. `tools/list` is the same six tools on both. Approval belongs to the client.
|
|
1080
|
+
`readOnly` grants no tool or connector access and cannot be set by guest code,
|
|
1081
|
+
request arguments, or a downstream catalog. `execute.approval`,
|
|
1082
|
+
`Connector.approval`, per-tool approval exemptions, and pool `trust` are
|
|
1083
|
+
removed. `W1`–`W8` and `W11` remain retired.
|
|
1078
1084
|
|
|
1079
1085
|
## Executor exceptions
|
|
1080
1086
|
|
|
@@ -1185,7 +1191,13 @@ brand check and reads only own string data descriptors for diagnostics; guest
|
|
|
1185
1191
|
accessors, serialization hooks, and Proxy traps do not run. Other thrown objects
|
|
1186
1192
|
receive a fixed description.
|
|
1187
1193
|
|
|
1188
|
-
##
|
|
1194
|
+
## Contributor reference
|
|
1195
|
+
|
|
1196
|
+
### Verification
|
|
1197
|
+
|
|
1198
|
+
The earlier alternatives are in [decision history](https://github.com/zackbart/connecta/blob/main/decisions/0001-ethos-verdict-table.md)
|
|
1199
|
+
([#267](https://github.com/zackbart/connecta/issues/267),
|
|
1200
|
+
[#270](https://github.com/zackbart/connecta/issues/270)).
|
|
1189
1201
|
|
|
1190
1202
|
`test/guest-contract-cases.ts` runs on QuickJS in `test/guest-api-contract-quickjs.node.test.ts`
|
|
1191
1203
|
and on the Worker adapter with a real Miniflare Loader in `test/guest-api-contract.test.ts`.
|
|
@@ -1225,8 +1237,8 @@ rejection, and branded adapter acceptance across module copies.
|
|
|
1225
1237
|
| `L5`, `L7`, `X2` | `test/quickjs-executor.node.test.ts` (CPU, heap), `test/execute.test.ts` and `test/executor-admission.test.ts` (bounded admission and queue) |
|
|
1226
1238
|
| `L6`, `X10` | `test/guest-api-contract-quickjs.node.test.ts` and `test/guest-api-contract.test.ts` (whole oversized reads and one-write pageable handles), `test/sqlite-storage.node.test.ts` and `test/d1-storage.node.test.ts` (shared stash transfers), `test/quickjs-executor.node.test.ts` (bridge and IPC bounds for arguments and result; the address in the over-bound message), `test/quickjs-child-stderr.node.test.ts` (outer reply serialization failure settles the call) |
|
|
1227
1239
|
| `V1`–`V4` | `test/guest-api-contract.test.ts` (dispatched calls, every refusal class including an address no connector owns, the friction each derives, no event for the execution itself), `test/activity.test.ts` (the shared code → friction table, the identity clamp, the one-attempt floor), `test/operator-view.test.ts`, `test/sql-storage-contract.ts`, run by `test/d1-storage.node.test.ts` and `test/sqlite-storage.node.test.ts` (historical pause and approval rows still render and round-trip) |
|
|
1228
|
-
| `V5`, `W9` | `test/program-writes.test.ts` (an unawaited
|
|
1229
|
-
| `W10`, `W12` | `test/program-writes.test.ts` (a
|
|
1240
|
+
| `V5`, `W9` | `test/program-writes.test.ts` (an unawaited program write finished and recorded, its unknown outcome reported, counts on a failed program, the classification table), `test/invocation-pipeline.test.ts` (the gate after validation, an unrecorded refusal) |
|
|
1241
|
+
| `W10`, `W12` | `test/program-writes.test.ts` (a writable endpoint's program write runs, a read-only endpoint omits writes from search and describe and refuses every write call on every path, including a write its guide names, a required deployment `readOnly`, the write budget, `readOnly` inheritance and overrides, `call_tool` still refusing, search and describe verdicts, construction refusals including retired `trust`), `test/operator-ui-model.test.ts`, `test/browser/operator-ui.spec.ts` (the badge) |
|
|
1230
1242
|
| `M1` | `test/guest-api-contract.test.ts` (invalid emits throw catchably, accept nothing), `test/execute-emit.test.ts` (rejected shapes, bounded native snapshots, paging before metadata traversal, and cyclic presentation refusal) |
|
|
1231
1243
|
| `M2`, `M3` | `test/guest-api-contract.test.ts` (delivery order, truncated return plus delivered blocks), `test/execute-emit.test.ts` (envelope, `structuredContent`, byte-for-byte no-emit path) |
|
|
1232
1244
|
| `M4` | `test/guest-api-contract.test.ts` (discard is visible), `test/execute-emit.test.ts` (structured and plain paths), `test/quickjs-executor.node.test.ts` (mid-run shutdown) |
|
|
@@ -27,20 +27,25 @@ path and pins the generated project's Connecta dependency to the CLI version:
|
|
|
27
27
|
npx @zackbart/connecta init my-connecta
|
|
28
28
|
cd my-connecta
|
|
29
29
|
npm install
|
|
30
|
-
npm run --silent
|
|
30
|
+
npm run --silent rotate-token -- local-machine
|
|
31
31
|
# Save the returned cta_ token privately. It is shown only once.
|
|
32
32
|
npm start
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
-
The
|
|
36
|
-
`
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
The agent connects to its pool's agent endpoint,
|
|
36
|
+
`http://localhost:8787/agent/local-machine`, with
|
|
37
|
+
`Authorization: Bearer <returned-cta-token>`. People use `/mcp` and
|
|
38
|
+
`/mcp/<pool>`, which refuse `cta_` tokens. Machine clients are the agents
|
|
39
|
+
declared in `agents` in `src/connecta.config.ts`; the generated project declares
|
|
40
|
+
`local-machine` and always installs `accessTokens(storage)`. An agent with no
|
|
41
|
+
issued token admits no MCP caller even though `/health` works. Rotating with the
|
|
42
|
+
same command replaces the token immediately. `CONNECTA_TOKEN` is only a client/doctor variable;
|
|
39
43
|
it never configures server authentication. The local commands read the process
|
|
40
44
|
environment and do not load `.env`; Docker Compose does.
|
|
41
45
|
|
|
42
|
-
Edit `src/connecta.config.ts` for connectors, public URL, auth,
|
|
43
|
-
and optional modules.
|
|
46
|
+
Edit `src/connecta.config.ts` for connectors, public URL, auth, maintainers,
|
|
47
|
+
agents, pools, and optional modules. Lay out each agent's pools by
|
|
48
|
+
[Organizing an agent's pools](./auth.md#organizing-an-agents-pools). `src/index.ts` only constructs and starts the deployment.
|
|
44
49
|
Follow the [template README](../templates/node/README.md) for storage paths,
|
|
45
50
|
backups, Docker provisioning, secrets, and optional modules. Run the deployment's
|
|
46
51
|
`npm run typecheck` after configuration changes.
|
|
@@ -56,15 +61,77 @@ must be installed for the Worker executor.
|
|
|
56
61
|
|
|
57
62
|
Attach Cloudflare Access to the Worker destination. Interactive MCP clients
|
|
58
63
|
need Managed OAuth, Dynamic Client Registration, and the documented redirect
|
|
59
|
-
allowlist. Machines
|
|
60
|
-
`cta_` bearer
|
|
64
|
+
allowlist. Machines are declared agents: they use `/agent/<pool>` with the
|
|
65
|
+
agent's `cta_` bearer as their only credential, once the
|
|
66
|
+
[agent bypass application](#agent-endpoints-behind-cloudflare-access) exists;
|
|
67
|
+
Access service identity alone is refused. Keep
|
|
61
68
|
`enable_request_signal`, construct Connecta once per isolate, and pass `ctx`
|
|
62
69
|
through to `fetch`. The example owns those details and
|
|
63
70
|
[the machine-token procedure](../examples/worker/README.md#machine-tokens).
|
|
64
71
|
|
|
72
|
+
## Agent endpoints behind Cloudflare Access
|
|
73
|
+
|
|
74
|
+
Agents use `/agent/<pool>`, which connecta authenticates with the `cta_` token
|
|
75
|
+
alone and which ignores Access context entirely
|
|
76
|
+
([agent endpoints](./auth.md#agent-endpoints)). Behind Access, the edge must
|
|
77
|
+
let those requests through without an Access login or service token. The P0
|
|
78
|
+
probe ([observations](./architecture.md#production-access-bypass-for-agent-endpoints))
|
|
79
|
+
verified this shape on 2026-10-15:
|
|
80
|
+
|
|
81
|
+
1. Keep the Worker-level application, whose destination is
|
|
82
|
+
`{ "type": "worker", "worker_id": "<the Worker script tag>" }`, exactly as
|
|
83
|
+
[Cloudflare Access on Workers](./auth.md#cloudflare-access-on-workers)
|
|
84
|
+
describes. It still protects every other path and supplies `ctx.access` to
|
|
85
|
+
human routes.
|
|
86
|
+
2. For each hostname agents use (the `workers.dev` hostname, each Custom
|
|
87
|
+
Domain, each route host), add one more **self-hosted** Access application.
|
|
88
|
+
In the dashboard, set the domain to that hostname and the path to
|
|
89
|
+
`agent/*`. Give it a single policy whose action is **Bypass** and whose
|
|
90
|
+
include rule is **Everyone**. Through the API:
|
|
91
|
+
|
|
92
|
+
```json
|
|
93
|
+
{
|
|
94
|
+
"type": "self_hosted",
|
|
95
|
+
"name": "connecta agents",
|
|
96
|
+
"destinations": [{ "type": "public", "uri": "connecta.example.com/agent/*" }],
|
|
97
|
+
"policies": [{ "name": "agents bypass", "decision": "bypass", "include": [{ "everyone": {} }] }]
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
The more specific hostname-and-path application takes precedence over the
|
|
102
|
+
Worker-level one on matching paths only. Do not use a Worker destination
|
|
103
|
+
for it: a Worker destination belongs to one application, and a second one
|
|
104
|
+
is refused with 409 `destination belongs to another application`. For the
|
|
105
|
+
same reason a second hostname without Access is not an alternative.
|
|
106
|
+
|
|
107
|
+
3. Point each agent at `https://<host>/agent/<pool>` with
|
|
108
|
+
`Authorization: Bearer cta_…` and drop its `CF-Access-Client-Id` and
|
|
109
|
+
`CF-Access-Client-Secret` headers. The pool must list `"agent:<name>"`.
|
|
110
|
+
4. Verify after the change has settled. Access changes took 15–19 seconds to
|
|
111
|
+
settle in the probe, and while they propagate the edge can answer with
|
|
112
|
+
transient 500 (`error code: 1104`) or 404 (`error code: 1042` or `1043`)
|
|
113
|
+
responses, and in one round a 403 on a bypassed path after more than 30
|
|
114
|
+
seconds. Do not rely on a fixed wait: repeat these checks until they agree
|
|
115
|
+
for several consecutive rounds. Without credentials, `/agent/<pool>`
|
|
116
|
+
reaches connecta (its 401 carries `WWW-Authenticate: Bearer`, not Access's
|
|
117
|
+
403 page), while `/mcp` and `/` still get Access's refusal. Then run
|
|
118
|
+
`connecta doctor --pool <pool>` with the agent's token.
|
|
119
|
+
|
|
120
|
+
The bypass makes `/agent/*` reachable from the internet without Access.
|
|
121
|
+
Connecta answers there only an issued token of an agent listed in the pool,
|
|
122
|
+
and gives every other spelling of the agent namespace a 404 before auth,
|
|
123
|
+
because Access matches `/agent/*` after resolving dot segments, folding case,
|
|
124
|
+
decoding unreserved escapes, and collapsing a leading `//`, while the Worker
|
|
125
|
+
sees the raw path. Two cases were not tested: a human's `CF_Authorization`
|
|
126
|
+
cookie on a bypassed path, whose `ctx.access` identity is unknown (connecta
|
|
127
|
+
never reads it at `/agent/*`), and Custom Domains, which use the same
|
|
128
|
+
documented hostname-and-path form but were not observed; only `workers.dev`
|
|
129
|
+
was probed. Pinning the Worker-level application's AUD on human routes is
|
|
130
|
+
recommended hardening that connecta does not yet do.
|
|
131
|
+
|
|
65
132
|
## Compose capabilities and access
|
|
66
133
|
|
|
67
|
-
Both configurations use `defineConfig((env) => …)
|
|
134
|
+
Both configurations use `defineConfig((env) => …)`, a required executor, and a required `readOnly` choice.
|
|
68
135
|
[Integrating services](./integrating.md) explains the `connectors` array.
|
|
69
136
|
Configuration selects optional factories through explicit slots:
|
|
70
137
|
|
|
@@ -90,51 +157,86 @@ outside the database and source control, and preserve it across upgrades.
|
|
|
90
157
|
existing-record migration.
|
|
91
158
|
|
|
92
159
|
One deployment serves one tenant and may admit several people. Node uses Clerk
|
|
93
|
-
for human auth; Access is Workers-only.
|
|
94
|
-
|
|
95
|
-
|
|
160
|
+
for human auth; Access is Workers-only. With inbound auth, `maintainers` is
|
|
161
|
+
required: only they reach plain `/mcp` and the operator UI. Everyone else
|
|
162
|
+
reaches a pool that lists them in `members`: people at `/mcp/<pool>`, agents
|
|
163
|
+
at `/agent/<pool>`. Maintainers alone administer shared credentials, manage
|
|
164
|
+
agent tokens, and read activity; members connect their own accounts on
|
|
165
|
+
personal connectors in their pools.
|
|
166
|
+
[Auth](./auth.md#principals-visibility-and-operators) owns maintainers and members;
|
|
96
167
|
[Clerk setup](./auth.md#clerk-oauth-tokens-and-operator-sessions) owns resource-bound
|
|
97
168
|
tokens and `aud_claim_enabled`. A person's operator session is not an MCP token.
|
|
98
169
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
170
|
+
Every deployment must set `readOnly` in its configuration; startup fails without
|
|
171
|
+
it, and the template and Worker example set `readOnly: false`. Each named pool
|
|
172
|
+
inherits that value unless it sets its own. A writable endpoint (`false`) allows
|
|
173
|
+
writes through `call_destructive_tool` and programs and marks `execute_code` as
|
|
174
|
+
a write; the client decides what to approve. A read-only endpoint (`true`) omits
|
|
175
|
+
write tools from search and describe and refuses every write call; provider
|
|
176
|
+
guides may still name those tools. A pool serves exactly its `tools` to its
|
|
177
|
+
`members`. See [pools](./auth.md#pools) before changing `readOnly`.
|
|
103
178
|
|
|
104
179
|
## Verify and diagnose
|
|
105
180
|
|
|
106
|
-
With the deployment running, replace the placeholder with its saved
|
|
107
|
-
token and run doctor:
|
|
181
|
+
With the deployment running, replace the placeholder with its saved agent
|
|
182
|
+
token and run doctor against a pool that lists the agent:
|
|
183
|
+
|
|
184
|
+
```sh
|
|
185
|
+
CONNECTA_TOKEN='<stored-cta-token>' npx connecta doctor --url http://localhost:8787 --pool local-machine
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Doctor checks health, the required executor, and the current six-tool set. A
|
|
189
|
+
`cta_` token is checked at `/agent/<pool>` and needs `--pool`.
|
|
190
|
+
For a Worker protected by Access, `/health` still needs edge admission even
|
|
191
|
+
though `/agent/*` bypasses Access. Use an Access service token admitted by the
|
|
192
|
+
Worker-level policy for that check, alongside the agent token:
|
|
108
193
|
|
|
109
194
|
```sh
|
|
110
|
-
CONNECTA_TOKEN='<stored-cta-token>' npx connecta doctor --url
|
|
195
|
+
CF_ACCESS_CLIENT_ID='<access-service-id>' CF_ACCESS_CLIENT_SECRET='<access-service-secret>' CONNECTA_TOKEN='<stored-cta-token>' npx connecta doctor --url https://connecta.example.com --pool assistant
|
|
111
196
|
```
|
|
112
197
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
and service-header setup. If the operator UI is enabled, authenticated
|
|
198
|
+
The service headers admit the health probe at the edge; only the `cta_` token
|
|
199
|
+
authenticates the agent endpoint inside Connecta. If the operator UI is enabled, maintainer-authenticated
|
|
116
200
|
`connecta doctor --config --url <public-url>` prints the caller-scoped
|
|
117
201
|
configuration snapshot as JSON. It runs no diagnostic program and prints no
|
|
118
202
|
raw HTTP failure body. [Operator UI](./operator-ui.md) describes the returned
|
|
119
|
-
configuration, live facts, and permission rules.
|
|
203
|
+
configuration, live facts, and permission rules. The config route is a human
|
|
204
|
+
endpoint: an agent token cannot authenticate it.
|
|
120
205
|
|
|
121
206
|
Health success alone does not prove a client can authenticate or reach an
|
|
122
207
|
integration. Check client connection and a bounded read through a chosen
|
|
123
208
|
connector; resolve credentials using [authorization recovery](./meta-tools.md#authorization-recovery).
|
|
124
209
|
|
|
210
|
+
Use the failed check to choose the next step:
|
|
211
|
+
|
|
212
|
+
| Symptom | Action |
|
|
213
|
+
| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
214
|
+
| Connection refused or timeout | Check the public URL, listening process/port, proxy, and Worker deployment. |
|
|
215
|
+
| `/health` fails behind Access | Check the Worker-level Access policy and the two service headers above. Do not broaden the agent bypass. |
|
|
216
|
+
| Executor check fails | Retain `quickJsExecutor()` and its peer on Node, or `workerExecutor({ loader })`, the codemode peer, and `LOADER` on Workers. |
|
|
217
|
+
| MCP 401 | Check the saved token, declared agent, and slot state; rotated/revoked tokens refuse. Use `/agent/<pool>` with `--pool`. |
|
|
218
|
+
| MCP 404 | Check the pool name and `members: ["agent:assistant"]`; an existing but inaccessible pool is deliberately indistinguishable from a missing one. |
|
|
219
|
+
| Doctor passes but a connector fails | Discover its tools in that pool, check credential status/account ownership, and perform a bounded read. Doctor does not prove downstream access. |
|
|
220
|
+
|
|
221
|
+
After a fix, repeat doctor with the same client credentials and pool. Never
|
|
222
|
+
paste a token or raw downstream failure body into a committed diagnostic log.
|
|
223
|
+
|
|
125
224
|
## Upgrade an existing deployment
|
|
126
225
|
|
|
127
226
|
Bump the exact package pin, read the [changelog](../CHANGELOG.md) for every
|
|
128
227
|
intervening release, and apply the relevant migration before startup. `init`
|
|
129
228
|
does not merge changes into an existing deployment.
|
|
130
229
|
|
|
131
|
-
- [
|
|
230
|
+
- [Migration to 0.33](./migration-0.33.md) maps every removed access option to `maintainers`, pool `members`, and `agents`, moves agents to `/agent/<pool>`, and covers pool owners, token revisions, operator contract v2 with its operator route changes, and the pre-auth listen fix.
|
|
231
|
+
- [Tokens issued before agents](./auth.md#agent-tokens-and-upgrading-from-earlier-tokens) stop admitting until each machine's token is bound once to a declared agent with `npm run adopt-token -- <token-id> <agent>` (Node) or `AccessTokenManager.adopt`, which keeps its secret. Human-bound tokens stay refused; issue those agents new tokens. Pool members name `"agent:<name>"` instead of matching token record ids.
|
|
132
232
|
- [Node storage from 0.28](../templates/node/README.md#storage) uses `connecta migrate-state` to copy the JSON state into SQLite. Activity JSONL is not imported.
|
|
133
233
|
- [Worker storage from 0.28](../examples/worker/README.md#upgrading-from-028) copies KV into D1 with a one-shot migration.
|
|
134
234
|
- [Notion, Vercel, and Cloudflare for 0.29](./provider-migration-0.29.md) change defaults and retained API tool names.
|
|
135
235
|
- [Executor wiring](./code-mode.md#deploy-time-capability) requires branded shipped executors or a self-managed custom executor.
|
|
136
236
|
|
|
137
|
-
##
|
|
237
|
+
## Contributor reference
|
|
238
|
+
|
|
239
|
+
### Implementation and evidence
|
|
138
240
|
|
|
139
241
|
Check the [CLI](https://github.com/zackbart/connecta/blob/main/bin/connecta.mjs),
|
|
140
242
|
[Node configuration](../templates/node/src/connecta.config.ts), and
|