There is a classic security engineering question that reveals a lot about a system’s design philosophy: what does it do when something unexpected happens? When a system encounters ambiguity – a request it cannot fully parse, a condition it was not designed to handle, an edge case that falls between the rules – does it allow the action or block it?
Systems that allow when unsure are called fail-open. Systems that block when unsure are called fail-closed. Ethosure and its underlying coding-ethos engine are designed to fail closed. This article explains why that choice matters and what it means in practice.
The fail-open trap
Fail-open behavior is often the path of least resistance. If a firewall cannot parse an unusual packet, letting it through avoids blocking legitimate traffic. If a content filter encounters a language it does not recognize, allowing the content avoids frustrating users. If a governance check runs into an ambiguous command, permitting it avoids interrupting the developer’s workflow.
The problem is that adversaries – and in the AI agent context, agents that overfit to local context or receive manipulated prompts – can exploit fail-open behavior. A known technique for bypassing security controls is to craft inputs that the control cannot parse, triggering an ambiguity state that defaults to allow. This is precisely the category of risk that coding-ethos’s fail-closed design eliminates.
For AI agent governance, the stakes are higher still. An AI agent that encounters a restriction it cannot handle may improvise – trying alternate paths, rewording commands, using indirect approaches. A fail-open system will eventually find a gap. A fail-closed system treats those attempts as enforcement failures, not as workflow to accommodate.
What fail-closed means in coding-ethos
The coding ethos project applies fail-closed defaults at multiple levels:
Malformed shell text is denied. When an agent proposes running a shell command, the system parses that command before evaluating it. If the command is malformed – ambiguous syntax, unexpected characters, shell constructs the parser cannot handle – it is denied outright. The reason: partial parsing creates policy gaps. If the system only parses part of a command and evaluates policy over that partial picture, an attacker can hide policy-violating behavior in the unparsed portion. By denying rather than partially evaluating, coding-ethos eliminates that gap.
Indeterminate outcomes are blocked. If policy evaluation cannot reach a clear ALLOW, TRANSFORM, or ESCALATE decision, the result is BLOCK. There is no “probably fine, let it through” path.
Bypass attempts are enforcement failures. If an agent tries to run `git commit –no-verify` (which would skip Git hooks), tries to use an alternate Git binary, or attempts subprocess indirection to avoid the policy wrapper, these are not treated as unusual-but-acceptable workflow variations. They are classified as enforcement failures and blocked.
Sandbox failures are blocking. When the runtime sandbox cannot be set up – because a required kernel feature is unavailable, or because the sandbox configuration is invalid – managed tools do not fall back to running unsandboxed. The operation fails. A tool without a sandbox is not a sandboxed tool with a caveat; it is an unsandboxed tool, which is a fundamentally different security posture.
The analogy: a bank vault door
Think of a bank vault door. The default state of the mechanism is locked. If the door’s electronics fail, the door stays locked. The designers did not assume that a failure mode producing an open door would be acceptable, even if that meant inconvenience. The value being protected – access to the vault – outweighs the cost of occasionally needing a locksmith.
AI agent governance faces the same tradeoff. The cost of occasionally blocking a legitimate action is a developer or agent needing to review and retry. The cost of failing open – allowing a policy-violating action because the system encountered an unexpected case – is a security incident, a compliance failure, or a loss of the audit trail that a regulator requires. The asymmetry is stark.
Fail-closed and developer experience are not opposites
A common concern about fail-closed systems is that they create friction. If every ambiguous case results in a block, won’t developers and agents be constantly interrupted?
coding-ethos addresses this through the quality of its responses, not by relaxing the fail-closed default. When something is blocked, the system emits a structured finding that includes the policy ID, the principle it belongs to, a specific suggestion for fixing the issue, and the exact command to re-run after the fix. Agents receive actionable repair guidance, not just an opaque error. The remediation path is explicit.
Additionally, the MCP server (the query interface that agents can consult before attempting an action) lets agents ask “is this allowed?” and get a policy check result before running a command that would be blocked. This shifts friction earlier – catching problems before they become blocked commits – while keeping the fail-closed default intact.
What this means for your risk posture
For a Chief Risk Officer or Chief Information Security Officer, the fail-closed default has a clear meaning: the system’s default behavior, when anything goes wrong, is to protect the assets being governed. Unknown edge cases do not become unknown permissions. The bias is always toward protection, and the evidence log reflects that bias in every recorded decision.
This posture aligns with what frameworks like NIST AI RMF and ISO/IEC 42001 describe as “bounded control” – the ability to demonstrate that your AI governance controls do not have uncontrolled failure modes. Fail-closed is the foundation of that demonstration.