Installation model
Granary installs selected reference material into consumer-owned paths, defaulting to .granary/context/.
Definition, payload, and intent
A portable pack describes existing files with granary.json. A curated pack composes sources under packs in that same format. Consumers can also select material from a repository without a manifest.
The consumer's granary.json selects only material that project needs. Distribution manifests can live separately: this repository consumes TypeScript in its root manifest and declares all language sets in packs/granary.json. The lock retains composition provenance, exact commits, selected files, hashes, and destinations.
Versioned destinations
Explicit member output adopts content directly beneath that destination; root output supplies its base. Without overrides, source locators and requested revisions namespace destinations. Code is ordinary selected content, not forced into a separate hidden tree. Arrays support independent revisions of one source.
Configuration and lockfiles stay at the project root regardless of output overrides. Granary writes .granary/.gitignore containing * to ignore generated context and the shared baseline cache without editing the root .gitignore. Explicit destinations outside .granary/ are not automatically ignored. Existing differing ignore files fail preflight rather than being overwritten.
Installation stages
- Read current manifest intent and expand declared members.
- Resolve source revisions and selected files.
- Read definition commits and selected upstream bytes.
- Record source commits and content hashes.
- Build payload, agent-instruction, config, and lock changes.
- Check all destinations before writing.
- Recheck observed destination bytes and apply changes with rollback on reported failure.
Retrieval failures do not write consumer files. Escaping paths and symlinks are rejected. Unmanaged files and edited managed files are preserved by failing the operation. Unrelated files are left in place.
Writes use adjacent temporary files and atomic rename per file. Recovery restores attempted writes on reported I/O failures; this is not a crash-safe, multi-file filesystem transaction. Concurrent installer runs are not supported.
Restoration
install requires matching config and lock intent, verifies ordered composition membership, then reads pinned Git commits and checks hashes. Local upstream material must still match locked bytes. Source updates are never substituted silently.
Reviewed updates can record accepted local additions, edits, and deletions separately from upstream hashes. install validates and overlays those materialized results, restores missing accepted files, and rejects later unaccepted edits. See pack maintenance for review decisions, baseline recovery, and restoration limits.
Granary creates or refreshes a dedicated <granary-context> region in root AGENTS.md linking directly to selected reference entrypoints. There is no intermediate generated INDEX.md. The Almanac SDK edits a disposable staging copy; the resulting instruction change joins the same preflight/recovery transaction as installed content. Existing instructions and other managed regions stay unchanged. No compatibility aliases, hooks, staging, or consumer Almanac configuration are added.