Skip to content

v0.20.0

Choose a tag to compare

@sblattj sblattj released this 12 Oct 20:42
· 50 commits to main since this release

Added

  • ach smoke <message-file> (#139): before you send someone setup or how-to steps, the harness runs those exact steps itself as a brand-new user and reports the friction. The steps come from the message's sh/bash/zsh/console fences, prompt fences (typed into an agent through ach run, with tokens counted) and open fences or "Open https://..." lines. Each step runs literally in one sandboxed terminal session: a fresh HOME, config dirs for the common CLIs (npm, git, gh, Claude Code, Codex, Gemini, Azure, gcloud, AWS, Docker, kube and more), a minimal PATH with none of your installs (--allow-path adds a dir), and on macOS its own empty-password login.keychain-db, so CLIs inside no longer raise "A keychain cannot be found" popups on the host. The host keychain search list and default are read before the run, checked after, and restored if they changed; measured byte-identical. Every process a step starts is killed on exit, including on Ctrl-C: tracked process groups, then any escapee with the sandbox's HOME in its environment or its cwd under the sandbox. Browser logins run in your real browser over CDP (--cdp, default $CDP_BASE or http://127.0.0.1:9333) in a new background tab that is always closed. Device codes are filled in, and Continue/Authorize is clicked only when the page shows the account the step needs (--account or a fence's account=). If the browser is signed in to a different account, or the step names none, nothing is clicked and you get a one-line login command instead. Electron endpoints such as an IDE are refused. A device-code login blocked by policy (for example AADSTS53003 conditional access) is rerun as the normal browser login. Outward writes go to local stubs (--stub jira=JIRA_BASE_URL, presets for Jira, GitHub, Linear and Slack, --stub host:*.atlassian.net or --block-host refused through a local proxy), so the run creates nothing real. Each step records pass/fail, time, tokens, prompts and denials. Fixes are made in place and the step is rerun in the same sandbox: a missing install is inserted before the first step that needs it (with its own prerequisites), a health check that says a binary is installed when it is not on PATH is flagged as tool-lied, a policy-blocked device-code login becomes the browser login, and a confirm prompt gets its non-interactive flag. --fix-agent A hands other failures to a coding agent to rewrite the step, and --fix-tool REPO lets it patch the lying tool (uncommitted, reported as a diffstat). Host-level commands (sudo, Homebrew, xcode-select, writes under /usr/local, /opt and so on) are never run, because the sandbox shares the OS. The output is the friction table, the details, and <name>.smoked.md with every fix applied; --copy copies it as rich text, and --json prints the report. Exit 0 clean, 1 friction left, 2 usage. macOS only for now. See docs/SMOKE.md.

Fixes #139 — Smoke the instructions: run a how-to as a brand-new user in an isolated sandbox and fix friction before sending