Skip to content

Downloads, ownership, and cache

Ownership and adoption

Each config uses .sentiary/<config-filename>.json to record output names, absolute file paths, and SHA-256 checksums. A missing generated file can be restored. An existing untracked destination or a manually changed owned file blocks overwrite or removal, even when its content happens to match the new export.

Review existing files and the preview, then use sentiary-cli pull --force to adopt destinations or discard edits. --force does not bypass invalid paths, symlink protection, case-only rename restrictions, or ownership of an unselected output. Never expect manual Xcode catalog edits to merge into server translations.

After a successful pull, obsolete owned files for selected outputs are removed. Unrelated files and unselected outputs remain. A full pull also cleans ownership for removed output definitions; a selected pull limits cleanup to those names. Empty directories may remain.

Concurrency and write guarantees

A kernel-backed per-config lock at .sentiary/<config-filename>.lock covers fetching, cache publication, and destination writes. Concurrent pulls sharing the same manifest wait until the lock is available; cancellation stops the wait. A process exit releases the lock. The lock file may remain: its presence alone does not indicate an active lock. Do not delete a lock file while another pull may hold it.

Different configs sharing destinations are not coordinated. Avoid overlapping ownership. The cache has a separate process lock around reads, publication, and cleanup, released during network requests. Online and offline previews do not acquire the ownership lock.

All requested exports must succeed before any generated destination changes. Files are staged beside their destinations and renamed individually. The manifest is replaced after file writes and obsolete-file cleanup. This is not a multi-file filesystem transaction: an I/O failure can leave some files updated.

Conditional requests and completed sets

Online pulls authenticate and request backend export/state protocol 1, then send stored ETags via If-None-Match. A valid 304 reuses verified bytes. The response generation, data revision, and exporter version must match the observed project state. Each changing project is retried up to three times, then fails. A server/access/download error never silently selects offline data.

A completed set is published only after all requested exports are verified and saved as immutable SHA-256 objects. Publication precedes destination validation/writes. A destination conflict can therefore leave a usable completed set. Snapshot consistency is per project; it is not a cross-project transaction or a translation lockfile. A committed intermediate state of a bulk edit may be captured.

Cache location and identity

Precedence: --cache-dir, then SENTIARY_CACHE_DIR, then os.UserCacheDir()/sentiary/exports-v1. Relative overrides are relative to the process working directory.

OS Usual default base
macOS $HOME/Library/Caches/sentiary/exports-v1
Linux $XDG_CACHE_HOME/sentiary/exports-v1, otherwise $HOME/.cache/sentiary/exports-v1
Windows %LocalAppData%\sentiary\exports-v1

The cache adds a hash of the normalized server URL, then stores objects/ and sets/ with a cache.lock. Identity includes project ID, format, layout, language selection, combined source language, and empty-translation policy. Keys, output names, checkout paths, and destination paths are excluded. Renaming outputs, changing keys, or moving checkouts can reuse exports.

There is one latest completed set per exact export request selection. Replacement removes only objects unreferenced by remaining selections; cleanup is best effort. Sets do not expire automatically. Protect cache contents like generated translations.

Offline restoration

pull --offline makes no network calls and needs no credentials. It finds the newest single completed set covering the requested exports, including a selected subset. It does not combine several sets. Wildcard expansion uses that set's saved project languages. Every selected object's checksum must verify before writes. Completion time and age are printed to stderr.

Deleting build/ does not invalidate a cache set. Restore it with the same config and cache location. Changing format, selected languages, source language, or empty-value policy may require another online pull. Offline mode does not establish current access or freshness.

Failure recovery

Failure Recovery
Untracked or edited destination Review/back up files; deliberately adopt with --force
Case-only owned rename Move through a distinct destination in a successful pull
Unsupported export/state protocol Use a compatible backend; legacy commands remain separate
Project changed during three attempts Retry after edits settle
No completed set covers request Run an online pull for that selection and cache location
Missing/corrupt object Run online to fetch valid content; do not edit hashes
Corrupt cache metadata Preserve for diagnosis, choose a fresh cache directory, then pull online
Partial destination write or manifest save Inspect the affected files; retry with --force only after accepting replacements
Invalid ownership manifest Preserve it and inspect previous owned paths before rebuilding ownership; unrecorded obsolete files cannot be cleaned automatically

A cache publication failure leaves destinations unchanged and retains the previously published set where possible. A later destination error leaves the completed set available for recovery. See the recovery walkthrough.