| name | archive-author |
| description | Move files into long-term storage with `archive` —
date-prefixed filenames, hidden rec-format sidecars
carrying sha256 + EXIF + (optional) Bitcoin block-
height stamps, deduplication by hash, recutils-based
search verbs, and account-scoped sync. Trigger when
the user wants to archive scans / receipts / signed
PDFs / photos / ebooks, dedup an existing pile, run a
reverse-hash lookup, or sync archives across machines.
|
archive-author skill
1. Design principles
- Educational. The on-disk format is two files per
archived item: the file itself, date-prefixed, plus a
hidden
.meta rec-format sidecar. Reading
bin/archive end-to-end teaches the recutils metadata
model.
- Functional. No database. The sidecars ARE the
index;
recsel queries them directly. A TSV
.index/sha256.tsv is the only derived state, and it
rebuilds from sidecars on demand.
- Decentralized. Per-user archive root; sync is
account-scoped and msync/rsync-shaped (FEAT-138).
- Simple.
archive calls only account + config
at runtime (FEAT-134 pins this with a grep-based
audit).
2. The model
For every archived file foo.pdf saved on 2026-05-06:
$XDG_ARCHIVE_HOME/2026/05/2026-05-06 - foo.pdf
$XDG_ARCHIVE_HOME/2026/05/.2026-05-06 - foo.pdf.meta
The hidden .meta sidecar carries:
| Field | Source |
|---|
sha256 | sha256sum |
size | stat -c %s |
mime | file -b --mime-type |
ctime | original mtime as RFC 3339 |
archived | move timestamp as RFC 3339 |
source | absolute path before the move |
tags | space-separated; user-managed |
note | free text; user-managed |
exif_* | exiftool (image files) |
bitcoin_block | bitcoin block-height (via stamp) |
bitcoin_stamp | bitcoin block-hash <height> |
duplicate_of | put --force only |
Field names use [a-zA-Z][a-zA-Z0-9_]* so recsel accepts
them — hyphens (e.g. bitcoin-block) are encoded as
underscores (bitcoin_block). Extending the format is
recutils-native: add a field, backfill via recfix --auto.
No schema migration.
3. Workflow recipes
-
Initialise.
export XDG_ARCHIVE_HOME=$HOME/archive
mkdir -p "$XDG_ARCHIVE_HOME"
-
Archive one file.
archive put receipt.pdf
# → $XDG_ARCHIVE_HOME/2026/05/2026-05-06 - receipt.pdf
# → .2026-05-06 - receipt.pdf.meta
-
Archive many.
archive put ~/Downloads/scan-*.pdf
Duplicates (by sha256) are skipped with a clear info
line; pass --force to archive them anyway with
duplicate_of: set.
-
Inspect a sidecar.
archive meta "$XDG_ARCHIVE_HOME/2026/05/2026-05-06 - receipt.pdf"
recsel -p sha256,mime $XDG_ARCHIVE_HOME/2026/05/.*.meta | head
-
Edit sidecar fields.
archive meta set "$file" tags "tax 2026"
archive meta set "$file" note "K1, schedule E"
-
Reverse-lookup by hash (FEAT-136).
archive locate 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
-
Search (FEAT-137).
archive find "mime = 'application/pdf'"
archive find "tags ~ 'tax'"
archive find "archived >= '2024-01-01' && size > 1000000"
archive tags # tag → count
archive where mime # mime → count
archive recent 10 # newest 10
archive find ... --format=rec | data rec project tags,size,sha256
-
Stamp (FEAT-135, optional).
archive stamp "$file"
# writes bitcoin_block / bitcoin_stamp to the sidecar.
# Idempotent: re-runs are no-ops once stamped.
archive put --auto-stamp paper.pdf
# stamps at archive-time.
-
Sync (FEAT-138).
archive remote add laptop
archive push laptop
archive pull laptop
archive sync laptop # pull then push
Uses msync if installed, else rsync --delete.
push reindexes first; pull reindexes after.
-
Re-file loose entries.
archive run
-
Rebuild the index after manual cleanup.
archive reindex
4. Guardrails
- Do not edit archived files in place. The sha256 is
the index. Re-archive the modified version; the old
one stays as the as-of-then-stamped artefact.
- Sidecars belong to their files. Renaming a file
without renaming its
.meta sidecar breaks the link.
archive never renames after put; do it yourself
only via a script that handles both atomically.
archive put is destructive at the source. It
mvs, not cps. Pipe through archive put-name
first to preview.
- Dedup is hash-only (FEAT-136). Two files with
identical content but different filenames collapse to
one storage slot. Pass
--force to keep both;
the new sidecar's duplicate_of: points at the
original.
- Bitcoin stamping is opt-in. Per FEAT-135 it
requires a configured
bitcoin instance (signet or
mainnet). Stamping per file is wasteful; batch via
the bitcoin package's batch verb (the OTS pattern)
for cost amortisation.
find requires data (or recsel). The search
layer soft-probes both; missing both fails the search
verbs clearly but doesn't affect put.
5. Where to read more
man archive
share/doc/archive/standards/README.md — recutils,
EXIF 2.32, RFC 3339, FIPS 180-4, OpenTimestamps
docs/archive-walkthrough.md — Downloads folder →
searchable, stamped, synced archive
docs/templates/CLAUDE.md.archive — the per-package
CLAUDE.md template (FEAT-134)
- This package's
CLAUDE.md