From 6407a6a92f5d7b82967ea1c9418eaa80475f7f55 Mon Sep 17 00:00:00 2001 From: James Ross Date: Sat, 18 Jul 2026 16:53:23 -0700 Subject: [PATCH 1/2] release: prepare git-cas v6.5.1 --- CHANGELOG.md | 2 + README.md | 4 +- ROADMAP.md | 5 +- STATUS.md | 16 +-- UPGRADING.md | 22 ++++ .../bounded-page-payload-reuse.md | 2 +- .../witness/release-candidate.md | 92 ++++++++++++++ docs/design/README.md | 2 +- docs/releases/v6.5.1.md | 13 +- 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 | 113 ++++++------------ test/unit/docs/release-truth.test.js | 15 +++ 15 files changed, 202 insertions(+), 93 deletions(-) create mode 100644 docs/design/0051-bounded-page-payload-reuse/witness/release-candidate.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d6cb8d..2e741ad 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.1] — 2026-07-18 + ### Performance - **Bounded immutable page payload reuse** - repeated `pages.get()` calls now diff --git a/README.md b/README.md index 6c32b04..7d27e67 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,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.0 Release Notes](./docs/releases/v6.5.0.md). +[v6.5.1 Release Notes](./docs/releases/v6.5.1.md). ### 1. CLI Usage @@ -204,6 +204,8 @@ All three runtimes are tested in CI on every push. The hexagonal architecture is workspaces for temporary multi-object reachability, promotion, and cleanup. - **[v6.5.0 Release Notes](./docs/releases/v6.5.0.md)**: Bounded direct bundle references, immutable metadata reuse, and corrected concurrency settlement. +- **[v6.5.1 Release Notes](./docs/releases/v6.5.1.md)**: Bounded immutable page + payload reuse with zero-command warm reads. - **[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 71cfa5d..e6c2422 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -38,6 +38,7 @@ GitHub wins and this file should be corrected. | [`v6.4.0`](https://github.com/git-stunts/git-cas/milestone/4) | Scoped staging workspaces | [#75](https://github.com/git-stunts/git-cas/issues/75), [#77](https://github.com/git-stunts/git-cas/issues/77) | | [`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.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 | @@ -46,10 +47,10 @@ GitHub wins and this file should be corrected. The latest landed design record is: -- [0050-lazy-bundle-reference-reads](./docs/design/0050-lazy-bundle-reference-reads/lazy-bundle-reference-reads.md) +- [0051-bounded-page-payload-reuse](./docs/design/0051-bounded-page-payload-reuse/bounded-page-payload-reuse.md) Its GitHub goalpost issue, -[#81](https://github.com/git-stunts/git-cas/issues/81), owns the release +[#85](https://github.com/git-stunts/git-cas/issues/85), 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 4ebf896..f86e0fb 100644 --- a/STATUS.md +++ b/STATUS.md @@ -1,8 +1,8 @@ # STATUS **Last tagged release:** `v6.5.0` (`2026-07-18`) -**Current release state:** `v6.5.0` is published to npm with provenance and to GitHub Releases. -**Latest verification:** the exact reviewed merge `f464b929` passed 14/14 release-verifier steps with 6,625 observed tests across Node.js, Bun, and Deno; release workflow `29655337483` then passed validation, tests, trusted npm publication, and final GitHub Release creation. +**Current release state:** `v6.5.1` release candidate; tag, npm publication, and GitHub Release remain pending the reviewed tag workflow. +**Latest verification:** the versioned `v6.5.1` candidate passed 14/14 release-verifier steps with 6,676 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,10 @@ - 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.1 candidate posture** — bounded immutable page payload reuse is merged + through reviewed commit `ad5b91b2`; npm, JSR, and runtime version metadata + identify `6.5.1`, while the tag and registry artifacts remain deliberately + absent until release-candidate review completes. - **v6.5.0 artifact posture** — signed tag `v6.5.0` resolves to reviewed merge `f464b929`; npm reports `@git-stunts/git-cas@6.5.0` as `latest` with SLSA provenance, and the final GitHub Release is published. Bounded direct bundle @@ -111,13 +115,11 @@ - GitHub Issues are canonical. If this section and GitHub disagree, GitHub wins and this section should be corrected. - Current release goalpost: - [#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) + [#85 Bounded immutable page payload reuse](https://github.com/git-stunts/git-cas/issues/85) under the - [`v6.6.0` milestone](https://github.com/git-stunts/git-cas/milestone/9). + [`v6.5.1` milestone](https://github.com/git-stunts/git-cas/milestone/11). - The latest landed design record is - [0050-lazy-bundle-reference-reads](./docs/design/0050-lazy-bundle-reference-reads/lazy-bundle-reference-reads.md). + [0051-bounded-page-payload-reuse](./docs/design/0051-bounded-page-payload-reuse/bounded-page-payload-reuse.md). ## Read Next diff --git a/UPGRADING.md b/UPGRADING.md index 114bba0..34f87c6 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -2,6 +2,28 @@ 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.0 To v6.5.1 + +v6.5.1 is API-additive and does not require stored-data migration. Repeated +`pages.get()` calls now reuse immutable payload bytes through a process-local +LRU bounded by entry count and aggregate bytes. Applications may tune the +defaults with `pageCacheEntries` and `pageCacheBytes` when constructing the +store. + +Every caller still receives an independent `Uint8Array`, and each call's +`maxBytes` limit remains authoritative on cold, resident, and shared in-flight +reads. Rejected work remains retryable, and an individually oversized payload +does not displace unrelated residents. + +`pages.open()` remains the streaming API and never enters the payload cache. +Cache residence is an optimization, not retention evidence; keep each handle +reachable through a workspace, RootSet, cache acquisition, publication, or +other documented lifetime while consuming it. + +See [v6.5.1 Release Notes](./docs/releases/v6.5.1.md) and +[Application Storage](./docs/API.md#application-storage) for the complete +residency and lifetime contract. + ## v6.4.0 To v6.5.0 v6.5.0 is API-additive and does not require stored-data migration. It adds diff --git a/docs/design/0051-bounded-page-payload-reuse/bounded-page-payload-reuse.md b/docs/design/0051-bounded-page-payload-reuse/bounded-page-payload-reuse.md index 6255d51..f29a9c0 100644 --- a/docs/design/0051-bounded-page-payload-reuse/bounded-page-payload-reuse.md +++ b/docs/design/0051-bounded-page-payload-reuse/bounded-page-payload-reuse.md @@ -2,7 +2,7 @@ schema: 'method.design/v1' cycle: '0051' slug: 'bounded-page-payload-reuse' -status: 'active' +status: 'landed' sponsor_human: 'James Ross' sponsor_agent: 'Codex' created: '2026-07-18' diff --git a/docs/design/0051-bounded-page-payload-reuse/witness/release-candidate.md b/docs/design/0051-bounded-page-payload-reuse/witness/release-candidate.md new file mode 100644 index 0000000..5ec63c9 --- /dev/null +++ b/docs/design/0051-bounded-page-payload-reuse/witness/release-candidate.md @@ -0,0 +1,92 @@ +# PERF-0051 v6.5.1 Release Candidate Witness + +Date: 2026-07-18 + +Issue: #85 + +Review: #87 + +## Scope + +This witness records the pre-publication release candidate for bounded immutable +page payload reuse. It does not claim that a `v6.5.1` 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.1`; +- moves bounded page payload reuse from `Unreleased` to `6.5.1`; +- packages and links `docs/releases/v6.5.1.md`; +- adds v6.5.0-to-v6.5.1 adoption guidance to `UPGRADING.md`; +- marks design 0051 landed and records the v6.5.1 milestone in `ROADMAP.md`; +- records an honest release-candidate posture in `STATUS.md`; and +- preserves the v6.5.0 publication witness as immutable history. + +## Implementation Provenance + +| Capability | Review anchor | Commit | +| ------------------------------------------- | ------------- | ------------------------------------------ | +| Bounded immutable page payload reuse | #87 | `5495eefbc83a2dcc21366cf5e0ebd960998c3c48` | +| Internal-only cache defaults | #87 | `4343163ed18a6e8f96ecb39f21daf4de8c55b9f7` | +| In-flight, metadata, and test review repairs | #87 | `3a5360d21656d62dc90c6632658cfefa0fbf3f36` | +| Reviewed feature merge | #87 | `ad5b91b2ff7c156526961a8d0575be1a250d92c6` | + +The public constructor accepts independent entry and byte residency bounds. +`pages.get()` probes immutable OID payload state before Git metadata, validates +cold misses before materialization, checks every caller's limit after +resolution, and returns an independent byte copy. + +[cite: `index.d.ts#709-712@ad5b91b2ff7c156526961a8d0575be1a250d92c6`] +[cite: `index.js#135-137@ad5b91b2ff7c156526961a8d0575be1a250d92c6`] +[cite: `src/domain/services/PageService.js#84-103@ad5b91b2ff7c156526961a8d0575be1a250d92c6`] + +The shared cache keeps unresolved work separate from completed LRU residence. +Only completed entries participate in count and byte eviction, so capacity +pressure cannot break A/B/A coalescing or displace a resident before an +in-flight value's weight is known. + +[cite: `src/helpers/boundedPromiseCache.js#44-85@ad5b91b2ff7c156526961a8d0575be1a250d92c6`] +[cite: `src/helpers/boundedPromiseCache.js#96-115@ad5b91b2ff7c156526961a8d0575be1a250d92c6`] + +The real-Git regression contract requires an identical warm page read to issue +zero additional Git commands. + +[cite: `test/integration/bundle-reference-performance.test.js#111-125@ad5b91b2ff7c156526961a8d0575be1a250d92c6`] + +## Verification + +The versioned candidate passed the complete `pnpm run release:verify` method: + +| Gate | Result | Observed tests | +| -------------------------- | ------ | -------------: | +| Lint | PASS | - | +| Unit tests (Node) | PASS | 2,036 | +| Unit tests (Bun) | PASS | 2,035 | +| Unit tests (Deno) | PASS | 2,026 | +| Public type compatibility | PASS | - | +| Integration tests (Node) | PASS | 193 | +| Integration tests (Bun) | PASS | 193 | +| Integration tests (Deno) | PASS | 193 | +| Examples and build stamp | PASS | - | +| npm and JSR dry-runs | PASS | - | +| **Release method summary** | **PASS (14/14)** | **6,676** | + +The feature PR also merged only after GitHub lint and all Node/Bun/Deno jobs +passed, CodeRabbit approved, and every review thread was resolved. 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, self-review, Code Lawyer review, and the + agreed CodeRabbit posture; +3. the release PR is merged without unresolved findings; +4. a signed annotated `v6.5.1` 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.1` with provenance; and +7. GitHub reports the final non-draft `v6.5.1` Release. + +Downstream git-warp adoption and its CPU, wall-clock, Git-command, and +bounded-memory evidence remain separate post-publication obligations. diff --git a/docs/design/README.md b/docs/design/README.md index 678311f..7abd132 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -11,7 +11,6 @@ process in [docs/method/process.md](../method/process.md). ## Active METHOD Cycles -- [0051-bounded-page-payload-reuse - bounded-page-payload-reuse](./0051-bounded-page-payload-reuse/bounded-page-payload-reuse.md) - [0050-lazy-bundle-reference-reads - lazy-bundle-reference-reads](./0050-lazy-bundle-reference-reads/lazy-bundle-reference-reads.md) - [0049-scoped-staging-workspaces — scoped-staging-workspaces](./0049-scoped-staging-workspaces/scoped-staging-workspaces.md) - [0048-scoped-cache-acquisitions — scoped-cache-acquisitions](./0048-scoped-cache-acquisitions/scoped-cache-acquisitions.md) @@ -44,6 +43,7 @@ process in [docs/method/process.md](../method/process.md). ## Landed METHOD Cycles +- [0051-bounded-page-payload-reuse - bounded-page-payload-reuse](./0051-bounded-page-payload-reuse/bounded-page-payload-reuse.md) - [0046-gc-retention-root-sets — gc-retention-root-sets](./0046-gc-retention-root-sets/gc-retention-root-sets.md) - [0047-application-storage-cache-boundary — application-storage-cache-boundary](./0047-application-storage-cache-boundary/application-storage-cache-boundary.md) diff --git a/docs/releases/v6.5.1.md b/docs/releases/v6.5.1.md index 8a57ff4..01b5e06 100644 --- a/docs/releases/v6.5.1.md +++ b/docs/releases/v6.5.1.md @@ -29,7 +29,16 @@ The real-Git command-count integration contract proves that an identical warm end-to-end CPU, wall-clock, Git-command, and bounded-memory deltas after adopting this release. +## Verification + +The versioned candidate passed all 14 release-verifier steps with 6,676 observed +tests: 2,036 Node unit tests, 2,035 Bun unit tests, 2,026 Deno unit tests, and +193 real-Git integration tests on each runtime. Lint, examples, public type +compatibility, build stamping, npm packaging dry-run, and JSR publication +dry-run also passed. + ## Compatibility -This release changes no persisted formats, handles, refs, witnesses, or existing -method signatures. The two constructor options are additive and optional. +This release does not require stored-data migration. It changes no persisted +formats, handles, refs, witnesses, or existing method signatures. The two +constructor options are additive and optional. diff --git a/jsr.json b/jsr.json index d690e1e..95fdf82 100644 --- a/jsr.json +++ b/jsr.json @@ -1,6 +1,6 @@ { "name": "@git-stunts/git-cas", - "version": "6.5.0", + "version": "6.5.1", "exports": { ".": "./index.js", "./service": "./src/domain/services/CasService.js", diff --git a/package.json b/package.json index 57d74b2..da78a6c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@git-stunts/git-cas", - "version": "6.5.0", + "version": "6.5.1", "description": "Content-addressed storage backed by Git's object database, with optional encryption and pluggable codecs", "type": "module", "main": "index.js", @@ -37,6 +37,7 @@ "docs/releases/v6.3.0.md", "docs/releases/v6.4.0.md", "docs/releases/v6.5.0.md", + "docs/releases/v6.5.1.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 e2d056e..4a211ac 100644 --- a/src/package-version.js +++ b/src/package-version.js @@ -1 +1 @@ -export const PACKAGE_VERSION = '6.5.0'; +export const PACKAGE_VERSION = '6.5.1'; diff --git a/test/unit/docs/package-docs.test.js b/test/unit/docs/package-docs.test.js index c2f8e4c..edfd098 100644 --- a/test/unit/docs/package-docs.test.js +++ b/test/unit/docs/package-docs.test.js @@ -15,6 +15,7 @@ const requiredStandardDocs = [ 'docs/releases/v6.3.0.md', 'docs/releases/v6.4.0.md', 'docs/releases/v6.5.0.md', + 'docs/releases/v6.5.1.md', ]; const forbiddenPackagePrefixes = ['docs/audit/', 'docs/archive/', 'docs/method/']; const forbiddenPackageFiles = ['docs/cli.gif', 'docs/vault.gif']; @@ -86,6 +87,7 @@ function publicPackagedMarkdownFiles(files) { 'docs/releases/v6.3.0.md', 'docs/releases/v6.4.0.md', 'docs/releases/v6.5.0.md', + 'docs/releases/v6.5.1.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 259e4e1..41fd800 100644 --- a/test/unit/docs/release-state.test.js +++ b/test/unit/docs/release-state.test.js @@ -3,10 +3,11 @@ import { existsSync, readFileSync } from 'node:fs'; import path from 'node:path'; const repoRoot = process.cwd(); -const v650CandidateMarker = '**Current release state:** `v6.5.0` release candidate'; -const v650PublishedMarker = '**Current release state:** `v6.5.0` is published'; -const v650CandidatePath = - 'docs/design/0050-lazy-bundle-reference-reads/witness/release-candidate.md'; +const v651CandidateMarker = '**Current release state:** `v6.5.1` release candidate'; +const v651CandidatePath = + 'docs/design/0051-bounded-page-payload-reuse/witness/release-candidate.md'; +const v651PublicationPath = + 'docs/design/0051-bounded-page-payload-reuse/witness/release-publication.md'; const v650PublicationPath = 'docs/design/0050-lazy-bundle-reference-reads/witness/release-publication.md'; const v640PublicationPath = @@ -24,16 +25,16 @@ function v6Heading(changelog) { return changelog.match(/^## \[6\.0\.0\] — (.+)$/m)?.[1]; } -function expectNoV650PublicationEvidence(...documents) { +function expectNoV651PublicationEvidence(...documents) { const forbiddenMarkers = [ - '**Last tagged release:** `v6.5.0`', - '**Current release state:** `v6.5.0` is published', - '- Signed annotated tag: `v6.5.0`', - 'https://github.com/git-stunts/git-cas/releases/tag/v6.5.0', + '**Last tagged release:** `v6.5.1`', + '**Current release state:** `v6.5.1` is published', + '- Signed annotated tag: `v6.5.1`', + 'https://github.com/git-stunts/git-cas/releases/tag/v6.5.1', '## npm Registry Evidence', - /\| Package\s+\| `@git-stunts\/git-cas@6\.5\.0`\s+\|/, - /\| Dist-tag\s+\| `latest` -> `6\.5\.0`\s+\|/, - 'attestations/@git-stunts%2fgit-cas@6.5.0', + /\| Package\s+\| `@git-stunts\/git-cas@6\.5\.1`\s+\|/, + /\| Dist-tag\s+\| `latest` -> `6\.5\.1`\s+\|/, + 'attestations/@git-stunts%2fgit-cas@6.5.1', ]; for (const document of documents) { @@ -47,29 +48,26 @@ function expectNoV650PublicationEvidence(...documents) { } } -function expectV650CandidateState(status, candidate, publication) { - expect(status).toContain('**Last tagged release:** `v6.4.0` (`2026-07-18`)'); - expect(status).toContain(v650CandidateMarker); +function expectV651CandidateState(status, candidate, publication) { + expect(status).toContain('**Last tagged release:** `v6.5.0` (`2026-07-18`)'); + expect(status).toContain(v651CandidateMarker); expect(status).toContain('remain pending the reviewed tag workflow'); - expect(status).toContain('#81 Bounded lazy bundle references and immutable metadata reads'); - expect(candidate).toContain('# PERF-0050 v6.5.0 Release Candidate Witness'); - expect(candidate).toContain('d5f770fb4589cd33d2244c83232ee7ede1df9ec1'); - expect(candidate).toMatch(/passed 14\/14 steps with 6,625 observed tests/); - expect(candidate).toContain('249 files totaling 769,785 packed bytes'); - expect(candidate).toMatch(/2,149,364\s+unpacked bytes/); - expect(candidate).toMatch(/500\/500 two-writer\s+races/); + expect(status).toContain( + 'passed 14/14 release-verifier steps with 6,676 observed tests' + ); + expect(status).toContain('#85 Bounded immutable page payload reuse'); + expect(candidate).toContain('# PERF-0051 v6.5.1 Release Candidate Witness'); + expect(candidate).toContain('ad5b91b2ff7c156526961a8d0575be1a250d92c6'); + expect(candidate).toContain('**PASS (14/14)**'); + expect(candidate).toContain('**6,676**'); expect(candidate).toMatch(/explicitly\s+unpublished candidate/); expect(publication).toBeNull(); - expectNoV650PublicationEvidence(status, candidate); + expectNoV651PublicationEvidence(status, candidate); } -function expectV650PublishedState(status, publication) { - expect(status).toMatch(/\*\*Last tagged release:\*\* `v6\.5\.0` \(`\d{4}-\d{2}-\d{2}`\)/); - expect(status).toContain(v650PublishedMarker); +function expectV650PublishedEvidence(status, publication) { + expect(status).toContain('**v6.5.0 artifact posture**'); expect(status).toContain('f464b929'); - expect(status).toContain('#39 v6.6.0: Operator TUI'); - expect(status).toContain('#40 v6.6.0: Agent automation follow-through'); - expect(status).toContain('[`v6.6.0` milestone]'); expect(publication).toContain('# PERF-0050 v6.5.0 Publication Witness'); expect(publication).toContain('f464b9292a07dbc98cda24aad6712e9d9a3bcefa'); expect(publication).toContain('fa955936f1e3feb4fe07e8456b983d5a535801a8'); @@ -99,59 +97,22 @@ function expectCurrentV640PublicationEvidence(publication) { expect(publication).toContain('2,129,716'); } -function expectV650Lifecycle(status, candidate, publication) { - const isCandidate = status.includes(v650CandidateMarker); - const isPublished = status.includes(v650PublishedMarker); - - expect(Number(isCandidate) + Number(isPublished)).toBe(1); - if (isCandidate) { - expectV650CandidateState(status, candidate, publication); - return; - } - expect(publication).not.toBeNull(); - expectV650PublishedState(status, publication); -} - -function expectFutureV650PublicationState() { - const status = [ - '**Last tagged release:** `v6.5.0` (`2026-07-18`)', - `${v650PublishedMarker} to npm with provenance and to GitHub Releases.`, - 'f464b929', - '#39 v6.6.0: Operator TUI', - '#40 v6.6.0: Agent automation follow-through', - '[`v6.6.0` milestone]', - ].join('\n'); - const publication = [ - '# PERF-0050 v6.5.0 Publication Witness', - 'f464b9292a07dbc98cda24aad6712e9d9a3bcefa', - 'fa955936f1e3feb4fe07e8456b983d5a535801a8', - '01A63D8E9DBEEDE32918AF9C39560E0406CA9135', - '- Signed annotated tag: `v6.5.0`', - 'https://github.com/git-stunts/git-cas/releases/tag/v6.5.0', - 'actions/runs/29655337483', - '| Package | `@git-stunts/git-cas@6.5.0` |', - '| Dist-tag | `latest` -> `6.5.0` |', - 'sha512-KfKperNdXu3xWw07tpo1yYpLTynhwAP60PhYiZ5MRsSydPdNspQzJmi6Pv0Jz+6WULD883/NJCR0V1IUhBwOBw==', - '4d05349bb8373bab57e12be65621bdc08325f278', - '2,149,363', - 'attestations/@git-stunts%2fgit-cas@6.5.0', - ].join('\n'); - - expectV650Lifecycle(status, '', publication); -} - describe('release state docs', () => { - it('enforces the v6.5.0 candidate-to-publication lifecycle', () => { + it('enforces the v6.5.1 candidate boundary while preserving v6.5.0 publication', () => { const status = read('STATUS.md'); - const candidate = read(v650CandidatePath); - const publication = readOptional(v650PublicationPath); + const candidate = read(v651CandidatePath); + const releaseNotes = read('docs/releases/v6.5.1.md'); + const publication = readOptional(v651PublicationPath); + const v650Publication = read(v650PublicationPath); const v640Publication = read(v640PublicationPath); - expectV650Lifecycle(status, candidate, publication); - expectFutureV650PublicationState(); + expectV651CandidateState(status, candidate, publication); + expect(releaseNotes).toContain( + 'passed all 14 release-verifier steps with 6,676 observed' + ); + expectV650PublishedEvidence(status, v650Publication); expectCurrentV640PublicationEvidence(v640Publication); expect(status).toContain('Current release goalpost:'); - expect(status).toContain('d47af74a'); 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 6c29253..787a17c 100644 --- a/test/unit/docs/release-truth.test.js +++ b/test/unit/docs/release-truth.test.js @@ -233,6 +233,21 @@ describe('lazy bundle reference release documentation', () => { }); }); +describe('page payload reuse release documentation', () => { + it('ships and links the v6.5.1 bounded page cache contract', () => { + const readme = read('README.md'); + const upgrading = read('UPGRADING.md'); + const releaseNotes = read('docs/releases/v6.5.1.md'); + + expect(readme).toContain('[v6.5.1 Release Notes](./docs/releases/v6.5.1.md)'); + expect(upgrading).toContain('pageCacheEntries'); + expect(upgrading).toContain('Cache residence is an optimization, not retention evidence'); + expect(releaseNotes).toContain('# git-cas v6.5.1 Release Notes'); + expect(releaseNotes).toContain('zero additional Git commands'); + expect(releaseNotes).toContain('does not require stored-data migration'); + }); +}); + describe('advanced guide rendering', () => { it('keeps the table of contents rendered as Markdown links', () => { const advancedGuide = read('ADVANCED_GUIDE.md'); From b73ee15a610dbb4a19b265d884c4a232ffdb5808 Mon Sep 17 00:00:00 2001 From: James Ross Date: Sat, 18 Jul 2026 16:57:48 -0700 Subject: [PATCH 2/2] docs: clarify v6.5.1 review provenance --- .../witness/release-candidate.md | 4 +++- test/unit/docs/release-state.test.js | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/design/0051-bounded-page-payload-reuse/witness/release-candidate.md b/docs/design/0051-bounded-page-payload-reuse/witness/release-candidate.md index 5ec63c9..32d1714 100644 --- a/docs/design/0051-bounded-page-payload-reuse/witness/release-candidate.md +++ b/docs/design/0051-bounded-page-payload-reuse/witness/release-candidate.md @@ -4,7 +4,9 @@ Date: 2026-07-18 Issue: #85 -Review: #87 +Implementation review: #87 + +Release review: #88 ## Scope diff --git a/test/unit/docs/release-state.test.js b/test/unit/docs/release-state.test.js index 41fd800..242a8ef 100644 --- a/test/unit/docs/release-state.test.js +++ b/test/unit/docs/release-state.test.js @@ -57,6 +57,8 @@ function expectV651CandidateState(status, candidate, publication) { ); expect(status).toContain('#85 Bounded immutable page payload reuse'); expect(candidate).toContain('# PERF-0051 v6.5.1 Release Candidate Witness'); + expect(candidate).toContain('Implementation review: #87'); + expect(candidate).toContain('Release review: #88'); expect(candidate).toContain('ad5b91b2ff7c156526961a8d0575be1a250d92c6'); expect(candidate).toContain('**PASS (14/14)**'); expect(candidate).toContain('**6,676**');