An executable task state machine for coding agents — a fuse between an agent and the word "done".
🇷🇺 Читать по-русски: README.ru.md
Status: working alpha — the flow engine ships (per-type flows + executable, gated status transitions with history, structured commands + rollback), plus tasks/hierarchy/dependencies, the knowledge base (
mtt note/mtt prime), verifiable references (mtt ref/mtt check), and agent-config scaffolding (mtt agent). Runmtt versionfor the build andmtt --helpfor the live surface. Theadvance/start/donemeta-walk is parked (single-edgestatusis the norm); comment threads, text search,mtt-ui, and external adapters are later phases. Full plan in DESIGN.md.
Pitch — why you need mtt. You already have a Definition of Done: tests, lint, review, "spec before code". It lives as prose in AGENTS.md, in Make targets, in CI. Prose doesn't stop an agent — it hopes. An agent silently skips whatever isn't mechanically checked and writes "done" where done isn't. The problem isn't that you lack a Definition of Done — it's that nothing enforces it inside the tracker itself.
mtt turns a task's lifecycle into a small state machine you define per task type (a bugfix isn't a refactor), and every transition runs your own shell commands as blocking gates: checks fail, the transition doesn't happen, and the status can't lie. The flow is committed repo data, not personal settings; it works with any CLI agent; every move is written to append-only history with its check results. And because the status can't lie, when you look —
mtt show/mtt list/mtt roadmap— you see a true map: what's still an idea, what's blocked, what's two steps from release. In one line: "done" isn't what the agent declares — it's what the tool refuses to record until it's earned.Not for everyone. mtt is useless until you author a flow — that authoring step is the price, not a flaw. If you just want a to-do list, use something lighter. mtt wins decisively only when you want the process itself enforced — especially under agents, which skip anything not mechanically gated.
mtt is a small Go CLI (mtt add, mtt status, mtt done, …). Its defining idea: a config-driven
per-type status flow whose transitions run gates (shell commands that must pass) — so an agent can't mark
a task done without meeting its Definition of Done. Its second idea, the adoption ladder: storage is
abstracted behind ports, so the same CLI runs over local files or your existing tracker.
- Solo / zero-footprint: the default backend is local YAML files (one file per task, in
.mtt/) — no daemon, no database, no ports; clean git merges and PR-reviewable diffs. - Corporate: point mtt at an existing "tracker + knowledge base" pairing (Jira+Confluence, GitHub Issues+Wiki, …) via an adapter. Agents get the same clean CLI; humans keep their native UIs.
beads is great but heavy for this use: it conflicts with other tooling, and its flow is a flat status
enum. mtt's wedge is lightness and a real per-type flow — plus the ability to adapt to whatever
backend you already have. (An honest comparison lives in
DESIGN.md.)
- Executable, per-type transitions (the killer feature). A status transition carries shell commands
that must all pass —
["make lint", "make test"]gating→ done— or perform actions (create a branch). The Definition of Done differs per task type (bugfix/refactor/feature). Agents work in task terms (a gated status move likemtt done) while the tool enforces the discipline. - Config-driven types & hierarchy. Epic → task → subtask is just the
hierarchytemplate (mtt init --template templates/hierarchy.yaml); no type names or ID structure are hardcoded. IDs are readable and flat per-prefix (e1,t17,s3) — stable under re-parenting (hierarchy lives in aparentfield, not the ID). - Priorities, tags, dependencies & a roadmap.
--priority,#hashtags/--tag,depends_on/ready, andmtt roadmapgive an agent an ordered, filterable backlog; acurrentpointer tracks the task in flight, and batch/pipeline (--ids, stdin-) makes it Unix-composable. - Hexagonal, pluggable backends. A public contract (
pkg/mtt) withTaskStoreandKnowledgeStoreports; the YAML adapter is the reference. Optional per-adapter capabilities: history and dependencies today; comment trees and text search are planned. - Verifiable references & append-only history. Tasks carry checkable
refsto notes/tasks; every status transition is recorded for audit. (Threaded comments are planned.) - Optional human UI (
mtt-ui, planned). A small local web server (task management, Gantt, KB browser) — only needed on the YAML default; with an external backend, humans use its native UI.
Task and dependency management from the command line and knowledge storage (mtt note) today; threaded
comments, text search, and an optional external indexer hook are planned.
(Planned.) mtt-ui (a small local web server): minimal task management, a Gantt chart, a KB browser.
Plus CLI text output for task info, KB search, and an ASCII Gantt.
Download the binary for your platform from the latest release:
| Platform | Asset |
|---|---|
| Linux x86-64 | mtt_<version>_linux_amd64 |
| Linux ARM64 | mtt_<version>_linux_arm64 |
| macOS (Intel) | mtt_<version>_darwin_amd64 |
| macOS (Apple Silicon) | mtt_<version>_darwin_arm64 |
| Windows x86-64 | mtt_<version>_windows_amd64.exe |
Then, on Unix:
chmod +x mtt_<version>_<os>_<arch>
sudo mv mtt_<version>_<os>_<arch> /usr/local/bin/mtt
mtt versionVerify integrity against SHA256SUMS from the same release (sha256sum -c on your asset's line).
go install github.com/pashukhin/mtt/cmd/mtt@latestgit clone https://github.com/pashukhin/mtt && cd mtt
make build # -> bin/mttmtt init # create .mtt/ + scaffold agent hooks + docs (AGENTS.md/CLAUDE.md/GEMINI.md; --no-agent-hooks/--no-agent-docs to skip)
mtt add "Ship auth" # -> t1 (a root task; no --parent needed)
mtt add "Login endpoint" # -> t2
mtt status t1 in_progress # move through the flow (a transition's commands run + gate here)
mtt done t1 # -> the done terminal (default flow has no gate commands)
mtt list # all tasks
mtt tree # the task tree
mtt roadmap # dependency + priority execution order
# For an epic > task > subtask hierarchy: mtt init --template templates/hierarchy.yamlWhich flow?
defaultis minimal (task + chore). For a per-type coding DoD, a docs/no-code loop, an epic→task→subtask hierarchy, or the full git branch→PR→deliver flow, browse the example-flow gallery in FLOW_GUIDE.md §2b.
See CLI_REFERENCE.md for the full command surface and exit codes.
Existing projects:
mtt initnow also writes a.mtt/.gitignorethat keeps the personalconfig.local.yamloverlay out of git. If your project was initialized before this shipped, add it by hand:echo config.local.yaml > .mtt/.gitignore.
- DESIGN.md — architecture and decisions (the source of truth)
- FLOW_GUIDE.md — author your own flow (gates/
post:/git integration) on mtt's engine - CLI_REFERENCE.md — the full CLI command surface (target design)
- CONFIG_REFERENCE.md — the full
.mtt/config.yamlfield reference - AGENTS.md — how to work in this repo (rules, gate, principles)
- The backlog is dogfooded: this repo tracks its own tasks in mtt — run
mtt roadmapin a checkout - Coding-template demo — a runnable, tested
coding-flow walkthrough