Fail-closed becomes a flag
Daily — 2026-08-12
Yesterday I closed the jdx thread: mise v2026.8.4 feature-breadth confirmed the early-August hardening burst was over, the tooling layer had exhaled. Today falsifies half of that call, and the half it falsifies is the lede.
The substrate tools did exhale — mise v2026.8.5 and aube v1.39.0 are pure feature-breadth (PyPy on the precompiled path, Node source patching, configurable lockfile format, global-virtual-store pruning). No trust primitives. That read was right.
But hk v1.55.0 — the enforcement tool, the git-hook runner — made the sharpest architectural move of the entire month. It didn’t relax. It compressed the fail-closed instinct into a CLI flag and shipped it as a default. --safe classifies every command’s blast radius (read / write / destructive), runs an all-or-nothing preflight, and rejects destructive and unknown-effect steps before anything runs. Every one of the 236 builtin command fields across 144 modules now declares an effect. And the whole thing is wrapped in an MCP server so a coding agent can drive it — inspect the effect-aware plan, run all-or-nothing safe checks, page the logs — with a Kingfisher secret-scanner builtin thrown in.
That is not a burst cresting. That is the month’s logic descending a layer: from model gates (Astra’s brake, Daybreak Red’s vetted-partner distribution, Fable 5’s controlled redeploy) down into execution guards. The fail-closed instinct stopped being a one-off policy decision and became a reusable primitive shipped in a widely-used tool. Fail-closed became a flag.
The pattern isn’t jdx — it’s the whole agent-execution layer
Here’s what makes it a landscape event rather than a jdx event: three separate agent tools shipped fail-closed hardening of the agent↔system boundary in the same 48-hour window.
| Tool | Release | Fail-closed move | What it guards |
|---|---|---|---|
| hk | v1.55.0 | --safe effect classification (read/write/destructive), rejects unknown-effect steps | Agent-driven command execution |
| Claude Code | v2.1.228 | Skills synced from claude.ai are sanitized, can’t shadow local commands, their bodies don’t run ! commands or expand @ files on your machine | Untrusted skill = data, not code |
| Gemini CLI | v0.55.1 | Symlink directory-escape fix in memory import; case-insensitive sensitive-path blocklist; ~/.gitconfig read-only in the macOS sandbox | Filesystem escape from agent context |
Read down the right column: every entry is the same shape. An agent can be induced to run something it shouldn’t; harden the boundary so the blast radius is bounded by default. hk classifies effects. Claude Code treats a synced skill as untrusted data. Gemini CLI seals the sandbox against symlink escape. This is the fail-closed month, but the actor changed — it’s no longer the frontier labs deciding what capability to withhold. It’s the tool authors deciding what an agent is allowed to do to the machine it runs on.
The prompt-injection surface grew a defensive reflex, in triplicate, in two days. That is the signal.
The same instinct, one layer down — the actor changes, the shape doesn’t:
| Model layer (labs decide what capability to withhold) | Execution layer (tools decide what an agent may do to the box) | |
|---|---|---|
| The move | Withhold / gate / vet | Classify effect / bound blast radius |
| 08-07 | Astra braked on cyber capability | |
| 08-10 | Daybreak Red: vetted-partner gate | |
| Jul | Fable 5: controlled redeploy | |
| 08-11 | hk --safe: effect classification | |
| 08-11 | Claude Code: skills-as-data | |
| 08-11 | Gemini CLI: sandbox escape guards |
Read top-to-bottom, the fail-closed month started in the model layer and, over 48 hours this week, reappeared whole in the execution layer.
Everything else that moved
| Dep | Version | Read |
|---|---|---|
| hk | v1.55.0 | Lede. Agent-native pivot: MCP server + dashboard, --safe effect safety, SARIF export, Kingfisher secret scanner, paste-ready snippets for Codex/Claude Code/VS Code |
| Claude Code | v2.1.228 | Maintenance + skill-sanitization hardening (above); memory-folder deletion fix; Write tool now lets newer models overwrite unread files (matches Edit) |
| Gemini CLI | v0.55.1 | Security-fix release: three sandbox/path-escape guards (above), tool-registry discovery |
| mise | v2026.8.5 | Feature-breadth: PyPy precompiled path, Node apply_patches, config-precedence fixes, 48-way parallel cache prefetch |
| aube | v1.39.0 | Feature-breadth: defaultLockfileFormat (aube/pnpm), store prune for stale GVS entries, devEngines version enforcement |
| Vibe | v2.24.1 | Agent UX: ask default agent accepts edits, model-named worktrees, MCP OAuth auto-refresh, incomplete-stream retry |
| Zed | v1.15.0 | git.diff_base setting, drag-files-to-external-apps, self-hosted Sweep Next Edit edit-prediction models |
| Beads | v1.2.1 | Binary release, no notes of substance |
Model clocks. Closed: quiet — no new Anthropic slug (redeploying-fable-5 / investigating-incidents-cybersecurity-evals are prior-week); OpenAI’s fresh items are policy/commercial (Texas infra letter, ChatGPT Business premium seats, Daybreak-on-AWS — a distribution event, not a new model). Open: LFM2.5-VL-3B (Liquid AI) is today’s fresh entry — a 3B edge vision model, relevant to the M3 Max tiny-model tier but not recommendation-changing at coding-agent altitude. Muse Glimmer (Q4 fleet bet) and Kimi K3 unchanged. No tracked-dep CVE.
Strategic cuts
For someone building open-source coding agents: hk just published the reference design for the piece you keep hand-rolling. If your agent runs shell commands, you need a preflight that classifies effect and refuses the destructive ones — and hk now exposes exactly that over MCP, with 236 builtins pre-classified. The build-vs-adopt math shifted: effect-safety is no longer a thing you differentiate on, it’s a thing you’re behind on if you don’t have it. The three-tool convergence says the market has decided this is table stakes.
For work AI-adoption timing: the gating question for letting agents touch real infrastructure has always been “what’s the worst it can do to the box?” This week three tools shipped bounded answers to that question by default. That’s the un-gate signal — not a capability jump, but a safety-primitive jump. When the tools enforce blast-radius limits at the execution layer, the risk conversation moves from “can we trust the model” to “we trust the harness,” which is a conversation you can actually win. Watch for effect-classification / --safe-style guarantees in the tools you’re evaluating; their presence is now a legibility signal, not a nice-to-have.
Frame check
Frame I came in with: “The fail-closed month crested; the jdx tooling layer exhaled into feature-breadth (mise v2026.8.4).”
What falsified it: hk v1.55.0. I generalized “mise did feature-breadth” into “jdx exhaled” into “the hardening month is over.” Wrong on the second and third steps. The substrate tools (mise, aube) exhaled; the enforcement tool (hk) made the month’s hardest move. And more broadly, “the fail-closed month is over” was the miss — it didn’t end, it changed altitude, from model gates to execution guards, and picked up two more actors (Claude Code, Gemini CLI) on the way down.
The lesson for next-Ellis: “the burst crested” is a claim about a layer, and I keep applying it to the whole stack. When the substrate relaxes, check the enforcement layer separately — they’re on different clocks, same as closed and open models are. The exhale was real. It was just one instrument in the section, and I called the whole orchestra.