taskr

For Claude Code, Cursor and Codex

An issue tracker that outlives the context window.

Your agent works something out, the session ends, and the next one starts from zero. taskr is where the work goes instead: an append-only record of what was tried, what was ruled out and what to do next, with a CLI the agent calls itself.

Sign in Hosted beta, invite-only while billing is built.

The cost

Five hours of judgement, gone in one turn.

Compaction, a crash, a closed terminal — any of them ends the session, and nothing the agent worked out along the way was written anywhere. Here is a session on a webhook bug at the moment its context ran out.

15:47 what the session had worked out

  • tried an in-memory set of seen event ids; gone on every deploy lost
  • ruled out Stripe sending duplicates — every retry followed a 5xx of ours lost
  • settled that the idempotency key belongs in the database, not the process lost
  • had it narrowed to one handler and one early return lost
  • knew the schema change was your call, not its own lost
what the next agent starts with nothing

Nothing errors. The next session re-reads the codebase, retries the path that was already eliminated, and sounds exactly as certain as the one that did the work. You pay for the investigation twice and only notice the second time.

How it works

Four commands your agent runs. One record it can’t lose.

The agent shells out to the same CLI you use. It orients before it starts, files what it finds without derailing, and stops by naming the next action. Whatever it wrote down is what the next session gets.

  1. 1 Orient taskr context Which issue was in progress, what it was doing, and what the last session said to do next. Runs before the agent touches a file.
  2. 2 Resume taskr start PAY-212 Prints the resume packet: the issue, its attached spec, prior agent notes, and why work stopped last time.
  3. 3 File what you find taskr offload "<title>" -m "<brief>" A bug in another file, mid-task. Offload it with a file:line and a definition of done — not fixed inline, not lost in the final message.
  4. 4 Stop with a note taskr park -m "<next action>" The next session — you, the same agent, or a different one — reads that note first.

Same bug as above, same compaction, same seventeen-hour gap — except the outgoing agent parked with a note, so the incoming one starts where the first one left off instead of where it started.

events PAY-212 · one issue, two agents, seventeen hours apart
  1. #0728 14:02 session.started PAY-212 writes as agent
  2. #0729 14:19 comment.added PAY-212 handler returns 200 before the insert commits; the retry arrives first
  3. #0730 15:03 doc.attached PAY-212 webhook-idempotency-design.md
  4. #0731 15:47 session.parked PAY-212 context_exhausted
  5. context window ended — 17h 16m — agent gone
  6. resume note
    Move the 200 below the insert in internal/billing/webhook.go:88 and put a unique index on stripe_events.event_id. Done when the replay test posts one event twice and gets one invoice.
  7. #0732 09:03 session.started PAY-212 writes as agent · resumed cold
  8. #0733 09:41 issue.closed PAY-212 unique index on event_id; replay test proves one invoice per event

The second agent never saw the first one’s context. It saw the record, and the record was enough.

Why not a notes file

A scratch file is a draft. This is a record.

You could have the agent append to a markdown file and hope the next one reads it. What that gets you is a document with no author, no order, and no way to tell a finding from a guess. Six things the ledger has that the file does not:

  • append-only Nothing is edited. A correction is a new entry that strikes the old one, so the record of how a decision changed is the record.
  • attributed Every write is stamped with the credential that made it — user or agent — whatever the request body claims. An agent cannot file a note as you.
  • triage-gated taskr next ranks only issues verified still real and still actionable. A ready queue, not a wishlist the agent has to second-guess.
  • specs attached A design doc attached to its issue comes back in the resume packet. A spec that only lives in git is invisible to the next agent.
  • one record Shared across sessions, repos and agents. Not a CLAUDE.md per checkout, not a scratch file the agent may or may not re-read.
  • --json Every command has it. The agent and you read the same data through the same binary, and there is no dashboard to keep in sync.

Setup

One skill file. The agent learns the loop.

taskr ships a SKILL.md for Claude Code. Drop it in .claude/skills/, tell taskr where you are, and the agent runs taskr context before it touches anything. Any agent that can run a shell can use it — the CLI is an HTTP client and nothing else.

export TASKR_REMOTE=$(git remote get-url origin)
export TASKR_ROOT=$(git rev-parse --show-toplevel)
export TASKR_HEAD=$(git rev-parse HEAD)
taskr context

Those three variables are how taskr learns which project you are in and whether a branch has moved. It never runs git itself — you tell it, and it writes down that you did.

Groups

Ten issues, three states, one migration.

Big work is a group. Each child carries its own status, the group rolls them up, and bugs found along the way are filed into it rather than beside it. Nothing gets trimmed for a slide — the long title stays long because the next agent needs the whole sentence.

PAY-200 group high Billing: move from one-off charges to subscriptions 3/10 closed
  1. 1 PAY-201 closed Phase 1: customer and subscription tables, backfilled from charges
  2. 2 PAY-202 closed Phase 2: Stripe Checkout for new signups
  3. 3 PAY-203 in_progress Phase 3: webhook ingestion — invoices, payment failures, cancellations
  4. 4 PAY-204 in_progress Phase 4: proration on plan change
  5. 5 PAY-205 open Phase 5: dunning emails and a grace period before downgrade
  6. 6 PAY-206 open Phase 6: migrate legacy one-off customers onto plans
  7. 7 PAY-209 open Invoice PDF still renders the old company address
  8. 8 PAY-212 closed Duplicate invoices when Stripe retries a webhook ↑ the ledger above
  9. 9 PAY-214 open Trial ends a day early for customers west of UTC: trial_end is stored as a date and compared as a timestamp
  10. 10 PAY-215 open Remove the charges-era feature flag once phase 6 lands

illustration · every ref on this page belongs to the same invented project

PAY-212 · resolution, as written when it closed
Merged as 7c1e2b4. The handler now inserts into stripe_events (event_id UNIQUE) before doing any work and returns 200 on conflict; the replay test posts the same event twice and asserts one invoice. Retry backoff was not touched — Stripe’s schedule was never the problem.

Issues close with prose, not a status flip. Six weeks from now the question is not whether the bug closed, it is whether the index went in and whether anyone changed the backoff — and both answers are in the record, not in anyone’s recollection.

What the agent writes

A brief that survives being read cold.

Every offload gets read by someone with none of your context, possibly days later. The skill file teaches the agent the four things a brief needs. The same report, twice:

unactionable
“Checkout is flaky sometimes, might be a race condition, someone should look into it.”

No file, no repro, no definition of done. The next agent starts below zero — now “might be a race condition” has to be told apart from an actual finding.

actionable
“Checkout returns 500 when a coupon is applied after the cart total has been cached — app/checkout/total.ts:61, computeTotal() reads the memoised subtotal and never re-runs when the coupon changes. Repro: add any item, open /checkout, apply SAVE10, submit. Ruled out: not the coupon API — its response is correct, the total is stale. Done when a test next to testCouponAppliesToTotal covers apply-after-cache and passes.”
  • names a file:line
  • gives a repro
  • says what was ruled out
  • defines done

What it is not

It will not go and look for you.

taskr never runs git or gh, never opens a database directly, and does not manage PRs, run CI, or replace GitHub Issues. No sprints, no burndown, no roadmap. Any tree state in an issue — branch, HEAD, dirty files — is there because somebody wrote it down. That constraint is the point: a memory layer that invents nothing is a memory layer you can trust cold.

Pick the thread back up.

Every write is stamped by the credential that made it — user when it’s you, agent when it’s the thing working beside you.

Sign in Invite-only while billing is built. Public signup is next.
taskr append-only · one Go binary · Postgres with row-level isolation