Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ The public entrypoint is [index.js](./index.js).
- exposes `retention`, `publications`, `caches`, and `expiringSets` for explicit
reachability and lifecycle policy
- exposes read-only repository evidence through `diagnostics.doctor()`
- owns explicit local resource closure without coupling closure to object or ref
mutation

The facade is orchestration glue. It is not the storage engine itself.

Expand Down Expand Up @@ -329,7 +331,10 @@ Crypto:

Git:
- **`GitPersistenceAdapter`** — `GitPersistencePort` implementation using
`@git-stunts/plumbing` to shell out to the `git` CLI.
`@git-stunts/plumbing` to shell out to the `git` CLI. It reuses typed
cat-file and mktree sessions, keeps parsed immutable trees count-and-byte
bounded, uses scoped fast-import only for explicit page batches, preserves
streaming payload reads, and owns deterministic child-process closure.
- **`GitRefAdapter`** — `GitRefPort` implementation using
`@git-stunts/plumbing`.
- **`GitRepositoryInspectionAdapter`** — `RepositoryInspectionPort`
Expand All @@ -354,6 +359,8 @@ File I/O:

- **`JsonCodec`** — `CodecPort` using JSON serialization (default).
- **`CborCodec`** — `CodecPort` using CBOR serialization.
- **`GitTreeObjectCodec`** — boundary decoder for canonical SHA-1 and SHA-256
Git tree bytes plus typed mktree session entries.

#### Chunkers (`src/infrastructure/chunkers/`)

Expand Down
30 changes: 18 additions & 12 deletions BEARING.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ timeline

## Current State

`v6.2.0` shipped on `2026-07-13`. Application asset, bundle, page, cache,
expiry, witness, and repository-diagnostics APIs now sit above mutable root
sets and the low-level CAS pipeline. npm plus GitHub Releases are the active
publication surfaces. JSR validation is healthy, but JSR publication remains
outside the release workflow.
`v6.5.1` shipped on `2026-07-18`. Application asset, bundle, page, cache,
expiry, witness, and repository-diagnostics APIs sit above mutable root sets
and the low-level CAS pipeline. Direct bundle-reference reads and bounded
immutable metadata/page reuse are published. npm plus GitHub Releases are the
active publication surfaces. JSR validation is healthy, but JSR publication
remains outside the release workflow.

What exists now:

Expand Down Expand Up @@ -66,6 +67,10 @@ What exists now:
current-generation retention, and allowlisted compare-and-swap application
refs. Staged results and immutable witnesses keep content identity separate
from retention claims.
- **Persistent bounded Git object sessions.** The v6.5.2 candidate reuses typed
cat-file and mktree processes behind `GitPersistenceAdapter`, uses one scoped
fast-import process for an explicit page batch, and keeps individual blob
writes one-shot so external pruning cannot poison duplicate writes.
- **Migration script.** `scripts/migrate-encryption.js` upgrades legacy v1/v2
manifests to the current scheme identifiers.

Expand Down Expand Up @@ -121,19 +126,20 @@ These were the active tensions from the previous bearing. All resolved.

## Next Horizon

With v6.2.0 shipped, active work is tracked in GitHub Issues and Milestones.
Repo docs hold design and evidence records, not the active queue.
With v6.5.1 shipped and the v6.5.2 performance candidate under review, active
work is tracked in GitHub Issues and Milestones. Repo docs hold design and
evidence records, not the active queue.

The latest landed design record is
[0047-application-storage-cache-boundary](./docs/design/0047-application-storage-cache-boundary/application-storage-cache-boundary.md).
The current design under review is
[0052-persistent-git-object-sessions](./docs/design/0052-persistent-git-object-sessions/persistent-git-object-sessions.md).
Its release evidence is attached to
[#50](https://github.com/git-stunts/git-cas/issues/50) and the
[`v6.2.0` milestone](https://github.com/git-stunts/git-cas/milestone/3). No
[#90](https://github.com/git-stunts/git-cas/issues/90) and the
[`v6.5.2` milestone](https://github.com/git-stunts/git-cas/milestone/12). No
later design is selected here; GitHub owns that decision.

The broader horizon remains:

- **TUI modernization.** Carried forward to `v6.3.0`; track
- **TUI modernization.** Carried forward to `v6.6.0`; track
[#39](https://github.com/git-stunts/git-cas/issues/39). Keep dashboard and
wizard actions sharing executable
option-building truth while improving operator ergonomics around long-lived
Expand Down
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- **Bounded page batches and explicit resource closure** -
`pages.putBatch()` stores an explicitly count-and-byte-bounded page group in
input order, while `ContentAddressableStore.close()` and async disposal drain
started operations and release local adapter resources without mutating
objects, refs, retention, or publication state.

### Performance

- **Persistent Git object sessions** - immutable metadata and bounded tree
reads reuse one typed `cat-file` process, tree writes reuse typed `mktree`,
and page batches use one scoped `fast-import` process. Parsed tree reuse is
bounded by entry count and estimated bytes; payload streams remain streaming.
Individual blob writes deliberately remain one-shot so an object pruned by
an external process is recreated correctly on the next write.

## [6.5.1] — 2026-07-18

### Performance
Expand Down
16 changes: 13 additions & 3 deletions GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,13 @@ for await (const chunk of cas.assets.open({ handle: staged.handle })) {
}

console.log(retained.witness.root.generation);
await cas.close();
```

Node's file stream is an `AsyncIterable<Uint8Array>`; Bun and Deno callers can
supply their native async byte streams through the same contract.
supply their native async byte streams through the same contract. In production
code, call `close()` from `finally` or use async disposal. Closure releases
local resources only and does not change stored objects or retention.

## Application Storage Lifecycle

Expand Down Expand Up @@ -139,8 +142,9 @@ that is already sorted by canonical member path, so construction does not need
to collect the complete member set.

```js
const nodes = await cas.pages.put({ source: encodedNodePage });
const edges = await cas.pages.put({ source: encodedEdgePage });
const [nodes, edges] = await cas.pages.putBatch({
pages: [{ source: encodedNodePage }, { source: encodedEdgePage }],
});
const materialization = await cas.bundles.putOrdered({
members: (async function* members() {
yield ['edges/root', edges.handle];
Expand All @@ -163,6 +167,12 @@ lookup reads only the descriptor path and selected payload; retention and
publication perform full bounded graph validation. Identical page bytes and
identically constructed bundles produce identical handles.

`pages.putBatch()` collects and validates the complete explicit batch before
persistence. It accepts at most 256 pages and 32 MiB by default, preserves input
order, and uses one scoped Git write session when the plumbing adapter supports
it. Use individual `pages.put()` calls when inputs should not share one bounded
memory envelope.

Repeated `pages.get()` calls reuse immutable payload reads within the store's
bounded page cache. The defaults retain at most 128 payloads and 8 MiB; use
`pageCacheEntries` and `pageCacheBytes` to tune that ceiling. Every result is a
Expand Down
14 changes: 11 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ Unlike traditional LFS which moves files to external servers, `git-cas` treats t
and deterministic structured bundles through validated handles, then retain
or publish them with generation-scoped evidence instead of managing Git
objects, trees, or payload OIDs directly.
- **Bounded Git Process Reuse**: Immutable object metadata and tree reads reuse
typed Git sessions behind the adapter, while explicitly bounded page batches
amortize writes without changing content identity. Read and payload streams
remain streaming; complete page-batch inputs are collected and validated only
within the explicit count-and-byte envelope.
- **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.
- **Runtime-Adaptive**: A single core supports Node.js 22+, Bun, and Deno through a strict hexagonal port architecture with runtime-specific crypto adapters.

Expand Down Expand Up @@ -84,11 +89,13 @@ const retained = await cas.retention.retain({
root: { ref: 'refs/cas/rootsets/my-app', name: 'app/asset' },
policy: 'pinned',
});
await cas.close();
```

`staged.handle` is a content locator, not a durability promise. The returned
retention witness identifies the exact Git generation and tree edge that made
the asset reachable.
the asset reachable. `close()` releases local resources only; it never deletes
objects, updates refs, or changes retention.

## Capability Map

Expand Down Expand Up @@ -138,8 +145,9 @@ Core capabilities:
read-only, and `sweep()` can release only markers whose expiry has passed.
- **Application storage**: `assets`, `pages`, `bundles`, `retention`, and
`publications` compose streaming CAS writes, bounded structured
materializations, direct-reference or complete-validation member reads,
reachability roots, compare-and-swap refs, and immutable lifecycle evidence.
materializations, explicitly bounded page batches, direct-reference or
complete-validation member reads, reachability roots, compare-and-swap refs,
and immutable lifecycle evidence.
- **Scoped staging workspaces**: `workspaces.open()` mirrors application writes
behind one renewable temporary RootSet, returns only after each handle is
anchored, promotes destination-first, and exposes bounded age, expiry,
Expand Down
9 changes: 5 additions & 4 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,19 @@ GitHub wins and this file should be corrected.
| [`v6.4.1`](https://github.com/git-stunts/git-cas/milestone/8) | Historical bounded-residency proof closeout | [#38](https://github.com/git-stunts/git-cas/issues/38), [#46](https://github.com/git-stunts/git-cas/issues/46) |
| [`v6.5.0`](https://github.com/git-stunts/git-cas/milestone/5) | Bounded lazy bundle references and immutable metadata reads | [#81](https://github.com/git-stunts/git-cas/issues/81) |
| [`v6.5.1`](https://github.com/git-stunts/git-cas/milestone/11) | Bounded immutable page payload reuse | [#85](https://github.com/git-stunts/git-cas/issues/85) |
| [`v6.5.2`](https://github.com/git-stunts/git-cas/milestone/12) | Persistent bounded Git object sessions | [#90](https://github.com/git-stunts/git-cas/issues/90) |
| [`v6.6.0`](https://github.com/git-stunts/git-cas/milestone/9) | Operator TUI and agent automation follow-through | [#39](https://github.com/git-stunts/git-cas/issues/39), [#40](https://github.com/git-stunts/git-cas/issues/40) |
| [`v6.7.0`](https://github.com/git-stunts/git-cas/milestone/10) | Browser and edge read-path exploration | [#41](https://github.com/git-stunts/git-cas/issues/41) |
| [`v7.0.0`](https://github.com/git-stunts/git-cas/milestone/6) | Protocol break only if audit requires it | [#42](https://github.com/git-stunts/git-cas/issues/42), only when justified |

## Latest Landed Design
## Current Design

The latest landed design record is:
The current active design record is:

- [0051-bounded-page-payload-reuse](./docs/design/0051-bounded-page-payload-reuse/bounded-page-payload-reuse.md)
- [0052-persistent-git-object-sessions](./docs/design/0052-persistent-git-object-sessions/persistent-git-object-sessions.md)

Its GitHub goalpost issue,
[#85](https://github.com/git-stunts/git-cas/issues/85), owns the release
[#90](https://github.com/git-stunts/git-cas/issues/90), owns the release
evidence. The design doc is the durable contract; GitHub records completion.

The `v6.2.0` slice record is:
Expand Down
13 changes: 11 additions & 2 deletions STATUS.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
- The machine-facing `git cas agent` surface exists and now supports
OS-keychain passphrase sources for vault-derived key flows, but parity and
portability are still partial.
- **v6.5.2 candidate posture** - persistent bounded Git object sessions,
scoped page-write batches, and deterministic local resource closure are
implemented under [#90](https://github.com/git-stunts/git-cas/issues/90).
Unit, Docker real-Git integration, and Node/Bun/Deno platform gates pass; PR,
review, merge, and publication evidence remain outstanding.
- **v6.5.1 artifact posture** — signed tag `v6.5.1` resolves to reviewed merge
`49b7d5cb`; npm reports `@git-stunts/git-cas@6.5.1` as `latest` with SLSA
provenance, and the final GitHub Release is published. Bounded immutable page
Expand Down Expand Up @@ -116,13 +121,17 @@
- GitHub Issues are canonical. If this section and GitHub disagree, GitHub
wins and this section should be corrected.
- Current release goalpost:
[#90 v6.5.2: Reuse bounded Git object sessions](https://github.com/git-stunts/git-cas/issues/90)
under the
[`v6.5.2` milestone](https://github.com/git-stunts/git-cas/milestone/12).
- Next planned goalposts remain
[#39 v6.6.0: Operator TUI](https://github.com/git-stunts/git-cas/issues/39)
and
[#40 v6.6.0: Agent automation follow-through](https://github.com/git-stunts/git-cas/issues/40)
under the
[`v6.6.0` milestone](https://github.com/git-stunts/git-cas/milestone/9).
- The latest landed design record is
[0051-bounded-page-payload-reuse](./docs/design/0051-bounded-page-payload-reuse/bounded-page-payload-reuse.md).
- The latest active design record is
[0052-persistent-git-object-sessions](./docs/design/0052-persistent-git-object-sessions/persistent-git-object-sessions.md).

## Read Next

Expand Down
Loading
Loading