# git-cas v6.2.0 Release Notes

`v6.2.0` makes `git-cas` the storage and cache lifecycle owner for application
packages. Applications can define domain keys, payload schemas, causal
publication rules, and retention intent without constructing Git trees,
persisting naked object IDs, or maintaining a second cache protocol.

## The Contract

> A handle is not a durability claim.

`cas.assets`, `cas.pages`, and `cas.bundles` return immutable opaque handles.
The staged result explicitly reports that no root was created. A caller then
chooses how the handle graph should live:

| Policy surface | Intended lifecycle | Git reachability behavior |
| --- | --- | --- |
| `cas.retention` / RootSet | Caller-managed current set | Anchored while present |
| `cas.caches` | TTL/capacity/approximate-LRU cache | Anchored until managed eviction |
| `cas.expiringSets` | Security replay window | Anchored until expiry; no early eviction |
| `cas.publications` | Application causal history | Anchored by the allowlisted application ref |
| Vault | History-preserving named assets | Anchored by `refs/cas/vault` history |

Successful retention and publication operations return a `RetentionWitness`
that identifies the exact ref generation and tree edge that established
reachability.

## Application Storage

```javascript
const staged = await cas.assets.put({
  source,
  slug: 'warp/materialization',
  filename: 'materialization.bin',
});

const retained = await cas.retention.retain({
  handle: staged.handle,
  root: {
    ref: 'refs/cas/rootsets/git-warp/materializations',
    name: materializationKey,
  },
  policy: 'evictable',
});

console.log(retained.witness.root.generation);
```

- Asset writes stream through the existing chunking, deduplication,
  compression, encryption, manifest, and tree pipeline.
- Pages store bounded immutable blobs and expose targeted streams.
- Bundles build deterministic bounded-fanout trees from named streams or
  nested handles.
- `bundles.iterateMembers()` streams descriptors, while `getMember()` and
  `openMember()` traverse only the requested descriptor path and payload.
- `cas.publications.commit()` validates an entire handle graph, ordered commit
  parents, an explicit ref allowlist, and expected-head compare-and-swap state
  before changing a ref.

Handles contain no repository path and support canonical SHA-1 and SHA-256
object IDs. Importing a handle validates that its graph exists and has the
expected Git object and codec shape.

## Managed Cache And Replay Lifecycles

`cas.caches.open()` owns immutable cache indexes under `refs/cas/caches/*`.
CacheSet handles TTL, entry and logical-byte limits, approximate-LRU sweeps,
coalesced touches, retention witnesses, bounded inspection, doctor, and repair.
A cache miss is read-only.

`cas.expiringSets.open()` owns digest-only replay markers under
`refs/cas/expiring/*`. `addIfAbsent()` is atomic across writers, `contains()` is
read-only, and `sweep()` can release only entries whose expiry has passed. The
surface intentionally has no remove, repair, capacity, or recency eviction
operation that could shorten a security acceptance window.

Both services publish parentless current-generation commits. Superseded
generations do not remain reachable through their own storage history.

## Repository Diagnostics

```javascript
const report = await cas.diagnostics.doctor({
  gracePeriodMs: 14 * 24 * 60 * 60 * 1000,
});
```

The report streams Git object, ref, and reflog-reachability inventories;
classifies anchored, orphaned, grace-expired volatile, and total unreachable
objects; and summarizes CacheSet, RootSet, ExpiringSet, and Vault usage. It
fails closed if concurrent writes make derived arithmetic inconsistent.

Diagnostics use plumbing's exact prune dry-run contract for volatile objects.
The doctor does not run `git gc` or destructive prune and exposes no object or
ref mutation operation. Shared deduplicated bytes, packed-object age, reflog
entry count, alternate-store attribution, and pack metadata overhead remain
explicitly reported limitations rather than guessed values.

## Compatibility And Upgrade

This release is API-additive. Existing CAS manifests, RootSets, Vaults, refs,
and low-level `createTree()` callers remain compatible; no stored-data
migration is required. Repository diagnostics require
`@git-stunts/plumbing` 3.1.0 or newer.

Applications that currently store tree or blob IDs only in JSON should adopt
every still-live object into a RootSet or rebuild it through the matching
high-level capability before destructive Git cleanup. An object that Git
already pruned cannot be recovered by doctor or repair.

See [UPGRADING.md](../../UPGRADING.md) for the adoption sequence,
[Application Storage](../API.md#application-storage) for API contracts, and
[Repository Diagnostics](../API.md#repository-diagnostics) for report fields
and limitations.

## Verification

`pnpm run release:verify` passed 13/13 steps with 6,124 observed tests:

| Suite | Tests |
| --- | ---: |
| Node unit | 1,871 |
| Bun unit | 1,870 |
| Deno unit | 1,861 |
| Node integration | 174 |
| Bun integration | 174 |
| Deno integration | 174 |

The same run passed ESLint, all three runnable examples, build metadata
stamping, npm package-content inspection, and a JSR publish dry-run. GitHub CI,
self-review, and Code Lawyer review remain mandatory before tagging.
