Transactional coordination core for the AI software factory: task status, claims,
dependencies, resource leases, and history in one SQLite file (WAL, single writer,
one BEGIN IMMEDIATE transaction per operation). Task folders stay immutable-path
artifact storage; FTS owns all control-plane state. Zero runtime dependencies.
uvx fticket board # run from PyPI, no install (fticket and fts are the same CLI)
uv tool install fticket # puts fts + fticket on PATH
uv sync # dev
uv pip install . # as a libraryfrom fticket import FTS, Mode
FTS.init_db("factory.db", stages=["code", "review", "qa", "deploy"]) # create schema first
fts = FTS("factory.db")
t = fts.create_ticket(title="build parser", stage="code", folder_path="tasks/0001")
claim = fts.claim("code", worker_id="coder-1") # atomic, race-free
fts.start(claim.ticket.id, "coder-1") # claimed -> in_progress
fts.acquire(resource="staging", ticket_id=t.id, worker_id="coder-1", mode=Mode.EXCLUSIVE)
fts.complete(t.id, "coder-1") # records reached_stage
fts.advance(t.id, "coder-1", to_stage="review") # done -> queued @ review
fts.tick() # expire TTLs, promote waitlistsfts <cmd> --db factory.db — read commands work on a read-only database.
init |
create schema, seed config + stages |
board / show <id> / dag / queues |
board grid, ticket detail + history, dependency DAG, queue depths |
why <id> / triage / stats / doctor |
stuck-ticket root cause, dead-letter + orphans, AC16 metrics, health checks |
create / claim / renew / start / complete / advance |
ticket lifecycle |
transition / reject / dead-letter / revive |
generic edge, bounce, operator kill, un-kill |
add-dep / acquire / release / register-resource |
dependencies and resource leases |
tick / scheduler |
one sweep pass / loop until Ctrl-C |
events |
poll/tail the event stream |
config get|set |
tunables (bounce_limit, claim_ttl_ms, ...) |
serve |
read-only web dashboard |
fts serve --db factory.db --port 8377Read-only, bound to 127.0.0.1 only, GET-only, no external assets.