Work management for the delegation chain

Create, claim, close. That's the whole tool.

rd tracks work items as signed nostr events. Your local append-only event log is the source of truth — relays are replaceable caches for sync, never the authority. No database, no SaaS, works fully offline.

curl -fsSL https://ready.3dl.dev/install.sh | sh

Real demos, real output

These play back actual terminal sessions from the test suite. Hit play, or clone and run them yourself.

Create → Claim → Close

Every work item follows the same three-step lifecycle. Humans and agents use the same commands.

# Create a work item — returns the item ID directly rd create "Ship login page" --priority p1 --type task myproject-45e # What needs attention right now? rd ready myproject-45e p1 inbox 3h Ship login page # Claim it — you're now the performer rd claim myproject-45e claimed myproject-45e # Close with a reason — the audit trail records why rd done myproject-45e --reason "Login page ships with JWT auth" closed myproject-45e (done)

Delegation is explicit

Every item has for (who needs the outcome) and by (who's doing it). Delegation is an act, not an assumption.

rd delegate myproject-a1b --to atlas/worker-3 delegated myproject-a1b to atlas/worker-3 # See what you've delegated rd ready --view delegated

The attention engine

Named views filter by who you are. rd ready shows what's actionable. Priority drives ETA — P0 is now, P3 is 72 hours.

# Views: ready, work, pending, overdue, delegated, my-work rd ready --view overdue rd list --status active --priority p0,p1 rd list --by atlas/worker-3 --all --json

Full command reference

rd init --name <project>Initialize a project — local signed-event log + a nostr board
rd create "..." --type task --priority p1Create a work item (returns item ID when piped)
rd readyWhat needs attention now (bare IDs when piped)
rd list [--status ...] [--by ...] [--all]List items with filters
rd show <id>Item details + audit trail
rd claim <id>Accept work, become the performer
rd delegate <id> --to <identity>Assign to a person, agent, or automaton
rd done <id> --reason "..."Close with reason — records to the audit trail
rd inviteGenerate a one-use invite token for this project
rd join <token>Join a project via invite token (auto-syncs items)
rd dep add <id> <blocker-id>Wire a dependency (works across projects you own)
rd gate <id> --gate-type designEscalate to a human for a decision
rd update <id> --status <status>Change status, priority, ETA, or context

Recipes for Claude Code

Drop one of these into your project and Claude Code starts tracking work immediately. No MCP server, no special integration — just rd on PATH.

Recipe 1: Add to CLAUDE.md

Paste this into your project's CLAUDE.md. Claude reads it at session start and uses rd like any other CLI tool.

# Add to your CLAUDE.md: ## Work tracking This project uses `rd` for work management. - Start every session: `rd ready` (what needs attention) - Resuming after context loss: `rd ready --view work` (find your in-progress item) - When starting work: `rd claim <id>` - When done: `rd done <id> --reason "..."` - To create new items: `ITEM=$(rd create "..." --type task --priority p1)` - Pipe-friendly: `for id in $(rd ready); do rd show $id; done` - All commands support `--json` for structured output

Recipe 2: Drop in the skill file

Download SKILL.md into your project's .claude/skills/rd/ directory. Claude Code discovers it automatically and gains full rd command knowledge.

mkdir -p .claude/skills/rd curl -fsSL https://ready.3dl.dev/SKILL.md -o .claude/skills/rd/SKILL.md

Recipe 3: Multi-agent swarm

Spawn parallel Claude Code agents that share a work queue. Each agent gets its own identity via invite token. The filesystem handles isolation — no env vars needed.

# Owner sets up the project rd init --name myproject rd create "Build auth" --priority p0 --type task rd create "Build API" --priority p1 --type task rd create "Write tests" --priority p1 --type task # Generate invite tokens for each agent TOKEN_A=$(rd invite) TOKEN_B=$(rd invite) # Each agent joins from its own worktree mkdir -p worktree-a && cd worktree-a rd join $TOKEN_A joined d8301552... via invite token (expires in 1h59m) # Agent claims from the shared queue ITEM=$(rd ready | head -1) rd claim $ITEM rd done $ITEM --reason "Auth module complete"

Recipe 4: Agent escalation to human

Agent hits a decision point it can't resolve. Posts a gate. Human approves from their terminal. No dashboard, no ticket system — just signed nostr events.

# Agent: "I need a ruling on this" rd gate myapp-d4e --gate-type design \ --description "PKCE vs device flow for mobile auth" {"id":"myapp-d4e","gate_type":"design","status":"waiting"} # Human: sees it from anywhere rd gates myapp-d4e p1 design PKCE vs device flow Migrate auth rd approve myapp-d4e --reason "PKCE. Need browser redirect." # Agent: item is back to active, continues work

Recipe 5: Zero-config agent identity

Every actor signs with its own secp256k1 key under $RD_HOME. $RD_ACTOR selects which key signs — the owner and a named agent on the same host sign with distinct keys and are attributed distinctly.

# $RD_HOME holds one key per durable actor $RD_HOME/ keys/owner.json ← owner identity (trust root) keys/agent-pm.json ← named agent identity keys/agent-worker-3.json ← another named agent identity # Owner: default actor, no config needed cd myproject rd ready # Agent: selects its own key via $RD_ACTOR, signs distinctly RD_ACTOR=agent:pm rd claim myproject-a1b rd show myproject-a1b # Each transition attributed to the signing key that made it

Agents use the same commands

There's no separate agent API. rd create, rd claim, rd done work the same for a human at a terminal and a Claude session reading CLAUDE.md. Output is pipe-friendly — bare IDs when piped, tables when interactive.

Any nostr client can read the log

rd operations publish signed nostr events — a 30301 board, 30302 item cards, NIP-34 status events. The events are the integration surface: any nostr-aware tool can read them directly from a relay, no rd-specific API required.

From one project to your whole org

Same tool at every level. No migration, no import/export. Each tier adds capability without changing the commands you already know.

For one project

Solo

Free · Local

  • Local signed-event log per project
  • Your local log is the source of truth
  • Works fully offline
  • Full CLI — create, claim, close
  • Named views & attention engine
  • Append-only signed-event audit trail
rd init --name myproject initialized myproject board: 30301:9f2a1c...:myproject log: .ready/nostr-log.jsonl ITEM=$(rd create "Ship login page" --priority p1 --type task) rd ready myproject-45e p1 inbox 3h Ship login page rd claim $ITEM && rd done $ITEM --reason "..." claimed myproject-45e closed myproject-45e (done)

No account. No server. Just rd init and go.

For an individual

Multi-Project

Free · Local

  • Everything in Solo
  • One identity key, many projects
  • Cross-project delegation
  • Cross-project queries
  • $RD_HOME key reused across projects
  • Project-scoped views
# Each project gets its own board and local log cd ~/api && rd init --name api cd ~/frontend && rd init --name frontend # Query across projects rd ready --project api rd list --project frontend

One $RD_HOME owner key signs across every project. Each project keeps its own local log and board.

Enterprise

Org-Wide

Hosted · Contact us

  • Everything in Collaboration
  • Org home — cross-project discovery
  • Graded operator provenance levels
  • Owner-rooted, revocable role-grants
  • Permanent append-only audit trail
  • Bridge integration (Teams, Slack)
# Org-wide registration rd register --org acme # Agent hits a decision point — escalates rd gate myapp-d4e --gate-type design \ --description "PKCE vs device flow" {"id":"myapp-d4e","gate_type":"design","status":"waiting"} # Human sees it, approves from anywhere rd gates myapp-d4e p1 PKCE vs device flow Migrate auth layer rd approve myapp-d4e --reason "PKCE, need browser redirect" # Full audit trail — every state change is a signed event, kept forever rd show myapp-d4e

Owner-rooted, revocable role-grants. Every event signed and permanent. Bridge to existing tools.

Signed events, not a database

Ready isn't a project management app with a backend. rd is an operation set — a structured vocabulary of commands that maps onto signed nostr events any relay or client can read.

How it works underneath

When you run rd create, rd builds a signed nostr item card (kind 30302) and a NIP-34 status event, appends both to your local append-only signed-event log, and publishes them to your relays. rd claim appends another signed status event with a causal link back to the card. Item state is a projection of the signed-event log — there's no separate database.

Each project is a nostr board (kind 30301). The operation set below is the rd command vocabulary that maps onto that event schema — every operation is a signed event, not a campfire-specific message format.

The core work vocabulary

work:create — new item with full payload work:claim — accept work, become performer work:status — transition status work:delegate — assign/reassign performer work:block — wire a dependency work:unblock — remove a dependency work:gate — request human escalation work:gate-resolve — resolve a gate work:update — modify fields work:close — terminal close with reason

Federation topology

Each project is its own nostr board with its own local, authoritative signed-event log. Relays sync boards between machines — a self-hosted write-allowlist admits only owner-granted keys; reads stay open. Work stays local — the relay is a replaceable cache, never the source of truth.

Relays (self-hosted, 2+ for no single point of failure) ├ write-allowlist: owner-rooted role-grants ├ └ Board: api (local log authoritative) └ Board: frontend (local log authoritative) └ Board: infra (local log authoritative)

No compaction — ever

There's nothing to compact. The append-only signed-event log is the permanent audit trail. Every create, claim, status change, delegation, and gate is a signed event, appended once, kept forever.

The audit trail survives Every state change is a signed nostr event appended to your local log. Relays may drop old data — your local log never does. Nothing is archived away; nothing needs to be.

Built on open nostr standards

Ready layers a work-management vocabulary on public nostr NIPs — addressable boards and cards, NIP-34 status events, NIP-22 comments, NIP-77 Negentropy sync. No custom protocol to implement; any nostr client already speaks the transport.

Install rd

Nostr-native, self-contained binary — no separate server, no cf required.

Shell (Linux / macOS)

curl -fsSL https://ready.3dl.dev/install.sh | sh

Go install

go install github.com/campfire-net/ready/cmd/rd@latest

From source

git clone https://github.com/3dl-dev/ready cd ready && go build -o rd ./cmd/rd