* fix(#1151): drive codex sandbox_mode emission from runtime descriptor sandboxTier axis The sandboxTier runtime-capability axis was cosmetic: declared and validated on all 16 descriptors but read by nothing. The codex per-agent sandbox_mode line was emitted unconditionally from the hardcoded CODEX_AGENT_SANDBOX map, so the descriptor field drove no behaviour (ADR-857 audit finding F10; the "rides along in 5e/5g" promise in ADR-1016 §8 never landed). Make the axis load-bearing: - resolveInstallPlan projects sandboxTier as a 7th InstallPlan axis and fails loud (throws) on a missing/invalid value rather than coercing to 'none'. - installCodexConfig / generateCodexAgentToml gate sandbox_mode emission on sandboxTier !== 'none'. - The per-agent CODEX_AGENT_SANDBOX map is kept: it is GSD agent policy, not a runtime-descriptor property (different layer). Full removal of that map is tracked under #1138 (phase-6 descriptor-residue removal). For codex (sandboxTier === 'codex-agent-sandbox') the emitted TOML is byte-identical to before; for 'none' runtimes sandbox_mode is omitted. Adds leaf, projection, and installCodexConfig threading-seam regression tests; updates the enh-1082 InstallPlan golden master with sandboxTier for all 16 runtimes. Confirmed hypothesis: schema-first vocabulary closure outran consumer wiring, with no conformance gate to catch the orphaned axis. Closes #1151 Refs #857, #1138 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(#1151): stamp changeset with PR number 1152 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -30,6 +30,9 @@
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
const { runtimes } = require('./capability-registry.cjs') as { runtimes: Record<string, { runtime: Record<string, unknown> | undefined }> };
|
||||
|
||||
/** Valid sandboxTier enum values — mirrors the gen-capability-registry validator vocabulary. */
|
||||
const VALID_SANDBOX_TIERS = new Set(['none', 'codex-agent-sandbox']);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Types
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -71,6 +74,8 @@ interface InstallPlan extends RuntimeConfigIntent {
|
||||
extendedHookEvents: string[];
|
||||
/** Which surface owns the hook registration for this runtime. */
|
||||
hooksSurface: HooksSurface;
|
||||
/** Runtime sandbox tier ('none' | 'codex-agent-sandbox'); gates per-agent sandbox_mode emission. */
|
||||
sandboxTier: string;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -130,6 +135,10 @@ function resolveInstallPlan(runtime: string): InstallPlan {
|
||||
const desc = runtimes[runtime]?.runtime;
|
||||
if (!desc) throw new TypeError(`Unknown runtime for install plan: ${runtime}`);
|
||||
const configIntent = resolveRuntimeConfigIntent(runtime);
|
||||
const sandboxTier = desc['sandboxTier'];
|
||||
if (typeof sandboxTier !== 'string' || !VALID_SANDBOX_TIERS.has(sandboxTier)) {
|
||||
throw new TypeError(`Runtime '${runtime}' has a missing or invalid sandboxTier descriptor axis: ${JSON.stringify(sandboxTier)}`);
|
||||
}
|
||||
return {
|
||||
runtime,
|
||||
installSurface: configIntent.installSurface,
|
||||
@@ -140,6 +149,7 @@ function resolveInstallPlan(runtime: string): InstallPlan {
|
||||
hooksSurface: desc['hooksSurface'] != null
|
||||
? desc['hooksSurface'] as HooksSurface
|
||||
: ((runtime === 'opencode' || runtime === 'kilo') ? 'none' : 'settings-json'),
|
||||
sandboxTier,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user