@zackbart/connecta 0.37.1 → 0.38.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 (168) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +2 -2
  3. package/bin/connecta.mjs +1 -39
  4. package/bin/version.mjs +1 -1
  5. package/dist/access-tokens.js +2 -4
  6. package/dist/agent-identity.js +1 -1
  7. package/dist/auth/clerk-sdk/generated.js +2 -1
  8. package/dist/auth/downstream-oauth.js +19 -153
  9. package/dist/auth/downstream-revocation.js +1 -1
  10. package/dist/auth/oauth-grant.js +11 -0
  11. package/dist/auth/oauth-token-response.js +1 -1
  12. package/dist/auth/vercel-agent.js +2 -1
  13. package/dist/auth-elicitation.js +2 -2
  14. package/dist/branding.d.ts +1 -15
  15. package/dist/branding.js +2 -2
  16. package/dist/bytes.js +42 -0
  17. package/dist/call-admission-context.js +2 -5
  18. package/dist/call-recovery.js +0 -3
  19. package/dist/catalog-fingerprint.js +2 -18
  20. package/dist/catalog-service.js +1 -1
  21. package/dist/config-defaults.d.ts +1 -0
  22. package/dist/config-defaults.js +1 -0
  23. package/dist/config-schema.d.ts +1 -1
  24. package/dist/config-schema.js +6 -2
  25. package/dist/config.d.ts +41 -14
  26. package/dist/config.js +21 -71
  27. package/dist/connectors/api-connector.js +4 -3
  28. package/dist/connectors/guarded-fetch.d.ts +0 -6
  29. package/dist/connectors/guarded-fetch.js +1 -11
  30. package/dist/connectors/remote-mcp.js +10 -43
  31. package/dist/connectors/resource-uri.js +0 -4
  32. package/dist/d1.d.ts +0 -89
  33. package/dist/d1.js +0 -34
  34. package/dist/downstream-input.js +2 -2
  35. package/dist/execute.js +22 -13
  36. package/dist/executor-result.js +2 -1
  37. package/dist/executors/quickjs-runtime.js +2 -25
  38. package/dist/executors/quickjs.js +1 -1
  39. package/dist/guest-runtime.js +5 -3
  40. package/dist/guest-types.d.ts +5 -5
  41. package/dist/http/client.js +1 -1
  42. package/dist/http/errors.js +2 -2
  43. package/dist/http/json-schema.js +1 -1
  44. package/dist/http/node-transport.js +0 -1
  45. package/dist/http/oauth.js +1 -1
  46. package/dist/http/paging.js +6 -9
  47. package/dist/http/provider.js +1 -1
  48. package/dist/http/safety.js +1 -1
  49. package/dist/http/services.js +1 -8
  50. package/dist/http/tools.js +1 -7
  51. package/dist/http/vendor.js +7 -7
  52. package/dist/identity.js +2 -6
  53. package/dist/invocation-auth.js +2 -1
  54. package/dist/meta-tools.js +27 -27
  55. package/dist/native-tools.js +2 -1
  56. package/dist/oauth-handoff.js +2 -2
  57. package/dist/operation-vocabulary.js +1 -1
  58. package/dist/operator-record.js +1 -49
  59. package/dist/operator-ui/contract.d.ts +2 -2
  60. package/dist/operator-ui/generated.js +3 -3
  61. package/dist/program-writes.js +3 -8
  62. package/dist/provider-call.js +0 -7
  63. package/dist/provider.d.ts +1 -1
  64. package/dist/providers/_shared/google/kit.js +1 -6
  65. package/dist/providers/_shared/google/service-account.js +1 -3
  66. package/dist/providers/_shared/google/workspace.d.ts +1 -1
  67. package/dist/providers/_shared/guide.js +3 -0
  68. package/dist/providers/_shared/json.js +12 -0
  69. package/dist/providers/_shared/rest/compact-index.js +1 -1
  70. package/dist/providers/_shared/rest/kit.js +1 -3
  71. package/dist/providers/_shared/rest/operation-index.js +1 -3
  72. package/dist/providers/_shared/rest/value-safety.js +26 -28
  73. package/dist/providers/breeze/api.js +2 -7
  74. package/dist/providers/breeze/index.js +4 -2
  75. package/dist/providers/breeze/tools.js +3 -4
  76. package/dist/providers/ccb/api.js +1 -6
  77. package/dist/providers/ccb/index.js +2 -1
  78. package/dist/providers/ccb/tools.js +1 -6
  79. package/dist/providers/cloudflare/api.js +2 -2
  80. package/dist/providers/cloudflare/index.js +2 -1
  81. package/dist/providers/cloudflare/safety.js +3 -3
  82. package/dist/providers/docs/tools.js +2 -10
  83. package/dist/providers/drive/tools.js +12 -25
  84. package/dist/providers/forms/tools.js +1 -9
  85. package/dist/providers/gmail/tools.js +5 -21
  86. package/dist/providers/overflow/api.js +1 -3
  87. package/dist/providers/overflow/index.js +2 -1
  88. package/dist/providers/overflow/tools.js +3 -7
  89. package/dist/providers/planning-center/api.js +2 -1
  90. package/dist/providers/planning-center/lib/constants.d.ts +1 -1
  91. package/dist/providers/planning-center/lib/json-api.js +1 -9
  92. package/dist/providers/planning-center/tools.js +2 -1
  93. package/dist/providers/sheets/tools.js +1 -9
  94. package/dist/providers/slides/tools.js +4 -13
  95. package/dist/providers/stripe/index.js +2 -1
  96. package/dist/providers/stripe/safety.js +2 -2
  97. package/dist/providers/tithely/api.js +2 -7
  98. package/dist/providers/tithely/index.js +3 -2
  99. package/dist/providers/tithely/tools.js +7 -5
  100. package/dist/providers/vercel/api.js +1 -6
  101. package/dist/providers/vercel/lib/pin.js +1 -1
  102. package/dist/providers/vercel/safety.js +1 -1
  103. package/dist/providers/vercel/tools.js +2 -1
  104. package/dist/redaction-marker.js +2 -2
  105. package/dist/registry.d.ts +1 -1
  106. package/dist/registry.js +5 -7
  107. package/dist/request-principal.js +1 -1
  108. package/dist/request-state.js +2 -2
  109. package/dist/routes/access-tokens.js +1 -1
  110. package/dist/routes/activity-disclosure.js +1 -1
  111. package/dist/routes/connect.js +2 -2
  112. package/dist/routes/credentials.js +1 -1
  113. package/dist/routes/mcp.js +4 -3
  114. package/dist/routes/oauth-management.js +1 -1
  115. package/dist/routes/operator.js +4 -3
  116. package/dist/routes/shared.d.ts +8 -8
  117. package/dist/routes/shared.js +9 -9
  118. package/dist/routes/ui-config.js +1 -1
  119. package/dist/routes/ui.js +1 -1
  120. package/dist/runtime/call-admission.js +1 -1
  121. package/dist/runtime/call.js +1 -1
  122. package/dist/runtime/settlement.js +1 -1
  123. package/dist/runtime/shared-read.js +2 -15
  124. package/dist/sent-secrets.d.ts +1 -2
  125. package/dist/sent-secrets.js +3 -8
  126. package/dist/server.js +4 -4
  127. package/dist/skills.js +8 -35
  128. package/dist/sqlite.d.ts +0 -19
  129. package/dist/sqlite.js +2 -83
  130. package/dist/storage/keys.js +16 -125
  131. package/dist/storage/sql-native.js +0 -101
  132. package/dist/storage/sql.d.ts +1 -24
  133. package/dist/storage/sql.js +1 -12
  134. package/dist/tool-error.js +4 -0
  135. package/dist/url-safety.js +0 -4
  136. package/dist/usage-guide.js +2 -2
  137. package/dist/version.d.ts +1 -1
  138. package/dist/version.js +1 -1
  139. package/dist/worker.js +1 -1
  140. package/documentation/README.md +6 -42
  141. package/documentation/architecture.md +86 -496
  142. package/documentation/auth.md +12 -25
  143. package/documentation/code-mode.md +90 -66
  144. package/documentation/deploying.md +19 -40
  145. package/documentation/integrating.md +4 -19
  146. package/documentation/meta-tools.md +6 -6
  147. package/documentation/migration-0.33.md +5 -5
  148. package/documentation/migration-0.34.md +2 -4
  149. package/documentation/migration-retired-layouts.md +74 -0
  150. package/documentation/operator-tests.md +19 -119
  151. package/documentation/operator-ui.md +3 -4
  152. package/documentation/provider-auth-migration.md +4 -10
  153. package/documentation/provider-migration-0.29.md +4 -15
  154. package/examples/worker/AGENTS.md +4 -6
  155. package/examples/worker/README.md +20 -115
  156. package/guides/connecting-agents.md +7 -30
  157. package/guides/how-it-works.md +2 -2
  158. package/guides/safety-and-trust.md +4 -1
  159. package/package.json +19 -19
  160. package/templates/node/README.md +9 -26
  161. package/templates/node/package.json +1 -1
  162. package/dist/auth/oauth-v2-migration.js +0 -135
  163. package/dist/provider-call-facts.d.ts +0 -115
  164. package/dist/provider-call.d.ts +0 -112
  165. package/dist/storage/d1-copy.js +0 -255
  166. package/dist/storage/sql-schema.d.ts +0 -6
  167. package/examples/worker/kv-to-d1.wrangler.jsonc +0 -26
  168. package/examples/worker/scripts/copy-kv-to-d1.mjs +0 -162
@@ -1,3 +1,4 @@
1
+ import { toolError } from "./tool-error.js";
1
2
  import { upwardStep } from "./upward.js";
2
3
  import { authCall, authInvoke, authFlow, authMethod, authStorage, registerAuth } from "./auth/native.js";
3
4
  import { registryProgram } from "./runtime/registry.js";
@@ -20,7 +21,7 @@ import { AUTHORIZE_OUTPUT, SEARCH_OUTPUT, SKILLS_OUTPUT } from "./meta-output.js
20
21
  import { RESULT_TTL_SECONDS, resultKeys } from "./storage/keys.js";
21
22
  import { agentOutputOperations, sentSecretsForRequest } from "./sent-secrets.js";
22
23
  import { captureDownstreamInput } from "./downstream-input.js";
23
- import { PROGRAM_RESULT_WIRE_BYTES } from "./program-result.js";
24
+ import { PROGRAM_RESULT_PAGE_BYTES, PROGRAM_RESULT_WIRE_BYTES } from "./program-result.js";
24
25
  export { MAX_DESCRIBE_ADDRESSES, MAX_DISCOVERY_RESULT_BYTES, MAX_SEARCH_LIMIT };
25
26
  const enc = new TextEncoder();
26
27
  // Each page is a slice of payload bytes, so a leading U+FEFF is data.
@@ -37,15 +38,7 @@ function errorResult(message) {
37
38
  return { content: [{ type: "text", text: message }], isError: true };
38
39
  }
39
40
  function discoveryErrorResult(error) {
40
- const result = jsonResult({
41
- error: {
42
- code: error.code,
43
- message: error.message,
44
- retryable: false,
45
- },
46
- });
47
- result.isError = true;
48
- return result;
41
+ return toolError({ code: error.code, message: error.message, retryable: false });
49
42
  }
50
43
  const discoveryResult = function (operation, hint) {
51
44
  return authFlow(function* () {
@@ -86,8 +79,8 @@ function isValidResultOffset(value) {
86
79
  * Backwards, never forwards: re-serving a few bytes the caller already has is
87
80
  * recoverable, silently skipping the rest of a character is not. Offsets the
88
81
  * server itself produced (`nextOffset`) are already boundaries and come back
89
- * unchanged, so this only moves an offset a client computed on its own
90
- * (issue #38). An offset at or past `bytes.length` is left alone — there is no
82
+ * unchanged, so this only moves an offset a client computed on its own.
83
+ * An offset at or past `bytes.length` is left alone — there is no
91
84
  * character there to split.
92
85
  */
93
86
  function alignStartToCharBoundary(bytes, offset) {
@@ -149,6 +142,15 @@ function base64Of(bytes) {
149
142
  }
150
143
  return out;
151
144
  }
145
+ /**
146
+ * The page a notice's nextAction asks a program to read: it fits the program's
147
+ * return even if every byte escapes to six JSON characters, with room for the
148
+ * page envelope, and never asks for more than the stash or bridge will serve.
149
+ */
150
+ function programPageBytes(results) {
151
+ const fits = Math.floor(((results.programChars ?? MAX_EXECUTE_RESULT_CHARS) - 1024) / 6);
152
+ return Math.max(4, Math.min(fits, results.cap, PROGRAM_RESULT_PAGE_BYTES));
153
+ }
152
154
  /** Opens a write's notice, ahead of any paging instruction. */
153
155
  const WRITE_ALREADY_RAN = "This write already ran: do not call it again to see its result.";
154
156
  /** UTF-8 cannot represent lone UTF-16 surrogates without changing them. */
@@ -229,7 +231,7 @@ const stashResult = function (bytes, results, preview, rawText) {
229
231
  try {
230
232
  // Base64 permits byte-range decoding, and splitting the envelope across
231
233
  // keys keeps a page's storage read proportional to the page instead of to
232
- // the whole result (issue #540). Chunk 0 carries the header; the connecta.result
234
+ // the whole result. Chunk 0 carries the header; the connecta.result
233
235
  // reader below maps a byte offset back to chunk index and base64 quad.
234
236
  const chunkBytes = resultChunkBytes(totalBytes);
235
237
  const binding = base64Of(enc.encode(JSON.stringify(results.binding)));
@@ -280,7 +282,7 @@ const stashResult = function (bytes, results, preview, rawText) {
280
282
  // A byte may cost six JSON characters when escaped. Leave room for the
281
283
  // result id, page counters, and continuation metadata in the returned page.
282
284
  arguments: {
283
- code: `async () => await connecta.result(${JSON.stringify(id)}, { offset: ${preview.kind === "prefix" ? preview.bytes : 0}, maxBytes: ${Math.floor((MAX_EXECUTE_RESULT_CHARS - 1024) / 6)} })`,
285
+ code: `async () => await connecta.result(${JSON.stringify(id)}, { offset: ${preview.kind === "prefix" ? preview.bytes : 0}, maxBytes: ${programPageBytes(results)} })`,
284
286
  },
285
287
  },
286
288
  };
@@ -325,10 +327,10 @@ const pageProgramResultNative = /* @__PURE__ */ registerAuth(pageProgramResult,
325
327
  });
326
328
  });
327
329
  /** Program returns share the direct stash, with all host-admitted call dependencies. */
328
- export function guardProgramReturn(value, registry, baseUrl, dependencies, secrets, logger, maxChars, completedWrite) {
329
- return runEdge(guardProgramReturnNative(value, registry, baseUrl, dependencies, secrets, logger, maxChars, completedWrite));
330
+ export function guardProgramReturn(value, registry, baseUrl, dependencies, secrets, logger, maxChars, completedWrite, programChars) {
331
+ return runEdge(guardProgramReturnNative(value, registry, baseUrl, dependencies, secrets, logger, maxChars, completedWrite, programChars));
330
332
  }
331
- const guardProgramReturnNative = /* @__PURE__ */ registerAuth(guardProgramReturn, function (value, registry, baseUrl, dependencies, secrets, logger, maxChars, completedWrite) {
333
+ const guardProgramReturnNative = /* @__PURE__ */ registerAuth(guardProgramReturn, function (value, registry, baseUrl, dependencies, secrets, logger, maxChars, completedWrite, programChars) {
332
334
  return authFlow(function* () {
333
335
  const serialized = serializeResultText(value);
334
336
  if (serialized.length <= maxChars)
@@ -347,6 +349,7 @@ const guardProgramReturnNative = /* @__PURE__ */ registerAuth(guardProgramReturn
347
349
  },
348
350
  write: completedWrite,
349
351
  cap,
352
+ ...(programChars !== undefined ? { programChars } : {}),
350
353
  set: authMethod((id, chunks, ttl) => registryProgram(registry, "stashResult", id, chunks, ttl)),
351
354
  warn: () => logFailure(logger, "result paging unavailable", failureRecord({})),
352
355
  };
@@ -453,16 +456,11 @@ function escapedHeadOf(bytes, cap) {
453
456
  * Bound a downstream MCP `content` array by `cap`.
454
457
  *
455
458
  * A lone text block is measured, stashed, previewed, and paged as its text:
456
- * its envelope adds nothing but a wrapper and a second layer of JSON escaping,
457
- * which made a JSON payload's preview unreadable and inflated every page.
459
+ * its envelope adds nothing but a wrapper and a second layer of JSON escaping.
458
460
  *
459
461
  * Anything else is measured as the serialized envelope — the same string that
460
462
  * gets stashed and paged, and the one that counts every block rather than only
461
- * the text ones. Both halves matter (issue #43). Measuring only text blocks
462
- * meant an oversized all-image result scored zero bytes and was returned inline
463
- * unbounded, with no `resultId` to page from; and measuring one string while
464
- * truncating another left `totalBytes` describing something the cap was never
465
- * compared against.
463
+ * the text ones. Measure the same representation that gets truncated and paged.
466
464
  *
467
465
  * Over the cap, what a client gets depends on whether a preview is usable.
468
466
  * Several text blocks preview as their text joined by newlines, while
@@ -624,6 +622,7 @@ function metaToolsForRequest(registry, baseUrl, opts = {}) {
624
622
  write: resolved.definition.classification !== "read",
625
623
  cap,
626
624
  ...(opts.pagingTool ? { pagingTool: opts.pagingTool } : {}),
625
+ ...(opts.maxProgramResultChars !== undefined ? { programChars: opts.maxProgramResultChars } : {}),
627
626
  set: authMethod((id, value, ttlSeconds) => registryProgram(registry, "stashResult", id, value, ttlSeconds)),
628
627
  // The catalog entry, never `toolName`: a record names a tool
629
628
  // only through the grammar check (src/operator-record.ts).
@@ -670,7 +669,7 @@ function metaToolsForRequest(registry, baseUrl, opts = {}) {
670
669
  const structuredRecovery = outcome.error.nextAction !== undefined;
671
670
  const recoveryRequired = structuredRecovery ||
672
671
  // Sanitized `unavailable` diagnostics ride the structured shape too;
673
- // the plain-text path would drop them (#539).
672
+ // the plain-text path would drop them.
674
673
  outcome.error.details !== undefined ||
675
674
  // So does a conflict's `current`: where things stand is the retry.
676
675
  outcome.error.current !== undefined ||
@@ -733,7 +732,7 @@ function metaToolsForRequest(registry, baseUrl, opts = {}) {
733
732
  content: [
734
733
  {
735
734
  type: "text",
736
- text: 'Available skills. Fetch one with skills({ name: "<name>" }).\n\n' +
735
+ text: "Available skills. Fetch one by exact name with this tool.\n\n" +
737
736
  listing.map((skill) => `- \`${skill.name}\` — ${skill.description}`).join("\n"),
738
737
  },
739
738
  ],
@@ -949,7 +948,7 @@ function metaToolsForRequest(registry, baseUrl, opts = {}) {
949
948
  // client that computes its own offsets can land inside a multi-byte
950
949
  // character, which would decode as U+FFFD; the offset actually served is
951
950
  // the boundary at or before it, and it is what the response reports back
952
- // as `offset` (issue #38).
951
+ // as `offset`.
953
952
  const offset = start + alignStartToCharBoundary(bytes, requestedOffset - start);
954
953
  // Both sides of `maxBytes` are validated by now — the argument above, the
955
954
  // cap at intake — so `offset + maxBytes` always reaches past `offset`.
@@ -1084,6 +1083,7 @@ const AUTHORIZE_INPUT = advertisedSchema(z.object({
1084
1083
  */
1085
1084
  export function registerMetaTools(server, registry, ctx) {
1086
1085
  const mt = createMetaTools(registry, ctx.baseUrl, {
1086
+ maxProgramResultChars: ctx.maxProgramResultChars,
1087
1087
  ...(ctx.native && !ctx.native.executeCode ? { pagingTool: "read_result" } : {}),
1088
1088
  ...(ctx.native ? { activitySource: "native" } : {}),
1089
1089
  downstreamInput: Boolean(ctx.authElicitation),
@@ -1,3 +1,4 @@
1
+ import { bytesToHex } from "./bytes.js";
1
2
  import { duringViewEffect } from "./runtime/call.js";
2
3
  import { RequestScope, requestOwner } from "./runtime/request-scope.js";
3
4
  import { Effect } from "effect";
@@ -35,7 +36,7 @@ function shortHash(text) {
35
36
  const shortHashNative = /* @__PURE__ */ registerAuth(shortHash, function (text) {
36
37
  return authFlow(function* () {
37
38
  const digest = new Uint8Array(yield* upwardStep(authInvoke(crypto.subtle, "digest", ["SHA-256", enc.encode(text)])));
38
- return [...digest.subarray(0, HASH_CHARS / 2)].map((byte) => byte.toString(16).padStart(2, "0")).join("");
39
+ return bytesToHex(digest.subarray(0, HASH_CHARS / 2));
39
40
  });
40
41
  });
41
42
  /**
@@ -1,3 +1,4 @@
1
+ import { decodeBase64url } from "./bytes.js";
1
2
  import { upwardStep } from "./upward.js";
2
3
  import { authCall, authInvoke, authFlow, authStorage, registerAuth } from "./auth/native.js";
3
4
  import { runEdge } from "./runtime/run.js";
@@ -58,8 +59,7 @@ function encodeSegment(value) {
58
59
  function decodeSegment(value) {
59
60
  if (!/^[A-Za-z0-9_-]+$/.test(value))
60
61
  throw new Error("Invalid handoff encoding");
61
- const binary = atob(value.replace(/-/g, "+").replace(/_/g, "/"));
62
- const decoded = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(Uint8Array.from(binary, (char) => char.charCodeAt(0)));
62
+ const decoded = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(decodeBase64url(value));
63
63
  if (encodeSegment(decoded) !== value)
64
64
  throw new Error("Noncanonical handoff encoding");
65
65
  return decoded;
@@ -2,7 +2,7 @@
2
2
  import { lexicalSearchContent, lexicalQueryTerms } from "./catalog.js";
3
3
  const tools = new WeakMap();
4
4
  const connectors = new WeakMap();
5
- export const OPERATION_VOCABULARY_BOUNDS = {
5
+ const OPERATION_VOCABULARY_BOUNDS = {
6
6
  operations: 8192,
7
7
  rowChars: 1024,
8
8
  chars: 2_097_152,
@@ -1,52 +1,4 @@
1
- // What an operator may read about a failure: log records and status text.
2
- // Web-API only — no node: imports here.
3
- //
4
- // Inbound identity-provider text never enters operator logs or status, even
5
- // when it fits a grammar. Activity retains its separate typed actor fields.
6
- //
7
- // Threat model. INV-6 here covers records of calls and failures: logs,
8
- // activity rows, status and statusFor, health, doctor output, and any native
9
- // runtime output connecta triggers (workerd's console). Text a downstream
10
- // server, HTTP API, or client authored, and anything derived from it, never
11
- // reaches one as arbitrary text. Self-declared client name/version facts in
12
- // activity use the bounded ASCII grammars in activityClientFact; invalid values are
13
- // absent at recording, SQL write/read, and operator UI boundaries. Client
14
- // capabilities and other metadata are never recorded. Every typed field
15
- // connecta records is checked against a closed set or a grammar. Operator-
16
- // authored code (custom connectors, plugin `status()`, decorators) is trusted
17
- // to follow the contract, and connecta still checks
18
- // the typed fields it records from it; deliberately adversarial operator code
19
- // is out of scope.
20
- //
21
- // Catalog metadata a connector serves is configuration the operator chose to
22
- // load, and agents already see it: a tool name that fits MCP's tool-name
23
- // grammar, a description, and input and output schemas may appear in the
24
- // authenticated operator page's catalog views, and such a name may be
25
- // logged. A name outside the grammar is withheld everywhere operator-facing,
26
- // the page included. Names containing C0, DEL, or C1 are dropped at catalog
27
- // intake; spaces and non-ASCII names remain callable with withheld records.
28
- //
29
- // INV-6 says logs carry no arguments, results, code, or raw downstream error
30
- // text. Filtering errors where they arise kept missing sources: a validator's
31
- // diagnostic, a stream's TypeError, a JSON-RPC error the agent may see. So the
32
- // rule is enforced here, at the sink. A failure reaches an operator only as
33
- // the fields of a `FailureRecord`, which `failureRecord` alone builds: each
34
- // one copied from an explicit list, checked against a constant table or a
35
- // grammar, and never taken from an error's message, cause, stack, data,
36
- // nested errors, or name. `logFailure` writes nothing else, and every status
37
- // message about a failure comes from `describeFailure`
38
- // (test/operator-record-sources.node.test.ts holds src/ to that).
39
- //
40
- // Provenance is by identity, never by shape. Text that merely looks like
41
- // connecta's (an error named like one of its classes, a status sentence
42
- // shaped like a record) carries no weight: a class label comes from the
43
- // prototype chain, a status message from the status object connecta built.
44
- //
45
- // Agent-facing results are a different surface with a different rule: a
46
- // downstream's own answer to a call may reach the agent that made it (see
47
- // documentation/architecture.md, "Errors and records"). Core's sent-secrets
48
- // boundary removes credentials used by the upstream request from those answers, including
49
- // allowed diagnostics, tool results and nested error causes/data (INV-5).
1
+ // Payload-free operator failure records. See documentation/architecture.md, "Errors and records".
50
2
  import { carryProviderFailure } from "./provider-call-facts.js";
51
3
  import { followRedactedCopies, keepErrorName } from "./redaction-identity.js";
52
4
  import { classificationCode, ConnectorCallError, NETWORK_ERROR_CODES, WithheldTextError, } from "./errors.js";
@@ -26,7 +26,7 @@ export interface OperatorConnectorOverlay {
26
26
  /** Latest visible call in the bounded activity window, or null when unknown. */
27
27
  lastCall: OperatorLastCall | null;
28
28
  }
29
- /** Whole connector access, or exact tool grants. `requireReadOnly` is always false since guarded grants were removed (#837). */
29
+ /** Whole connector access, or exact tool grants. `requireReadOnly` is always false since guarded grants were removed. */
30
30
  export interface OperatorGrant {
31
31
  connectorId: string;
32
32
  tools: "all" | Array<{
@@ -197,5 +197,5 @@ export interface OperatorUiContractV2 {
197
197
  viewerKey: string;
198
198
  };
199
199
  }
200
- /** The operator contract `GET /ui/api/config` serves; schema version 1 was removed (#837). */
200
+ /** The operator contract `GET /ui/api/config` serves; schema version 1 was removed. */
201
201
  export type OperatorUiContract = OperatorUiContractV2;