fix: restrict AI Workspace denial text to explicit denies

This commit is contained in:
Codex
2026-06-25 10:13:39 +03:00
parent 5953b1bd0e
commit 1aceabee44
6 changed files with 40 additions and 18 deletions
+15 -7
View File
@@ -2101,6 +2101,7 @@ async function buildRunProfile({ owner, thread, executor, ownerSettings, bridgeP
appCatalogIds: appCatalog.map((app) => app.appId).sort(),
grantedAppIds: appAccess.grantedAppIds,
deniedAppIds: appAccess.deniedAppIds,
notGrantedAppIds: appAccess.notGrantedAppIds,
entitlementAdapters: grantResolution.diagnostics,
mcpServerNames,
requiredMcpServerNames,
@@ -2611,11 +2612,12 @@ function buildRunProfileAppCatalog({ appGrants, mcpServers, assistantActions })
skillId: entry.skillId,
status,
granted: status === "granted",
denied: status !== "granted",
deniedReason: status !== "granted"
denied: status === "denied",
notGranted: status === "not-granted",
deniedReason: status === "denied"
? optionalString(grant?.reason || grant?.deniedReason || grant?.denied_reason || grant?.status) || status
: null,
deniedText: status !== "granted"
deniedText: status === "denied"
? optionalString(grant?.deniedText || grant?.denied_text) || entry.deniedText || ACCESS_DENIED_TEXT
: null,
whenToUse: uniqueStrings(entry.whenToUse),
@@ -2633,9 +2635,9 @@ function summarizeRunAppAccess(appCatalog) {
return {
schemaVersion: "ai-workspace.app-access.v1",
grantedAppIds: apps.filter((app) => app?.granted === true).map((app) => app.appId).sort(),
deniedAppIds: apps.filter((app) => app?.granted !== true).map((app) => app.appId).sort(),
deniedAppIds: apps.filter((app) => app?.status === "denied" || app?.denied === true).map((app) => app.appId).sort(),
notGrantedAppIds: apps.filter((app) => app?.status === "not-granted").map((app) => app.appId).sort(),
availableSkillIds: apps.filter((app) => app?.granted === true).map((app) => app.skillId).filter(Boolean).sort(),
deniedText: ACCESS_DENIED_TEXT,
};
}
@@ -2659,16 +2661,22 @@ function buildRunProfilePolicyPrompt({ context, diagnostics, assistantActions })
`- entitlement source: ${diagnostics.entitlementAdapters?.source || "settings"}`,
`- enabled tool packs: ${diagnostics.enabledToolPacks.length ? diagnostics.enabledToolPacks.join(", ") : "none"}`,
`- app routes granted: ${diagnostics.grantedAppIds.length ? diagnostics.grantedAppIds.join(", ") : "none"}`,
`- app routes denied/not granted: ${diagnostics.deniedAppIds.length ? diagnostics.deniedAppIds.join(", ") : "none"}`,
`- MCP servers available in this run: ${diagnostics.mcpServerNames.length ? diagnostics.mcpServerNames.join(", ") : "none"}`,
`- assistant action ids available: ${Array.isArray(assistantActions?.actionIds) ? assistantActions.actionIds.join(", ") : "none"}`,
"- Interpret the user's natural-language request first; call assistant actions only after selecting a structured action id.",
"- Read assistant actions may execute after structured action selection. Privileged/write assistant actions require preview, explicit user confirmation, then execute.",
"- Ops card actions advertised in this run are valid assistant actions: use ops.card.list_recent for reading cards, ops.card.create for creating cards, and ops.card.add_comment for comments instead of refusing because direct Ops MCP tools are absent.",
"- Destructive assistant actions are forbidden; offer safe alternatives such as block/disable instead of delete.",
`- If the user requests a denied or not-granted app capability, do not bypass it. Say exactly: ${ACCESS_DENIED_TEXT}`,
"- MCP tokens and headers are runtime secrets and must never be printed in public answers.",
];
if (diagnostics.deniedAppIds.length) {
lines.push(
`- App routes explicitly denied by access control: ${diagnostics.deniedAppIds.join(", ")}.`,
`- If the user requests one of those explicitly denied app capabilities, do not bypass it. Say exactly: ${ACCESS_DENIED_TEXT}`,
);
} else {
lines.push("- No app route is explicitly denied in this run; do not claim module access is restricted.");
}
const opsContext = isPlainObject(context?.contexts?.ops) ? context.contexts.ops : {};
if (opsContext.opsWorkspaceSlug || opsContext.opsProjectId) {
lines.push(