# owainlewis/machinist: a supervisor that will not guess what your script is doing

> A Go supervisor for agentic coding workflows that wraps Codex, Claude Code or any executable accepting a prompt on standard input, keeps credentials local, and gates each step on human approval. It ships two commands at init but configures one, applies a single overall timeout per run, and treats a killed script as a restart from zero.

**owainlewis/machinist** — Open source software factory infrastructure for advanced AI coding workflows

- Repository: https://github.com/owainlewis/machinist
- Website: https://machinist.sh
- Stars: 483 · Forks: 91
- Language: Go
- License: MIT
- Published: 2026-09-10 · Updated: 2026-09-10 · Language: en
- Canonical page: https://hysenlabs.com/projects/owainlewis-machinist

## Init writes two commands and the example configures one

Initialization writes a config file at `~/.machinist/config.toml` containing two commands, named `task-to-pr` and `audit`. Each is described as three things: a prompt, an executor, and a timeout. The configuration shown immediately afterwards defines only the first:

```toml
# ~/.machinist/config.toml
[commands.task-to-pr]
executor = "codex"
prompt_file = "prompts/task-to-pr.md" # optional
timeout = "120m"
```

There is no block for `audit` anywhere in the quick start, so the one command whose entire purpose is to inspect work has no worked example of its executor, its prompt or its timeout. That may be deliberate, since a review command has different requirements from a task command, but it means the second half of the generated file is discovered by reading the file rather than by following the guide. The block also shows that a prompt can be inlined or pulled from a file, and that the timeout is written as a duration string rather than as a number.

## One timeout covers the whole run, and a kill means starting over

Execution is described in terms that make the failure model explicit. For a direct run, the configured command name maps to a fixed executable and the path given with `--repo` becomes the working directory. In both direct and managed cases Machinist renders the prompt, sends it on standard input, streams standard output and standard error, and applies one overall timeout plus cancellation. Exit code 0 is success and every non-zero code fails. The consequence worth planning around is stated plainly: a killed script restarts from the beginning unless the script owns its own checkpointing. Combined with a single overall timeout, that means a task running near its budget does not resume where it stopped. Durability lives in events, artifacts and saved files, not in resumed execution.

## Scripts stay opaque by design

Inside a command, the internals are deliberately not modelled. The documentation says scripts are intentionally opaque: their internal stages appear in the logs, but Machinist does not infer them. That is a real design position rather than a missing feature. Most orchestration layers try to parse a process's behaviour into stages so they can report progress and resume; this one declines, and the consequence is that everything between the command boundary and the process exit is the script's own responsibility, including any checkpointing. It also means the timeline shown for a run reflects the command as a unit, with a terminal outcome, a duration and the token use the executor reported, rather than a reconstructed step graph. Whether that suits you depends on whether your executors already report their own progress.

## Workers expose named commands, never shell text

The security claim is narrow and specific. Workers expose named commands and repositories, never arbitrary shell text or machine-local paths, and repositories, credentials, model aliases and executor configuration all stay on the worker. The harness is bring-your-own in the sense that any executable accepting a prompt on standard input will do, whether that is Codex, Claude Code, another agent CLI, a test runner, a shell script or repository-owned orchestration. One asymmetry is worth noticing in how a target is chosen. A direct run takes the filesystem path supplied with `--repo`, while a managed submission instead resolves an approved repository name from the worker configuration. So the same flag is not the same trust model in both modes, and the documented path form is only available on the direct route.

## Three direct dependencies, one of which is a cgo-free SQLite

The module is unusually small for a tool that persists runs. It declares three direct requirements: a TOML parser, the Cobra command framework, and `modernc.org/sqlite`. That last choice is the informative one, because it is a pure Go SQLite implementation rather than a cgo binding, which is consistent with a binary that builds and runs without a C toolchain on the worker. Everything else in the module file is marked indirect, including the X syscalls package, a terminal detection library and the libc, mathutil and memory modules that the pure-Go SQLite pulls in. The language version is declared as 1.26.6, a recent toolchain floor. For a project positioning itself as a supervisor that other teams will compile and deploy, a dependency surface this narrow is a genuine part of the pitch.

## An agent.py sits at the top of a Go repository

The top-level listing has `cmd/`, `internal/`, `deploy/`, `scripts/` and `skills/` alongside `go.mod` and `go.sum`, and it also has a single Python file, `agent.py`, sitting in the root. Nothing in the documentation explains what it is for, which agent it implements, or whether anything loads it. Alongside it sit `ARCHITECTURE.md`, a `Justfile`, an `install.sh`, an `evals/` directory and a `deploy/` directory, which is the material side of the deployment guide for running the control plane and worker as services. The mixture is not necessarily a problem, since an integration script written in another language is unremarkable, but a root-level script whose purpose is undocumented is exactly the kind of thing an auditor should resolve before trusting the tree.

## Three build entry points, and the quick start names one

The documented path from clone to running binary is four lines:

```sh
git clone https://github.com/owainlewis/machinist.git
cd machinist
mkdir -p ./bin && go build -o ./bin/machinist ./cmd/machinist
./bin/machinist init
```

Note that it builds into a `./bin` directory created by hand, and that the package path is given explicitly. The tree also contains a `Justfile` and an `install.sh`, neither of which appears in the quick start or in the table of guides, where the Development guide is the only entry covering local building and testing. So there are three plausible ways in and one is documented. That is a small thing, but for a project whose argument is that setup should be controlled and repeatable, an undocumented installer sitting next to a documented manual build is the first place a new operator will hesitate.

## Approval is the actual control surface

The fifth design point is where most of the leverage sits. You can pause before a step, review the files it produced, and either approve or request changes, and optional merge policies exist to automate narrowly defined low-risk changes. The worked example for this is called classify-then-merge and adds independent risk assessment ahead of a conservative merge policy, which is the pattern to copy if you want automation without giving up the review gate. Workflow tasks retain their results and saved files, support approval and feedback, and keep earlier attempts in history, so a rejected attempt does not erase what the previous one learned. Stages share a folder through a single templated path, and Machinist restores and saves it between stages. The project labels itself early access software subject to change, which fits three releases landing inside three days.

## Conclusion

This suits a team that wants agent runs to be reviewable and credentials to stay on the worker, and that already has an executor it trusts. Read the timeout behaviour before scheduling anything long, decide whether opaque scripts are acceptable to you, and treat the early access label as accurate, since three releases landed inside three days.

## FAQ

### How do I build and initialize machinist?

Clone the repository, change into it, create a bin directory and build the cmd/machinist package into it with `go build`, then run `./bin/machinist init`. That writes `~/.machinist/config.toml` containing two commands, `task-to-pr` and `audit`, though the documented example configures only `task-to-pr`.

### What happens if a machinist run is killed by its timeout?

The script restarts from the beginning unless the script owns its own checkpointing. Machinist applies one overall timeout per run rather than per stage, and exit code 0 is treated as success with every non-zero code treated as failure. Retained artifacts and saved files survive, but execution does not resume.

### Does machinist understand the stages inside a script it runs?

No, by design. Scripts are treated as intentionally opaque: their internal stages appear in the logs but Machinist does not infer them, so checkpointing and progress reporting inside a command are the script's responsibility.

### Which executors can machinist drive?

Any executable that accepts a prompt on standard input, which the documentation frames as bring your own harness. Named examples are Codex, Claude Code, another agent CLI, a test runner, a shell script, or repository-owned orchestration, and executors are configured per command in the config file.

### How does machinist handle approvals and merging?

You can pause before a step, review its files, and approve or request changes, and optional merge policies can automate narrowly defined low-risk changes. A worked example named classify-then-merge adds independent risk assessment and a conservative merge policy, and workflow tasks keep earlier attempts in history.

## Sources

- [License: MIT](https://github.com/owainlewis/machinist/blob/main/LICENSE)
- [owainlewis/machinist on GitHub](https://github.com/owainlewis/machinist)
- [Project website](https://machinist.sh)
- [README](https://github.com/owainlewis/machinist/blob/main/README.md)
- [Releases](https://github.com/owainlewis/machinist/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/owainlewis-machinist
