Artshelfdocs

01Start · Overview

A shelf for temporary work.

Artshelf is an approval-first artifact retention CLI for coding agents and the humans reviewing them. Agents create files they should not forget: backups, reports, quarantines, debug output. Artshelf records why each one exists, when to look at it again, and what cleanup is allowed to do with it.

First command

# install the CLI
npm install -g artshelf

# put a file on the shelf: where it is, why it exists, when to look again
artshelf put ./backup-2026-06-10.tar.gz \
  --reason "pre-migration backup" --ttl 7d --cleanup trash

# ask what needs attention (reads only, moves nothing)
artshelf review --json

That is the whole habit. Every temporary file gets a ledger entry, and review tells you what needs attention without touching anything.

The loop

One simple rhythm runs the whole shelf, four moves: Capture automatically, Review calmly, Approve exactly, and Verify quiet. Agents capture and review; a human approves one exact target; everyone confirms the shelf went quiet again.

Everything in Artshelf follows five stages: Create, Monitor, Review, Clean, Purge. The agent docs use the same names, and each stage links to its page.

Safety model

The same rules apply everywhere, to agents and humans alike. There are no escape hatches.

  • Refused No automatic cleanup. Nothing runs on a schedule or daemon, ever.
  • Refused cleanup --execute --all does not exist. Execution names one ledger and one reviewed plan id.
  • Refused dispose --all does not exist. Disposition is one reviewed record and one plan id at a time.
  • Refused Delete is refused in v1. cleanup=trash quarantines; physical deletion needs a separate reviewed purge plan.
  • Approval Execute runs only from an already-reviewed ledger plus plan id, after exact human approval.
  • Read-only review, status, and doctor never write plans, receipts, or records.
  • Session-only artshelf ui stores exact-target triage intents and agent replies, but the browser never gets a direct cleanup, dispose, reconcile, registry-prune, resolve, or purge path.

What a record looks like

A record is one line of JSON in the ledger file (.artshelf/ledger.jsonl):

{
  "id": "shf_20260610_091400_4be1",
  "path": "/repo/backup-2026-06-10.tar.gz",
  "kind": "backup",
  "reason": "pre-migration backup",
  "createdAt": "2026-06-10T09:14:00.000Z",
  "retention": { "mode": "ttl", "ttl": "7d" },
  "retainUntil": "2026-06-17T09:14:00.000Z",
  "cleanup": "trash",
  "owner": "manual",
  "labels": ["migration"],
  "status": "active"
}

Three fields drive the loop. retention decides when the record comes due, cleanup decides what an approved plan may do with the file, and status tracks where the record sits in that loop. The id is what you quote in reports and handoffs.

Ledgers stay with the work. Each project keeps its own ledger file, and a global registry keeps track of every ledger it has seen, so one read-only command can answer for all of them without merging records into one global file.

# each project writes its own ledger
~/work/api/.artshelf/ledger.jsonl
~/work/site/.artshelf/ledger.jsonl

# the global registry keeps track of every known ledger
~/.artshelf/ledgers.json

# put registers its ledger automatically; add existing ones explicitly
artshelf ledgers add --ledger <repo>/.artshelf/ledger.jsonl --name <project> --scope repo --json

# --all commands read across every registered ledger
artshelf review --all --json

Where next

  • Install: get the CLI from npm and check it with artshelf doctor.
  • Quickstart: walk one real artifact through the whole loop in five minutes.
  • Agent usage: the Create, Monitor, Review, Clean, Purge contract for coding agents.
  • CLI reference: every command on one page.