@cygnuxlabs/tracekit 0.0.0-stage → 1.2.2

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 (40) hide show
  1. package/README.md +294 -2
  2. package/bin/tracekit.mjs +30 -0
  3. package/dist/v1.d.ts +97 -0
  4. package/dist/v1.js +535 -0
  5. package/dist/v2/adapters/claude-agent-sdk.d.ts +45 -0
  6. package/dist/v2/adapters/claude-agent-sdk.js +142 -0
  7. package/dist/v2/adapters/gate.d.ts +62 -0
  8. package/dist/v2/adapters/gate.js +195 -0
  9. package/dist/v2/adapters/openai-agents.d.ts +85 -0
  10. package/dist/v2/adapters/openai-agents.js +114 -0
  11. package/dist/v2/adapters/vercel-ai.d.ts +51 -0
  12. package/dist/v2/adapters/vercel-ai.js +132 -0
  13. package/dist/v2/client.d.ts +159 -0
  14. package/dist/v2/client.js +749 -0
  15. package/dist/v2/executor.d.ts +49 -0
  16. package/dist/v2/executor.js +57 -0
  17. package/dist/v2/jcs.d.ts +5 -0
  18. package/dist/v2/jcs.js +12 -0
  19. package/dist/v2/launcher.d.ts +10 -0
  20. package/dist/v2/launcher.js +50 -0
  21. package/dist/v2/rpc_schema.d.ts +3 -0
  22. package/dist/v2/rpc_schema.js +43 -0
  23. package/dist/v2/validate.d.ts +6 -0
  24. package/dist/v2/validate.js +70 -0
  25. package/dist/verify/cli.d.ts +1 -0
  26. package/dist/verify/cli.js +46 -0
  27. package/dist/verify/detect.d.ts +41 -0
  28. package/dist/verify/detect.js +289 -0
  29. package/dist/verify/index.d.ts +34 -0
  30. package/dist/verify/index.js +930 -0
  31. package/dist/verify/jcs.d.ts +19 -0
  32. package/dist/verify/jcs.js +154 -0
  33. package/dist/verify/primitives.d.ts +62 -0
  34. package/dist/verify/primitives.js +298 -0
  35. package/dist/verify/schema.d.ts +11 -0
  36. package/dist/verify/schema.js +98 -0
  37. package/dist/verify/tracekit.event.v2.json +4588 -0
  38. package/dist/verify/zip.d.ts +17 -0
  39. package/dist/verify/zip.js +145 -0
  40. package/package.json +42 -4
@@ -0,0 +1,49 @@
1
+ /**
2
+ * The actions of a tool executor (`tracekit executor`, docs/executor.md) as framework tools. The agent holds only its
3
+ * run: the executor holds the actions' credentials and decides, runs and records each call in the signer (tier T2).
4
+ *
5
+ * import { tool } from "@openai/agents";
6
+ * import { jsonSchema } from "ai";
7
+ * import { executorActions, openaiAgentsTool, vercelTool } from "@cygnuxlabs/tracekit/v2/executor";
8
+ * const actions = await executorActions("https://executor.internal:8090", run, { headers: { authorization: `Bearer ${token}` } });
9
+ * new Agent({ tools: actions.map((a) => openaiAgentsTool(tool, a)) });
10
+ * generateText({ tools: Object.fromEntries(actions.map((a) => [a.name, vercelTool(a, jsonSchema)])) });
11
+ *
12
+ * `headers` authenticate the agent to the executor (a bearer or service-account token); for a client certificate pass
13
+ * a `fetch` that presents one. The tools carry EXECUTOR, so the Tracekit adapters leave them to the executor, which
14
+ * decides and records them (T2). A
15
+ * refusal (deny, an approval not given, the signer unreachable) throws ExecutorRefused with the executor's message,
16
+ * which the framework hands the model as the tool's error.
17
+ */
18
+ import type { Frame, RunHandle } from "./client.js";
19
+ export declare class ExecutorRefused extends Error {
20
+ }
21
+ /** Set on the tools built here: the Tracekit adapters don't gate them. */
22
+ export declare const EXECUTOR: unique symbol;
23
+ /** The Claude Agent SDK hooks leave the tools of an MCP server of this name (mcp__tracekit-executor__<action>) alone. */
24
+ export declare const SERVER = "tracekit-executor";
25
+ export type Action = {
26
+ name: string;
27
+ description: string;
28
+ args: Frame;
29
+ /** {status: the upstream's HTTP status, result: its JSON or text}; rejects with ExecutorRefused when it did not run. */
30
+ call(args: unknown, toolCallId?: string): Promise<Frame>;
31
+ };
32
+ type Options = {
33
+ headers?: Record<string, string>;
34
+ fetch?: typeof globalThis.fetch;
35
+ };
36
+ /** The executor's actions, each callable for `run`. */
37
+ export declare function executorActions(url: string, run: RunHandle, { headers, fetch }?: Options): Promise<Action[]>;
38
+ /** An @openai/agents function tool; `build` is the SDK's `tool`. */
39
+ export declare const openaiAgentsTool: <T>(build: (options: any) => T, a: Action) => T;
40
+ /** A Vercel AI SDK tool; `jsonSchema` is the `ai` package's. */
41
+ export declare const vercelTool: (a: Action, jsonSchema: (s: any) => unknown) => {
42
+ [EXECUTOR]: boolean;
43
+ description: string;
44
+ inputSchema: unknown;
45
+ execute: (input: unknown, opts?: {
46
+ toolCallId?: string;
47
+ }) => Promise<Frame>;
48
+ };
49
+ export {};
@@ -0,0 +1,57 @@
1
+ export class ExecutorRefused extends Error {
2
+ }
3
+ /** Set on the tools built here: the Tracekit adapters don't gate them. */
4
+ export const EXECUTOR = Symbol.for("tracekit.executor");
5
+ /** The Claude Agent SDK hooks leave the tools of an MCP server of this name (mcp__tracekit-executor__<action>) alone. */
6
+ export const SERVER = "tracekit-executor";
7
+ /** Why `url` may not receive the run token and the agent's credential, or null: https, or plain http to loopback. */
8
+ function remoteUrlError(url) {
9
+ let u;
10
+ try {
11
+ u = new URL(url);
12
+ }
13
+ catch {
14
+ return "invalid URL";
15
+ }
16
+ if (u.username || u.password)
17
+ return "URL must not contain user@ credentials";
18
+ if (u.protocol === "https:" || (u.protocol === "http:" && ["localhost", "127.0.0.1", "[::1]"].includes(u.hostname)))
19
+ return null;
20
+ return "URL must use https (plain http only for localhost, 127.0.0.1 or ::1)";
21
+ }
22
+ /** The executor's actions, each callable for `run`. */
23
+ export async function executorActions(url, run, { headers = {}, fetch = globalThis.fetch } = {}) {
24
+ const why = remoteUrlError(url);
25
+ if (why)
26
+ throw new Error(`${url.slice(0, 256)}: ${why}`); // the run token and the credential never go in clear
27
+ let base = url;
28
+ while (base.endsWith("/"))
29
+ base = base.slice(0, -1);
30
+ // the agent's credential for the executor never follows a redirect
31
+ const get = async (path, init = {}) => {
32
+ const r = await fetch(base + path, { ...init, redirect: "manual", headers: { ...headers, ...init.headers } });
33
+ const body = await r.json().catch(() => null);
34
+ if (!r.ok)
35
+ throw new ExecutorRefused(body?.error?.message ?? `tracekit executor: HTTP ${r.status}`);
36
+ return body;
37
+ };
38
+ const { actions } = await get("/v1/actions");
39
+ return actions.map((a) => ({
40
+ ...a,
41
+ call: (args, toolCallId) => get(`/v1/actions/${encodeURIComponent(a.name)}`, {
42
+ method: "POST",
43
+ headers: { "content-type": "application/json", "x-tracekit-run": `${run.runId}.${run.runToken}` },
44
+ body: JSON.stringify({ args, ...(toolCallId ? { tool_call_id: toolCallId } : {}) }),
45
+ }),
46
+ }));
47
+ }
48
+ /** An @openai/agents function tool; `build` is the SDK's `tool`. */
49
+ export const openaiAgentsTool = (build, a) => Object.assign(build({
50
+ name: a.name, description: a.description, parameters: a.args, strict: false,
51
+ execute: async (input, _ctx, details) => JSON.stringify(await a.call(input, details?.toolCall?.callId)),
52
+ }), { [EXECUTOR]: true });
53
+ /** A Vercel AI SDK tool; `jsonSchema` is the `ai` package's. */
54
+ export const vercelTool = (a, jsonSchema) => ({
55
+ [EXECUTOR]: true, description: a.description, inputSchema: jsonSchema(a.args),
56
+ execute: (input, opts) => a.call(input, opts?.toolCallId),
57
+ });
@@ -0,0 +1,5 @@
1
+ export { canonicalize, strictParse, StrictJSONError } from "../verify/jcs.js";
2
+ /** sha256(JCS(v)), as tracekit/format/canon.py `event_hash`. */
3
+ export declare function digest(v: unknown): string;
4
+ /** sha256(JCS({tool, args})): `args` is the model's raw arguments string (strictly parsed first) or a parsed value. */
5
+ export declare function argsDigest(tool: string, args: unknown): string;
package/dist/v2/jcs.js ADDED
@@ -0,0 +1,12 @@
1
+ /** Content digests of the native client; JCS and the strict parser are shared with the verifier (src/verify/jcs.ts). */
2
+ import { createHash } from "node:crypto";
3
+ import { canonicalize, strictParse } from "../verify/jcs.js";
4
+ export { canonicalize, strictParse, StrictJSONError } from "../verify/jcs.js";
5
+ /** sha256(JCS(v)), as tracekit/format/canon.py `event_hash`. */
6
+ export function digest(v) {
7
+ return "sha256:" + createHash("sha256").update(canonicalize(v), "utf8").digest("hex");
8
+ }
9
+ /** sha256(JCS({tool, args})): `args` is the model's raw arguments string (strictly parsed first) or a parsed value. */
10
+ export function argsDigest(tool, args) {
11
+ return digest({ tool, args: typeof args === "string" ? strictParse(args) : args });
12
+ }
@@ -0,0 +1,10 @@
1
+ export declare const INSTALL_HINT: string;
2
+ /** This platform's signer package suffix, as the optionalDependencies name them; null where none is built. */
3
+ export declare function platformKey(): string | null;
4
+ /** The command line that runs `tracekit`, or null when there is none. */
5
+ export declare function signerCommand(env?: NodeJS.ProcessEnv): string[] | null;
6
+ /**
7
+ * The environment to run `cmd` in: it adds cmd[0] to $TRACEKIT_LAUNCHER_TRIED, so when the `tracekit` found on PATH is
8
+ * this launcher again (npm's .bin link, a pnpm shim), that run looks past it instead of starting itself forever.
9
+ */
10
+ export declare function signerEnv(cmd: string[], env?: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Where the `tracekit` command is: $TRACEKIT_PYTHON's `-m tracekit`, else a pip-installed `tracekit` on PATH, else the
3
+ * Python bundled in the installed @cygnuxlabs/tracekit-signer-<platform> package. Used by bin/tracekit.mjs and the v2
4
+ * client's dev auto-spawn.
5
+ */
6
+ import { existsSync } from "node:fs";
7
+ import { createRequire } from "node:module";
8
+ import { delimiter, dirname, join } from "node:path";
9
+ export const INSTALL_HINT = "no Tracekit signer found. Install one: `pip install 'tracekit-ai[signer]'` (puts `tracekit` " +
10
+ "on PATH), or reinstall @cygnuxlabs/tracekit without --omit=optional so npm adds the signer package for this platform";
11
+ /** This platform's signer package suffix, as the optionalDependencies name them; null where none is built. */
12
+ export function platformKey() {
13
+ let key = `${process.platform}-${process.arch}`;
14
+ if (process.platform === "linux") {
15
+ const header = process.report?.getReport()?.header;
16
+ if (!header?.glibcVersionRuntime)
17
+ return null; // musl: no bundle
18
+ key += "-gnu";
19
+ }
20
+ return ["darwin-arm64", "linux-x64-gnu", "linux-arm64-gnu", "win32-x64"].includes(key) ? key : null;
21
+ }
22
+ /** The command line that runs `tracekit`, or null when there is none. */
23
+ export function signerCommand(env = process.env) {
24
+ if (env.TRACEKIT_PYTHON)
25
+ return [env.TRACEKIT_PYTHON, "-m", "tracekit"];
26
+ const tried = (env.TRACEKIT_LAUNCHER_TRIED ?? "").split(delimiter);
27
+ const exe = process.platform === "win32" ? "tracekit.exe" : "tracekit";
28
+ for (const dir of (env.PATH ?? "").split(delimiter)) {
29
+ const p = join(dir, exe);
30
+ if (dir && existsSync(p) && !tried.includes(p))
31
+ return [p];
32
+ }
33
+ const key = platformKey();
34
+ if (!key)
35
+ return null;
36
+ try {
37
+ const pkg = dirname(createRequire(import.meta.url).resolve(`@cygnuxlabs/tracekit-signer-${key}/package.json`));
38
+ return [join(pkg, process.platform === "win32" ? "python/python.exe" : "python/bin/python3"), "-m", "tracekit"];
39
+ }
40
+ catch {
41
+ return null;
42
+ }
43
+ }
44
+ /**
45
+ * The environment to run `cmd` in: it adds cmd[0] to $TRACEKIT_LAUNCHER_TRIED, so when the `tracekit` found on PATH is
46
+ * this launcher again (npm's .bin link, a pnpm shim), that run looks past it instead of starting itself forever.
47
+ */
48
+ export function signerEnv(cmd, env = process.env) {
49
+ return { ...env, TRACEKIT_LAUNCHER_TRIED: [env.TRACEKIT_LAUNCHER_TRIED, cmd[0]].filter(Boolean).join(delimiter) };
50
+ }
@@ -0,0 +1,3 @@
1
+ import type { Schema } from "./validate.js";
2
+ export declare const RPC_VERSION = 16;
3
+ export declare const REQUESTS: Record<string, Schema>;
@@ -0,0 +1,43 @@
1
+ export const RPC_VERSION = 16;
2
+ export const REQUESTS = {
3
+ "register_run": { "type": "object", "additionalProperties": false, "required": ["request_id", "agent"], "properties": { "request_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "run_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "tenant": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "principal": { "type": "string", "maxLength": 256 }, "principal_token": { "type": "string", "maxLength": 16384 }, "source": { "const": "migrated" }, "analyzes": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "replay_of": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "investigation": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "parent": { "type": "object", "additionalProperties": false, "required": ["run_id", "run_token"], "properties": { "run_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "run_token": { "type": "string", "maxLength": 1024, "minLength": 1 } } }, "agent": { "type": "object", "additionalProperties": false, "required": ["name"], "properties": { "name": { "type": "string", "maxLength": 128, "minLength": 1 }, "version": { "type": "string", "maxLength": 64 } } } } },
4
+ "decide": { "type": "object", "additionalProperties": false, "required": ["request_id", "run_id", "run_token", "stream", "client_seq", "tool_call_id", "tool", "args_source", "args"], "properties": { "request_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "run_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "run_token": { "type": "string", "maxLength": 1024, "minLength": 1 }, "stream": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "client_seq": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "caller": { "type": "string", "maxLength": 256, "pattern": "^[a-z0-9_]+:.+(?![\\s\\S])" }, "tool_call_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "attempt": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "tool": { "type": "string", "maxLength": 256, "minLength": 1 }, "tool_class_hint": { "type": "string", "maxLength": 64 }, "args_source": { "enum": ["raw", "parsed", "coerced"] }, "args": {} }, "if": { "properties": { "args_source": { "const": "raw" } } }, "then": { "properties": { "args": { "type": "string", "maxLength": 1048576 } } } },
5
+ "complete": { "type": "object", "additionalProperties": false, "required": ["request_id", "run_id", "run_token", "stream", "client_seq", "tool_call_id", "decision_id", "args_digest", "status"], "properties": { "request_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "run_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "run_token": { "type": "string", "maxLength": 1024, "minLength": 1 }, "stream": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "client_seq": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "caller": { "type": "string", "maxLength": 256, "pattern": "^[a-z0-9_]+:.+(?![\\s\\S])" }, "tool_call_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "attempt": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "decision_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "args_digest": { "type": "string", "maxLength": 71, "pattern": "^sha256:[0-9a-f]{64}(?![\\s\\S])" }, "status": { "enum": ["ok", "error"] }, "result": {}, "error": { "type": "string", "maxLength": 4096 }, "redacted": { "const": true }, "redaction": { "type": "object", "additionalProperties": false, "required": [], "properties": { "rules": { "type": "array", "maxItems": 32, "items": { "type": "string", "maxLength": 64 } }, "count": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 } } } } },
6
+ "observe": { "type": "object", "additionalProperties": false, "required": ["request_id", "run_id", "run_token", "stream", "client_seq", "source", "trust", "value"], "properties": { "request_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "run_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "run_token": { "type": "string", "maxLength": 1024, "minLength": 1 }, "stream": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "client_seq": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "caller": { "type": "string", "maxLength": 256, "pattern": "^[a-z0-9_]+:.+(?![\\s\\S])" }, "source": { "type": "string", "maxLength": 256, "minLength": 1 }, "trust": { "enum": ["trusted", "untrusted"] }, "value": {} } },
7
+ "state_write": { "type": "object", "additionalProperties": false, "required": ["request_id", "run_id", "run_token", "stream", "client_seq", "key", "value_digest"], "properties": { "request_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "run_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "run_token": { "type": "string", "maxLength": 1024, "minLength": 1 }, "stream": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "client_seq": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "key": { "type": "string", "maxLength": 256, "minLength": 1 }, "value_digest": { "type": "string", "maxLength": 71, "pattern": "^sha256:[0-9a-f]{64}(?![\\s\\S])" }, "prev_digest": { "oneOf": [{ "type": "string", "maxLength": 71, "pattern": "^sha256:[0-9a-f]{64}(?![\\s\\S])" }, { "type": "null" }] } } },
8
+ "model_event": { "type": "object", "additionalProperties": false, "required": ["request_id", "run_id", "run_token", "stream", "client_seq", "provider", "model", "phase"], "properties": { "request_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "run_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "run_token": { "type": "string", "maxLength": 1024, "minLength": 1 }, "stream": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "client_seq": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "provider": { "type": "string", "maxLength": 64 }, "model": { "type": "string", "maxLength": 128 }, "phase": { "enum": ["request", "response"] }, "content_digest": { "type": "string", "maxLength": 71, "pattern": "^sha256:[0-9a-f]{64}(?![\\s\\S])" }, "exchange_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "streamed": { "type": "boolean" }, "stop_reason": { "type": "string", "maxLength": 100 }, "error": { "type": "string", "maxLength": 1024 }, "usage": { "type": "object", "additionalProperties": false, "required": [], "properties": { "input_tokens": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "output_tokens": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "cache_read_tokens": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "cache_write_tokens": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "reasoning_tokens": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 } } }, "tool_uses": { "type": "array", "maxItems": 128, "items": { "type": "object", "additionalProperties": false, "required": ["id", "name", "executed_by"], "properties": { "id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "name": { "type": "string", "maxLength": 256, "minLength": 1 }, "executed_by": { "enum": ["client", "provider"] }, "args_source": { "enum": ["raw", "parsed", "coerced"] }, "args_digest": { "type": "string", "maxLength": 71, "pattern": "^sha256:[0-9a-f]{64}(?![\\s\\S])" }, "args_unparseable": { "const": true }, "id_synthetic": { "const": true } }, "oneOf": [{ "additionalProperties": false, "properties": { "id": {}, "name": {}, "executed_by": { "const": "provider" }, "id_synthetic": {} } }, { "required": ["args_source", "args_digest"], "additionalProperties": false, "properties": { "id": {}, "name": {}, "executed_by": { "const": "provider" }, "id_synthetic": {}, "args_source": {}, "args_digest": {} } }, { "required": ["args_source", "args_digest"], "properties": { "executed_by": { "const": "client" } } }, { "required": ["args_source", "args_unparseable"], "properties": { "executed_by": { "const": "client" } } }] } }, "tool_results_sent": { "type": "array", "maxItems": 1024, "items": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" } }, "caller": { "type": "string", "maxLength": 256, "pattern": "^[a-z0-9_]+:.+(?![\\s\\S])" }, "body": {} } },
9
+ "approval_request": { "type": "object", "additionalProperties": false, "required": ["request_id", "run_id", "run_token", "tool_call_id"], "properties": { "request_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "run_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "run_token": { "type": "string", "maxLength": 1024, "minLength": 1 }, "caller": { "type": "string", "maxLength": 256, "pattern": "^[a-z0-9_]+:.+(?![\\s\\S])" }, "tool_call_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "attempt": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "reason": { "type": "string", "maxLength": 1024 } } },
10
+ "approval_decide": { "type": "object", "additionalProperties": false, "required": ["request_id", "approval_id", "decision"], "properties": { "request_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "approval_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "decision": { "enum": ["approve", "reject", "escalate"] }, "reason": { "type": "string", "maxLength": 1024 }, "on_behalf": { "type": "object", "additionalProperties": false, "required": ["subject", "person"], "properties": { "subject": { "type": "string", "maxLength": 256, "minLength": 1 }, "person": { "type": "string", "maxLength": 256, "minLength": 1 }, "groups": { "type": "array", "maxItems": 64, "items": { "type": "string", "maxLength": 256 } }, "tenant": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" } } }, "passkey": { "type": "object", "additionalProperties": false, "required": ["credential_id", "client_data_json", "authenticator_data", "signature"], "properties": { "credential_id": { "type": "string", "maxLength": 4096, "minLength": 1, "pattern": "^[A-Za-z0-9_-]+(?![\\s\\S])" }, "client_data_json": { "type": "string", "maxLength": 4096, "minLength": 1, "pattern": "^[A-Za-z0-9_-]+(?![\\s\\S])" }, "authenticator_data": { "type": "string", "maxLength": 4096, "minLength": 1, "pattern": "^[A-Za-z0-9_-]+(?![\\s\\S])" }, "signature": { "type": "string", "maxLength": 4096, "minLength": 1, "pattern": "^[A-Za-z0-9_-]+(?![\\s\\S])" } } }, "asserted": { "type": "object", "additionalProperties": false, "required": [], "properties": { "model": { "type": "string", "maxLength": 128 }, "version": { "type": "string", "maxLength": 64 }, "prompt_hash": { "type": "string", "maxLength": 71, "pattern": "^sha256:[0-9a-f]{64}(?![\\s\\S])" } } } } },
11
+ "approval_decide_on_behalf": { "type": "object", "additionalProperties": false, "required": ["request_id", "approval_id", "decision", "approver"], "properties": { "request_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "approval_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "decision": { "enum": ["approve", "reject"] }, "approver": { "type": "string", "maxLength": 64, "pattern": "^slack:[A-Z0-9]+/[A-Z0-9]+(?![\\s\\S])" }, "groups": { "type": "array", "maxItems": 32, "items": { "type": "string", "maxLength": 64, "pattern": "^slack:[A-Z0-9]+/[A-Z0-9]+(?![\\s\\S])" } } } },
12
+ "approval_wait": { "type": "object", "additionalProperties": false, "required": ["run_id", "run_token", "approval_id"], "properties": { "run_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "run_token": { "type": "string", "maxLength": 1024, "minLength": 1 }, "caller": { "type": "string", "maxLength": 256, "pattern": "^[a-z0-9_]+:.+(?![\\s\\S])" }, "approval_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "timeout_ms": { "type": "integer", "minimum": 0, "maximum": 300000 } } },
13
+ "approval_consume": { "type": "object", "additionalProperties": false, "required": ["request_id", "run_id", "run_token", "tool_call_id", "tool", "args_source", "args"], "properties": { "request_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "run_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "run_token": { "type": "string", "maxLength": 1024, "minLength": 1 }, "caller": { "type": "string", "maxLength": 256, "pattern": "^[a-z0-9_]+:.+(?![\\s\\S])" }, "tool_call_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "attempt": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "tool": { "type": "string", "maxLength": 256, "minLength": 1 }, "args_source": { "enum": ["raw", "parsed", "coerced"] }, "args": {}, "approval_id_hint": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" } }, "if": { "properties": { "args_source": { "const": "raw" } } }, "then": { "properties": { "args": { "type": "string", "maxLength": 1048576 } } } },
14
+ "approval_get": { "type": "object", "additionalProperties": false, "required": ["approval_id"], "properties": { "approval_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "on_behalf": { "type": "object", "additionalProperties": false, "required": ["subject", "person"], "properties": { "subject": { "type": "string", "maxLength": 256, "minLength": 1 }, "person": { "type": "string", "maxLength": 256, "minLength": 1 }, "groups": { "type": "array", "maxItems": 64, "items": { "type": "string", "maxLength": 256 } }, "tenant": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" } } } } },
15
+ "approval_list": { "type": "object", "additionalProperties": false, "required": [], "properties": { "run_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "cursor": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "limit": { "type": "integer", "minimum": 1, "maximum": 1000 }, "on_behalf": { "type": "object", "additionalProperties": false, "required": ["subject", "person"], "properties": { "subject": { "type": "string", "maxLength": 256, "minLength": 1 }, "person": { "type": "string", "maxLength": 256, "minLength": 1 }, "groups": { "type": "array", "maxItems": 64, "items": { "type": "string", "maxLength": 256 } }, "tenant": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" } } }, "state": { "enum": ["requested", "approved", "rejected", "expired", "consumed"] }, "escalated": { "type": "boolean" }, "for": { "enum": ["agent", "person"] } } },
16
+ "approval_review": { "type": "object", "additionalProperties": false, "required": ["approval_id"], "properties": { "approval_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" } } },
17
+ "approval_revoke": { "type": "object", "additionalProperties": false, "required": ["request_id", "approval_id"], "properties": { "request_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "approval_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "reason": { "type": "string", "maxLength": 1024 }, "on_behalf": { "type": "object", "additionalProperties": false, "required": ["subject", "person"], "properties": { "subject": { "type": "string", "maxLength": 256, "minLength": 1 }, "person": { "type": "string", "maxLength": 256, "minLength": 1 }, "groups": { "type": "array", "maxItems": 64, "items": { "type": "string", "maxLength": 256 } }, "tenant": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" } } } } },
18
+ "approval_agents": { "type": "object", "additionalProperties": false, "required": ["request_id", "enabled"], "properties": { "request_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "enabled": { "type": "boolean" }, "reason": { "type": "string", "maxLength": 1024 } } },
19
+ "approval_abandon": { "type": "object", "additionalProperties": false, "required": ["request_id", "run_id", "run_token", "approval_id"], "properties": { "request_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "run_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "run_token": { "type": "string", "maxLength": 1024, "minLength": 1 }, "approval_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "reason": { "type": "string", "maxLength": 1024 } } },
20
+ "close_run": { "type": "object", "additionalProperties": false, "required": ["request_id", "run_id", "run_token"], "properties": { "request_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "run_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "run_token": { "type": "string", "maxLength": 1024, "minLength": 1 }, "reason": { "type": "string", "maxLength": 256 }, "caller": { "type": "string", "maxLength": 256, "pattern": "^[a-z0-9_]+:.+(?![\\s\\S])" }, "last_client_seq": { "type": "array", "maxItems": 64, "items": { "type": "object", "additionalProperties": false, "required": ["stream", "client_seq"], "properties": { "stream": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "client_seq": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 } } } } } },
21
+ "delegate_run": { "type": "object", "additionalProperties": false, "required": ["run_id", "run_token", "identity"], "properties": { "run_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "run_token": { "type": "string", "maxLength": 1024, "minLength": 1 }, "identity": { "type": "string", "maxLength": 256, "pattern": "^[a-z0-9_]+:.+(?![\\s\\S])" } } },
22
+ "tailer_lost": { "type": "object", "additionalProperties": false, "required": ["request_id", "run_id", "run_token", "reason", "offset"], "properties": { "request_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "run_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "run_token": { "type": "string", "maxLength": 1024, "minLength": 1 }, "reason": { "type": "string", "maxLength": 1024 }, "offset": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 } } },
23
+ "tailer_heartbeat": { "type": "object", "additionalProperties": false, "required": ["run_id", "run_token"], "properties": { "run_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "run_token": { "type": "string", "maxLength": 1024, "minLength": 1 } } },
24
+ "observe_effect": { "type": "object", "additionalProperties": false, "required": ["request_id", "instance", "effects"], "properties": { "request_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "instance": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "effects": { "type": "array", "maxItems": 256, "items": { "type": "object", "additionalProperties": false, "required": ["kind", "host", "port", "bytes_out", "bytes_in", "connections", "first_ts", "last_ts"], "properties": { "run_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "run_token": { "type": "string", "maxLength": 1024, "minLength": 1 }, "caller": { "type": "string", "maxLength": 256, "pattern": "^[a-z0-9_]+:.+(?![\\s\\S])" }, "kind": { "const": "net" }, "host": { "type": "string", "maxLength": 253, "minLength": 1, "pattern": "^[a-z0-9._:-]+(?![\\s\\S])" }, "port": { "type": "integer", "minimum": 1, "maximum": 65535 }, "bytes_out": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "bytes_in": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "connections": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "first_ts": { "type": "string", "maxLength": 27, "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{6}Z(?![\\s\\S])" }, "last_ts": { "type": "string", "maxLength": 27, "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{6}Z(?![\\s\\S])" } } } }, "check": { "type": "object", "additionalProperties": false, "required": ["run_id", "run_token"], "properties": { "run_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "run_token": { "type": "string", "maxLength": 1024, "minLength": 1 } } } } },
25
+ "status": { "type": "object", "additionalProperties": false, "required": [], "properties": {} },
26
+ "read": { "type": "object", "additionalProperties": false, "required": ["run_id", "run_token"], "properties": { "run_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "run_token": { "type": "string", "maxLength": 1024, "minLength": 1 }, "from_seq": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "limit": { "type": "integer", "minimum": 1, "maximum": 1000 } } },
27
+ "checkpoint_nudge": { "type": "object", "additionalProperties": false, "required": [], "properties": {} },
28
+ "decision_import": { "type": "object", "additionalProperties": false, "required": ["request_id", "run_id", "system", "decision", "tool_call_id", "tool", "record"], "properties": { "request_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "run_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "system": { "type": "string", "maxLength": 64, "minLength": 1 }, "decision": { "enum": ["allow", "deny", "ask"] }, "tool_call_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "tool": { "type": "string", "maxLength": 256, "minLength": 1 }, "rule_ids": { "type": "array", "maxItems": 32, "items": { "type": "string", "maxLength": 64 } }, "reason": { "type": "string", "maxLength": 1024 }, "record": { "type": "string", "maxLength": 65536, "minLength": 1 }, "signature": { "type": "string", "maxLength": 128 } } },
29
+ "passkey_register": { "type": "object", "additionalProperties": false, "required": ["on_behalf", "credential_id", "public_key"], "properties": { "on_behalf": { "type": "object", "additionalProperties": false, "required": ["subject", "person"], "properties": { "subject": { "type": "string", "maxLength": 256, "minLength": 1 }, "person": { "type": "string", "maxLength": 256, "minLength": 1 }, "groups": { "type": "array", "maxItems": 64, "items": { "type": "string", "maxLength": 256 } }, "tenant": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" } } }, "credential_id": { "type": "string", "maxLength": 4096, "minLength": 1, "pattern": "^[A-Za-z0-9_-]+(?![\\s\\S])" }, "public_key": { "type": "string", "maxLength": 4096, "minLength": 1, "pattern": "^[A-Za-z0-9_-]+(?![\\s\\S])" } } },
30
+ "content_get": { "type": "object", "additionalProperties": false, "required": ["run_id", "seqs", "purpose"], "properties": { "run_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "seqs": { "type": "array", "maxItems": 1000, "items": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 } }, "purpose": { "type": "string", "maxLength": 512, "minLength": 1 } } },
31
+ "content_erase": { "type": "object", "additionalProperties": false, "required": ["request_id", "run_id"], "properties": { "request_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "run_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "reason": { "type": "string", "maxLength": 1024 } } },
32
+ "why_finding": { "type": "object", "additionalProperties": false, "required": ["request_id", "run_id", "run_token", "finding"], "properties": { "request_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "run_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "run_token": { "type": "string", "maxLength": 1024, "minLength": 1 }, "finding": { "type": "object", "additionalProperties": false, "required": ["target", "intervention", "n", "p_with", "p_without", "effect", "interval", "verdict", "replay_runs", "models", "rung", "off_tape", "investigation", "looks", "family", "min_effect", "applied", "stopped"], "properties": { "target": { "type": "string", "maxLength": 1024 }, "intervention": { "type": "string", "maxLength": 1024 }, "n": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "p_with": { "type": "number", "minimum": 0, "maximum": 1 }, "p_without": { "type": "number", "minimum": 0, "maximum": 1 }, "effect": { "type": "number", "minimum": -1, "maximum": 1 }, "interval": { "type": "array", "minItems": 2, "maxItems": 2, "items": { "type": "number", "minimum": -1, "maximum": 1 } }, "verdict": { "enum": ["causal", "suppressive", "ruled-out", "inconclusive", "not-applied"] }, "replay_runs": { "type": "array", "maxItems": 4096, "items": { "type": "object", "additionalProperties": false, "required": ["run_id", "arm", "hit"], "properties": { "run_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "arm": { "enum": ["control", "ablated"] }, "hit": { "type": "boolean" } } } }, "models": { "type": "array", "maxItems": 32, "items": { "type": "string", "maxLength": 128 } }, "rung": { "enum": [1, 2] }, "off_tape": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "investigation": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "looks": { "type": "integer", "minimum": 1, "maximum": 4096 }, "family": { "type": "integer", "minimum": 1, "maximum": 4096 }, "min_effect": { "type": "number", "minimum": 0, "maximum": 1 }, "applied": { "type": "boolean" }, "stopped": { "enum": ["decisive", "futility", "n_max", "budget"] }, "uncounted": { "type": "array", "maxItems": 4096, "items": { "type": "object", "additionalProperties": false, "required": ["run_id", "reason"], "properties": { "run_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "reason": { "enum": ["ranking", "budget"] } } } } } } } },
33
+ "incident_list": { "type": "object", "additionalProperties": false, "required": [], "properties": { "state": { "enum": ["open", "resolved"] }, "cursor": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "limit": { "type": "integer", "minimum": 1, "maximum": 1000 } } },
34
+ "incident_show": { "type": "object", "additionalProperties": false, "required": ["incident_id"], "properties": { "incident_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" } } },
35
+ "incident_resolve": { "type": "object", "additionalProperties": false, "required": ["request_id", "incident_id"], "properties": { "request_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "incident_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "reason": { "type": "string", "maxLength": 1024 } } },
36
+ "run_hold": { "type": "object", "additionalProperties": false, "required": ["request_id", "run_id"], "properties": { "request_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "run_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "reason": { "type": "string", "maxLength": 1024 } } },
37
+ "run_quarantine": { "type": "object", "additionalProperties": false, "required": ["request_id", "run_id"], "properties": { "request_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "run_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "reason": { "type": "string", "maxLength": 1024 } } },
38
+ "run_resume": { "type": "object", "additionalProperties": false, "required": ["request_id", "run_id"], "properties": { "request_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "run_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "reason": { "type": "string", "maxLength": 1024 } } },
39
+ "response_pause": { "type": "object", "additionalProperties": false, "required": ["request_id"], "properties": { "request_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "reason": { "type": "string", "maxLength": 1024 } } },
40
+ "response_resume": { "type": "object", "additionalProperties": false, "required": ["request_id"], "properties": { "request_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "reason": { "type": "string", "maxLength": 1024 } } },
41
+ "suspend": { "type": "object", "additionalProperties": false, "required": ["request_id", "identity"], "properties": { "request_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "identity": { "type": "string", "maxLength": 256, "pattern": "^[a-z0-9_]+:.+(?![\\s\\S])" }, "reason": { "type": "string", "maxLength": 1024 } } },
42
+ "unsuspend": { "type": "object", "additionalProperties": false, "required": ["request_id", "identity"], "properties": { "request_id": { "type": "string", "maxLength": 128, "minLength": 1, "pattern": "^[A-Za-z0-9._:-]+(?![\\s\\S])" }, "identity": { "type": "string", "maxLength": 256, "pattern": "^[a-z0-9_]+:.+(?![\\s\\S])" }, "reason": { "type": "string", "maxLength": 1024 } } },
43
+ };
@@ -0,0 +1,6 @@
1
+ /** The JSON Schema subset of tracekit/schema.py `_check`, as rpc_schema.validate uses it (patterns searched, not anchored). */
2
+ export type Schema = {
3
+ [keyword: string]: any;
4
+ };
5
+ /** Error strings for `v` against `s` (empty when valid); throws on a keyword it doesn't implement, like `_check`. */
6
+ export declare function validate(s: Schema, v: any, path?: string, errs?: string[]): string[];
@@ -0,0 +1,70 @@
1
+ const TYPES = {
2
+ object: (v) => typeof v === "object" && v !== null && !Array.isArray(v),
3
+ array: Array.isArray,
4
+ string: (v) => typeof v === "string",
5
+ integer: Number.isInteger,
6
+ number: (v) => typeof v === "number",
7
+ boolean: (v) => typeof v === "boolean",
8
+ null: (v) => v === null,
9
+ };
10
+ const KEYWORDS = new Set(["type", "const", "enum", "pattern", "minLength", "maxLength", "minimum", "maximum", "minItems", "maxItems",
11
+ "items", "required", "properties", "additionalProperties", "oneOf", "if", "then"]);
12
+ /** Error strings for `v` against `s` (empty when valid); throws on a keyword it doesn't implement, like `_check`. */
13
+ export function validate(s, v, path = "$", errs = []) {
14
+ const unknown = Object.keys(s).filter((k) => !KEYWORDS.has(k));
15
+ if (unknown.length)
16
+ throw new Error(`unsupported schema keywords at ${path}: ${unknown.join(", ")}`);
17
+ if ("type" in s) {
18
+ const ts = Array.isArray(s.type) ? s.type : [s.type];
19
+ if (!ts.some((t) => TYPES[t](v))) {
20
+ errs.push(`${path}: expected ${ts.join("/")}`);
21
+ return errs;
22
+ }
23
+ }
24
+ if ("const" in s && v !== s.const)
25
+ errs.push(`${path}: must be ${JSON.stringify(s.const)}`);
26
+ if ("enum" in s && !s.enum.includes(v))
27
+ errs.push(`${path}: ${JSON.stringify(v)} not in ${JSON.stringify(s.enum)}`);
28
+ if (typeof v === "string") {
29
+ if ("pattern" in s && !new RegExp(s.pattern).test(v))
30
+ errs.push(`${path}: does not match ${s.pattern}`);
31
+ const n = [...v].length; // code points, like Python's len
32
+ if ("minLength" in s && n < s.minLength)
33
+ errs.push(`${path}: shorter than ${s.minLength}`);
34
+ if ("maxLength" in s && n > s.maxLength)
35
+ errs.push(`${path}: longer than ${s.maxLength}`);
36
+ }
37
+ if (typeof v === "number" && "minimum" in s && v < s.minimum)
38
+ errs.push(`${path}: below ${s.minimum}`);
39
+ if (typeof v === "number" && "maximum" in s && v > s.maximum)
40
+ errs.push(`${path}: above ${s.maximum}`);
41
+ if (Array.isArray(v)) {
42
+ if ("maxItems" in s && v.length > s.maxItems)
43
+ errs.push(`${path}: more than ${s.maxItems} items`);
44
+ if ("minItems" in s && v.length < s.minItems)
45
+ errs.push(`${path}: fewer than ${s.minItems} items`);
46
+ if ("items" in s)
47
+ v.forEach((it, i) => validate(s.items, it, `${path}[${i}]`, errs));
48
+ }
49
+ if (TYPES.object(v)) {
50
+ for (const k of s.required ?? [])
51
+ if (!Object.hasOwn(v, k))
52
+ errs.push(`${path}: missing required '${k}'`);
53
+ for (const [k, val] of Object.entries(v)) {
54
+ if (s.properties && Object.hasOwn(s.properties, k))
55
+ validate(s.properties[k], val, `${path}.${k}`, errs);
56
+ else if (s.additionalProperties === false)
57
+ errs.push(`${path}: unexpected field '${k}'`);
58
+ else if (typeof s.additionalProperties === "object")
59
+ validate(s.additionalProperties, val, `${path}.${k}`, errs);
60
+ }
61
+ }
62
+ if ("oneOf" in s) {
63
+ const matched = s.oneOf.filter((sub) => !validate(sub, v, path).length).length;
64
+ if (matched !== 1)
65
+ errs.push(`${path}: must match exactly one alternative (matched ${matched})`);
66
+ }
67
+ if ("if" in s && !validate(s.if, v, path).length && "then" in s)
68
+ validate(s.then, v, path, errs);
69
+ return errs;
70
+ }
@@ -0,0 +1 @@
1
+ export declare function main(argv: string[]): Promise<number>;
@@ -0,0 +1,46 @@
1
+ /**
2
+ * `npx @cygnuxlabs/tracekit verify BUNDLE --trust trust.json [--json] [--strict]`: the TypeScript verifier, with the reference
3
+ * CLI's report and exit codes (0 verified, 1 failed, 2 unusable or unverifiable, 3 a warning under --strict).
4
+ */
5
+ import { readFile } from "node:fs/promises";
6
+ import { EXIT_BAD, EXIT_OK, EXIT_WARN, formatReport, verify } from "./index.js";
7
+ const USAGE = "usage: tracekit verify BUNDLE --trust TRUST.json [--json] [--strict]";
8
+ export async function main(argv) {
9
+ let bundle, trust, json = false, strict = false;
10
+ for (let i = 0; i < argv.length; i++) {
11
+ const a = argv[i];
12
+ if (a === "--trust" && i + 1 < argv.length)
13
+ trust = argv[++i];
14
+ else if (a === "--json")
15
+ json = true;
16
+ else if (a === "--strict")
17
+ strict = true;
18
+ else if (!a.startsWith("-") && bundle === undefined)
19
+ bundle = a;
20
+ else {
21
+ console.error(`tracekit verify: ${a} is not supported by the TypeScript verifier (the format bridge, monitor reports `
22
+ + `and revocations need the reference verifier: pip install tracekit)\n${USAGE}`);
23
+ return EXIT_BAD;
24
+ }
25
+ }
26
+ if (!bundle || !trust) {
27
+ console.error(USAGE);
28
+ return EXIT_BAD;
29
+ }
30
+ let data;
31
+ try {
32
+ data = [await readFile(bundle), await readFile(trust)];
33
+ }
34
+ catch (e) {
35
+ console.error(`tracekit verify: ${e.message}`);
36
+ return EXIT_BAD;
37
+ }
38
+ const { report, code: verdict } = await verify(...data);
39
+ const code = verdict === EXIT_OK && strict && report.warnings.length ? EXIT_WARN : verdict;
40
+ if (json)
41
+ console.log(JSON.stringify({ exit_code: code, checks: report.checks, failures: report.failures,
42
+ warnings: report.warnings, integrity: report.integrity, assurance: report.assurance, notes: report.notes }, null, 2));
43
+ else
44
+ process.stdout.write(formatReport(report));
45
+ return code;
46
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * tracekit/signer/detect.py's Detector, without the decision's `detect` view: which incidents a run's records fire,
3
+ * for the verifier's `incidents` check. A port kept in step with the reference by tests/test_ts_verifier.py.
4
+ */
5
+ type J = any;
6
+ type Fired = [string, string[], string, {
7
+ kind: string;
8
+ id: string;
9
+ }, [string, number][]];
10
+ export declare class Detector {
11
+ label: Map<string, string>;
12
+ untrusted: Set<string>;
13
+ deny: Set<string>;
14
+ sequences: J[];
15
+ limits: J[];
16
+ respond: Map<string, any>;
17
+ every: Map<string, number>;
18
+ idle: number;
19
+ tools: Record<string, string>;
20
+ constructor(policy: J);
21
+ toolClass(tool: string): string;
22
+ names(ids: string[]): Set<string>;
23
+ on(trigger: string): boolean;
24
+ static state(): {
25
+ runs: Map<string, any>;
26
+ scopes: Map<string, any>;
27
+ minute: Map<string, number[]>;
28
+ };
29
+ scope(det: J, e: J, run: J, kind: string): [string, {
30
+ kind: string;
31
+ id: string;
32
+ }, J];
33
+ /** The incident records (type, data without ids) record `e` fires, after indexing it into `det`. */
34
+ observe(det: J, e: J): [string, J][];
35
+ /** As detect.py's _count: `unless` exempts only a call the policy's own reading names, never one a hint added. */
36
+ count(det: J, e: J, run: J, names: Set<string>, unknown: boolean, sums: J, hinted: boolean, cite: [string, number], fired: Fired[]): void;
37
+ denied(det: J, e: J, run: J, t: number, cite: [string, number], fired: Fired[]): void;
38
+ incidents(det: J, e: J, run: J, t: number, fired: Fired[]): [string, J][];
39
+ countIncident(det: J, e: J, run: J, t: number): void;
40
+ }
41
+ export {};