diff --git a/.changeset/untrack-compiled-compliance-modules.md b/.changeset/untrack-compiled-compliance-modules.md new file mode 100644 index 00000000000..6a5db60182b --- /dev/null +++ b/.changeset/untrack-compiled-compliance-modules.md @@ -0,0 +1,5 @@ +--- +"adcontextprotocol": patch +--- + +Stop tracking the compiled `storyboard-runner-options` module at the top level of `dist/compliance/`. It is a build output of `server/src/compliance/`, stale since adcp#8272, and nothing imports the committed copy. The released `dist/compliance//` bundles are unchanged. diff --git a/.gitignore b/.gitignore index 2501c634500..8a053b25e1c 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,10 @@ server/node_modules /dist/schemas/*.js.map /dist/schemas/*.d.ts /dist/schemas/*.d.ts.map +/dist/compliance/*.js +/dist/compliance/*.js.map +/dist/compliance/*.d.ts +/dist/compliance/*.d.ts.map /dist/compliance/latest /dist/compliance/v* /dist/protocol/latest.tgz diff --git a/dist/compliance/storyboard-runner-options.d.ts b/dist/compliance/storyboard-runner-options.d.ts deleted file mode 100644 index 8e49a3d60a5..00000000000 --- a/dist/compliance/storyboard-runner-options.d.ts +++ /dev/null @@ -1,102 +0,0 @@ -import type { StoryboardRunOptions } from '@adcp/sdk/testing'; -export interface LoadedTestKit { - brand?: { - house?: { - domain?: string; - }; - brand_id?: string; - }; - commercial_relationship?: string; - auth?: { - api_key?: string; - basic?: { - username?: string; - password?: string; - credentials?: string; - }; - probe_task?: string; - }; -} -/** - * Per-tenant probe-task override for security_baseline's auth probes. - * - * Most shared test-kits declare `auth.probe_task: list_creatives`, but cached - * prerelease kits can lag the allowlist. Sales/creative explicitly pin the - * allowlisted protected read they serve. /signals and /governance serve - * different SDK-allowlisted protected reads. - */ -export declare const PROBE_TASK_BY_TENANT: Record; -/** - * Thread the test-kit's auth material through to the storyboard runner so - * kit-gated auth phases execute instead of being skipped by `skip_if`. - */ -export declare function testKitOptionsFromKit(kit: LoadedTestKit | undefined, tenantPath?: string | undefined): StoryboardRunOptions['test_kit'] | undefined; -/** - * Pick run-scoped transport auth for the manual storyboard runner. - * - * `security_baseline` positive credential probes use normal initialized - * transport calls, so a single run can only prove one static credential type. - * Dual-credential kits must be split into per-mechanism runs before they can - * be graded safely here. - */ -export declare function authForStoryboard(storyboardId: string, kit: LoadedTestKit | undefined, defaultBearerToken: string): StoryboardRunOptions['auth']; -/** Training-agent tenants served under `//mcp` by one process. */ -export declare const TRAINING_AGENT_TENANTS: ReadonlySet; -/** Structural subset of a storyboard the multi-agent router reads. */ -export interface MultiAgentStoryboardShape { - id: string; - requires?: readonly string[]; - default_agent?: string; - context?: Record; - phases?: ReadonlyArray<{ - steps?: ReadonlyArray<{ - agent?: string; - }>; - }>; -} -export interface MultiAgentRoutingInput { - storyboard: MultiAgentStoryboardShape; - /** Tenant whose job is running the storyboard (TENANT_PATH). */ - tenantPath: string; - /** Endpoint of the tenant under test. */ - tenantAgentUrl: string; - /** Path-routed base serving every tenant, e.g. `http://127.0.0.1:1234/api/training-agent`. */ - trainingAgentBaseUrl: string; - /** - * Canonical base the training agent identifies its tenants under - * (`/` is the audience a governed tenant verifies). - */ - serviceIdentityBase: string; - auth: StoryboardRunOptions['auth']; -} -/** - * Authored context keys that name the governed agent under test. Governed - * storyboards bind the governance token's `aud` to this value and tell the - * runner to override it with the endpoint under test. - */ -export declare const GOVERNED_AGENT_CONTEXT_KEYS: readonly ['seller_agent_url', 'signal_agent_url', 'brand_agent_url', 'creative_agent_url']; -export type MultiAgentRouting = { - kind: 'single_agent'; -} | { - kind: 'routed'; - agents: NonNullable; - default_agent: string; - context: Record; -}; -/** - * Route a `requires: [multi_agent]` storyboard across training-agent tenants. - * - * Storyboard agent keys name training-agent tenants (`sales`, `governance`, - * `brand`, `signals`, `creative-builder`, ...). The storyboard's - * `default_agent` is the agent under test, so it must be the tenant whose job - * is running it; it keeps the exact tenant URL the job selected. Every other - * key routes to its sibling tenant in the same training-agent process with the - * same credentials. Controller seeding follows the routed agent that owns - * each fixture. The authored context keys that name the governed agent - * (`signal_agent_url`, ...) are overridden with that tenant's service - * identity, as the storyboards' prerequisites instruct. Storyboards that do - * not require `multi_agent` are left untouched so single-tenant runs keep - * their existing behavior. - */ -export declare function multiAgentRoutingForStoryboard(input: MultiAgentRoutingInput): MultiAgentRouting; -//# sourceMappingURL=storyboard-runner-options.d.ts.map \ No newline at end of file diff --git a/dist/compliance/storyboard-runner-options.d.ts.map b/dist/compliance/storyboard-runner-options.d.ts.map deleted file mode 100644 index 540c43083aa..00000000000 --- a/dist/compliance/storyboard-runner-options.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"storyboard-runner-options.d.ts","sourceRoot":"","sources":["../../server/src/compliance/storyboard-runner-options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAE9D,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE;YAAE,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3D,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,IAAI,CAAC,EAAE;QACL,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,KAAK,CAAC,EAAE;YAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;YAAC,WAAW,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QACvE,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAKvD,CAAC;AAEF;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,aAAa,GAAG,SAAS,EAC9B,UAAU,qBAA0B,GACnC,oBAAoB,CAAC,UAAU,CAAC,GAAG,SAAS,CAkB9C;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,MAAM,EACpB,GAAG,EAAE,aAAa,GAAG,SAAS,EAC9B,kBAAkB,EAAE,MAAM,GACzB,oBAAoB,CAAC,MAAM,CAAC,CAmC9B;AAED,gFAAgF;AAChF,eAAO,MAAM,sBAAsB,EAAE,WAAW,CAAC,MAAM,CAQrD,CAAC;AAEH,sEAAsE;AACtE,MAAM,WAAW,yBAAyB;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,MAAM,CAAC,EAAE,aAAa,CAAC;QAAE,KAAK,CAAC,EAAE,aAAa,CAAC;YAAE,KAAK,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC,CAAC;CACvE;AAED,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,yBAAyB,CAAC;IACtC,gEAAgE;IAChE,UAAU,EAAE,MAAM,CAAC;IACnB,yCAAyC;IACzC,cAAc,EAAE,MAAM,CAAC;IACvB,8FAA8F;IAC9F,oBAAoB,EAAE,MAAM,CAAC;IAC7B;;;OAGG;IACH,mBAAmB,EAAE,MAAM,CAAC;IAC5B,IAAI,EAAE,oBAAoB,CAAC,MAAM,CAAC,CAAC;CACpC;AAED;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,YACtC,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,oBAAoB,CACZ,CAAC;AAEX,MAAM,MAAM,iBAAiB,GACzB;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,GACxB;IACA,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,WAAW,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC,CAAC;IACpD,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC,CAAC;AAEJ;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,sBAAsB,GAAG,iBAAiB,CAwC/F"} \ No newline at end of file diff --git a/dist/compliance/storyboard-runner-options.js b/dist/compliance/storyboard-runner-options.js deleted file mode 100644 index c971881e1c4..00000000000 --- a/dist/compliance/storyboard-runner-options.js +++ /dev/null @@ -1,151 +0,0 @@ -/** - * Per-tenant probe-task override for security_baseline's auth probes. - * - * Most shared test-kits declare `auth.probe_task: list_creatives`, but cached - * prerelease kits can lag the allowlist. Sales/creative explicitly pin the - * allowlisted protected read they serve. /signals and /governance serve - * different SDK-allowlisted protected reads. - */ -export const PROBE_TASK_BY_TENANT = { - sales: 'list_creatives', - creative: 'list_creatives', - signals: 'get_signals', - governance: 'list_content_standards', -}; -/** - * Thread the test-kit's auth material through to the storyboard runner so - * kit-gated auth phases execute instead of being skipped by `skip_if`. - */ -export function testKitOptionsFromKit(kit, tenantPath = process.env.TENANT_PATH) { - const auth = kit?.auth; - if (!auth?.api_key && !auth?.basic && !auth?.probe_task) - return undefined; - if (!auth.probe_task) { - throw new Error('test kit declares auth credentials without auth.probe_task — required by runner'); - } - const probeTask = (tenantPath && PROBE_TASK_BY_TENANT[tenantPath]) ?? auth.probe_task; - const commercialRelationship = kit?.commercial_relationship; - return { - ...(commercialRelationship !== undefined && { - commercial_relationship: commercialRelationship, - }), - auth: { - ...(auth.api_key !== undefined && { api_key: auth.api_key }), - ...(auth.basic !== undefined && { basic: auth.basic }), - probe_task: probeTask, - }, - }; -} -/** - * Pick run-scoped transport auth for the manual storyboard runner. - * - * `security_baseline` positive credential probes use normal initialized - * transport calls, so a single run can only prove one static credential type. - * Dual-credential kits must be split into per-mechanism runs before they can - * be graded safely here. - */ -export function authForStoryboard(storyboardId, kit, defaultBearerToken) { - if (storyboardId === 'security_baseline' && kit?.auth?.api_key && kit.auth.basic) { - throw new Error('security_baseline test kit declares both auth.api_key and auth.basic; manual runner cannot grade both initialized-session credential paths in one run'); - } - if ((storyboardId === 'billing_gate_dispatch' || - storyboardId === 'comply_controller_mode_gate' || - storyboardId === 'security_baseline') && - kit?.auth?.api_key) { - return { type: 'bearer', token: kit.auth.api_key }; - } - if (storyboardId === 'security_baseline' && kit?.auth?.basic) { - const { username, password, credentials } = kit.auth.basic; - if (typeof username === 'string' && username && typeof password === 'string') { - return { type: 'basic', username, password }; - } - if (typeof credentials === 'string') { - const colonIndex = credentials.indexOf(':'); - if (colonIndex > 0) { - return { - type: 'basic', - username: credentials.slice(0, colonIndex), - password: credentials.slice(colonIndex + 1), - }; - } - } - throw new Error('security_baseline auth.basic must provide a non-empty username and a password string, or credentials in "username:password" form; the password may be empty'); - } - return { type: 'bearer', token: defaultBearerToken }; -} -/** Training-agent tenants served under `//mcp` by one process. */ -export const TRAINING_AGENT_TENANTS = new Set([ - 'signals', - 'sales', - 'governance', - 'creative', - 'creative-builder', - 'brand', - 'si', -]); -/** - * Authored context keys that name the governed agent under test. Governed - * storyboards bind the governance token's `aud` to this value and tell the - * runner to override it with the endpoint under test. - */ -export const GOVERNED_AGENT_CONTEXT_KEYS = [ - 'seller_agent_url', - 'signal_agent_url', - 'brand_agent_url', - 'creative_agent_url', -]; -/** - * Route a `requires: [multi_agent]` storyboard across training-agent tenants. - * - * Storyboard agent keys name training-agent tenants (`sales`, `governance`, - * `brand`, `signals`, `creative-builder`, ...). The storyboard's - * `default_agent` is the agent under test, so it must be the tenant whose job - * is running it; it keeps the exact tenant URL the job selected. Every other - * key routes to its sibling tenant in the same training-agent process with the - * same credentials. Controller seeding follows the routed agent that owns - * each fixture. The authored context keys that name the governed agent - * (`signal_agent_url`, ...) are overridden with that tenant's service - * identity, as the storyboards' prerequisites instruct. Storyboards that do - * not require `multi_agent` are left untouched so single-tenant runs keep - * their existing behavior. - */ -export function multiAgentRoutingForStoryboard(input) { - const { storyboard } = input; - if (!storyboard.requires?.includes('multi_agent')) - return { kind: 'single_agent' }; - const defaultAgent = storyboard.default_agent; - if (!defaultAgent) { - throw new Error(`${storyboard.id} requires multi_agent but declares no default_agent; cannot tell which tenant is under test`); - } - if (defaultAgent !== input.tenantPath) { - throw new Error(`${storyboard.id} routes its default_agent "${defaultAgent}" but is running under tenant "${input.tenantPath}"; run it from the ${defaultAgent} tenant`); - } - const keys = new Set([defaultAgent]); - for (const phase of storyboard.phases ?? []) { - for (const step of phase.steps ?? []) { - if (step.agent !== undefined) - keys.add(step.agent); - } - } - const base = input.trainingAgentBaseUrl.replace(/\/+$/, ''); - const agents = {}; - for (const key of keys) { - if (!TRAINING_AGENT_TENANTS.has(key)) { - throw new Error(`${storyboard.id} routes agent key "${key}", which is not a training-agent tenant`); - } - agents[key] = { - url: key === defaultAgent ? input.tenantAgentUrl : `${base}/${key}/mcp`, - ...(input.auth && { auth: input.auth }), - }; - } - // The governed tenant identifies itself as `/`; that - // is the audience it verifies, so it is the value the buyer must name. - const identityBase = input.serviceIdentityBase.replace(/\/+$/, ''); - const context = {}; - for (const key of GOVERNED_AGENT_CONTEXT_KEYS) { - if (storyboard.context?.[key] !== undefined) - context[key] = `${identityBase}/${defaultAgent}`; - } - return { kind: 'routed', agents, default_agent: defaultAgent, context }; -} -//# sourceMappingURL=storyboard-runner-options.js.map \ No newline at end of file diff --git a/dist/compliance/storyboard-runner-options.js.map b/dist/compliance/storyboard-runner-options.js.map deleted file mode 100644 index 8ed0e09f4b6..00000000000 --- a/dist/compliance/storyboard-runner-options.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"storyboard-runner-options.js","sourceRoot":"","sources":["../../server/src/compliance/storyboard-runner-options.ts"],"names":[],"mappings":"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"} \ No newline at end of file