CLI reference¶
The installed command is citefold. It emits UTF-8 JSON by default; recall --markdown emits only the rendered MemoryPack.
Identity options¶
All identity options are global and must appear before the subcommand:
| Option | Environment variable | Meaning |
|---|---|---|
--root |
CITEFOLD_ROOT |
Storage root; default ~/.citefold |
--tenant-id |
CITEFOLD_TENANT_ID |
Tenant/organization boundary; default local |
--user-id |
CITEFOLD_USER_ID |
User boundary; default me |
--namespace |
CITEFOLD_NAMESPACE |
Memory namespace; default personal |
--agent-id |
CITEFOLD_AGENT_ID |
Agent provenance; default citefold-cli |
--session-id |
CITEFOLD_SESSION_ID |
Session provenance; default default |
--openrouter |
— | Explicitly enable the optional OpenRouter client |
The defaults make local evaluation quick; production hosts should derive all scope fields from authenticated application state.
--root must name a dedicated Citefold directory. Do not put source media, application uploads, logs, or unrelated files inside it. Storage commands operate on the whole root; the tenant/user/namespace options do not narrow a migration, backup, or restore.
Commands¶
status¶
citefold --root /path/to/citefold-data status
status inspects the root without writing. It reports the recognized state (uninitialized, current, legacy, future, recovery_required, or invalid), detected and current schema versions, scope count, store/generation IDs when available, and an issue when the root cannot be used safely.
migrate¶
Always preflight a legacy v0.1 root first:
citefold --root /path/to/citefold-data migrate --dry-run
The dry run performs semantic and integrity checks and reports ready, blockers, warnings, the proposed backup path, counts, bytes, and a fingerprint without changing the storage root. Stop every v0.1 process before the preflight and migration; old processes do not participate in the v0.2 root lock. The actual migration also holds the v0.1 scope-writer and known ledger locks and aborts if canonical data changes despite them.
When ready is true, run:
citefold --root /path/to/citefold-data migrate
citefold --root /path/to/citefold-data migrate \
--backup-to /secure/backups/citefold-before-v0.2.zip
Migration always creates and verifies a backup outside the root before adding schema 2 management metadata. It is additive: pre-existing v0.1 canonical files are not rewritten, and concurrent changes cause an abort without restoring older backup data over them. The backup remains available for explicit operator recovery only.
A current root returns up_to_date. Normal memory commands fail closed on legacy, future, recovery, and invalid states. Rerunning migrate after an interruption verifies the recorded backup, then either completes a committed manifest by removing stale owned state or removes only the uncommitted event/state and retries. It never automatically restores the whole root from the backup.
backup¶
citefold --root /path/to/citefold-data backup
citefold --root /path/to/citefold-data backup \
--output /secure/backups/citefold-2026-08-03.zip
The default archive is placed in a sibling {root}.backups directory. The command writes a ZIP manifest, hashes every included file, verifies the complete archive, and refuses an output inside the root or an existing output path. Backups include sensitive durable history; protect and expire them separately from the active store.
restore¶
citefold --root /path/to/restored-citefold restore \
/secure/backups/citefold-2026-08-03.zip
citefold --root /path/to/citefold-data restore \
/secure/backups/citefold-2026-08-03.zip \
--replace
The first form requires a missing or empty target. --replace is required for a non-empty target. Citefold verifies archive paths, declarations, hashes, and the store fingerprint before swapping directories. Replacement retains the previous root as a sibling path and returns it as displaced_root; it is not automatically deleted.
Before the directory swap, restore writes a sibling intent journal. If a crash leaves that journal, status and normal APIs return recovery_required. Rerun restore for the same archive transaction to roll the validated replacement forward. If the archive was lost after journaling but the journal and temporary replacement are intact, pass the same original archive path to complete recovery. A changed archive, a nonmatching digest, or inconsistent directory identity fails closed; a byte-identical archive at another path is accepted.
See Storage, migration, backup, and restore for the full upgrade sequence, Python API, backup contents, recovery behavior, and local-POSIX boundary.
init, doctor, and demo¶
citefold init
citefold doctor
citefold demo
init creates schema 2 root metadata plus the scoped storage/index when the root is missing or empty, doctor reports storage, FFmpeg, and OpenRouter readiness, and demo runs a local ingest → cited recall. doctor is read-only with respect to the root and does not make a model request. init does not silently adopt an unrelated non-empty directory or migrate legacy data.
ingest-text¶
citefold ingest-text 'The launch codename is ORCHID-77.' --source chat
citefold ingest-text --file meeting.txt --source meeting_note
printf '%s' 'final voice transcript' | citefold ingest-text --mode voice
citefold ingest-text 'interim transcript' --mode voice --not-final
Interim voice text remains a small working buffer; it is not promoted to a durable fact.
ingest-image¶
Store an image with supplied observations:
[
{"content": "The whiteboard says ORCHID-7.", "confidence": 0.96, "locator": {}}
]
citefold ingest-image whiteboard.png \
--source camera_upload \
--observations-json image-observations.json
Without supplied observations or --openrouter, the asset is stored and returned as pending.
ingest-audio¶
[
{"start_ms": 100, "end_ms": 1850, "text": "Send the brief Friday.", "confidence": 0.94}
]
citefold ingest-audio meeting.wav \
--source recorder \
--transcript-json transcript.json
Audio processing can use ffmpeg/ffprobe. Supplied transcripts preserve absolute time ranges.
ingest-video¶
citefold ingest-video meeting.mp4 \
--source meeting_upload \
--duration-ms 5000 \
--transcript-json transcript.json \
--frames-json frames.json
Each frame item has timestamp_ms, content, and confidence. Transcript, subtitle, and frame observations share one timeline.
recall¶
citefold recall 'What are my open tasks?'
citefold recall 'What are my open tasks?' --token-budget 1200 --markdown
citefold recall 'Show archived context for audit' --include-archived
The minimum logical token budget is 256. Archived records are excluded by default.
consolidate¶
citefold --openrouter consolidate
citefold --openrouter consolidate --episode-id episode_example
Model-produced candidates remain pending until reviewed.
candidates¶
citefold candidates list
citefold candidates list --status pending
citefold candidates approve candidate_example
citefold candidates reject candidate_example --reason 'not a durable user fact'
Approval activates a pending candidate through the same policy/evidence validation path as the Python API. Rejection appends a rejected state and preserves its audit history.
correct¶
citefold correct mem_example \
'Alex now prefers Monday follow-ups.' \
--reason 'explicit user correction'
Correction appends a revision and creates a new version.
pin and unpin¶
citefold pin mem_example --reason 'keep this preference stable'
citefold unpin mem_example --reason 'resume normal decay'
Each real state change appends an auditable revision; repeating the same command does not append a duplicate revision, while its audit event is marked changed: false. Only active records can be pinned or unpinned. Pinning freezes the current access strength against decay; after unpinning, decay resumes from the unpin time without retroactively charging the pinned interval. Pinning does not increase confidence, guarantee recall, or prevent correction, archival, evidence invalidation, or deletion.
archive¶
citefold archive mem_example --reason 'project completed'
Archival changes visibility but retains evidence.
forget¶
citefold forget observation:obs_example --reason 'user requested deletion'
citefold forget asset:asset_example --hard
--hard additionally deletes the referenced original and derived asset bytes. See Security for the deletion boundary.
rebuild¶
citefold rebuild
citefold --openrouter rebuild --embeddings
The first form stays local. The embedding form sends indexed text to the configured model route.
list¶
citefold list
citefold list --all
--all includes archived, superseded, and deleted record states.
Exit behavior¶
Successful commands exit 0. Handled filesystem, validation, lookup, and runtime failures print citefold: error: ... to stderr and exit 1. Unexpected programming errors are not intentionally converted into success-shaped JSON.