From a04fcddfccdcd45f08d758e60d1f077587eb7cba Mon Sep 17 00:00:00 2001 From: James Ross Date: Sun, 26 Jul 2026 05:58:07 -0700 Subject: [PATCH 1/3] release: prepare git-cas v6.5.4 --- BEARING.md | 16 +-- CHANGELOG.md | 2 + README.md | 4 +- ROADMAP.md | 5 +- STATUS.md | 11 +- UPGRADING.md | 21 ++++ .../batched-page-retention.md | 11 +- .../witness/release-candidate.md | 102 ++++++++++++++++++ docs/releases/v6.5.4.md | 47 ++++++++ jsr.json | 2 +- package.json | 3 +- src/package-version.js | 2 +- test/unit/docs/package-docs.test.js | 2 + test/unit/docs/release-state.test.js | 48 ++++++++- test/unit/docs/release-truth.test.js | 15 +++ 15 files changed, 271 insertions(+), 20 deletions(-) create mode 100644 docs/design/0054-batched-page-retention/witness/release-candidate.md create mode 100644 docs/releases/v6.5.4.md diff --git a/BEARING.md b/BEARING.md index 9bef5e7..b42c8c2 100644 --- a/BEARING.md +++ b/BEARING.md @@ -14,7 +14,7 @@ timeline ## Current State -`v6.5.2` shipped on `2026-07-19`. Application asset, bundle, page, cache, +`v6.5.3` shipped on `2026-07-19`. 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, bounded Git object sessions, page batches, and @@ -72,11 +72,15 @@ What exists now: 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. -- **Coherent session reuse.** The v6.5.3 candidate preserves `cat-file` across +- **Coherent session reuse.** v6.5.3 preserves `cat-file` across successful immutable writes and preserves `mktree` across loose writes. It still retires `mktree` after a bounded bulk write because Git's quick lookup cannot discover a pack created after that process prepared its object database. +- **Batched workspace page retention.** The v6.5.4 candidate adds + `workspace.pages.putBatch()` so one bounded ordered page group is written and + retained under one exact workspace generation instead of rewriting a growing + root set for every page. - **Migration script.** `scripts/migrate-encryption.js` upgrades legacy v1/v2 manifests to the current scheme identifiers. @@ -132,15 +136,15 @@ These were the active tensions from the previous bearing. All resolved. ## Next Horizon -With v6.5.2 shipped and the versioned v6.5.3 release candidate being prepared, +With v6.5.3 shipped and the versioned v6.5.4 release candidate being prepared, active work is tracked in GitHub Issues and Milestones. Repo docs hold design and evidence records, not the active queue. The latest landed design is -[0053-git-object-session-coherence](./docs/design/0053-git-object-session-coherence/git-object-session-coherence.md). +[0054-batched-page-retention](./docs/design/0054-batched-page-retention/batched-page-retention.md). Its release evidence is attached to -[#94](https://github.com/git-stunts/git-cas/issues/94) and the -[`v6.5.3` milestone](https://github.com/git-stunts/git-cas/milestone/13). Tag +[#99](https://github.com/git-stunts/git-cas/issues/99) and the +[`v6.5.4` milestone](https://github.com/git-stunts/git-cas/milestone/14). Tag and publication evidence remain pending; no later design is selected here. The broader horizon remains: diff --git a/CHANGELOG.md b/CHANGELOG.md index 59d4e4b..23aa3d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [6.5.4] — 2026-07-26 + ### Added - **Batched staging-workspace page retention** - diff --git a/README.md b/README.md index f9cd228..71c27e0 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ Unlike traditional LFS which moves files to external servers, `git-cas` treats t Existing v5 users should read [UPGRADING.md](./UPGRADING.md) and run `npm run upgrade` in dry-run mode before restoring old encrypted vault entries. For the release overview, see the -[v6.5.3 Release Notes](./docs/releases/v6.5.3.md). +[v6.5.4 Release Notes](./docs/releases/v6.5.4.md). ### 1. CLI Usage @@ -219,6 +219,8 @@ All three runtimes are tested in CI on every push. The hexagonal architecture is object sessions, scoped page batches, and deterministic resource closure. - **[v6.5.3 Release Notes](./docs/releases/v6.5.3.md)**: Coherent reuse of persistent Git object sessions across compatible immutable writes. +- **[v6.5.4 Release Notes](./docs/releases/v6.5.4.md)**: Ordered page batches + retained under one exact staging-workspace generation. - **[Upgrading](./UPGRADING.md)**: Migration guide for v5 → v6. - **[Changelog](./CHANGELOG.md)**: Version history and migration notes. diff --git a/ROADMAP.md b/ROADMAP.md index 93bd706..63e417e 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -41,6 +41,7 @@ GitHub wins and this file should be corrected. | [`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.5.3`](https://github.com/git-stunts/git-cas/milestone/13) | Coherent Git object sessions across immutable writes | [#94](https://github.com/git-stunts/git-cas/issues/94) | +| [`v6.5.4`](https://github.com/git-stunts/git-cas/milestone/14) | Batched staging-workspace page retention | [#99](https://github.com/git-stunts/git-cas/issues/99) | | [`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 | @@ -49,10 +50,10 @@ GitHub wins and this file should be corrected. The latest landed design record is: -- [0053-git-object-session-coherence](./docs/design/0053-git-object-session-coherence/git-object-session-coherence.md) +- [0054-batched-page-retention](./docs/design/0054-batched-page-retention/batched-page-retention.md) Its GitHub goalpost issue, -[#94](https://github.com/git-stunts/git-cas/issues/94), owns the release +[#99](https://github.com/git-stunts/git-cas/issues/99), owns the release evidence. The design doc is the durable contract; GitHub records completion. The `v6.2.0` slice record is: diff --git a/STATUS.md b/STATUS.md index e5d63f6..2339434 100644 --- a/STATUS.md +++ b/STATUS.md @@ -1,8 +1,8 @@ # STATUS **Last tagged release:** `v6.5.3` (`2026-07-19`) -**Current release state:** `v6.5.3` is published to npm with provenance and to GitHub Releases. -**Latest verification:** merge `00df6077` passed 14/14 release-verifier steps with 6,829 observed tests; release workflow `29696131557` then passed validation, tests, trusted npm publication, and final GitHub Release creation from signed tag `v6.5.3`. +**Current release state:** `v6.5.4` release candidate; tag, npm publication, and GitHub Release remain pending the reviewed tag workflow. +**Latest verification:** the versioned `v6.5.4` candidate passed 14/14 release-verifier steps with 6,844 observed tests across Node, Bun, Deno, and all three real-Git integration suites; tag and publication verification remain pending. **Playback truth:** `main` **Runtimes:** Node.js 22.x, Bun, Deno **Current planning method:** [WORKFLOW.md](./WORKFLOW.md) @@ -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.4 candidate posture** — batched staging-workspace page retention + merged through reviewed commit `e6c58f10` under + [#99](https://github.com/git-stunts/git-cas/issues/99). npm, JSR, and runtime + version metadata identify `6.5.4`; tag and registry artifacts remain + deliberately absent until release-candidate review completes. - **v6.5.3 artifact posture** — signed tag `v6.5.3` resolves to reviewed merge `00df6077`; npm reports `@git-stunts/git-cas@6.5.3` as `latest` with SLSA provenance, and release workflow `29696131557` published the final GitHub @@ -134,7 +139,7 @@ under the [`v6.6.0` milestone](https://github.com/git-stunts/git-cas/milestone/9). - The latest landed design record is - [0053-git-object-session-coherence](./docs/design/0053-git-object-session-coherence/git-object-session-coherence.md). + [0054-batched-page-retention](./docs/design/0054-batched-page-retention/batched-page-retention.md). ## Read Next diff --git a/UPGRADING.md b/UPGRADING.md index fa085c2..0b2f0bd 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -2,6 +2,27 @@ v6.0.0 is a major release that simplifies the encryption model, hardens security defaults, and cleans up the architecture. This guide covers every breaking change and what you need to do. +## v6.5.3 To v6.5.4 + +v6.5.4 adds `workspace.pages.putBatch()` and requires no stored-data migration. +Callers that stage many bounded pages can opt into one count-and-byte-bounded +page write plus one workspace-generation installation: + +```js +const staged = await workspace.pages.putBatch({ + pages: sources.map((source) => ({ source })), + maxBatchPages: 256, +}); +``` + +Results preserve input order, including repeated content, and every result has +an exact retained witness for the same workspace generation. Existing +`workspace.pages.put()` behavior is unchanged. Applications do not need to +adopt the batch API unless they need to remove per-page root-set rewrites. + +See [v6.5.4 Release Notes](./docs/releases/v6.5.4.md) for the measured +8,188-page migration workload and compatibility details. + ## v6.5.2 To v6.5.3 v6.5.3 changes no public API and requires no stored-data migration. Long-lived diff --git a/docs/design/0054-batched-page-retention/batched-page-retention.md b/docs/design/0054-batched-page-retention/batched-page-retention.md index 49708da..34334de 100644 --- a/docs/design/0054-batched-page-retention/batched-page-retention.md +++ b/docs/design/0054-batched-page-retention/batched-page-retention.md @@ -7,7 +7,7 @@ release_home: 'v6.5.4' issue: 'https://github.com/git-stunts/git-cas/issues/99' goalpost_issue: 'https://github.com/git-stunts/git-cas/issues/99' tracker_source: 'github' -status: 'active' +status: 'landed' base_commit: 'd446d97e0436afccdfc0398091ba18888375d8b0' owners: - '@git-stunts' @@ -297,4 +297,11 @@ does it authorize git-warp v19 release without its full migration rehearsal. ## Retrospective -Fill this section after implementation and review. +PR #100 landed the bounded batch surface without changing stored formats or +existing staging methods. The final review repair strengthened the order proof +by deriving expected handles independently from the returned batch. + +The synthetic 8,188-page workload completed in 32 workspace generations and +15.546 seconds, replacing the pre-change per-page rewrite path that had retained +only 5,213 pages after 75 minutes. Downstream git-warp adoption and a complete +disposable migration rehearsal remain separate release gates for git-warp v19. diff --git a/docs/design/0054-batched-page-retention/witness/release-candidate.md b/docs/design/0054-batched-page-retention/witness/release-candidate.md new file mode 100644 index 0000000..1bd7341 --- /dev/null +++ b/docs/design/0054-batched-page-retention/witness/release-candidate.md @@ -0,0 +1,102 @@ +# PERF-0054 v6.5.4 Release Candidate Witness + +Date: 2026-07-26 + +Issue: #99 + +Implementation review: #100 + +Release review: pending + +## Scope + +This witness records the pre-publication release candidate for batched +staging-workspace page retention. It does not claim that a `v6.5.4` tag, npm +artifact, or GitHub Release exists. This is an explicitly unpublished +candidate. + +The candidate: + +- sets npm, JSR, and the runtime `PACKAGE_VERSION` export to `6.5.4`; +- moves batched workspace page retention from `Unreleased` to `6.5.4`; +- packages and links `docs/releases/v6.5.4.md`; +- adds v6.5.3-to-v6.5.4 compatibility guidance to `UPGRADING.md`; +- marks design 0054 landed and records its release-candidate posture; +- preserves all v6.5.3 publication evidence as immutable history; and +- leaves tag and registry publication claims deliberately absent. + +## Implementation Provenance + +| Capability | Review anchor | Commit | +| ---------------------------------- | ------------- | ------------------------------------------ | +| Batched workspace page retention | #100 | `6dba2bab22241276a316d2af12f06704f7582eee` | +| Independent ordered-result proof | #100 | `18d3c9e66b4c1cef6c6c148dd6d21eeb544d5b5d` | +| Reviewed feature merge | #100 | `e6c58f10bf5244d0ee815a60636dec3c896ef38f` | + +The staging workspace delegates one bounded page batch, resolves every page, +deduplicates only the installed target map, installs one generation, and maps +the exact witness back to every ordered result. + +[cite: `src/domain/services/StagingWorkspace.js#209-269@e6c58f10bf5244d0ee815a60636dec3c896ef38f`] + +Unit coverage derives expected handles independently and proves input order, +duplicate-result preservation, a shared generation, one ref update, bounded +failure, and failure containment. Real-Git integration proves reachability +through prune and exact release cleanup. + +[cite: `test/unit/domain/services/StagingWorkspace.test.js#87-185@e6c58f10bf5244d0ee815a60636dec3c896ef38f`] +[cite: `test/integration/staging-workspace.test.js#117-154@e6c58f10bf5244d0ee815a60636dec3c896ef38f`] + +The change adds one public method and changes no stored format, handle identity, +existing staging behavior, retention policy, ref authority, or release +lifecycle. + +## Scale Witness + +A disposable bare repository staged 8,188 deterministic tiny pages in 32 +batches of at most 256 pages. It completed in 15.546 seconds, the final +generation matched the workspace ref, 8,188 page objects were reachable, and +Git reported no garbage. + +The pre-change downstream rehearsal had retained only 5,213 pages after 75 +minutes and produced about 1.16 GiB of loose scratch objects. The scale witness +contained no Think data and no large benchmark repository or fixture is part of +this release candidate. + +## Verification + +The versioned candidate passed the complete `pnpm run release:verify` method: + +| Gate | Result | Observed tests | +| -------------------------- | ---------------- | -------------: | +| Lint | PASS | - | +| Unit tests (Node) | PASS | 2,086 | +| Unit tests (Bun) | PASS | 2,085 | +| Unit tests (Deno) | PASS | 2,076 | +| Public type compatibility | PASS | - | +| Integration tests (Node) | PASS | 199 | +| Integration tests (Bun) | PASS | 199 | +| Integration tests (Deno) | PASS | 199 | +| Examples and build stamp | PASS | - | +| npm and JSR dry-runs | PASS | - | +| **Release method summary** | **PASS (14/14)** | **6,844** | + +The implementation PR merged only after GitHub lint and all Node/Bun/Deno jobs +passed, CodeRabbit approved the exact head commit, and its only review thread +was resolved against the independently derived order proof. Tag and publication +evidence remain deliberately absent from this candidate witness. + +## Publication Gate + +Publication remains blocked until all of the following are true: + +1. the versioned candidate passes every release-verifier step; +2. the release PR passes GitHub CI and review without unresolved findings; +3. the release PR is merged; +4. a signed annotated `v6.5.4` tag points at the reviewed merge commit; +5. the release workflow passes version validation and runtime tests; +6. npm reports `@git-stunts/git-cas@6.5.4` with provenance; and +7. GitHub reports the final non-draft `v6.5.4` Release. + +Downstream git-warp adoption and its full disposable v18-to-v19 migration +rehearsal remain separate post-publication obligations. diff --git a/docs/releases/v6.5.4.md b/docs/releases/v6.5.4.md new file mode 100644 index 0000000..d5abeb4 --- /dev/null +++ b/docs/releases/v6.5.4.md @@ -0,0 +1,47 @@ +# git-cas v6.5.4 Release Notes + +v6.5.4 adds ordered page-batch retention to scoped staging workspaces. It lets +applications write a bounded page group and retain the complete group under one +exact workspace generation instead of rewriting a growing root set for every +page. + +## Batched Workspace Pages + +`workspace.pages.putBatch()` accepts the existing page-batch count and byte +limits, delegates page creation to the bounded page service, and installs the +resulting handles in one compare-and-swap workspace update. Returned pages stay +in input order and each carries an exact retained witness for the shared +generation. + +Repeated content still produces one result per input position while the +workspace target set deduplicates the content handle. An oversized batch fails +before workspace-ref mutation, and a failed generation installation returns no +retained batch. + +## Measured Effect + +A disposable bare repository staged 8,188 deterministic tiny pages in 32 +batches of at most 256 pages. It completed in 15.546 seconds, installed 8,188 +page objects under the expected generation chain, and left no garbage reported +by Git. + +The motivating pre-change git-warp rehearsal had retained only 5,213 of the +same 8,188-page cardinality after 75 minutes while producing about 1.16 GiB of +loose scratch objects. These measurements establish the removed quadratic +root-set rewrite at that workload; they are local evidence, not a +cross-platform timing guarantee. The benchmark used synthetic tiny pages, +contained no Think data, and added no large fixture to this repository. + +## Verification + +The versioned candidate passed 2,086 Node unit tests, 2,085 Bun unit tests, +2,076 Deno unit tests, and 199 real-Git integration tests on each runtime. The +full release verifier passed all 14 steps with 6,844 observed tests, including +public type compatibility, examples, build stamping, and npm and JSR dry-runs. + +## Compatibility + +This release is API-additive and requires no application or stored-data +migration. Existing `workspace.pages.put()` calls, handles, object identities, +workspace refs, witnesses, retention semantics, limits, release behavior, and +pruning behavior are unchanged. Callers opt into batching explicitly. diff --git a/jsr.json b/jsr.json index 6e4f5b5..1ea3d21 100644 --- a/jsr.json +++ b/jsr.json @@ -1,6 +1,6 @@ { "name": "@git-stunts/git-cas", - "version": "6.5.3", + "version": "6.5.4", "exports": { ".": "./index.js", "./service": "./src/domain/services/CasService.js", diff --git a/package.json b/package.json index de53cfd..491971d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@git-stunts/git-cas", - "version": "6.5.3", + "version": "6.5.4", "description": "Content-addressed storage backed by Git's object database, with optional encryption and pluggable codecs", "type": "module", "main": "index.js", @@ -40,6 +40,7 @@ "docs/releases/v6.5.1.md", "docs/releases/v6.5.2.md", "docs/releases/v6.5.3.md", + "docs/releases/v6.5.4.md", "docs/THREAT_MODEL.md", "docs/VAULT_INTERNALS.md", "docs/WALKTHROUGH.md", diff --git a/src/package-version.js b/src/package-version.js index d8e7cce..8e63844 100644 --- a/src/package-version.js +++ b/src/package-version.js @@ -1 +1 @@ -export const PACKAGE_VERSION = '6.5.3'; +export const PACKAGE_VERSION = '6.5.4'; diff --git a/test/unit/docs/package-docs.test.js b/test/unit/docs/package-docs.test.js index 2d909bd..3cc7e6a 100644 --- a/test/unit/docs/package-docs.test.js +++ b/test/unit/docs/package-docs.test.js @@ -18,6 +18,7 @@ const requiredStandardDocs = [ 'docs/releases/v6.5.1.md', 'docs/releases/v6.5.2.md', 'docs/releases/v6.5.3.md', + 'docs/releases/v6.5.4.md', ]; const forbiddenPackagePrefixes = ['docs/audit/', 'docs/archive/', 'docs/method/']; const forbiddenPackageFiles = ['docs/cli.gif', 'docs/vault.gif']; @@ -92,6 +93,7 @@ function publicPackagedMarkdownFiles(files) { 'docs/releases/v6.5.1.md', 'docs/releases/v6.5.2.md', 'docs/releases/v6.5.3.md', + 'docs/releases/v6.5.4.md', 'docs/THREAT_MODEL.md', 'docs/WALKTHROUGH.md', ].filter((file) => files.has(file)); diff --git a/test/unit/docs/release-state.test.js b/test/unit/docs/release-state.test.js index 503aace..6e2d4a8 100644 --- a/test/unit/docs/release-state.test.js +++ b/test/unit/docs/release-state.test.js @@ -3,7 +3,9 @@ import { readFileSync } from 'node:fs'; import path from 'node:path'; const repoRoot = process.cwd(); -const v653PublishedMarker = '**Current release state:** `v6.5.3` is published'; +const v653PublishedMarker = '**v6.5.3 artifact posture**'; +const v654CandidatePath = + 'docs/design/0054-batched-page-retention/witness/release-candidate.md'; const v653CandidatePath = 'docs/design/0053-git-object-session-coherence/witness/release-candidate.md'; const v653PublicationPath = @@ -29,6 +31,29 @@ function v6Heading(changelog) { return changelog.match(/^## \[6\.0\.0\] — (.+)$/m)?.[1]; } +function expectNoV654PublicationEvidence(...documents) { + const forbiddenMarkers = [ + '**Last tagged release:** `v6.5.4`', + '**Current release state:** `v6.5.4` is published', + '- Signed annotated tag: `v6.5.4`', + 'https://github.com/git-stunts/git-cas/releases/tag/v6.5.4', + '## npm Registry Evidence', + /\| Package\s+\| `@git-stunts\/git-cas@6\.5\.4`\s+\|/, + /\| Dist-tag\s+\| `latest` -> `6\.5\.4`\s+\|/, + 'attestations/@git-stunts%2fgit-cas@6.5.4', + ]; + + for (const document of documents) { + for (const marker of forbiddenMarkers) { + if (marker instanceof RegExp) { + expect(document).not.toMatch(marker); + } else { + expect(document).not.toContain(marker); + } + } + } +} + function expectNoV651PublicationEvidence(...documents) { const forbiddenMarkers = [ '**Last tagged release:** `v6.5.1`', @@ -109,6 +134,19 @@ function expectV653CandidateEvidence(candidate) { expectNoV653PublicationEvidence(candidate); } +function expectV654CandidateEvidence(status, candidate) { + expect(status).toContain('**Last tagged release:** `v6.5.3` (`2026-07-19`)'); + expect(status).toContain('**Current release state:** `v6.5.4` release candidate'); + expect(candidate).toContain('# PERF-0054 v6.5.4 Release Candidate Witness'); + expect(candidate).toContain('Implementation review: #100'); + expect(candidate).toContain('Release review: pending'); + expect(candidate).toContain('e6c58f10bf5244d0ee815a60636dec3c896ef38f'); + expect(candidate).toContain('**PASS (14/14)**'); + expect(candidate).toContain('**6,844**'); + expect(candidate).toMatch(/explicitly\s+unpublished\s+candidate/); + expectNoV654PublicationEvidence(status, candidate); +} + function expectV653PublishedEvidence(status, publication) { expect(status).toContain('**Last tagged release:** `v6.5.3` (`2026-07-19`)'); expect(status).toContain(v653PublishedMarker); @@ -234,19 +272,22 @@ function expectCurrentV640PublicationEvidence(publication) { } describe('release state docs', () => { - it('enforces v6.5.3 publication while preserving candidate and prior evidence', () => { + it('enforces the v6.5.4 candidate while preserving published evidence', () => { const status = read('STATUS.md'); + const v654Candidate = read(v654CandidatePath); const candidate = read(v653CandidatePath); const v653Publication = read(v653PublicationPath); const v652Candidate = read(v652CandidatePath); const v652Publication = read(v652PublicationPath); const v651Candidate = read(v651CandidatePath); const v653ReleaseNotes = read('docs/releases/v6.5.3.md'); + const v654ReleaseNotes = read('docs/releases/v6.5.4.md'); const v652ReleaseNotes = read('docs/releases/v6.5.2.md'); const publication = read(v651PublicationPath); const v650Publication = read(v650PublicationPath); const v640Publication = read(v640PublicationPath); + expectV654CandidateEvidence(status, v654Candidate); expectV653CandidateEvidence(candidate); expectV653PublishedEvidence(status, v653Publication); expectV652CandidateEvidence(v652Candidate); @@ -254,13 +295,14 @@ describe('release state docs', () => { expectV651CandidateEvidence(v651Candidate); expectV651PublishedEvidence(status, publication); expect(v653ReleaseNotes).toContain('release verifier passed all 14 steps with 6,829'); + expect(v654ReleaseNotes).toContain('full release verifier passed all 14 steps with 6,844'); expect(v652ReleaseNotes).toContain('passed all 14 release-verifier steps with 6,817 observed'); expectV650PublishedEvidence(status, v650Publication); expectCurrentV640PublicationEvidence(v640Publication); expect(status).toContain('Current release goalpost:'); expect(status).toContain('#39 v6.6.0: Operator TUI'); expect(status).toContain('#40 v6.6.0: Agent automation follow-through'); - expect(status).toContain('0053-git-object-session-coherence'); + expect(status).toContain('0054-batched-page-retention'); expect(v640Publication).toContain('https://slsa.dev/provenance/v1'); expect(v640Publication).toContain('https://github.com/git-stunts/git-cas/releases/tag/v6.4.0'); }); diff --git a/test/unit/docs/release-truth.test.js b/test/unit/docs/release-truth.test.js index 7c8fb2b..08ac241 100644 --- a/test/unit/docs/release-truth.test.js +++ b/test/unit/docs/release-truth.test.js @@ -278,6 +278,21 @@ describe('Git object session coherence release documentation', () => { }); }); +describe('batched workspace page retention release documentation', () => { + it('ships and links the v6.5.4 ordered retention contract', () => { + const readme = read('README.md'); + const upgrading = read('UPGRADING.md'); + const releaseNotes = read('docs/releases/v6.5.4.md'); + + expect(readme).toContain('[v6.5.4 Release Notes](./docs/releases/v6.5.4.md)'); + expect(upgrading).toContain('## v6.5.3 To v6.5.4'); + expect(upgrading).toContain('workspace.pages.putBatch()'); + expect(releaseNotes).toContain('# git-cas v6.5.4 Release Notes'); + expect(releaseNotes).toMatch(/8,188 deterministic tiny pages in 32\s+batches/); + expect(releaseNotes).toMatch(/requires no application or stored-data\s+migration/); + }); +}); + describe('advanced guide rendering', () => { it('keeps the table of contents rendered as Markdown links', () => { const advancedGuide = read('ADVANCED_GUIDE.md'); From 63cf58c69315b0a60a1a0fd9071cba023b5d3d4f Mon Sep 17 00:00:00 2001 From: James Ross Date: Sun, 26 Jul 2026 05:59:07 -0700 Subject: [PATCH 2/3] docs: anchor v6.5.4 release review --- .../0054-batched-page-retention/witness/release-candidate.md | 2 +- test/unit/docs/release-state.test.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/design/0054-batched-page-retention/witness/release-candidate.md b/docs/design/0054-batched-page-retention/witness/release-candidate.md index 1bd7341..d7956c2 100644 --- a/docs/design/0054-batched-page-retention/witness/release-candidate.md +++ b/docs/design/0054-batched-page-retention/witness/release-candidate.md @@ -6,7 +6,7 @@ Issue: #99 Implementation review: #100 -Release review: pending +Release review: #101 ## Scope diff --git a/test/unit/docs/release-state.test.js b/test/unit/docs/release-state.test.js index 6e2d4a8..ba926c4 100644 --- a/test/unit/docs/release-state.test.js +++ b/test/unit/docs/release-state.test.js @@ -139,7 +139,7 @@ function expectV654CandidateEvidence(status, candidate) { expect(status).toContain('**Current release state:** `v6.5.4` release candidate'); expect(candidate).toContain('# PERF-0054 v6.5.4 Release Candidate Witness'); expect(candidate).toContain('Implementation review: #100'); - expect(candidate).toContain('Release review: pending'); + expect(candidate).toContain('Release review: #101'); expect(candidate).toContain('e6c58f10bf5244d0ee815a60636dec3c896ef38f'); expect(candidate).toContain('**PASS (14/14)**'); expect(candidate).toContain('**6,844**'); From 54f37d912205a3c0150dd46d56ebdd659333e9c2 Mon Sep 17 00:00:00 2001 From: James Ross Date: Sun, 26 Jul 2026 06:48:29 -0700 Subject: [PATCH 3/3] docs: make batch upgrade example self-contained --- UPGRADING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/UPGRADING.md b/UPGRADING.md index 0b2f0bd..d0944d5 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -9,6 +9,7 @@ Callers that stage many bounded pages can opt into one count-and-byte-bounded page write plus one workspace-generation installation: ```js +const sources = [Uint8Array.of(1), Uint8Array.of(2)]; const staged = await workspace.pages.putBatch({ pages: sources.map((source) => ({ source })), maxBatchPages: 256,