Skip to main content

Core Workflow

td manages the full lifecycle of issues from creation through review, with structured handoffs between AI sessions to prevent context loss.

Creating Issues​

Create issues with a title, type, and optional priority:

td create "Add user authentication" --type feature --priority P1
td create "Login button misaligned" --type bug
td create "Refactor auth module" --type task --priority P2
td create "Capture sync edge cases" --description-file docs/issue-description.md

Types: bug, feature, task, epic, chore

Priorities: P0 (critical) through P4 (lowest). Defaults to P2 if omitted.

For markdown-heavy descriptions or acceptance criteria, prefer --description-file and --acceptance-file. They preserve blank lines, indentation, and fenced code blocks exactly, and - reads the whole field from stdin:

cat docs/acceptance.md | td update td-a1b2 --append --acceptance-file -

Starting Work​

Pick up an issue to work on:

td start td-a1b2        # Begin work, sets status to in_progress
td next # Show highest-priority open issue
td focus td-a1b2 # Set current focus without changing status

td start transitions the issue to in_progress and records which session is working on it. Use td focus when you want to track what you're looking at without formally starting work.

Logging Progress​

Record decisions, blockers, and findings as you work:

td log "OAuth callback working"
td log --decision "Using JWT for stateless auth"
td log --blocker "Unclear on refresh token rotation"
td log --hypothesis "Token refresh might conflict with SSO"
td log --tried "Attempted session-based approach, too complex"
td log --result "Benchmarks show 2ms token validation"

Logs attach to your current focus issue. They build a timeline that future sessions can read to understand what happened and why.

Handoffs​

Handoffs are the key feature of td. They capture structured state so the next session can pick up work without guessing:

td handoff td-a1b2 \
--done "OAuth flow, token storage" \
--remaining "Refresh token rotation" \
--decision "Using JWT for stateless auth" \
--uncertain "Should tokens expire on password change?"

Each field serves a purpose:

  • --done: What was completed this session
  • --remaining: What still needs to be done
  • --decision: Choices made and why (prevents re-litigating)
  • --uncertain: Open questions for the next session to resolve

Without handoffs, the next AI session starts from scratch, re-reads code, and may redo work or contradict earlier decisions. Handoffs eliminate that waste.

Review Workflow​

Submit completed work for review:

td review td-a1b2                # Submit for review (status -> in_review)
td reviewable # Issues you can independently review
td reviewable --include-approved # Also show reviewed issues you can close
td approve td-a1b2 # Approve and close
td reject td-a1b2 --reason "Missing error handling" # Back to open

Independent review is preferred when practical. In the default trusted mode, an implementer who cannot get one is asked to say who reviewed the work:

# A sub-agent reviewed it — credit them (no reason required)
td approve td-a1b2 --reviewed-by "code-reviewer sub-agent"

# You reviewed your own work — say so
td approve td-a1b2 --self-review --reason "Reviewed own diff; tests pass"

Both are recorded on the review row, and neither is verifiable by td. Naming a reviewer who did not review is worse than an honest self-review, because it reads as independent in the audit trail.

Review Policy Modes​

td exposes four policy modes via review_policy_mode:

  • trusted — default for new installs. Prefers independent review; an involved session may approve by naming who reviewed the work (--reviewed-by "<who>") or acknowledging a self-review (--self-review --reason). Both are audited. Supports --record-only.
  • delegated — review attestations with delegated close. Reviewer independence is enforced; any session may perform the final close once an independent approval review has been recorded.
  • strict — no prior involvement allowed on the reviewer at all. Preserved for orchestrators that want the legacy close-time session lock.
  • balanced — strict, plus a creator-approval exception (see below). Retained for projects that explicitly opt in.

The legacy balanced_review_policy flag is deprecated; prefer review_policy_mode=balanced instead. Setting the legacy flag still works but emits a one-time deprecation warning.

Set the mode per-project or via env:

td feature set review_policy_mode strict   # or trusted, delegated, balanced
# or, one-off:
TD_FEATURE_REVIEW_POLICY_MODE=strict td approve td-a1b2

Balanced (Legacy) — Creator Exception​

Under balanced, a session that created a task (but didn't implement it) can approve with a reason:

  • Implementer self-approval is always blocked — if you started or worked on a task, you can't approve it.
  • Creator-approval is allowed when a different session did the implementation, with --reason.
  • All other previously-involved sessions remain blocked.
# Lead creates work, agent implements, lead approves
td add "Build feature X"
td start td-a1b2 # agent session
td review td-a1b2
td approve td-a1b2 --reason "Reviewed output, looks good" # lead session

Creator-exception approvals are audited in td security.

Delegated — Review Attestations and Delegated Close​

Under delegated, the review step and the close step are separate:

  • A reviewer session records an approval (or requests changes) via td approve --record-only --reason "...".
  • Once an approval review exists, any session may close with td approve --reason "...".

Two flows are natural under this mode:

Direct reviewer-close — the reviewer both approves and closes in one step:

td review td-a1b2
td approve td-a1b2 # reviewer session: approve + close

Record approval, close later — a reviewer sub-agent attests, and the orchestrator or implementer closes when convenient:

td review td-a1b2                                                          # orchestrator submits
td approve td-a1b2 --record-only --reason "Reviewed diff, tests pass" # reviewer records
td approve td-a1b2 --reason "Closing after recorded independent approval" # orchestrator closes

The second flow is the typical orchestrator pattern. The orchestrator does not need to reserve a special issue role; the independent approval is the close gate, and closed_by_session records who performed the final close.

A reviewer can also record a non-approving decision:

td approve td-a1b2 --record-only --decision changes_requested --reason "fix X"

Use td reviewable --include-approved to surface reviewed issues you can close.

Issue Lifecycle​

open --> in_progress --> in_review --> closed
| |
v | (reject)
blocked -----------+
  • open: Created, not yet started
  • in_progress: Actively being worked on
  • blocked: Waiting on a dependency (auto-unblocks when all dependencies close)
  • in_review: Implementation complete, awaiting review
  • closed: Approved and done

Rejection sends an issue back to in_progress with a reason attached, so the implementer knows what to fix.

Session Isolation​

Every terminal or context window gets an automatic session ID. This keeps implementation, review, and closure attributable without dictating how much ceremony every task needs.

Why this matters:

  • Supports structured handoffs between sessions
  • A fresh session reading the code with new eyes catches issues the implementer missed
  • Distinguishes independent review from acknowledged self-review
  • Mirrors real code review, where a different person checks the work

Let sessions reflect real agent contexts. Creating a new session merely to make a review appear independent defeats the audit trail; use an independent context or acknowledge a trusted-mode self-review instead.

Under delegated mode the review must be independent but the close may be delegated to any session. Under balanced mode, a creator-approval exception allows the same session that created a task to approve it once a different session implemented it.