Keep long-running work on the rails — in your repo, in plain Markdown, for humans and AI agents alike.
An agent finishes a session and the plan is gone. The next session re-derives it, picks a task someone already did, or declares work "done" with nothing to show for it. You get plausible-looking progress and no way to audit it.
Chat history is not a work ledger. Neither is an issue tracker your agent cannot
reach, or a TODO.md nobody validates.
Taskrail puts the ledger in the repository: tracked work as Markdown files with a machine-checkable schema, a generated current-state projection, and a CLI that owns every status transition. Same repo, same question, same answer — whether a person or an agent is at the keyboard. Git supplies history and review. There is no database, no daemon, and no hidden automation.
taskrail init # adopt Taskrail in an existing repo, non-destructively
taskrail validate # confirm the layout and state are consistent
taskrail status # active spec, task counts, and what's nextThe agent asks the CLI what to do next instead of guessing, and cannot fake a transition — every status change goes through a command that rewrites the ledger.
taskrail next --json # deterministic selection
taskrail start T-001 # mark it active
taskrail complete T-001 --note "implemented" # implementation done
taskrail verify T-001 --result pass --summary "acceptance met"Selection follows status, dependencies, priority, and stable tie-breaking, and is
anchored to the active spec — so a fresh session lands on the same task a stale
one would. Every --json command emits one versioned envelope
(schema_version, command, warnings, and exactly one of result or
error), so an agent parses one shape.
The packaged autonomous-task and autonomous-backlog skills follow your
repository's manual-testing policy, including requirements for non-visible
changes. Without a policy, they require manual testing for visible workflow
behavior, not for every task. Required manual testing stays sandbox-first.
The packaged autonomous-recovery entry point delegates to taskrail-repair
for the shared inspect, dry-run, review, apply, and revalidate procedure. Both
entry points stop on ambiguous or non-mechanical state; neither permits
hand-editing authoritative state or implementing unrelated changes.
The autonomous-manual-test skill exercises your product's acceptance criteria
using your documented test modes, with a temporary sandbox fallback when none
are documented. Its evidence and temporary test code are never committed.
For unattended runs, loop executes explicitly allowed tasks inside operator-set
bounds — see docs/loop.md. A failed or interrupted child that
leaves HEAD unchanged reports child_failed; repository integrity violations
still take precedence as invalid_postflight. Canonical lifecycle writes without
verification are accepted: a clean committed completion reports
completed_unverified, while start or block alone has candidate no_progress.
Sequential runs optionally accept a caller-owned --check <path>: a read-only
executable gate after each delivered completed pass. Failure stops with
check_failed and retains the delivered commit and result-file evidence.
Each verification gets a fresh identity, so sequential children can complete
and verify multiple tasks in one invocation, with or without a check.
Effective parallel widths above one require --check: each replayed integration
commit must pass, and the aggregate child is followed by a final check on the
same head before local publication. Failed candidate checks roll back without
blocking later independent work; mutation stops publication fail-closed.
Parallel --delivery review refuses unsupported before any adapter call by
default. Explicit --review-protocol checked-combined-v1 with --timeout opts
into a cooperating schema-2 adapter: one combined change preserves per-task
commits and can advance the target only to the exact aggregate-checked head.
Checks precede branch/change publication; target/source/check/approval drift
refuses without retry. Receipts distinguish applied, refused, and unknown
outcomes, never claiming remote rollback. See review delivery.
Parallel integration commits include reprojected STATE.md counts for all work
accepted so far, rather than the last worker's isolated counts.
If publication refuses after integration passes, the default failure retention
keeps the integration workspace and reports unpublished tasks as pending.
--keep-workspaces never removes it and warns that unpublished work may be lost.
Conflict-resolution children must leave HEAD unchanged and resolve every unmerged
path. Otherwise that candidate is rejected and rolled back to the prior
integration head; earlier and later independent successes can still publish.
An abruptly killed coordinator's staged binary no longer blocks later runs with the same executable. See guarded loop recovery before clearing an abandoned lock or removing leftover staged copies.
Nothing is rewritten and nothing is generated behind your back.
taskrail init --apply # scaffold specs/ + planning/
taskrail import notes.md --to tasks # rough notes -> task drafts, no LLM
taskrail import --apply draft.json # validate a draft and write real filesretrofit handles messier existing layouts, repair reconciles mechanical
STATE.md drift, and --with-skills installs the packaged agent skills. import
never calls a model: it structures what you wrote, and --emit-prompt hands an
agent a prompt for a richer draft you then review.
Completing implementation and verifying it are separate steps. Verification records a pass/fail outcome, writes inspectable evidence, and can open the follow-up task in the same breath:
taskrail verify T-001 \
--result fail \
--summary "missing dependency check" \
--create-followup \
--followup-title "Add dependency validation" \
--followup-priority highEach run leaves plain files under
planning/artifacts/verify/<task-id>/<timestamp>-<verification-id>/ —
plan.md, report.json, report.md. That tree is gitignored (a fresh
taskrail init inside a Git worktree writes the .gitignore rule for you),
reproducible local output: committed state never depends on it surviving a Git
round-trip.
All read-only, all safe to run mid-session:
taskrail status # live snapshot, incl. work pointing away from the active spec
taskrail stats # aggregate metrics and dependency graphs
taskrail coverage # which spec areas have no task linkedcoverage --gaps extends this with mechanical structural-gap candidates —
never violations, and never a reason validate fails.
- Not a built-in LLM provider integration — Taskrail is provider-agnostic and manual-first.
- Not a sandbox, container, or worktree orchestrator.
- Not a background daemon, distributed worker pool, or multi-lane scheduler.
- Not a built-in semantic spec-to-task generator or reviewer — the binary provides mechanical reports and reviewed write boundaries, while optional skills let an external agent supply judgement.
brew install tessariq/tap/taskrail # macOS and Linux
winget install Tessariq.Taskrail # Windows
taskrail --versionFrom source (needs Go 1.26):
go install github.com/tessariq/taskrail/cmd/taskrail@latestA plain go build/go install reports version 0.0.0-dev; release builds inject
it with -ldflags "-X main.version=vX.Y.Z". Tagged v* releases are published
automatically with GoReleaser for Linux/macOS/Windows on
amd64/arm64. Shell completion ships via Cobra —
source <(taskrail completion bash), and taskrail completion --help for zsh and
fish.
---
id: T-001
title: Bootstrap repository structure
status: todo
priority: high
spec_ref: specs/v0.1.0.md#summary
dependencies: []
updated_at: "2026-08-05T00:00:00Z"
---
# T-001 Bootstrap repository structure
## Description
Create the initial Taskrail structure, specs, and planning area.
## Acceptance
- `planning/STATE.md` exists.
- `taskrail validate` passes.
## Verification Notes
- Run `taskrail validate` and record the successful observation.
## Implementation NotesTask files are the durable ledger. planning/STATE.md is the generated
projection of them — active spec, current task, status summary, blockers, next
action, latest verification result. Never hand-edit it or a status field; the
taskrail commands own those writes. Repository-wide human context belongs in
planning/NOTES.md, a human-owned sidecar the CLI creates once and never
rewrites.
Create and steer tasks through the CLI rather than editing frontmatter:
taskrail task new --title "Add machine envelope" --area uniform-agent-machine-results
taskrail task rename T-007 --slug add-slug # re-slug id + filename atomically
taskrail task repoint T-007 --area some-anchor # move it onto another spec area
taskrail task dependency add T-010-api T-009-model # one reviewed edge.
├── AGENTS.md # guidance for coding agents
├── cmd/taskrail/ # CLI entry point
├── internal/ # core packages
├── planning/ # task ledger, generated STATE.md, optional human NOTES.md
└── specs/ # versioned, normative product specs
mise provisions the pinned toolchain (Go, task,
lefthook) from mise.toml — optional; direct go commands and the
Taskfile.yml targets work without it:
mise run setup # provision, build taskrail onto PATH, wire the opt-in git hooks
go build ./cmd/taskrail && go test ./...CI (.github/workflows/ci.yml) is the authoritative gate and runs the build/test
matrix over Linux, Windows, and macOS. Optional
lefthook hooks mirror it locally
(task hooks:install), with pre-push on the shorter task test:short lane;
pre-commit also runs the agent-identity guard, and commit-msg/pre-push
refuse agent-attribution trailers and session links. Do not bypass them with
--no-verify. See
CONTRIBUTING.md for the PR checklist and the AI-assisted
contribution policy, and
AGENTS.md for the binary-freshness
contract that matters when hacking on Taskrail itself.
Maintainer skill evaluations seal artifact namespace identities for resume and optional pinned baseline adoption. Legacy stages and explicitly enumerated raw-copy adoption remain compatible, without claiming historical namespace protection.
Taskrail is an in-progress open-source project. The current release is v0.4.0;
the active development specification is v0.5.0.
v0.1.0— the repository contract: deterministic task progression, the authoritativeSTATE.md, verification as a first-class concept.v0.2.0— adoption in existing repositories:retrofit, LLM-freeimport, opt-in agent skills, non-destructiveinit,STATE.mdrepair.v0.3.0— read-only insight (status,stats,coverage), thespecfamily,unblock, WinGet install.v0.4.0— active-spec selection and authoring, slugged creation with atomic rename/repoint, mechanical spec/gap review, version-skew detection.v0.5.0(in development) — uniform agent results, lifecycle-complete skills, human-owned repository notes, configurable review, safe review publication, a bounded external-process loop.
New v0.5 spec reviews publish schema-2 manifests retaining declared review rounds and explicitly unverified disposition claims. Decomposition requires that evidence; schema-1 spec reviews remain readable as history only. See the reviewed import contract for the boundary.
Roadmap beyond that is tracked in specs/README.md. The
versioned specs in specs/ are the normative source of truth for release scope
and behavior.
docs/commands.md— command reference: write effects, the JSON envelope, selection, locks and recovery, slugs, repoint, importsdocs/loop.md— bounded unattended executiondocs/migration.md— layout upgradesAGENTS.md— guidance for coding agentsCHANGELOG.md
Apache-2.0. See LICENSE.