# git-cas v6.1.0 Release Notes

`v6.1.0` adds a middle retention surface between unrooted CAS plumbing and the
history-preserving vault.

## Root Sets

Applications can now retain the current generation of cache, checkpoint,
index, or derived-state objects under a caller-owned ref:

```javascript
const cas = await ContentAddressableStore.open({ cwd: '.' });
const rootSet = await cas.rootSets.open({
  ref: 'refs/cas/rootsets/my-application/cache',
});

await rootSet.put({
  name: cacheKey,
  oid: payloadTreeOid,
  type: 'tree',
  retention: 'evictable',
});
```

Entries are Git-reachable while present. Each update writes a parentless
current-generation commit, so removing an entry releases it from root-set
history. If no other branch, tag, reflog, vault, or root set reaches the target,
it follows normal Git grace-period and pruning rules.

## Retention Vocabulary

- `pinned` and `evictable` describe application retention policy.
- `anchored`, `orphaned`, and `volatile` describe Git reachability state.
- Root-set `pinned` does not create pack `.keep` files.
- The vault still preserves mutation history and remains the durable named
  asset surface.

## Doctor And Repair

`rootSet.doctor()` checks ref, commit, metadata, reachability edges, target
existence, and target type. `rootSet.repair({ entries })` rebuilds a missing or
malformed current head from an authoritative list without trusting existing
metadata.

Applications upgrading from JSON-only OID indexes should adopt every still-live
object into a root set before any destructive cleanup. Objects already pruned
by Git cannot be recovered by this API.

## Compatibility

This release is API-additive. Existing manifests, vaults, branches, tags, and
`createTree()` behavior are unchanged. `createTree()` remains low-level and
unrooted until a caller anchors its returned OID.

Custom persistence implementations that support root sets must add
`readObjectType(oid)`, and custom ref adapters must add
`resolveParents(commitOid)`. Existing CAS store/restore paths do not call those
methods.

## Proof

The release includes a real-Git integration test using
`git prune -n --expire=now`:

- a target tree is not reported while present in a root set
- the same tree is reported after removal when no other ref reaches it
- root-set commits have no parent
- missing and mismatched targets are rejected before the ref changes

See [API Reference: Root Sets](../API.md#root-sets) and
[UPGRADING.md](../../UPGRADING.md#v601-to-v610).

The release verifier passed 12/12 steps with 5,521 observed tests across Node,
Bun, Deno, and all three integration runtimes. The JSR publish dry-run remains
intentionally skipped under the documented upstream toolchain gate.
