fix(wechat): bind protected dispatch provider schema

This commit is contained in:
ChatGPT Release Governance
2026-07-22 13:21:47 +08:00
parent 05835675b6
commit 4b35eb52cb
2 changed files with 19 additions and 4 deletions
+8 -2
View File
@@ -24,11 +24,16 @@ const MAX_RUN_AGE_MS = 60 * 60 * 1000;
const MAX_DISPATCH_CACHE_AGE_MS = 60 * 60 * 1000;
const MAX_SECURITY_CACHE_ENTRIES = 4096;
const DEFAULT_PERMIT_TTL_MS = 2 * 60 * 1000;
const DEFAULT_PROTECTED_DISPATCH_PROVIDER = "chatgpt-supervisor";
function pluginConfig(event, api) {
return event?.context?.pluginConfig ?? api.pluginConfig ?? {};
}
function protectedDispatchProvider(config = {}) {
return String(config.protectedDispatchProvider || DEFAULT_PROTECTED_DISPATCH_PROVIDER);
}
function trimToLimit(map, limit = MAX_SECURITY_CACHE_ENTRIES) {
while (map.size > limit) map.delete(map.keys().next().value);
}
@@ -148,7 +153,7 @@ export function authorizeProtectedDispatchCall({ event, ctx = {}, trust, config,
const params = eventParams(event);
const paramsCheck = protectedDispatchParams(params);
if (!paramsCheck.ok) return paramsCheck;
const expectedProvider = String(config.protectedDispatchProvider || "chatgpt-supervisor");
const expectedProvider = protectedDispatchProvider(config);
if (params.provider !== expectedProvider) return { ok: false, code: "provider_mismatch" };
const runId = runKey(event, ctx) || trust.runId;
const agentId = String(ctx.agentId || trust.agentId || "");
@@ -274,6 +279,7 @@ function registerWriterTool(api) {
}
function registerProtectedDispatchTool(api) {
const expectedProvider = protectedDispatchProvider(api.pluginConfig);
api.registerTool(() => ({
name: "aios_protected_dispatch",
label: "AIOS Protected Dispatch",
@@ -284,7 +290,7 @@ function registerProtectedDispatchTool(api) {
required: ["task_id", "provider", "action", "payload", "idempotency_key"],
properties: {
task_id: { type: "string" },
provider: { type: "string" },
provider: { type: "string", enum: [expectedProvider] },
action: { type: "string" },
payload: { type: "object" },
idempotency_key: { type: "string" },
@@ -193,7 +193,9 @@ test("plugin registers the native writer factory and required hook names", () =>
assert.equal(tool.name, "aios_evidence_write");
assert.equal(tool.label, "AIOS Evidence Writer");
assert.equal(tool.executionMode, "sequential");
assert.equal(factories.aios_protected_dispatch({}).name, "aios_protected_dispatch");
const protectedTool = factories.aios_protected_dispatch({});
assert.equal(protectedTool.name, "aios_protected_dispatch");
assert.deepEqual(protectedTool.parameters.properties.provider.enum, ["chatgpt-supervisor"]);
assert.deepEqual(routes.map((route) => route.path), ["/v1/health", "/v1/execute", "/v1/commands/"]);
assert.deepEqual(hooks.sort(), ["agent_end", "before_agent_run", "before_tool_call"]);
});
@@ -340,6 +342,7 @@ test("explicitly blocked senders and strict conversation mode stay fail-closed",
function ownerPluginFixture({
mockFailFirstDelivery = false,
ownerTtlMs = 60_000,
protectedDispatchProvider = "chatgpt-supervisor",
trustedSenderIds = ["synthetic-owner", "synthetic-user-a", "synthetic-user-b"],
} = {}) {
const root = fs.mkdtempSync(path.join(os.tmpdir(), "aios-owner-plugin-"));
@@ -362,7 +365,7 @@ function ownerPluginFixture({
provenancePublicKeyPath: publicKeyPath,
provenanceKeyId: "owner-key-1",
tenantId: "v2r1c2-wechat-acceptance",
protectedDispatchProvider: "chatgpt-supervisor",
protectedDispatchProvider,
protectedDispatchTransport: "mock",
mockFailFirstDelivery,
ownerProvenanceTtlMs: ownerTtlMs,
@@ -380,6 +383,12 @@ function ownerPluginFixture({
return { root, keys, api, hooks, factories };
}
test("protected dispatch schema constrains provider to the configured value", () => {
const fixtureValue = ownerPluginFixture({ protectedDispatchProvider: "configured-supervisor" });
const tool = fixtureValue.factories.aios_protected_dispatch({});
assert.deepEqual(tool.parameters.properties.provider.enum, ["configured-supervisor"]);
});
async function startSyntheticRun(fixtureValue, { senderId, senderIsOwner, runId }) {
const event = {
prompt: "synthetic acceptance message", messages: [], accountId: "sandbox",