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 --alldoes not exist. Execution names one ledger and one reviewed plan id. -
Refused
dispose --alldoes not exist. Disposition is one reviewed record and one plan id at a time. -
Refused
Delete is refused in v1.
cleanup=trashquarantines; 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, anddoctornever write plans, receipts, or records. -
Session-only
artshelf uistores 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.