@koda-sl/baker-bridge 0.125.0-dev.ee2f8e252 → 0.126.0-dev.0d67e41b9

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 (78) hide show
  1. package/README.md +3 -3
  2. package/dist/broker/broker-process.d.ts +10 -0
  3. package/dist/broker/broker-process.d.ts.map +1 -0
  4. package/dist/broker/broker-process.js +20 -0
  5. package/dist/broker/broker-process.js.map +1 -0
  6. package/dist/broker/broker-process.test.d.ts +2 -0
  7. package/dist/broker/broker-process.test.d.ts.map +1 -0
  8. package/dist/broker/broker-process.test.js +13 -0
  9. package/dist/broker/broker-process.test.js.map +1 -0
  10. package/dist/broker/credential-cache.d.ts.map +1 -1
  11. package/dist/broker/credential-cache.js +8 -1
  12. package/dist/broker/credential-cache.js.map +1 -1
  13. package/dist/broker/credential-cache.test.js +16 -0
  14. package/dist/broker/credential-cache.test.js.map +1 -1
  15. package/dist/broker/env.d.ts +2 -0
  16. package/dist/broker/env.d.ts.map +1 -1
  17. package/dist/broker/env.js +4 -0
  18. package/dist/broker/env.js.map +1 -1
  19. package/dist/broker/main.js +8 -2
  20. package/dist/broker/main.js.map +1 -1
  21. package/dist/broker/socket-service.d.ts.map +1 -1
  22. package/dist/broker/socket-service.js +12 -2
  23. package/dist/broker/socket-service.js.map +1 -1
  24. package/dist/broker/socket-service.test.js +7 -0
  25. package/dist/broker/socket-service.test.js.map +1 -1
  26. package/dist/broker/supervisor-main.d.ts +3 -0
  27. package/dist/broker/supervisor-main.d.ts.map +1 -0
  28. package/dist/broker/supervisor-main.js +70 -0
  29. package/dist/broker/supervisor-main.js.map +1 -0
  30. package/dist/broker/supervisor.d.ts +25 -0
  31. package/dist/broker/supervisor.d.ts.map +1 -0
  32. package/dist/broker/supervisor.js +88 -0
  33. package/dist/broker/supervisor.js.map +1 -0
  34. package/dist/broker/supervisor.test.d.ts +2 -0
  35. package/dist/broker/supervisor.test.d.ts.map +1 -0
  36. package/dist/broker/supervisor.test.js +161 -0
  37. package/dist/broker/supervisor.test.js.map +1 -0
  38. package/dist/cli.d.ts.map +1 -1
  39. package/dist/cli.js +2 -0
  40. package/dist/cli.js.map +1 -1
  41. package/dist/hono/agent.test.js +6 -0
  42. package/dist/hono/agent.test.js.map +1 -1
  43. package/dist/hono/bridge-job.d.ts.map +1 -1
  44. package/dist/hono/bridge-job.js +15 -1
  45. package/dist/hono/bridge-job.js.map +1 -1
  46. package/dist/hono/bridge-job.test.js +13 -0
  47. package/dist/hono/bridge-job.test.js.map +1 -1
  48. package/dist/hono/credential-scrub.d.ts +2 -1
  49. package/dist/hono/credential-scrub.d.ts.map +1 -1
  50. package/dist/hono/credential-scrub.js +23 -2
  51. package/dist/hono/credential-scrub.js.map +1 -1
  52. package/dist/hono/credential-scrub.test.js +25 -0
  53. package/dist/hono/credential-scrub.test.js.map +1 -1
  54. package/dist/hono/flow-input-card-fields.test.d.ts +10 -0
  55. package/dist/hono/flow-input-card-fields.test.d.ts.map +1 -0
  56. package/dist/hono/flow-input-card-fields.test.js +26 -0
  57. package/dist/hono/flow-input-card-fields.test.js.map +1 -0
  58. package/dist/hono/flow-input.d.ts +23 -0
  59. package/dist/hono/flow-input.d.ts.map +1 -1
  60. package/dist/hono/flow-input.js +59 -2
  61. package/dist/hono/flow-input.js.map +1 -1
  62. package/dist/hono/flow-input.test.js +56 -1
  63. package/dist/hono/flow-input.test.js.map +1 -1
  64. package/dist/hono/oom-priority.agent.test.d.ts +2 -0
  65. package/dist/hono/oom-priority.agent.test.d.ts.map +1 -0
  66. package/dist/hono/oom-priority.agent.test.js +138 -0
  67. package/dist/hono/oom-priority.agent.test.js.map +1 -0
  68. package/dist/hono/oom-priority.d.ts +39 -0
  69. package/dist/hono/oom-priority.d.ts.map +1 -0
  70. package/dist/hono/oom-priority.js +138 -0
  71. package/dist/hono/oom-priority.js.map +1 -0
  72. package/dist/hono/oom-priority.test.d.ts +2 -0
  73. package/dist/hono/oom-priority.test.d.ts.map +1 -0
  74. package/dist/hono/oom-priority.test.js +52 -0
  75. package/dist/hono/oom-priority.test.js.map +1 -0
  76. package/dist/hono/session-continuity.integration.test.js +5 -0
  77. package/dist/hono/session-continuity.integration.test.js.map +1 -1
  78. package/package.json +3 -2
package/README.md CHANGED
@@ -59,7 +59,7 @@ All variables are validated at startup via `@t3-oss/env-core` + `zod`.
59
59
 
60
60
  ## Credential broker (`baker-credential-broker`)
61
61
 
62
- A second bin, run as root in the sandbox before the agent starts, so the agent can use the user's stored credentials without ever seeing them. The agent writes `{{credential:NAME}}` in a request; the broker is an HTTP(S) proxy on `127.0.0.1` that swaps in the real value and swaps it back out of the response.
62
+ A second bin, run as root in the sandbox before the agent starts, so the agent can use the user's stored credentials without ever seeing them. A third, `baker-credential-broker-supervisor`, takes the same environment, runs the broker and starts it again whenever it exits, stops answering `GET /health`, or fails to start at all; on `SIGTERM` it stops the broker and kills it if it is still running 5 s later; it is what a Runtime starts. It runs out of the OOM killer's reach with the broker's heap capped, and the bridge marks every process its agent starts as the OOM killer's first choice — through a command wrapper it passes as `CLAUDE_CODE_SHELL_PREFIX` (unless the Runtime set one), backed by a 2-second scan — so memory pressure ends one command, never the turn. `src/hono/oom-priority.agent.test.ts` runs the SDK's own agent binary through the wrapper, so an upgrade that changes how it calls `CLAUDE_CODE_SHELL_PREFIX` fails the suite. The agent writes `{{credential:NAME}}` in a request; the broker is an HTTP(S) proxy on `127.0.0.1` that swaps in the real value and swaps it back out of the response.
63
63
 
64
64
  | Variable | Description |
65
65
  |---|---|
@@ -71,7 +71,7 @@ A second bin, run as root in the sandbox before the agent starts, so the agent c
71
71
 
72
72
  The agent's processes get `agentProxyEnv()`: `HTTP(S)_PROXY` pointing at the broker, `NO_PROXY` for loopback plus the model gateway, `NODE_USE_ENV_PROXY=1`, `NODE_EXTRA_CA_CERTS` set to the broker's CA, and `REQUESTS_CA_BUNDLE` / `SSL_CERT_FILE` / `CURL_CA_BUNDLE` set to the system bundle.
73
73
 
74
- Security model: a value is only substituted over https, and only for a host the user allowed for that credential. A placeholder in the URL or a header that is not allowed for the host, or that names no stored credential, is refused (403 / 404, or 503 while credentials can't be fetched) before anything leaves the sandbox. A placeholder that appears only in the body is left as plain text unless it names a credential allowed for that host. Response headers and text bodies up to 10 MB are scrubbed back to placeholders; those responses arrive buffered rather than streamed. The socket never returns a value.
74
+ Security model: a value is only substituted over https, and only for a host the user allowed for that credential. A placeholder in the URL or a header that is not allowed for the host, or that names no stored credential, is refused (403 / 404, or 503 while credentials can't be fetched) before anything leaves the sandbox. A placeholder that appears only in the body is left as plain text unless it names a credential allowed for that host. Response headers and text bodies up to 10 MB are scrubbed back to placeholders; those responses arrive buffered rather than streamed. The socket never returns a value. Once one fetch has succeeded, `/scrub` answers from the last good table while a refresh is in flight; the bridge retries a failed `/scrub` three times (0.25 s, 1 s, 3 s) before withholding a tool result.
75
75
 
76
76
  ## Session surface
77
77
 
@@ -307,7 +307,7 @@ Every turn also carries an in-process SDK MCP server named `baker_ui` hosting in
307
307
 
308
308
  A ChatGPT Ads tag pre-fills its Pixel ID and requests the optional Conversions API key in this secure form. The bridge classifies `apiKey` as a secret, so the agent never sees it and the published page receives only the Pixel ID and a signed server-event reference.
309
309
 
310
- Its second tool, `request_flow_input`, is the **blocking form-configuration form**: the agent invokes it to configure the confidential parts of a flow ("Form") it cannot author itself — side-effect credentials/connections (`encryptedConfig`, `oauthProviderId`) and widget third-party field definitions (`nodeData.form.external` for HubSpot/Calendly/HighLevel/SavvyCal). The agent authors the surrounding structure in `_data.json` and references it by `nodeId`/`sideEffectId`. Same `canUseTool` park pattern: the bridge POSTs `/api/chat/flow-input-request`, the dashboard renders a tabbed form (secret inputs / OAuth connect+account picker / live resource picker), and on submit Convex delivers the resolved values to `POST /flow-input-decision`. Unlike tags, the resolved values are written **into the branch flow file** through the encrypting `writeFlow` (read → patch node/side-effect → write); the model only ever sees a redacted result: `{ status, nodeId, sideEffectId?, secretFieldsSet, destination?, connected?, fields?, note? }`. `destination` is the non-secret half of what the user chose — the spreadsheet, the sheet, the portal, the Calendly event — so an agent that has just configured an integration does not have to spend a turn on `baker flows show --full` to learn what it configured, and does not map columns against a guess. For a widget node, `fields` carries the autofill keys the picked resource accepts — literally the left-hand side of an `autofilledFields` entry, adapter prefix included, so a SavvyCal custom field arrives as `questions.<id>` because that is what its adapter reads. They come from each provider's own field container (`fieldGroups[].fields[]`, `customQuestions[]`, `customParams.formFields[]`, `customFormFields[]`, `fields[]`, `customFields[]`) rather than from a search for name-shaped strings, so a select's option labels and the resource's own title are not among them (a HubSpot form's `name` is "Contact us"; it is reported under `destination`). A widget with no field list of its own returns none rather than a guess. Both targets go through the same filter: only plain strings and numbers are echoed, and anything in that type's secret list is redacted to a name in `secretFieldsSet`. A few non-secret keys are withheld from `destination` on top of that, because they are not an answer either — an `httpWebhook`'s basic-auth `username` is not a typed credential, so it is not in the secret list, but echoing it hands the model half a credential and nothing on the side effect is addressed by it. Leaked secret values in `prefilledConfig` are stripped bridge-side (and again backend-side). Live wait matches `AskUserQuestion` (15 min); like all blocking prompts, the form itself never expires — the thread parks and a later submission recovers the turn.
310
+ Its second tool, `request_flow_input`, is the **blocking form-configuration form**: the agent invokes it to configure the confidential parts of a flow ("Form") it cannot author itself — side-effect credentials/connections (`encryptedConfig`, `oauthProviderId`) and widget third-party field definitions (`nodeData.form.external` for HubSpot/Calendly/HighLevel/SavvyCal). The agent authors the surrounding structure in `_data.json` and references it by `nodeId`/`sideEffectId`. Same `canUseTool` park pattern: the bridge POSTs `/api/chat/flow-input-request`, the dashboard renders a tabbed form (secret inputs / OAuth connect+account picker / live resource picker), and on submit Convex delivers the resolved values to `POST /flow-input-decision`. Unlike tags, the resolved values are written **into the branch flow file** through the encrypting `writeFlow` (read → patch node/side-effect → write); the model only ever sees a redacted result: `{ status, nodeId, sideEffectId?, secretFieldsSet, destination?, connected?, fields?, note? }`. `destination` is the non-secret half of what the user chose — the spreadsheet, the sheet, the portal, the Calendly event — so an agent that has just configured an integration does not have to spend a turn on `baker flows show --full` to learn what it configured, and does not map columns against a guess. For a widget node, `fields` carries the autofill keys the picked resource accepts — literally the left-hand side of an `autofilledFields` entry, adapter prefix included, so a SavvyCal custom field arrives as `questions.<id>` because that is what its adapter reads. They come from each provider's own field container (`fieldGroups[].fields[]`, `customQuestions[]`, `customParams.formFields[]`, `customFormFields[]`, `fields[]`, `customFields[]`) rather than from a search for name-shaped strings, so a select's option labels and the resource's own title are not among them (a HubSpot form's `name` is "Contact us"; it is reported under `destination`). A widget with no field list of its own returns none rather than a guess. Both targets go through the same filter: only plain strings and numbers are echoed, and anything in that type's secret list is redacted to a name in `secretFieldsSet`. A few non-secret keys are withheld from `destination` on top of that, because they are not an answer either — an `httpWebhook`'s basic-auth `username` is not a typed credential, so it is not in the secret list, but echoing it hands the model half a credential and nothing on the side effect is addressed by it. Leaked secret values in `prefilledConfig` are stripped bridge-side (and again backend-side), and a call whose `prefilledConfig` names a key the side effect's card does not render (an email card reads `email` and `subject`, not `to`) is denied with the valid keys, because the card would drop it silently. Live wait matches `AskUserQuestion` (15 min); like all blocking prompts, the form itself never expires — the thread parks and a later submission recovers the turn.
311
311
 
312
312
  Its third tool, `request_connection`, is the **blocking connection request**: the agent invokes it when a data platform the task needs — Google Ads, LinkedIn Ads, Meta Ads, X Ads, Google Analytics 4, Google Search Console, or Google Tag Manager — is not connected yet, instead of telling the user to go to Settings. Same `canUseTool` park pattern: the bridge POSTs `/api/chat/connection-input-request`, the dashboard renders one tab per platform with the OAuth connect button and the account/property/site/container picker, and on submit Convex delivers the outcome to `POST /connection-input-decision`. Nothing confidential passes through the bridge or the model: the dashboard writes the selection onto the company's connection, and the resolution carries only `{ status, platform, accountLabel?, selected[] }`. A Google Drive tab may add `choose: "media-folder"` (kept only on Google Drive): the user picks a folder that Baker imports as a media source, and the connected result also carries its `mediaSourceKey`. An ad or data platform tab may add `pick: true` (kept only on platforms with accounts to choose): when the platform is already connected, the card opens its account picker straight away, for the agent that found the account it needs is not selected. Live wait matches `AskUserQuestion` (15 min).
313
313
 
@@ -0,0 +1,10 @@
1
+ import type { BrokerProcess } from "./supervisor.ts";
2
+ /**
3
+ * Starts the broker as a child of the supervisor. A spawn that fails (ENOENT,
4
+ * EAGAIN, EMFILE — likeliest under the memory pressure the supervisor exists
5
+ * for) emits `error` and possibly no `exit`; it settles `exited` all the same,
6
+ * so the supervisor's back-off retries it. A synchronous throw is the
7
+ * supervisor's to catch.
8
+ */
9
+ export declare function spawnBroker(command: string, args: readonly string[], env: NodeJS.ProcessEnv, log: (message: string) => void): BrokerProcess;
10
+ //# sourceMappingURL=broker-process.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"broker-process.d.ts","sourceRoot":"","sources":["../../src/broker/broker-process.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAc,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEjE;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,GAAG,EAAE,MAAM,CAAC,UAAU,EACtB,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAC7B,aAAa,CAUf"}
@@ -0,0 +1,20 @@
1
+ import { spawn } from "node:child_process";
2
+ /**
3
+ * Starts the broker as a child of the supervisor. A spawn that fails (ENOENT,
4
+ * EAGAIN, EMFILE — likeliest under the memory pressure the supervisor exists
5
+ * for) emits `error` and possibly no `exit`; it settles `exited` all the same,
6
+ * so the supervisor's back-off retries it. A synchronous throw is the
7
+ * supervisor's to catch.
8
+ */
9
+ export function spawnBroker(command, args, env, log) {
10
+ const child = spawn(command, args, { stdio: "inherit", env });
11
+ const exited = new Promise((resolve) => {
12
+ child.once("exit", (code, signal) => resolve({ code, signal }));
13
+ child.once("error", (error) => {
14
+ log(`could not start broker: ${error.message}`);
15
+ resolve({ code: null, signal: null });
16
+ });
17
+ });
18
+ return { exited, kill: (signal) => void child.kill(signal) };
19
+ }
20
+ //# sourceMappingURL=broker-process.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"broker-process.js","sourceRoot":"","sources":["../../src/broker/broker-process.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAG3C;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CACzB,OAAe,EACf,IAAuB,EACvB,GAAsB,EACtB,GAA8B;IAE9B,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC;IAC9D,MAAM,MAAM,GAAG,IAAI,OAAO,CAAa,CAAC,OAAO,EAAE,EAAE;QACjD,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;QAChE,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YAC5B,GAAG,CAAC,2BAA2B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YAChD,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;AAC/D,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=broker-process.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"broker-process.test.d.ts","sourceRoot":"","sources":["../../src/broker/broker-process.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,13 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { spawnBroker } from "./broker-process.js";
3
+ describe("spawnBroker", () => {
4
+ // Node reports ENOENT, EAGAIN and EMFILE as an `error` event, with no `exit`
5
+ // after it: unheard, it crashed the supervisor; heard, it is a broker that exited.
6
+ it("reports a broker that could not be spawned as one that exited, with the reason", async () => {
7
+ const reasons = [];
8
+ const broker = spawnBroker("/nonexistent/node", [], {}, (line) => reasons.push(line));
9
+ await expect(broker.exited).resolves.toEqual({ code: null, signal: null });
10
+ expect(reasons.join("")).toContain("ENOENT");
11
+ });
12
+ });
13
+ //# sourceMappingURL=broker-process.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"broker-process.test.js","sourceRoot":"","sources":["../../src/broker/broker-process.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAElD,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,6EAA6E;IAC7E,mFAAmF;IACnF,EAAE,CAAC,gFAAgF,EAAE,KAAK,IAAI,EAAE;QAC9F,MAAM,OAAO,GAAa,EAAE,CAAC;QAE7B,MAAM,MAAM,GAAG,WAAW,CAAC,mBAAmB,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAEtF,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3E,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"credential-cache.d.ts","sourceRoot":"","sources":["../../src/broker/credential-cache.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE/D,eAAO,MAAM,iBAAiB,QAAS,CAAC;AACxC,6GAA6G;AAC7G,eAAO,MAAM,uBAAuB,OAAQ,CAAC;AAE7C,MAAM,MAAM,gBAAgB,GAAG,MAAM,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;AAEnE,MAAM,MAAM,eAAe,GAAG;IAC5B,GAAG,IAAI,OAAO,CAAC,kBAAkB,EAAE,GAAG,IAAI,CAAC,CAAC;IAC5C,+EAA+E;IAC/E,UAAU,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAC5C;;;OAGG;IACH,OAAO,IAAI,OAAO,CAAC;IACnB,yEAAyE;IACzE,IAAI,IAAI,MAAM,CAAC;CAChB,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,OAAO,EAAE;IAC7C,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC,GAAG,eAAe,CAsDlB"}
1
+ {"version":3,"file":"credential-cache.d.ts","sourceRoot":"","sources":["../../src/broker/credential-cache.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE/D,eAAO,MAAM,iBAAiB,QAAS,CAAC;AACxC,6GAA6G;AAC7G,eAAO,MAAM,uBAAuB,OAAQ,CAAC;AAE7C,MAAM,MAAM,gBAAgB,GAAG,MAAM,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;AAEnE,MAAM,MAAM,eAAe,GAAG;IAC5B,GAAG,IAAI,OAAO,CAAC,kBAAkB,EAAE,GAAG,IAAI,CAAC,CAAC;IAC5C,+EAA+E;IAC/E,UAAU,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAC5C;;;OAGG;IACH,OAAO,IAAI,OAAO,CAAC;IACnB,yEAAyE;IACzE,IAAI,IAAI,MAAM,CAAC;CAChB,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,OAAO,EAAE;IAC7C,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC,GAAG,eAAe,CA0DlB"}
@@ -6,6 +6,9 @@
6
6
  * has succeeded there is no table (null), which callers must treat as
7
7
  * "credentials unavailable", not "no credentials".
8
8
  *
9
+ * A scrub uses the last good table while a refresh is in flight, so a slow
10
+ * Baker never holds a tool result back once one fetch has succeeded.
11
+ *
9
12
  * A value that leaves the table — refused or removed — may still be on its
10
13
  * way back in a response to a request that carried it, so `scrubbable()`
11
14
  * keeps scrubbing it for the broker's lifetime. It is never sent again.
@@ -52,7 +55,11 @@ export function createCredentialCache(options) {
52
55
  return {
53
56
  get,
54
57
  async scrubbable() {
55
- return [...((await get()) ?? []), ...retired.values()];
58
+ const pending = get();
59
+ // A scrub never waits on a refresh it can do without: the last good table
60
+ // still covers every value the proxy could have sent.
61
+ const table = lastGood ?? (await pending);
62
+ return [...(table ?? []), ...retired.values()];
56
63
  },
57
64
  refresh() {
58
65
  if (now() - lastRefreshAt < MIN_REFRESH_INTERVAL_MS)
@@ -1 +1 @@
1
- {"version":3,"file":"credential-cache.js","sourceRoot":"","sources":["../../src/broker/credential-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAGpD,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC;AACxC,6GAA6G;AAC7G,MAAM,CAAC,MAAM,uBAAuB,GAAG,KAAK,CAAC;AAiB7C,MAAM,UAAU,qBAAqB,CAAC,OAKrC;IACC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACpC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,iBAAiB,CAAC;IACjD,IAAI,KAAK,GAAuE,IAAI,CAAC;IACrF,IAAI,QAAQ,GAAgC,IAAI,CAAC;IACjD,IAAI,aAAa,GAAG,MAAM,CAAC,iBAAiB,CAAC;IAC7C,MAAM,OAAO,GAAG,IAAI,GAAG,EAA8B,CAAC;IAEtD,SAAS,YAAY,CAAC,IAAiC;QACrD,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;QAClE,KAAK,MAAM,UAAU,IAAI,QAAQ,IAAI,EAAE,EAAE,CAAC;YACxC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC;gBAAE,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;QAC7E,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,IAAI;YAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAChD,QAAQ,GAAG,IAAI,CAAC;IAClB,CAAC;IAED,SAAS,GAAG;QACV,IAAI,KAAK,KAAK,IAAI,IAAI,GAAG,EAAE,GAAG,KAAK,CAAC,EAAE,IAAI,KAAK,EAAE,CAAC;YAChD,MAAM,KAAK,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,IAAI,CAC3C,CAAC,WAAW,EAAE,EAAE;gBACd,YAAY,CAAC,WAAW,CAAC,CAAC;gBAC1B,OAAO,WAAW,CAAC;YACrB,CAAC,EACD,CAAC,KAAc,EAAE,EAAE;gBACjB,IAAI,KAAK,YAAY,kBAAkB,EAAE,CAAC;oBACxC,OAAO,CAAC,GAAG,EAAE,CAAC,GAAG,KAAK,CAAC,OAAO,cAAc,QAAQ,EAAE,MAAM,IAAI,CAAC,qBAAqB,CAAC,CAAC;oBACxF,YAAY,CAAC,IAAI,CAAC,CAAC;oBACnB,OAAO,IAAI,CAAC;gBACd,CAAC;gBACD,OAAO,CAAC,GAAG,EAAE,CAAC,oCAAoC,QAAQ,EAAE,MAAM,IAAI,CAAC,YAAY,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBACpG,OAAO,QAAQ,CAAC;YAClB,CAAC,CACF,CAAC;YACF,KAAK,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC;QAC/B,CAAC;QACD,OAAO,KAAK,CAAC,KAAK,CAAC;IACrB,CAAC;IAED,OAAO;QACL,GAAG;QACH,KAAK,CAAC,UAAU;YACd,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QACzD,CAAC;QACD,OAAO;YACL,IAAI,GAAG,EAAE,GAAG,aAAa,GAAG,uBAAuB;gBAAE,OAAO,KAAK,CAAC;YAClE,aAAa,GAAG,GAAG,EAAE,CAAC;YACtB,KAAK,GAAG,IAAI,CAAC;YACb,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI;YACF,OAAO,QAAQ,EAAE,MAAM,IAAI,CAAC,CAAC;QAC/B,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"credential-cache.js","sourceRoot":"","sources":["../../src/broker/credential-cache.ts"],"names":[],"mappings":"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"}
@@ -92,6 +92,22 @@ describe("createCredentialCache", () => {
92
92
  expect(afterRefusal.sort()).toEqual(["ads-secret-value", "shop-secret-value"]);
93
93
  expect(await cache.get()).toBeNull();
94
94
  });
95
+ it("scrubs with the last good table while a slow refresh is still in flight", async () => {
96
+ let clock = 0;
97
+ let hang = false;
98
+ const cache = createCredentialCache({
99
+ fetchCredentials: () => hang
100
+ ? new Promise(() => {
101
+ // Baker never answers.
102
+ })
103
+ : Promise.resolve([{ name: "shop", value: "secret-value", allowedHosts: ["api.example.com"] }]),
104
+ now: () => clock,
105
+ });
106
+ await cache.get();
107
+ hang = true;
108
+ clock = 10_000;
109
+ expect((await cache.scrubbable()).map((credential) => credential.name)).toEqual(["shop"]);
110
+ });
95
111
  it("fetches again on the next read after a refresh", async () => {
96
112
  const source = fetcher();
97
113
  const cache = createCredentialCache({ fetchCredentials: source.fetchCredentials, now: () => 0 });
@@ -1 +1 @@
1
- {"version":3,"file":"credential-cache.test.js","sourceRoot":"","sources":["../../src/broker/credential-cache.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"credential-cache.test.js","sourceRoot":"","sources":["../../src/broker/credential-cache.test.ts"],"names":[],"mappings":"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"}
@@ -15,5 +15,7 @@ export declare function parseBrokerEnv(env?: NodeJS.ProcessEnv): z.ZodSafeParseR
15
15
  BAKER_CA_DIR: string;
16
16
  BAKER_BROKER_SOCKET: string;
17
17
  }>;
18
+ /** The supervisor's own environment for the broker it starts, with `NODE_OPTIONS` set. */
19
+ export declare function brokerChildEnv(nodeOptions: string, env?: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
18
20
  export {};
19
21
  //# sourceMappingURL=env.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/broker/env.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,QAAA,MAAM,SAAS;;;;;;iBAMb,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAC;AAElD,wBAAgB,cAAc,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB;;;;;;GAElE"}
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/broker/env.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,QAAA,MAAM,SAAS;;;;;;iBAMb,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAC;AAElD,wBAAgB,cAAc,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB;;;;;;GAElE;AAED,0FAA0F;AAC1F,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAAC,UAAU,CAE3G"}
@@ -13,4 +13,8 @@ const envSchema = z.object({
13
13
  export function parseBrokerEnv(env = process.env) {
14
14
  return envSchema.safeParse(env);
15
15
  }
16
+ /** The supervisor's own environment for the broker it starts, with `NODE_OPTIONS` set. */
17
+ export function brokerChildEnv(nodeOptions, env = process.env) {
18
+ return { ...env, NODE_OPTIONS: nodeOptions };
19
+ }
16
20
  //# sourceMappingURL=env.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/broker/env.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC;IACzB,uBAAuB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1C,qBAAqB,EAAE,CAAC,CAAC,GAAG,EAAE;IAC9B,2BAA2B,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAAC;IACnG,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC;IACvD,mBAAmB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,qBAAqB,CAAC;CACtE,CAAC,CAAC;AAIH,MAAM,UAAU,cAAc,CAAC,GAAG,GAAsB,OAAO,CAAC,GAAG;IACjE,OAAO,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;AAClC,CAAC"}
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/broker/env.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC;IACzB,uBAAuB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1C,qBAAqB,EAAE,CAAC,CAAC,GAAG,EAAE;IAC9B,2BAA2B,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAAC;IACnG,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC;IACvD,mBAAmB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,qBAAqB,CAAC;CACtE,CAAC,CAAC;AAIH,MAAM,UAAU,cAAc,CAAC,GAAG,GAAsB,OAAO,CAAC,GAAG;IACjE,OAAO,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;AAClC,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,cAAc,CAAC,WAAmB,EAAE,GAAG,GAAsB,OAAO,CAAC,GAAG;IACtF,OAAO,EAAE,GAAG,GAAG,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC;AAC/C,CAAC"}
@@ -37,12 +37,18 @@ async function main() {
37
37
  const port = await broker.start();
38
38
  await socket.listen();
39
39
  log(`listening on 127.0.0.1:${port}, socket ${env.BAKER_BROKER_SOCKET}`);
40
+ // A stop signals the broker twice — once directly, once from its supervisor —
41
+ // and a second signal with no handler would kill it before it removes its socket.
42
+ let stopping = false;
40
43
  const shutdown = async () => {
44
+ if (stopping)
45
+ return;
46
+ stopping = true;
41
47
  await Promise.allSettled([socket.close(), broker.stop()]);
42
48
  process.exit(0);
43
49
  };
44
- process.once("SIGTERM", () => void shutdown());
45
- process.once("SIGINT", () => void shutdown());
50
+ process.on("SIGTERM", () => void shutdown());
51
+ process.on("SIGINT", () => void shutdown());
46
52
  }
47
53
  main().catch((error) => {
48
54
  log(`failed to start: ${error instanceof Error ? error.message : String(error)}`);
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/broker/main.ts"],"names":[],"mappings":";AACA;;;;;GAKG;AACH,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,0BAA0B,EAAE,MAAM,SAAS,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1D,SAAS,GAAG,CAAC,OAAe;IAC1B,OAAO,CAAC,KAAK,CAAC,uBAAuB,OAAO,EAAE,CAAC,CAAC;AAClD,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,cAAc,EAAE,CAAC;IAChC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,GAAG,CAAC,wBAAwB,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACnG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC;IACxB,MAAM,GAAG,GAAG,oBAAoB,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,qBAAqB,EAAE,KAAK,EAAE,GAAG,CAAC,uBAAuB,EAAE,CAAC,CAAC;IAC7G,MAAM,EAAE,GAAG,MAAM,0BAA0B,CAAC;QAC1C,GAAG,EAAE,GAAG,CAAC,YAAY;QACrB,kBAAkB,EAAE,OAAO,CAAC,MAAM,EAAE,EAAE,KAAK,CAAC;QAC5C,GAAG;KACJ,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,YAAY,CAAC;QAC1B,EAAE;QACF,IAAI,EAAE,GAAG,CAAC,2BAA2B;QACrC,gBAAgB,EAAE,GAAG,CAAC,gBAAgB;QACtC,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,GAAG;KACJ,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,mBAAmB,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,CAAC,mBAAmB,EAAE,GAAG,EAAE,CAAC,CAAC;IACtG,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IAClC,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC;IACtB,GAAG,CAAC,0BAA0B,IAAI,YAAY,GAAG,CAAC,mBAAmB,EAAE,CAAC,CAAC;IAEzE,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;QAC1B,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAC1D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,EAAE,CAAC,CAAC;IAC/C,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,EAAE,CAAC,CAAC;AAChD,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;IAC9B,GAAG,CAAC,oBAAoB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/broker/main.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"socket-service.d.ts","sourceRoot":"","sources":["../../src/broker/socket-service.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAI7D,eAAO,MAAM,uBAAuB,QAAkB,CAAC;AAmBvD,MAAM,MAAM,aAAa,GAAG;IAAE,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAAC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC;AA6BhF,wBAAgB,mBAAmB,CAAC,OAAO,EAAE;IAC3C,KAAK,EAAE,eAAe,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,sGAAsG;IACtG,UAAU,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IACrD,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC,GAAG,aAAa,CAyChB"}
1
+ {"version":3,"file":"socket-service.d.ts","sourceRoot":"","sources":["../../src/broker/socket-service.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAI7D,eAAO,MAAM,uBAAuB,QAAkB,CAAC;AA0BvD,MAAM,MAAM,aAAa,GAAG;IAAE,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAAC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC;AA6BhF,wBAAgB,mBAAmB,CAAC,OAAO,EAAE;IAC3C,KAAK,EAAE,eAAe,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,sGAAsG;IACtG,UAAU,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IACrD,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC,GAAG,aAAa,CA4ChB"}
@@ -15,7 +15,14 @@ import { z } from "zod";
15
15
  import { scrub } from "./credential-text.js";
16
16
  import { createTokenBucket } from "./token-bucket.js";
17
17
  export const MAX_SCRUB_REQUEST_BYTES = 2 * 1024 * 1024;
18
- const DEFAULT_SCRUB_BYTES = { capacity: 8 * 1024 * 1024, perSecond: 256 * 1024 };
18
+ /**
19
+ * Sized for dozens of agents reading at once, not for one: every agent's tool
20
+ * results share this budget. It only bounds runaway use; what keeps the socket
21
+ * from being an oracle is that it confirms no value a wordlist could reach
22
+ * (`resistsGuessing`). At 256 KB/s a 20-agent run withheld 40% of its results.
23
+ */
24
+ const DEFAULT_SCRUB_BYTES = { capacity: 256 * 1024 * 1024, perSecond: 64 * 1024 * 1024 };
25
+ const DEFAULT_REQUESTS_PER_SECOND = 1_000;
19
26
  const scrubRequestSchema = z.object({ text: z.string() });
20
27
  /** Bits a value must carry — its length times its per-character entropy — before `/scrub` may confirm it. */
21
28
  const MIN_SCRUB_BITS = 64;
@@ -57,7 +64,10 @@ function send(res, status, body) {
57
64
  res.end(JSON.stringify(body));
58
65
  }
59
66
  export function createSocketService(options) {
60
- const bucket = createTokenBucket({ ratePerSecond: options.ratePerSecond ?? 50, burst: options.ratePerSecond ?? 50 });
67
+ const bucket = createTokenBucket({
68
+ ratePerSecond: options.ratePerSecond ?? DEFAULT_REQUESTS_PER_SECOND,
69
+ burst: options.ratePerSecond ?? DEFAULT_REQUESTS_PER_SECOND,
70
+ });
61
71
  const scrubBytes = options.scrubBytes ?? DEFAULT_SCRUB_BYTES;
62
72
  const bytes = createTokenBucket({ ratePerSecond: scrubBytes.perSecond, burst: scrubBytes.capacity });
63
73
  async function handle(req, res) {
@@ -1 +1 @@
1
- {"version":3,"file":"socket-service.js","sourceRoot":"","sources":["../../src/broker/socket-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"socket-service.js","sourceRoot":"","sources":["../../src/broker/socket-service.ts"],"names":[],"mappings":"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"}
@@ -59,6 +59,13 @@ describe("broker socket service", () => {
59
59
  expect(JSON.parse(health)).toEqual({ ok: true, credentials: 2 });
60
60
  expect(health).not.toContain(VALUE);
61
61
  });
62
+ it("keeps up with dozens of agents whose tool results all arrive at once", async () => {
63
+ // A 20-researcher run withheld 40% of its results on a 256 KB/s budget, with the broker healthy.
64
+ const { socketPath } = await start();
65
+ const result = `${"r".repeat(1024 * 1024 - 64)} ${VALUE}`;
66
+ const scrubbed = await Promise.all(Array.from({ length: 80 }, () => scrubViaBroker(result, { socketPath, timeoutMs: 30_000 })));
67
+ expect(scrubbed.every((text) => text.endsWith(" {{credential:shop}}"))).toBe(true);
68
+ });
62
69
  it("answers 429 once a caller has sent more text than its byte budget allows", async () => {
63
70
  const { socketPath } = await start({ scrubBytes: { capacity: 100, perSecond: 1 } });
64
71
  const text = "x".repeat(60);
@@ -1 +1 @@
1
- {"version":3,"file":"socket-service.test.js","sourceRoot":"","sources":["../../src/broker/socket-service.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"socket-service.test.js","sourceRoot":"","sources":["../../src/broker/socket-service.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=supervisor-main.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supervisor-main.d.ts","sourceRoot":"","sources":["../../src/broker/supervisor-main.ts"],"names":[],"mappings":""}
@@ -0,0 +1,70 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * `baker-credential-broker-supervisor` — what Runtime activation starts, as
4
+ * root: it runs `baker-credential-broker` and starts it again whenever it
5
+ * exits or stops answering on its socket (`superviseBroker`). Its command line
6
+ * names the same install as the broker's, so the activation's stop reaches both.
7
+ */
8
+ import { writeFileSync } from "node:fs";
9
+ import { request } from "node:http";
10
+ import { fileURLToPath } from "node:url";
11
+ import { spawnBroker } from "./broker-process.js";
12
+ import { brokerChildEnv, parseBrokerEnv } from "./env.js";
13
+ import { superviseBroker } from "./supervisor.js";
14
+ const BROKER_MAIN = fileURLToPath(new URL("./main.js", import.meta.url));
15
+ const HEALTH_TIMEOUT_MS = 2_000;
16
+ function log(message) {
17
+ console.error(`[credential-broker-supervisor] ${message}`);
18
+ }
19
+ // Parsed only for the socket path; the broker it starts inherits this environment and parses it again.
20
+ const parsed = parseBrokerEnv();
21
+ if (!parsed.success) {
22
+ log(`invalid environment: ${parsed.error.issues.map((issue) => issue.path.join(".")).join(", ")}`);
23
+ process.exit(1);
24
+ }
25
+ const SOCKET = parsed.data.BAKER_BROKER_SOCKET;
26
+ /**
27
+ * Out of the OOM killer's reach, and its brokers with it (the setting is
28
+ * inherited). With every process at the same score the kernel kills the
29
+ * biggest, and a busy broker was it: a 20-agent run filled the sandbox's 8 GB
30
+ * with the agent's own commands, the broker died, and the turn could read
31
+ * nothing more. The bridge marks the agent's commands as the ones to kill.
32
+ */
33
+ try {
34
+ writeFileSync("/proc/self/oom_score_adj", "-1000");
35
+ }
36
+ catch (error) {
37
+ log(`could not leave the OOM killer's reach: ${error instanceof Error ? error.message : String(error)}`);
38
+ }
39
+ /**
40
+ * Its heap, capped: V8 otherwise lets garbage pile up to hundreds of MB before
41
+ * collecting, and memory the broker holds is memory the agent's commands lack.
42
+ * 40 agents scrubbing at once fit in a 64 MB heap; a 10 MB proxied body needs room too.
43
+ */
44
+ const BROKER_NODE_OPTIONS = "--max-old-space-size=192";
45
+ function healthy() {
46
+ return new Promise((resolve) => {
47
+ const req = request({ socketPath: SOCKET, path: "/health", method: "GET", timeout: HEALTH_TIMEOUT_MS }, (res) => {
48
+ res.resume();
49
+ resolve(res.statusCode === 200);
50
+ });
51
+ req.on("timeout", () => req.destroy());
52
+ req.on("error", () => resolve(false));
53
+ req.end();
54
+ });
55
+ }
56
+ const supervisor = superviseBroker({
57
+ start: () => spawnBroker(process.execPath, [BROKER_MAIN], brokerChildEnv(BROKER_NODE_OPTIONS), log),
58
+ healthy,
59
+ log,
60
+ });
61
+ let stopping = false;
62
+ for (const signal of ["SIGTERM", "SIGINT"]) {
63
+ process.on(signal, () => {
64
+ if (stopping)
65
+ return;
66
+ stopping = true;
67
+ void supervisor.stop(signal).then(() => process.exit(0));
68
+ });
69
+ }
70
+ //# sourceMappingURL=supervisor-main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supervisor-main.js","sourceRoot":"","sources":["../../src/broker/supervisor-main.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Keeps the credential broker running for the life of the Runtime.
3
+ *
4
+ * The bridge withholds every tool result it cannot have scrubbed, and it takes
5
+ * the socket file's existence to mean a broker is running. A broker that dies
6
+ * hard (the kernel's OOM killer, a crash) leaves that file behind, and one that
7
+ * hangs keeps it open; either way, without a supervisor every result is
8
+ * withheld until the next activation — a whole turn.
9
+ */
10
+ export type BrokerExit = {
11
+ code: number | null;
12
+ signal: NodeJS.Signals | null;
13
+ };
14
+ export type BrokerProcess = {
15
+ exited: Promise<BrokerExit>;
16
+ kill(signal: NodeJS.Signals): void;
17
+ };
18
+ export declare function superviseBroker(options: {
19
+ start: () => BrokerProcess;
20
+ healthy: () => Promise<boolean>;
21
+ log?: (message: string) => void;
22
+ }): {
23
+ stop(signal: NodeJS.Signals): Promise<BrokerExit>;
24
+ };
25
+ //# sourceMappingURL=supervisor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supervisor.d.ts","sourceRoot":"","sources":["../../src/broker/supervisor.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,MAAM,UAAU,GAAG;IAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAA;CAAE,CAAC;AAChF,MAAM,MAAM,aAAa,GAAG;IAAE,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;IAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAA;CAAE,CAAC;AAkBhG,wBAAgB,eAAe,CAAC,OAAO,EAAE;IACvC,KAAK,EAAE,MAAM,aAAa,CAAC;IAC3B,OAAO,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAChC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC,GAAG;IAAE,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;CAAE,CAuExD"}
@@ -0,0 +1,88 @@
1
+ const HEALTH_INTERVAL_MS = 5_000;
2
+ /** Consecutive missed health checks before a live broker is taken for hung. */
3
+ const UNHEALTHY_AFTER = 3;
4
+ /** A broker that has never answered gets this long to start (a first start writes its CA). */
5
+ const STARTUP_GRACE_MS = 30_000;
6
+ /** Pauses before each restart in a row; a broker that exits as soon as it starts is retried ever more slowly, never given up on. */
7
+ const RESTART_DELAYS_MS = [250, 1_000, 2_000, 5_000, 10_000, 30_000];
8
+ /** A broker still running this long after the stop signal is killed. */
9
+ const STOP_GRACE_MS = 5_000;
10
+ /** A broker that ran this long was not crash-looping: the next restart is quick again. */
11
+ const STABLE_AFTER_MS = 60_000;
12
+ function describeExit(exit) {
13
+ return exit.signal === null ? `code ${exit.code}` : `signal ${exit.signal}`;
14
+ }
15
+ export function superviseBroker(options) {
16
+ let stopping = false;
17
+ let restarts = 0;
18
+ /** A broker that could not be spawned (ENOMEM, EAGAIN under memory pressure) is one that exited at once. */
19
+ function startOrFail() {
20
+ try {
21
+ return options.start();
22
+ }
23
+ catch (error) {
24
+ options.log?.(`could not start broker: ${error instanceof Error ? error.message : String(error)}`);
25
+ return { exited: Promise.resolve({ code: null, signal: null }), kill: () => undefined };
26
+ }
27
+ }
28
+ function run() {
29
+ const broker = startOrFail();
30
+ const startedAt = Date.now();
31
+ let answered = false;
32
+ let missed = 0;
33
+ let probing = false;
34
+ const watchdog = setInterval(() => {
35
+ if (probing)
36
+ return;
37
+ probing = true;
38
+ void options
39
+ .healthy()
40
+ .catch(() => false)
41
+ .then((ok) => {
42
+ probing = false;
43
+ if (ok) {
44
+ answered = true;
45
+ missed = 0;
46
+ return;
47
+ }
48
+ if (!answered && Date.now() - startedAt < STARTUP_GRACE_MS)
49
+ return;
50
+ missed += 1;
51
+ if (missed >= UNHEALTHY_AFTER) {
52
+ options.log?.(`broker missed ${missed} health checks in a row; killing it`);
53
+ broker.kill("SIGKILL");
54
+ }
55
+ });
56
+ }, HEALTH_INTERVAL_MS);
57
+ void broker.exited.then((exit) => {
58
+ clearInterval(watchdog);
59
+ if (stopping)
60
+ return;
61
+ const ranMs = Date.now() - startedAt;
62
+ if (ranMs >= STABLE_AFTER_MS)
63
+ restarts = 0;
64
+ const delay = RESTART_DELAYS_MS[Math.min(restarts, RESTART_DELAYS_MS.length - 1)];
65
+ restarts += 1;
66
+ options.log?.(`broker exited (${describeExit(exit)}) after ${Math.round(ranMs / 1000)}s; restarting in ${delay}ms`);
67
+ setTimeout(() => {
68
+ if (!stopping)
69
+ current = run();
70
+ }, delay);
71
+ });
72
+ return broker;
73
+ }
74
+ let current = run();
75
+ return {
76
+ stop(signal) {
77
+ stopping = true;
78
+ const broker = current;
79
+ broker.kill(signal);
80
+ const escalate = setTimeout(() => {
81
+ options.log?.(`broker still running ${STOP_GRACE_MS}ms after ${signal}; killing it`);
82
+ broker.kill("SIGKILL");
83
+ }, STOP_GRACE_MS);
84
+ return broker.exited.finally(() => clearTimeout(escalate));
85
+ },
86
+ };
87
+ }
88
+ //# sourceMappingURL=supervisor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supervisor.js","sourceRoot":"","sources":["../../src/broker/supervisor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=supervisor.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supervisor.test.d.ts","sourceRoot":"","sources":["../../src/broker/supervisor.test.ts"],"names":[],"mappings":""}