harness-dispatch 0.9.0 → 0.10.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 +560 -1
- package/README.md +74 -43
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js.map +1 -1
- package/dist/bin.d.ts.map +1 -1
- package/dist/bin.js +166 -29
- package/dist/bin.js.map +1 -1
- package/dist/config/coercions.d.ts +5 -0
- package/dist/config/coercions.d.ts.map +1 -1
- package/dist/config/coercions.js +8 -0
- package/dist/config/coercions.js.map +1 -1
- package/dist/config/protocol.js.map +1 -1
- package/dist/config/validation.d.ts.map +1 -1
- package/dist/config/validation.js.map +1 -1
- package/dist/config.d.ts +11 -3
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +111 -148
- package/dist/config.js.map +1 -1
- package/dist/configure-yaml.d.ts.map +1 -1
- package/dist/configure-yaml.js +57 -13
- package/dist/configure-yaml.js.map +1 -1
- package/dist/dispatch-log.d.ts.map +1 -1
- package/dist/dispatch-log.js +3 -1
- package/dist/dispatch-log.js.map +1 -1
- package/dist/dispatchers/generic-cli.d.ts.map +1 -1
- package/dist/dispatchers/generic-cli.js +189 -97
- package/dist/dispatchers/generic-cli.js.map +1 -1
- package/dist/dispatchers/openai-compatible.d.ts +0 -5
- package/dist/dispatchers/openai-compatible.d.ts.map +1 -1
- package/dist/dispatchers/openai-compatible.js +129 -82
- package/dist/dispatchers/openai-compatible.js.map +1 -1
- package/dist/dispatchers/shared/harness-login.d.ts.map +1 -1
- package/dist/dispatchers/shared/harness-login.js +7 -2
- package/dist/dispatchers/shared/harness-login.js.map +1 -1
- package/dist/dispatchers/shared/stream-subprocess.d.ts.map +1 -1
- package/dist/dispatchers/shared/stream-subprocess.js +7 -60
- package/dist/dispatchers/shared/stream-subprocess.js.map +1 -1
- package/dist/file-lock.d.ts.map +1 -1
- package/dist/file-lock.js +31 -19
- package/dist/file-lock.js.map +1 -1
- package/dist/harness-presets.d.ts +51 -0
- package/dist/harness-presets.d.ts.map +1 -0
- package/dist/harness-presets.js +154 -0
- package/dist/harness-presets.js.map +1 -0
- package/dist/http/parse.d.ts +8 -1
- package/dist/http/parse.d.ts.map +1 -1
- package/dist/http/parse.js +10 -3
- package/dist/http/parse.js.map +1 -1
- package/dist/http/server.d.ts.map +1 -1
- package/dist/http/server.js +9 -2
- package/dist/http/server.js.map +1 -1
- package/dist/job-runner.js +6 -0
- package/dist/job-runner.js.map +1 -1
- package/dist/jobs/lifecycle.d.ts +100 -0
- package/dist/jobs/lifecycle.d.ts.map +1 -0
- package/dist/jobs/lifecycle.js +263 -0
- package/dist/jobs/lifecycle.js.map +1 -0
- package/dist/jobs/read.d.ts +17 -0
- package/dist/jobs/read.d.ts.map +1 -0
- package/dist/jobs/read.js +103 -0
- package/dist/jobs/read.js.map +1 -0
- package/dist/jobs/run.d.ts +45 -0
- package/dist/jobs/run.d.ts.map +1 -0
- package/dist/jobs/run.js +351 -0
- package/dist/jobs/run.js.map +1 -0
- package/dist/jobs/start.d.ts +9 -0
- package/dist/jobs/start.d.ts.map +1 -0
- package/dist/jobs/start.js +126 -0
- package/dist/jobs/start.js.map +1 -0
- package/dist/jobs/store.d.ts.map +1 -1
- package/dist/jobs/store.js +13 -3
- package/dist/jobs/store.js.map +1 -1
- package/dist/jobs/supervisor.d.ts +151 -0
- package/dist/jobs/supervisor.d.ts.map +1 -0
- package/dist/jobs/supervisor.js +679 -0
- package/dist/jobs/supervisor.js.map +1 -0
- package/dist/jobs.d.ts +15 -233
- package/dist/jobs.d.ts.map +1 -1
- package/dist/jobs.js +14 -1409
- package/dist/jobs.js.map +1 -1
- package/dist/leaderboard.d.ts.map +1 -1
- package/dist/leaderboard.js +5 -1
- package/dist/leaderboard.js.map +1 -1
- package/dist/mcp/config-hot-reload.d.ts.map +1 -1
- package/dist/mcp/config-hot-reload.js +4 -1
- package/dist/mcp/config-hot-reload.js.map +1 -1
- package/dist/mcp/dispatcher-factory.js +1 -1
- package/dist/mcp/dispatcher-factory.js.map +1 -1
- package/dist/mcp/resources.d.ts.map +1 -1
- package/dist/mcp/resources.js +3 -2
- package/dist/mcp/resources.js.map +1 -1
- package/dist/mcp/tools.d.ts +9 -2
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +45 -6
- package/dist/mcp/tools.js.map +1 -1
- package/dist/observability/spans.d.ts.map +1 -1
- package/dist/observability/spans.js +10 -2
- package/dist/observability/spans.js.map +1 -1
- package/dist/redaction.d.ts +90 -0
- package/dist/redaction.d.ts.map +1 -0
- package/dist/redaction.js +221 -0
- package/dist/redaction.js.map +1 -0
- package/dist/router.d.ts +12 -23
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +83 -224
- package/dist/router.js.map +1 -1
- package/dist/state-dir.d.ts.map +1 -1
- package/dist/state-dir.js +15 -1
- package/dist/state-dir.js.map +1 -1
- package/dist/status.d.ts +14 -3
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +36 -3
- package/dist/status.js.map +1 -1
- package/dist/workspace-lock.d.ts +20 -0
- package/dist/workspace-lock.d.ts.map +1 -1
- package/dist/workspace-lock.js +63 -0
- package/dist/workspace-lock.js.map +1 -1
- package/dist/workspace-resolve.d.ts +0 -9
- package/dist/workspace-resolve.d.ts.map +1 -1
- package/dist/workspace-resolve.js +38 -183
- package/dist/workspace-resolve.js.map +1 -1
- package/dist/workspaces.d.ts.map +1 -1
- package/dist/workspaces.js +63 -139
- package/dist/workspaces.js.map +1 -1
- package/package.json +5 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spans.js","sourceRoot":"","sources":["../../src/observability/spans.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,cAAc,EAAE,KAAK,EAA8B,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"spans.js","sourceRoot":"","sources":["../../src/observability/spans.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One place that knows every secret this process holds, and one function that
|
|
3
|
+
* removes them from anything on its way out.
|
|
4
|
+
*
|
|
5
|
+
* WHY THIS EXISTS, because the alternative was tried six times and failed six
|
|
6
|
+
* times. The same defect — a configured credential reaching a caller, a log
|
|
7
|
+
* file or an agent's context — was found and "fixed" in six consecutive
|
|
8
|
+
* rounds. Every fix was correct. Every fix was also incomplete, because each
|
|
9
|
+
* one scrubbed at a SITE: a specific error path in a specific file. Four of
|
|
10
|
+
* the six were found as "the fix landed in one branch and the sibling beside
|
|
11
|
+
* it kept leaking", twice inside a single file. One round shipped a comment
|
|
12
|
+
* asserting that every branch was covered while a branch was not.
|
|
13
|
+
*
|
|
14
|
+
* Sites are the wrong unit. There is no bounded list of places a string can be
|
|
15
|
+
* built, and a new one is added by ordinary feature work with no reason for
|
|
16
|
+
* its author to think about credentials. What IS bounded is the set of ways a
|
|
17
|
+
* string leaves this process: it is serialized to JSON for a tool result or an
|
|
18
|
+
* HTTP response, appended to the dispatch log, written into a job file, or
|
|
19
|
+
* printed to the terminal. Those are sinks, there are few of them, and they
|
|
20
|
+
* change rarely.
|
|
21
|
+
*
|
|
22
|
+
* So: scrub at the sinks, and derive the secrets from the loaded config rather
|
|
23
|
+
* than naming them per call site. A leak then requires someone to add a whole
|
|
24
|
+
* new egress mechanism, not merely to write a new error message.
|
|
25
|
+
*
|
|
26
|
+
* This is deliberately more machinery than the individual fixes it replaces.
|
|
27
|
+
* It has earned that: it is not guarding against a hypothetical, it is
|
|
28
|
+
* guarding against six measured, reproduced disclosures, one of which put a
|
|
29
|
+
* key into a file on disk and another into an orchestrating agent's context.
|
|
30
|
+
*/
|
|
31
|
+
import type { RouterConfig } from "./types.js";
|
|
32
|
+
/** What a removed secret is replaced with. Matches `scrubEndpointSecrets`. */
|
|
33
|
+
export declare const REDACTED = "<redacted>";
|
|
34
|
+
/**
|
|
35
|
+
* Every secret value reachable from a loaded config.
|
|
36
|
+
*
|
|
37
|
+
* Collected from fields that HOLD credentials, and deliberately not from
|
|
38
|
+
* `envRefs`. Keying off `envRefs` was the obvious shortcut — it records every
|
|
39
|
+
* `${VAR}` in the file by resolved value — and it was wrong in a way that
|
|
40
|
+
* mattered: `${VAR}` is documented as legal in any string value, so a config
|
|
41
|
+
* writing `model: ${MY_MODEL}` or `command: ${CODEX_BIN}` turned a model name
|
|
42
|
+
* and a file path into process-wide redaction targets. An acceptance pass
|
|
43
|
+
* measured `model=<redacted>` in `status` output, and a harness answer
|
|
44
|
+
* mentioning that model would have been mangled the same way, silently.
|
|
45
|
+
*
|
|
46
|
+
* That failure is worse than the leak this guards against: a corrupted answer
|
|
47
|
+
* is wrong work product delivered as if it were right. A `${VAR}` in a
|
|
48
|
+
* credential field still resolves into `apiKey` before this runs, so nothing
|
|
49
|
+
* real is lost by dropping the shortcut.
|
|
50
|
+
*/
|
|
51
|
+
export declare function collectSecrets(config: RouterConfig | undefined): string[];
|
|
52
|
+
/** Remove every one of `secrets` from `text`, by value. */
|
|
53
|
+
export declare function scrubSecrets(text: string, secrets: readonly string[]): string;
|
|
54
|
+
/** Record a secret found while parsing, for redaction to pick up. */
|
|
55
|
+
export declare function registerSecretValue(value: string | undefined): void;
|
|
56
|
+
/** Install the secrets for a loaded config. Safe to call on every reload. */
|
|
57
|
+
export declare function setActiveSecrets(config: RouterConfig | undefined): void;
|
|
58
|
+
/** For tests that need to restore a clean slate. */
|
|
59
|
+
export declare function clearActiveSecrets(): void;
|
|
60
|
+
/** How many secrets are currently registered. For diagnostics and tests. */
|
|
61
|
+
export declare function activeSecretCount(): number;
|
|
62
|
+
/**
|
|
63
|
+
* Remove every registered secret from text that is about to leave the process.
|
|
64
|
+
*
|
|
65
|
+
* Call this at SINKS — serialization, disk writes, terminal output — not at
|
|
66
|
+
* the places strings are built. That distinction is the whole design.
|
|
67
|
+
*/
|
|
68
|
+
export declare function redact(text: string): string;
|
|
69
|
+
/**
|
|
70
|
+
* Redact everything written to stdout and stderr, for the life of the process.
|
|
71
|
+
*
|
|
72
|
+
* The terminal is a sink like any other, and it was the one left unwired when
|
|
73
|
+
* the JSON and disk sinks were done — measured immediately afterwards, with a
|
|
74
|
+
* path-embedded credential surviving into `status --json`, `usage` and
|
|
75
|
+
* `configure --print` while the same value was correctly removed from the MCP
|
|
76
|
+
* and HTTP payloads. That is the per-site failure this whole design exists to
|
|
77
|
+
* end, reproduced one more time by doing four sinks out of five.
|
|
78
|
+
*
|
|
79
|
+
* Installed once at the entrypoint rather than applied at each print, because
|
|
80
|
+
* `bin.ts` alone writes to stdout from dozens of places and every future
|
|
81
|
+
* command adds more. `redact` reads the registry at call time, so installing
|
|
82
|
+
* before config load is correct: writes made before any secret is known are
|
|
83
|
+
* unchanged, and everything after is covered with no ordering requirement.
|
|
84
|
+
*
|
|
85
|
+
* Non-string chunks pass through untouched — a Buffer write is not text this
|
|
86
|
+
* process composed, and decoding one to scan it would risk corrupting binary
|
|
87
|
+
* output for no benefit.
|
|
88
|
+
*/
|
|
89
|
+
export declare function installOutputRedaction(): void;
|
|
90
|
+
//# sourceMappingURL=redaction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redaction.d.ts","sourceRoot":"","sources":["../src/redaction.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,8EAA8E;AAC9E,eAAO,MAAM,QAAQ,eAAe,CAAC;AA4BrC;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,YAAY,GAAG,SAAS,GAAG,MAAM,EAAE,CAiCzE;AAED,2DAA2D;AAC3D,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAc7E;AA+BD,qEAAqE;AACrE,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAInE;AAED,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,SAAS,GAAG,IAAI,CAGvE;AAED,oDAAoD;AACpD,wBAAgB,kBAAkB,IAAI,IAAI,CAGzC;AAED,4EAA4E;AAC5E,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG3C;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CAY7C"}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One place that knows every secret this process holds, and one function that
|
|
3
|
+
* removes them from anything on its way out.
|
|
4
|
+
*
|
|
5
|
+
* WHY THIS EXISTS, because the alternative was tried six times and failed six
|
|
6
|
+
* times. The same defect — a configured credential reaching a caller, a log
|
|
7
|
+
* file or an agent's context — was found and "fixed" in six consecutive
|
|
8
|
+
* rounds. Every fix was correct. Every fix was also incomplete, because each
|
|
9
|
+
* one scrubbed at a SITE: a specific error path in a specific file. Four of
|
|
10
|
+
* the six were found as "the fix landed in one branch and the sibling beside
|
|
11
|
+
* it kept leaking", twice inside a single file. One round shipped a comment
|
|
12
|
+
* asserting that every branch was covered while a branch was not.
|
|
13
|
+
*
|
|
14
|
+
* Sites are the wrong unit. There is no bounded list of places a string can be
|
|
15
|
+
* built, and a new one is added by ordinary feature work with no reason for
|
|
16
|
+
* its author to think about credentials. What IS bounded is the set of ways a
|
|
17
|
+
* string leaves this process: it is serialized to JSON for a tool result or an
|
|
18
|
+
* HTTP response, appended to the dispatch log, written into a job file, or
|
|
19
|
+
* printed to the terminal. Those are sinks, there are few of them, and they
|
|
20
|
+
* change rarely.
|
|
21
|
+
*
|
|
22
|
+
* So: scrub at the sinks, and derive the secrets from the loaded config rather
|
|
23
|
+
* than naming them per call site. A leak then requires someone to add a whole
|
|
24
|
+
* new egress mechanism, not merely to write a new error message.
|
|
25
|
+
*
|
|
26
|
+
* This is deliberately more machinery than the individual fixes it replaces.
|
|
27
|
+
* It has earned that: it is not guarding against a hypothetical, it is
|
|
28
|
+
* guarding against six measured, reproduced disclosures, one of which put a
|
|
29
|
+
* key into a file on disk and another into an orchestrating agent's context.
|
|
30
|
+
*/
|
|
31
|
+
/** What a removed secret is replaced with. Matches `scrubEndpointSecrets`. */
|
|
32
|
+
export const REDACTED = "<redacted>";
|
|
33
|
+
/**
|
|
34
|
+
* Below this length a "secret" is more likely to be a coincidence than a
|
|
35
|
+
* credential, and redacting it would corrupt ordinary output.
|
|
36
|
+
*
|
|
37
|
+
* A real key is far longer. The risk being traded here is asymmetric and worth
|
|
38
|
+
* stating: too low a bound mangles legitimate text (a route named `a` would
|
|
39
|
+
* turn every `a` in an answer into a placeholder), while too high a bound
|
|
40
|
+
* misses a short key. Eight is below every provider key format in this
|
|
41
|
+
* project's own config and far above the length at which a value collides with
|
|
42
|
+
* prose by accident.
|
|
43
|
+
*/
|
|
44
|
+
const MIN_SECRET_LENGTH = 8;
|
|
45
|
+
/**
|
|
46
|
+
* Query keys whose VALUE is a credential.
|
|
47
|
+
*
|
|
48
|
+
* A name test, not a length test. The length heuristic this replaces treated
|
|
49
|
+
* any URL path segment of 16+ characters as a secret, which made an Azure
|
|
50
|
+
* deployment name (`.../deployments/gpt-4-turbo-preview`) a redaction target —
|
|
51
|
+
* measured by an acceptance pass. A credential in the path is a real shape,
|
|
52
|
+
* but it cannot be told from a deployment name by inspection, and guessing
|
|
53
|
+
* wrong corrupts output. `warnCredentialInUrlPath` in config.ts says so out
|
|
54
|
+
* loud instead, which is actionable where a silent guess is not.
|
|
55
|
+
*/
|
|
56
|
+
const CREDENTIAL_QUERY_KEY = /^(api[_-]?key|key|token|access[_-]?token|auth|password|secret|sig|signature)$/i;
|
|
57
|
+
/**
|
|
58
|
+
* Every secret value reachable from a loaded config.
|
|
59
|
+
*
|
|
60
|
+
* Collected from fields that HOLD credentials, and deliberately not from
|
|
61
|
+
* `envRefs`. Keying off `envRefs` was the obvious shortcut — it records every
|
|
62
|
+
* `${VAR}` in the file by resolved value — and it was wrong in a way that
|
|
63
|
+
* mattered: `${VAR}` is documented as legal in any string value, so a config
|
|
64
|
+
* writing `model: ${MY_MODEL}` or `command: ${CODEX_BIN}` turned a model name
|
|
65
|
+
* and a file path into process-wide redaction targets. An acceptance pass
|
|
66
|
+
* measured `model=<redacted>` in `status` output, and a harness answer
|
|
67
|
+
* mentioning that model would have been mangled the same way, silently.
|
|
68
|
+
*
|
|
69
|
+
* That failure is worse than the leak this guards against: a corrupted answer
|
|
70
|
+
* is wrong work product delivered as if it were right. A `${VAR}` in a
|
|
71
|
+
* credential field still resolves into `apiKey` before this runs, so nothing
|
|
72
|
+
* real is lost by dropping the shortcut.
|
|
73
|
+
*/
|
|
74
|
+
export function collectSecrets(config) {
|
|
75
|
+
const out = new Set();
|
|
76
|
+
if (!config)
|
|
77
|
+
return [];
|
|
78
|
+
const add = (value) => {
|
|
79
|
+
if (value === undefined)
|
|
80
|
+
return;
|
|
81
|
+
const trimmed = value.trim();
|
|
82
|
+
if (trimmed.length >= MIN_SECRET_LENGTH)
|
|
83
|
+
out.add(trimmed);
|
|
84
|
+
};
|
|
85
|
+
for (const svc of Object.values(config.services ?? {})) {
|
|
86
|
+
add(svc.apiKey);
|
|
87
|
+
if (svc.baseUrl === undefined)
|
|
88
|
+
continue;
|
|
89
|
+
try {
|
|
90
|
+
const url = new URL(svc.baseUrl);
|
|
91
|
+
add(url.password);
|
|
92
|
+
add(url.username);
|
|
93
|
+
// Only query values under a credential-looking KEY. Taking every value
|
|
94
|
+
// meant `?model=gemini-2.5-flash` made that model name a redaction
|
|
95
|
+
// target — measured. A query string carries ordinary parameters too.
|
|
96
|
+
for (const [key, value] of url.searchParams.entries()) {
|
|
97
|
+
if (CREDENTIAL_QUERY_KEY.test(key))
|
|
98
|
+
add(value);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
// An unparseable base_url has no parts to take apart. A credential
|
|
103
|
+
// written into one is still caught if it also appears as an api_key,
|
|
104
|
+
// which is how it is normally configured.
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// Longest first, so a secret that contains another is removed whole rather
|
|
108
|
+
// than being left as a recognisable fragment around a placeholder.
|
|
109
|
+
return [...out].sort((a, b) => b.length - a.length);
|
|
110
|
+
}
|
|
111
|
+
/** Remove every one of `secrets` from `text`, by value. */
|
|
112
|
+
export function scrubSecrets(text, secrets) {
|
|
113
|
+
let out = text;
|
|
114
|
+
for (const secret of secrets) {
|
|
115
|
+
if (out.includes(secret))
|
|
116
|
+
out = out.split(secret).join(REDACTED);
|
|
117
|
+
// Redaction runs AFTER JSON.stringify at most sinks, so a secret holding a
|
|
118
|
+
// character JSON escapes — a quote, or the backslashes in a Windows path —
|
|
119
|
+
// is no longer present in its raw form and survived. Measured with a key
|
|
120
|
+
// containing a double quote.
|
|
121
|
+
const escaped = JSON.stringify(secret).slice(1, -1);
|
|
122
|
+
if (escaped !== secret && out.includes(escaped)) {
|
|
123
|
+
out = out.split(escaped).join(REDACTED);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return out;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* The secrets of the config this process is currently running.
|
|
130
|
+
*
|
|
131
|
+
* Process-wide mutable state, which is normally a smell and is the right shape
|
|
132
|
+
* here: whether a given string is a credential is a property of the process,
|
|
133
|
+
* not of the call. Threading config into the dispatch log, the JSON
|
|
134
|
+
* serializers and the job-file writers is exactly the per-site plumbing whose
|
|
135
|
+
* absence caused six rounds of this bug — every one of those sinks would have
|
|
136
|
+
* needed a caller to remember to pass it.
|
|
137
|
+
*/
|
|
138
|
+
let activeSecrets = [];
|
|
139
|
+
/**
|
|
140
|
+
* Secrets seen while PARSING a config, which never become a route field.
|
|
141
|
+
*
|
|
142
|
+
* The top-level `api_keys:` block is the case that forced this. Its entries
|
|
143
|
+
* are applied to routes by name, so an entry whose route also declares an
|
|
144
|
+
* inline `api_key:` — or that names no route at all — is a live credential
|
|
145
|
+
* sitting in the config file that `collectSecrets` cannot see from the
|
|
146
|
+
* finished RouterConfig. A pass measured every entry after the first in that
|
|
147
|
+
* block leaking, and this is the machine setup this project documents.
|
|
148
|
+
*
|
|
149
|
+
* Accumulated rather than replaced on reload, deliberately: continuing to
|
|
150
|
+
* scrub a credential that has been removed from the config costs one
|
|
151
|
+
* unnecessary replacement in output that would not have contained it anyway,
|
|
152
|
+
* whereas forgetting one costs a disclosure.
|
|
153
|
+
*/
|
|
154
|
+
const parsedSecrets = new Set();
|
|
155
|
+
/** Record a secret found while parsing, for redaction to pick up. */
|
|
156
|
+
export function registerSecretValue(value) {
|
|
157
|
+
if (value === undefined)
|
|
158
|
+
return;
|
|
159
|
+
const trimmed = value.trim();
|
|
160
|
+
if (trimmed.length >= MIN_SECRET_LENGTH)
|
|
161
|
+
parsedSecrets.add(trimmed);
|
|
162
|
+
}
|
|
163
|
+
/** Install the secrets for a loaded config. Safe to call on every reload. */
|
|
164
|
+
export function setActiveSecrets(config) {
|
|
165
|
+
const merged = new Set([...collectSecrets(config), ...parsedSecrets]);
|
|
166
|
+
activeSecrets = [...merged].sort((a, b) => b.length - a.length);
|
|
167
|
+
}
|
|
168
|
+
/** For tests that need to restore a clean slate. */
|
|
169
|
+
export function clearActiveSecrets() {
|
|
170
|
+
activeSecrets = [];
|
|
171
|
+
parsedSecrets.clear();
|
|
172
|
+
}
|
|
173
|
+
/** How many secrets are currently registered. For diagnostics and tests. */
|
|
174
|
+
export function activeSecretCount() {
|
|
175
|
+
return activeSecrets.length;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Remove every registered secret from text that is about to leave the process.
|
|
179
|
+
*
|
|
180
|
+
* Call this at SINKS — serialization, disk writes, terminal output — not at
|
|
181
|
+
* the places strings are built. That distinction is the whole design.
|
|
182
|
+
*/
|
|
183
|
+
export function redact(text) {
|
|
184
|
+
if (activeSecrets.length === 0)
|
|
185
|
+
return text;
|
|
186
|
+
return scrubSecrets(text, activeSecrets);
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Redact everything written to stdout and stderr, for the life of the process.
|
|
190
|
+
*
|
|
191
|
+
* The terminal is a sink like any other, and it was the one left unwired when
|
|
192
|
+
* the JSON and disk sinks were done — measured immediately afterwards, with a
|
|
193
|
+
* path-embedded credential surviving into `status --json`, `usage` and
|
|
194
|
+
* `configure --print` while the same value was correctly removed from the MCP
|
|
195
|
+
* and HTTP payloads. That is the per-site failure this whole design exists to
|
|
196
|
+
* end, reproduced one more time by doing four sinks out of five.
|
|
197
|
+
*
|
|
198
|
+
* Installed once at the entrypoint rather than applied at each print, because
|
|
199
|
+
* `bin.ts` alone writes to stdout from dozens of places and every future
|
|
200
|
+
* command adds more. `redact` reads the registry at call time, so installing
|
|
201
|
+
* before config load is correct: writes made before any secret is known are
|
|
202
|
+
* unchanged, and everything after is covered with no ordering requirement.
|
|
203
|
+
*
|
|
204
|
+
* Non-string chunks pass through untouched — a Buffer write is not text this
|
|
205
|
+
* process composed, and decoding one to scan it would risk corrupting binary
|
|
206
|
+
* output for no benefit.
|
|
207
|
+
*/
|
|
208
|
+
export function installOutputRedaction() {
|
|
209
|
+
for (const stream of [process.stdout, process.stderr]) {
|
|
210
|
+
const original = stream.write.bind(stream);
|
|
211
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
212
|
+
stream.write = ((chunk, ...rest) => {
|
|
213
|
+
if (typeof chunk === "string" && activeSecrets.length > 0) {
|
|
214
|
+
return original(redact(chunk), ...rest);
|
|
215
|
+
}
|
|
216
|
+
return original(chunk, ...rest);
|
|
217
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
//# sourceMappingURL=redaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redaction.js","sourceRoot":"","sources":["../src/redaction.ts"],"names":[],"mappings":"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"}
|
package/dist/router.d.ts
CHANGED
|
@@ -55,8 +55,18 @@
|
|
|
55
55
|
* Explicit `tier` in config is the fallback when ELO is unavailable.
|
|
56
56
|
*
|
|
57
57
|
* R3: adds `stream()` / `streamTo()` that emit `DispatcherEvent`s with an
|
|
58
|
-
* attached `RoutingDecision`.
|
|
59
|
-
*
|
|
58
|
+
* attached `RoutingDecision`.
|
|
59
|
+
*
|
|
60
|
+
* There is ONE selection-and-fallback loop per shape — `#runStream` for the
|
|
61
|
+
* routed path, `#runStreamTo` for an explicit route — and the buffered
|
|
62
|
+
* `route()` / `routeTo()` drain them. This paragraph used to claim exactly
|
|
63
|
+
* that while it was false: the buffered methods were separate 120-line
|
|
64
|
+
* implementations, and the copies drifted. The timeout rule ended up written
|
|
65
|
+
* four times, and an audit mutation showed a test pinned only the `route()`
|
|
66
|
+
* copy, leaving the pair that jobs and the HTTP server actually use unguarded.
|
|
67
|
+
*
|
|
68
|
+
* What still differs between buffered and streaming is the dispatcher call
|
|
69
|
+
* itself, and only that: see `DispatcherInvoke`.
|
|
60
70
|
*/
|
|
61
71
|
import type { DispatchResult, DispatcherEvent, RouterConfig, RoutingDecision, RouteHints, RouteSkip, SafetyProfile, ServiceConfig, TaskType } from "./types.js";
|
|
62
72
|
import { CircuitBreaker } from "./circuit-breaker.js";
|
|
@@ -120,27 +130,6 @@ export interface ExplicitDispatchOpts {
|
|
|
120
130
|
*/
|
|
121
131
|
defaultTimeoutMs?: number;
|
|
122
132
|
}
|
|
123
|
-
/**
|
|
124
|
-
* Every hint that means something to an explicitly-chosen route, in one place.
|
|
125
|
-
*
|
|
126
|
-
* The HTTP fanout path built these options by naming three fields inline and
|
|
127
|
-
* missed two: `routePolicy` never reached `routeTo`, so
|
|
128
|
-
* `{"mode":"fanout","hints":{"routePolicy":"blocked"}}` — documented as
|
|
129
|
-
* "dry-run: block everything" — returned 200 having run a live agent in the
|
|
130
|
-
* caller's working tree, and `local_only` let a metered route run. `timeoutMs`
|
|
131
|
-
* was dropped the same way, so the bound the release notes describe never
|
|
132
|
-
* reached the child in fanout mode. Single mode enforced both correctly, so
|
|
133
|
-
* one surface disagreed with itself.
|
|
134
|
-
*
|
|
135
|
-
* Picking fields by name is what allowed that: nothing fails when a new hint
|
|
136
|
-
* is added and a call site is not updated. Adding one here reaches every
|
|
137
|
-
* caller, and `ExplicitDispatchOpts` is the compiler's list of what belongs.
|
|
138
|
-
*
|
|
139
|
-
* `model` is deliberately absent — fanout selects routes with `models`, and
|
|
140
|
-
* each arm runs its own. `preferLargeContext` and `service` only steer which
|
|
141
|
-
* route is PICKED, which an explicit route has already decided.
|
|
142
|
-
*/
|
|
143
|
-
export declare function explicitOptsFromHints(hints: RouteHints): ExplicitDispatchOpts;
|
|
144
133
|
/**
|
|
145
134
|
* Does this route actually DECLARE this model? The route's own name does not
|
|
146
135
|
* count.
|
package/dist/router.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"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"}
|