{"id":45938484,"url":"https://github.com/git-stunts/git-cas","last_synced_at":"2026-07-19T02:01:08.851Z","repository":{"id":336578095,"uuid":"1150225295","full_name":"git-stunts/git-cas","owner":"git-stunts","description":"Git, freebased: pure CAS that’ll knock your SHAs off. LFS hates this repo!","archived":false,"fork":false,"pushed_at":"2026-07-19T00:23:58.000Z","size":17539,"stargazers_count":0,"open_issues_count":8,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-19T01:22:33.996Z","etag":null,"topics":["cas","cbor","cli","content-addressable-storage","content-addressed-storage","encryption","git","git-extension","git-internals","git-stunts","merkle","object-storage","weird-experiments","why-not"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/git-stunts.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":"SUPPORT.md","governance":null,"roadmap":"ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-02-05T03:01:37.000Z","updated_at":"2026-07-19T00:24:01.000Z","dependencies_parsed_at":null,"dependency_job_id":"59d987f7-3a1f-4509-8ce4-870d2796d2c8","html_url":"https://github.com/git-stunts/git-cas","commit_stats":null,"previous_names":["git-stunts/git-cas"],"tags_count":21,"template":false,"template_full_name":null,"purl":"pkg:github/git-stunts/git-cas","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/git-stunts%2Fgit-cas","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/git-stunts%2Fgit-cas/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/git-stunts%2Fgit-cas/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/git-stunts%2Fgit-cas/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/git-stunts","download_url":"https://codeload.github.com/git-stunts/git-cas/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/git-stunts%2Fgit-cas/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35637763,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-19T02:00:06.923Z","response_time":112,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cas","cbor","cli","content-addressable-storage","content-addressed-storage","encryption","git","git-extension","git-internals","git-stunts","merkle","object-storage","weird-experiments","why-not"],"created_at":"2026-02-28T10:15:03.149Z","updated_at":"2026-07-19T02:01:08.826Z","avatar_url":"https://github.com/git-stunts.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# git-cas\n\n\u003e Modern open-source systems still rely on centralized infrastructure to distribute binary artifacts, even when their source code is fully decentralized. This creates a fragile dependency: if hosting endpoints are blocked, degraded, or removed, critical artifacts become unavailable or unverifiable.\n\u003e\n\u003e `git-cas` addresses this by making artifact distribution inherit Git’s existing replication model, allowing binaries to be stored, verified, and transported anywhere Git can operate, including mirrored networks, constrained environments, or fully offline contexts.\n\n`git-cas` is an industrial-grade Content-Addressable Storage (CAS) engine backed by Git’s object database. Its Security First posture makes explicit restore boundaries, bounded metadata reads, authenticated encryption, and legacy-scheme rejection the default. Stored content is chunked, deduplicated, and optionally encrypted — keeping high-fidelity assets and security-sensitive files directly within your repository history.\n\n`git-cas` is designed for the architect who demands mathematical certainty and the operator who needs a stable foundation for artifact storage. It scales from simple binary blob management to multi-recipient envelope-encrypted vaults with key rotation, privacy-mode slug hashing, and Merkle-style manifests for assets of any size.\n\n[![npm version](https://img.shields.io/npm/v/@git-stunts/git-cas)](https://www.npmjs.com/package/@git-stunts/git-cas)\n[![License](https://img.shields.io/github/license/git-stunts/git-cas)](./LICENSE)\n\n![git-cas demo](./docs/demo.gif)\n\n## Why git-cas?\n\nUnlike traditional LFS which moves files to external servers, `git-cas` treats the Git object database as a first-class storage substrate.\n\n- **Deduplication by Default**: Content-defined chunking (CDC) with Buzhash rolling hash identifies repeated patterns across files and versions, minimizing repository growth.\n- **Cryptographic Trust**: Every chunk is verified against a SHA-256 digest. Optional AES-256-GCM encryption with multi-recipient envelope support ensures privacy at rest, and `framed` binds per-frame AAD to prevent cross-manifest blob swaps.\n- **GC-Safe Vault**: Named assets are indexed through a stable ref (`refs/cas/vault`) with optimistic concurrency, preventing Git garbage collection from reclaiming referenced blobs.\n- **Mutable Root Sets**: Cache and derived-state trees can be anchored under\n  `refs/cas/rootsets/*` while live, then become collectible after eviction,\n  without vault history retaining every prior generation.\n- **Managed Cache Sets**: Applications can store handles under\n  `refs/cas/caches/*` with TTL, entry and logical-byte limits, approximate LRU\n  eviction, immutable retention evidence, bounded inspection, repair, and\n  scoped acquisitions that keep a selected generation reachable during use.\n  Cache indexes and object reachability remain git-cas responsibilities.\n- **Expiry-Safe Replay Sets**: Security-sensitive markers can live under\n  `refs/cas/expiring/*` with atomic add-if-absent, digest-only metadata, and\n  expiry-only release. Live markers have no remove, repair, capacity, or LRU\n  path that could shorten their acceptance window.\n- **Opaque Application Handles**: Applications stage assets, immutable pages,\n  and deterministic structured bundles through validated handles, then retain\n  or publish them with generation-scoped evidence instead of managing Git\n  objects, trees, or payload OIDs directly.\n- **Key Lifecycle**: Envelope encryption separates DEKs from KEKs. Rotate passphrases across an entire vault without re-encrypting data blobs. Privacy mode HMAC-hashes slug names to prevent metadata discovery.\n- **Runtime-Adaptive**: A single core supports Node.js 22+, Bun, and Deno through a strict hexagonal port architecture with runtime-specific crypto adapters.\n\n## Quick Start\n\nExisting v5 users should read [UPGRADING.md](./UPGRADING.md) and run\n`npm run upgrade` in dry-run mode before restoring old encrypted vault entries.\nFor the release overview, see the\n[v6.5.1 Release Notes](./docs/releases/v6.5.1.md).\n\n### 1. CLI Usage\n\nInitialize a vault and store your first asset.\n\n```bash\ngit init\ngit-cas vault init\ngit-cas store data.bin --slug assets/v1 --tree\ngit-cas restore --slug assets/v1 --out data-restored.bin\n```\n\n### 2. TUI Cockpit\n\nNavigate your stored assets through the reader-first interactive dashboard.\n\n```bash\ngit-cas vault dashboard\n```\n\n### 3. Library Ingress\n\nIntegrate managed blob storage directly into your TypeScript or JavaScript application.\n\n```js\nimport { createReadStream } from 'node:fs';\nimport ContentAddressableStore from '@git-stunts/git-cas';\n\nconst cas = await ContentAddressableStore.open({ cwd: '.' });\nconst staged = await cas.assets.put({\n  source: createReadStream('./asset.bin'),\n  slug: 'app/asset',\n  filename: 'asset.bin',\n});\nconst retained = await cas.retention.retain({\n  handle: staged.handle,\n  root: { ref: 'refs/cas/rootsets/my-app', name: 'app/asset' },\n  policy: 'pinned',\n});\n```\n\n`staged.handle` is a content locator, not a durability promise. The returned\nretention witness identifies the exact Git generation and tree edge that made\nthe asset reachable.\n\n## Capability Map\n\nThe README is the front door. Detailed mechanics live in the guide set:\n\n| Need                                                    | Start Here                                                           |\n| ------------------------------------------------------- | -------------------------------------------------------------------- |\n| Productive library and CLI workflows                    | [Developer Guide](./GUIDE.md)                                        |\n| Restore memory behavior                                 | [Streaming and restore matrix](./GUIDE.md#streaming-surface)         |\n| Encryption scheme selection                             | [Encryption Modes](./docs/ENCRYPTION_MODES.md)                       |\n| CDC internals, Merkle manifests, KDF policy, and tuning | [Advanced Guide](./ADVANCED_GUIDE.md)                                |\n| Ports, adapters, and collaborator boundaries            | [Architecture](./ARCHITECTURE.md)                                    |\n| Assets, pages, bundles, retention, and publication      | [Application storage](./docs/API.md#application-storage)             |\n| Temporary retention during multi-step composition       | [Scoped staging workspaces](./docs/API.md#scoped-staging-workspaces) |\n| GC retention for caches and derived state               | [Root Sets](./docs/API.md#root-sets)                                 |\n| Managed TTL and capacity caches                         | [Cache Sets](./docs/API.md#cache-sets)                               |\n| Scoped protection while consuming a cache hit           | [Cache acquisitions](./docs/API.md#acquire-and-release)              |\n| Durable replay markers with expiry-only release         | [Expiring Sets](./docs/API.md#expiring-sets)                         |\n| Repository reachability and git-cas usage evidence      | [Repository Diagnostics](./docs/API.md#repository-diagnostics)       |\n| v5 to v6 migration                                      | [Upgrading](./UPGRADING.md)                                          |\n\nCore capabilities:\n\n- **Content-addressed storage**: chunks are addressed by SHA-256 digest and\n  integrity-verified on read.\n- **Deduplication**: fixed chunking and content-defined chunking (CDC) support\n  predictable or shift-resistant chunk boundaries.\n- **Encryption**: AES-256-GCM with authenticated metadata. `whole` and\n  `framed` use fresh random 96-bit nonces; `convergent` derives per-chunk keys\n  and nonces deterministically from the plaintext content hash to preserve\n  deduplication.\n- **Vault indexing**: named assets live under `refs/cas/vault` so Git garbage\n  collection does not reclaim referenced blobs.\n- **Root-set retention**: current cache entries live under caller-owned\n  `refs/cas/rootsets/*` refs. Entries are Git-reachable while present, and old\n  set generations are not retained as commit history.\n- **Managed cache lifecycle**: `caches.open()` owns immutable cache indexes,\n  compare-and-swap replacement, expiry, capacity eviction, retention\n  witnesses, diagnostics, and repair. Reads do not write access metadata;\n  callers opt into coalesced access updates with `touch()`.\n- **Scoped cache acquisitions**: `cache.acquire()` performs a reference-only\n  lookup and atomically anchors the selected cache generation for the caller's\n  explicit lifetime. `release()` is idempotent, while inspection and checked\n  cleanup make abandoned acquisition refs observable and recoverable.\n- **Expiry-safe replay lifecycle**: `expiringSets.open()` atomically retains\n  digest-only replay markers through their declared window. `contains()` is\n  read-only, and `sweep()` can release only markers whose expiry has passed.\n- **Application storage**: `assets`, `pages`, `bundles`, `retention`, and\n  `publications` compose streaming CAS writes, bounded structured\n  materializations, direct-reference or complete-validation member reads,\n  reachability roots, compare-and-swap refs, and immutable lifecycle evidence.\n- **Scoped staging workspaces**: `workspaces.open()` mirrors application writes\n  behind one renewable temporary RootSet, returns only after each handle is\n  anchored, promotes destination-first, and exposes bounded age, expiry,\n  logical-content, and direct-root diagnostics with opaque cleanup pagination.\n- **Envelope recipients**: multi-recipient key wrapping and recipient rotation\n  avoid re-encrypting data blobs.\n- **Operational diagnostics**: `cas.diagnostics.doctor()` streams repository\n  object/ref evidence, classifies anchored, orphaned, and volatile objects,\n  and summarizes workspaces, cache acquisitions, CacheSet, RootSet,\n  ExpiringSet, and Vault usage without mutating Git. The `git-cas doctor` CLI\n  continues to validate vault health.\n\n## Safety Snapshot\n\nThe v6 line is Security First by default:\n\n- `restoreFile()` requires `baseDirectory` and refuses output paths that escape\n  it.\n- Manifest and sub-manifest blob reads default to a 10 MiB `maxBlobSize` safety\n  limit.\n- Legacy encryption scheme identifiers throw `LEGACY_SCHEME` with migration\n  guidance.\n- KDF parameters, salts, frame sizes, restore buffers, and concurrency are\n  policy-bounded.\n- Recipient trial decryption and vault verifier checks use constant-time\n  comparisons.\n\nFor the full hardening table, see\n[Advanced Guide: Security Hardening Summary](./ADVANCED_GUIDE.md#security-hardening-summary).\n\n## Runtime Support\n\n| Runtime     | Version | Crypto Backend       | Status                                               |\n| ----------- | ------- | -------------------- | ---------------------------------------------------- |\n| **Node.js** | 22+     | `node:crypto`        | Primary — full streaming support                     |\n| **Bun**     | Latest  | `node:crypto` compat | Tested via Docker                                    |\n| **Deno**    | Latest  | Web Crypto API       | Tested via Docker; `whole` decrypt is bounded-buffer |\n\nAll three runtimes are tested in CI on every push. The hexagonal architecture isolates runtime differences behind the `CryptoPort` boundary, so the domain core is runtime-agnostic.\n\n## Documentation\n\n- **[Guide](./GUIDE.md)**: Productive path, library/CLI usage, vault workflows, and the feature coverage map.\n- **[Advanced Guide](./ADVANCED_GUIDE.md)**: CDC internals, direct service contracts, security limits, operational tooling, and performance baselines.\n- **[Architecture](./ARCHITECTURE.md)**: The authoritative system map — Facade, Domain, Ports, and Adapters.\n- **[Extending](./docs/EXTENDING.md)**: Custom adapter contracts and extension-point checklist.\n- **[Store/Restore Pipeline](./docs/STORE_RESTORE_PIPELINE.md)**: Maintainer state machines for byte storage, restore, tree publication, and vault boundaries.\n- **[Vault Internals](./docs/VAULT_INTERNALS.md)**: Maintainer map for vault persistence, caching, codecs, privacy indexing, key verification, and retry policy.\n- **[Security](./SECURITY.md)**: Threat models, trust boundaries, and encryption internals.\n- **[Agent API](./docs/API.md)**: JSONL agent protocol for CI/CD automation.\n- **[Workflow](https://github.com/git-stunts/git-cas/blob/main/WORKFLOW.md)**: Repo work doctrine, cycles, and invariants.\n- **[Contributing](https://github.com/git-stunts/git-cas/blob/main/CONTRIBUTING.md)**, **[Code of Conduct](./CODE_OF_CONDUCT.md)**, and **[Support](./SUPPORT.md)**: Project participation and help paths.\n- **[v6.0.0 Release Notes](./docs/releases/v6.0.0.md)**: Major-release summary, upgrade call-to-action, and publication notes.\n- **[v6.1.0 Release Notes](./docs/releases/v6.1.0.md)**: Root-set retention,\n  doctor/repair, and GC-policy guidance.\n- **[v6.2.0 Release Notes](./docs/releases/v6.2.0.md)**: Opaque application\n  storage, managed cache and replay lifecycles, retention evidence, and\n  repository diagnostics.\n- **[v6.3.0 Release Notes](./docs/releases/v6.3.0.md)**: Lifetime-safe,\n  reference-only cache acquisitions with explicit release and doctor evidence.\n- **[v6.4.0 Release Notes](./docs/releases/v6.4.0.md)**: Scoped staging\n  workspaces for temporary multi-object reachability, promotion, and cleanup.\n- **[v6.5.0 Release Notes](./docs/releases/v6.5.0.md)**: Bounded direct bundle\n  references, immutable metadata reuse, and corrected concurrency settlement.\n- **[v6.5.1 Release Notes](./docs/releases/v6.5.1.md)**: Bounded immutable page\n  payload reuse with zero-command warm reads.\n- **[Upgrading](./UPGRADING.md)**: Migration guide for v5 → v6.\n- **[Changelog](./CHANGELOG.md)**: Version history and migration notes.\n\n---\n\nBuilt with terminal ambition by [FLYING ROBOTS](https://github.com/flyingrobots)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgit-stunts%2Fgit-cas","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgit-stunts%2Fgit-cas","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgit-stunts%2Fgit-cas/lists"}