diff --git a/BEARING.md b/BEARING.md index 8579614..9bef5e7 100644 --- a/BEARING.md +++ b/BEARING.md @@ -14,10 +14,11 @@ timeline ## Current State -`v6.5.1` shipped on `2026-07-18`. Application asset, bundle, page, cache, +`v6.5.2` 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 are published. npm plus GitHub Releases are the +immutable metadata/page reuse, bounded Git object sessions, page batches, and +deterministic resource closure are published. npm plus GitHub Releases are the active publication surfaces. JSR validation is healthy, but JSR publication remains outside the release workflow. @@ -67,10 +68,15 @@ 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 +- **Persistent bounded Git object sessions.** v6.5.2 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. +- **Coherent session reuse.** The v6.5.3 candidate 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. - **Migration script.** `scripts/migrate-encryption.js` upgrades legacy v1/v2 manifests to the current scheme identifiers. @@ -126,15 +132,15 @@ These were the active tensions from the previous bearing. All resolved. ## Next Horizon -With v6.5.1 shipped and the versioned v6.5.2 release candidate being prepared, +With v6.5.2 shipped and the versioned v6.5.3 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 -[0052-persistent-git-object-sessions](./docs/design/0052-persistent-git-object-sessions/persistent-git-object-sessions.md). +[0053-git-object-session-coherence](./docs/design/0053-git-object-session-coherence/git-object-session-coherence.md). Its release evidence is attached to -[#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). Tag +[#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 and publication evidence remain pending; no later design is selected here. The broader horizon remains: diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c4e5e5..c47ab45 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.3] — 2026-07-19 + ### Performance - **Coherent Git object session reuse** - successful loose object and tree diff --git a/README.md b/README.md index 4004cda..757d574 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.2 Release Notes](./docs/releases/v6.5.2.md). +[v6.5.3 Release Notes](./docs/releases/v6.5.3.md). ### 1. CLI Usage @@ -216,6 +216,8 @@ All three runtimes are tested in CI on every push. The hexagonal architecture is payload reuse with zero-command warm reads. - **[v6.5.2 Release Notes](./docs/releases/v6.5.2.md)**: Persistent bounded Git 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. - **[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 ba0db9e..93bd706 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -40,6 +40,7 @@ GitHub wins and this file should be corrected. | [`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.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.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 | @@ -48,10 +49,10 @@ GitHub wins and this file should be corrected. The latest landed design record is: -- [0052-persistent-git-object-sessions](./docs/design/0052-persistent-git-object-sessions/persistent-git-object-sessions.md) +- [0053-git-object-session-coherence](./docs/design/0053-git-object-session-coherence/git-object-session-coherence.md) Its GitHub goalpost issue, -[#90](https://github.com/git-stunts/git-cas/issues/90), owns the release +[#94](https://github.com/git-stunts/git-cas/issues/94), 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 18d9bde..04f0ca3 100644 --- a/STATUS.md +++ b/STATUS.md @@ -1,8 +1,8 @@ # STATUS **Last tagged release:** `v6.5.2` (`2026-07-19`) -**Current release state:** `v6.5.2` is published to npm with provenance and to GitHub Releases. -**Latest verification:** merge `c2d41f60` passed 14/14 release-verifier steps with 6,817 observed tests; release workflow `29690794540` then passed validation, tests, trusted npm publication, and final GitHub Release creation from signed tag `v6.5.2`. +**Current release state:** `v6.5.3` release candidate; tag, npm publication, and GitHub Release remain pending the reviewed tag workflow. +**Latest verification:** the versioned `v6.5.3` candidate passed 14/14 release-verifier steps with 6,829 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.3 candidate posture** — coherent Git object sessions merged through + reviewed commit `7bdcbf1f` under + [#94](https://github.com/git-stunts/git-cas/issues/94). npm, JSR, and runtime + version metadata identify `6.5.3`; tag and registry artifacts remain + deliberately absent until release-candidate review completes. - **v6.5.2 artifact posture** — signed tag `v6.5.2` resolves to reviewed merge `c2d41f60`; npm reports `@git-stunts/git-cas@6.5.2` as `latest` with SLSA provenance, and release workflow `29690794540` published the final GitHub @@ -129,7 +134,7 @@ under the [`v6.6.0` milestone](https://github.com/git-stunts/git-cas/milestone/9). - The latest landed design record is - [0052-persistent-git-object-sessions](./docs/design/0052-persistent-git-object-sessions/persistent-git-object-sessions.md). + [0053-git-object-session-coherence](./docs/design/0053-git-object-session-coherence/git-object-session-coherence.md). ## Read Next diff --git a/UPGRADING.md b/UPGRADING.md index a95378c..fa085c2 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -2,6 +2,21 @@ 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.2 To v6.5.3 + +v6.5.3 changes no public API and requires no stored-data migration. Long-lived +stores automatically preserve their typed `cat-file` session across successful +immutable writes. They also preserve typed `mktree` across loose blob and tree +writes, while bounded bulk writes still retire `mktree` because `fast-import` +may create a pack that an already prepared process cannot discover. + +No application code changes are required. Continue to call `await cas.close()` +when the store is no longer needed; explicit closure remains the deterministic +boundary for local Git children and bounded in-memory residency. + +See [v6.5.3 Release Notes](./docs/releases/v6.5.3.md) for the audited coherence +matrix and measured process-count reduction. + ## v6.5.1 To v6.5.2 v6.5.2 is API-additive and does not require stored-data migration. Immutable diff --git a/docs/design/0053-git-object-session-coherence/git-object-session-coherence.md b/docs/design/0053-git-object-session-coherence/git-object-session-coherence.md index b396109..a14950a 100644 --- a/docs/design/0053-git-object-session-coherence/git-object-session-coherence.md +++ b/docs/design/0053-git-object-session-coherence/git-object-session-coherence.md @@ -7,7 +7,7 @@ release_home: 'v6.5.3' issue: 'https://github.com/git-stunts/git-cas/issues/94' goalpost_issue: 'https://github.com/git-stunts/git-cas/issues/94' tracker_source: 'github' -status: 'active' +status: 'landed' base_commit: 'fb3d3c2b620bae11d52e8ecc7a78a7ea07f27e24' owners: - '@git-stunts' @@ -232,3 +232,19 @@ the one-change release boundary. Git-warp still performs one-shot blob writes and frequent workspace RootSet, ref, and commit updates. Their necessity and any safe coalescing contract remain separate work. This cycle neither solves nor obscures that remaining cost. + +## Landed Evidence + +The single runtime correction merged through PR #95 as +`7bdcbf1f9eccd16acd324c94d576e1ecd2e11d98`. The adapter preserves coherent +reader and tree-writer sessions while retaining the mandatory post-pack +`mktree` retirement boundary. + +[cite: `src/infrastructure/adapters/GitPersistenceAdapter.js#93-175@7bdcbf1f9eccd16acd324c94d576e1ecd2e11d98`] + +The unit matrix and real-Git integration cover safe loose-object reuse, packed +object refresh, mandatory tree-writer replacement after `fast-import`, SHA-1, +SHA-256, lifecycle, and failure behavior. + +[cite: `test/unit/infrastructure/adapters/GitPersistenceAdapter.sessionCoherence.test.js#6-45@7bdcbf1f9eccd16acd324c94d576e1ecd2e11d98`] +[cite: `test/integration/git-object-session-coherence.test.js#24-60@7bdcbf1f9eccd16acd324c94d576e1ecd2e11d98`] diff --git a/docs/design/0053-git-object-session-coherence/witness/release-candidate.md b/docs/design/0053-git-object-session-coherence/witness/release-candidate.md new file mode 100644 index 0000000..664e3f5 --- /dev/null +++ b/docs/design/0053-git-object-session-coherence/witness/release-candidate.md @@ -0,0 +1,89 @@ +# PERF-0053 v6.5.3 Release Candidate Witness + +Date: 2026-07-19 + +Issue: #94 + +Implementation review: #95 + +Release review: #96 + +## Scope + +This witness records the pre-publication release candidate for coherent Git +object session reuse. It does not claim that a `v6.5.3` 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.3`; +- moves the single session-coherence correction from `Unreleased` to `6.5.3`; +- packages and links `docs/releases/v6.5.3.md`; +- adds v6.5.2-to-v6.5.3 compatibility guidance to `UPGRADING.md`; +- marks design 0053 landed and records its release-candidate posture; +- preserves all v6.5.2 publication evidence as immutable history; and +- leaves tag and registry publication claims deliberately absent. + +## Implementation Provenance + +| Capability | Review anchor | Commit | +| ---------------------------------- | ------------- | ------------------------------------------ | +| Selective object-session retention | #95 | `9208871802a596cbc508be725353532110d40198` | +| Audited witness and measurements | #95 | `df05c4e40915fc510797e96c793f0e5f32889972` | +| Final review repair | #95 | `7adeabe950a3c841caffd1a3a4f82a696df86e71` | +| Reviewed feature merge | #95 | `7bdcbf1f9eccd16acd324c94d576e1ecd2e11d98` | + +The adapter preserves `cat-file` across successful immutable writes, preserves +`mktree` across loose writes, and retains the mandatory `mktree` retirement +barrier after a bounded `fast-import` batch. + +[cite: `src/infrastructure/adapters/GitPersistenceAdapter.js#93-175@7bdcbf1f9eccd16acd324c94d576e1ecd2e11d98`] + +The unit retirement matrix and real-Git integration prove coherent reuse and +mandatory refresh behavior in SHA-1 and SHA-256 repositories. + +[cite: `test/unit/infrastructure/adapters/GitPersistenceAdapter.sessionCoherence.test.js#6-45@7bdcbf1f9eccd16acd324c94d576e1ecd2e11d98`] +[cite: `test/integration/git-object-session-coherence.test.js#24-60@7bdcbf1f9eccd16acd324c94d576e1ecd2e11d98`] + +No public export, declaration, stored format, object identity, retention +policy, ref authority, idle bound, or explicit-close behavior changed. + +## Verification + +The versioned candidate passed the complete `pnpm run release:verify` method: + +| Gate | Result | Observed tests | +| -------------------------- | ---------------- | -------------: | +| Lint | PASS | - | +| Unit tests (Node) | PASS | 2,082 | +| Unit tests (Bun) | PASS | 2,081 | +| Unit tests (Deno) | PASS | 2,072 | +| Public type compatibility | PASS | - | +| Integration tests (Node) | PASS | 198 | +| Integration tests (Bun) | PASS | 198 | +| Integration tests (Deno) | PASS | 198 | +| Examples and build stamp | PASS | - | +| npm and JSR dry-runs | PASS | - | +| **Release method summary** | **PASS (14/14)** | **6,829** | + +The implementation PR merged only after GitHub lint and all Node/Bun/Deno jobs +passed, CodeRabbit approved the exact head commit, thread-aware review found no +review threads, and the complete diff received a clean self-review. 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.3` 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.3` with provenance; and +7. GitHub reports the final non-draft `v6.5.3` Release. + +Downstream git-warp adoption and its process-tree 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 a9377e5..169e52e 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 -- [0053-git-object-session-coherence - git-object-session-coherence](./0053-git-object-session-coherence/git-object-session-coherence.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 +- [0053-git-object-session-coherence - git-object-session-coherence](./0053-git-object-session-coherence/git-object-session-coherence.md) - [0052-persistent-git-object-sessions - persistent-git-object-sessions](./0052-persistent-git-object-sessions/persistent-git-object-sessions.md) - [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) diff --git a/docs/releases/v6.5.3.md b/docs/releases/v6.5.3.md new file mode 100644 index 0000000..c5c0141 --- /dev/null +++ b/docs/releases/v6.5.3.md @@ -0,0 +1,47 @@ +# git-cas v6.5.3 Release Notes + +v6.5.3 preserves coherent persistent Git object sessions across compatible +immutable writes. It is a process-topology correction to v6.5.2 and changes no +public API, stored format, object identity, retention policy, or lifecycle +contract. + +## Session Coherence + +`GitPersistenceAdapter` now preserves its typed `cat-file --batch-command` +session after successful loose blob, bulk blob, and tree writes. Git permits +that process to refresh object-database state and discover both new loose +objects and packs created after the session started. + +The adapter also preserves `mktree --batch -z` after loose blob and tree writes. +It deliberately retires `mktree` after a bounded `fast-import` batch because +Git's quick tree-entry lookup does not refresh packs created after the process +prepared its object database. The scoped `fast-import` process still +checkpoints and closes before any object ID escapes. + +## Measured Effect + +In the audited 128-node git-warp retained-materialization fixture, total Git +children fell from 558 to 401. `cat-file` openings fell from 80 to four and +`mktree` openings fell from 82 to one. The three-run median materialization test +time fell from 14.24 seconds to 12.72 seconds, and measured process CPU fell +from 15.74 seconds to 13.83 seconds. + +Process counts are deterministic regression evidence. Timings are local +observations, not cross-platform performance guarantees. The remaining 401 Git +children include 140 intentionally one-shot `hash-object` writes and git-warp +history, ref, and workspace operations outside this patch's scope. + +## Verification + +The versioned candidate passed 2,082 Node unit tests, 2,081 Bun unit tests, 2,072 +Deno unit tests, and 198 real-Git integration tests on each runtime. The full +release verifier passed all 14 steps with 6,829 observed tests. Real-Git +coverage exercises SHA-1 and SHA-256 repositories, later loose objects, later +packs above `fastimport.unpackLimit`, failure invalidation, idle retirement, and +explicit closure. + +## Compatibility + +This release requires no application changes or stored-data migration. +Existing public methods, handles, refs, witnesses, object IDs, and retention +semantics remain compatible with v6.5.2. diff --git a/jsr.json b/jsr.json index ae98d29..6e4f5b5 100644 --- a/jsr.json +++ b/jsr.json @@ -1,6 +1,6 @@ { "name": "@git-stunts/git-cas", - "version": "6.5.2", + "version": "6.5.3", "exports": { ".": "./index.js", "./service": "./src/domain/services/CasService.js", diff --git a/package.json b/package.json index 4aeb776..de53cfd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@git-stunts/git-cas", - "version": "6.5.2", + "version": "6.5.3", "description": "Content-addressed storage backed by Git's object database, with optional encryption and pluggable codecs", "type": "module", "main": "index.js", @@ -39,6 +39,7 @@ "docs/releases/v6.5.0.md", "docs/releases/v6.5.1.md", "docs/releases/v6.5.2.md", + "docs/releases/v6.5.3.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 87ed720..d8e7cce 100644 --- a/src/package-version.js +++ b/src/package-version.js @@ -1 +1 @@ -export const PACKAGE_VERSION = '6.5.2'; +export const PACKAGE_VERSION = '6.5.3'; diff --git a/test/unit/docs/package-docs.test.js b/test/unit/docs/package-docs.test.js index 2a7497d..2d909bd 100644 --- a/test/unit/docs/package-docs.test.js +++ b/test/unit/docs/package-docs.test.js @@ -17,6 +17,7 @@ const requiredStandardDocs = [ 'docs/releases/v6.5.0.md', 'docs/releases/v6.5.1.md', 'docs/releases/v6.5.2.md', + 'docs/releases/v6.5.3.md', ]; const forbiddenPackagePrefixes = ['docs/audit/', 'docs/archive/', 'docs/method/']; const forbiddenPackageFiles = ['docs/cli.gif', 'docs/vault.gif']; @@ -90,6 +91,7 @@ function publicPackagedMarkdownFiles(files) { 'docs/releases/v6.5.0.md', 'docs/releases/v6.5.1.md', 'docs/releases/v6.5.2.md', + 'docs/releases/v6.5.3.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 5a55e06..baaea66 100644 --- a/test/unit/docs/release-state.test.js +++ b/test/unit/docs/release-state.test.js @@ -1,9 +1,13 @@ import { describe, expect, it } from 'vitest'; -import { readFileSync } from 'node:fs'; +import { existsSync, readFileSync } from 'node:fs'; import path from 'node:path'; const repoRoot = process.cwd(); -const v652PublishedMarker = '**Current release state:** `v6.5.2` is published'; +const v653CandidateMarker = '**Current release state:** `v6.5.3` release candidate'; +const v653CandidatePath = + 'docs/design/0053-git-object-session-coherence/witness/release-candidate.md'; +const v653PublicationPath = + 'docs/design/0053-git-object-session-coherence/witness/release-publication.md'; const v652CandidatePath = 'docs/design/0052-persistent-git-object-sessions/witness/release-candidate.md'; const v652PublicationPath = @@ -71,6 +75,46 @@ function expectNoV652PublicationEvidence(...documents) { } } +function expectNoV653PublicationEvidence(...documents) { + const forbiddenMarkers = [ + '**Last tagged release:** `v6.5.3`', + '**Current release state:** `v6.5.3` is published', + '- Signed annotated tag: `v6.5.3`', + 'https://github.com/git-stunts/git-cas/releases/tag/v6.5.3', + '## npm Registry Evidence', + /\| Package\s+\| `@git-stunts\/git-cas@6\.5\.3`\s+\|/, + /\| Dist-tag\s+\| `latest` -> `6\.5\.3`\s+\|/, + 'attestations/@git-stunts%2fgit-cas@6.5.3', + ]; + + 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 expectV653CandidateEvidence(status, candidate) { + expect(status).toContain('**Last tagged release:** `v6.5.2` (`2026-07-19`)'); + expect(status).toContain(v653CandidateMarker); + expect(status).toContain('remain pending the reviewed tag workflow'); + expect(status).toContain('passed 14/14 release-verifier steps with 6,829 observed tests'); + expect(status).toContain('7bdcbf1f'); + expect(candidate).toContain('# PERF-0053 v6.5.3 Release Candidate Witness'); + expect(candidate).toContain('Implementation review: #95'); + expect(candidate).toContain('Release review: #96'); + expect(candidate).toContain('7bdcbf1f9eccd16acd324c94d576e1ecd2e11d98'); + expect(candidate).toContain('**PASS (14/14)**'); + expect(candidate).toContain('**6,829**'); + expect(candidate).toMatch(/explicitly\s+unpublished candidate/); + expectNoV653PublicationEvidence(status, candidate); + expect(existsSync(path.join(repoRoot, v653PublicationPath))).toBe(false); +} + function expectV652CandidateEvidence(candidate) { expect(candidate).toContain('# PERF-0052 v6.5.2 Release Candidate Witness'); expect(candidate).toContain('Implementation review: #91'); @@ -84,7 +128,7 @@ function expectV652CandidateEvidence(candidate) { function expectV652PublishedEvidence(status, publication) { expect(status).toContain('**Last tagged release:** `v6.5.2` (`2026-07-19`)'); - expect(status).toContain(v652PublishedMarker); + expect(status).toContain('**v6.5.2 artifact posture**'); expect(status).toContain('c2d41f60'); expect(status).toContain('29690794540'); expect(status).toContain('#39 v6.6.0: Operator TUI'); @@ -173,27 +217,31 @@ function expectCurrentV640PublicationEvidence(publication) { } describe('release state docs', () => { - it('enforces v6.5.2 publication while preserving candidate and prior evidence', () => { + it('enforces the v6.5.3 candidate while preserving prior evidence', () => { const status = read('STATUS.md'); - const candidate = read(v652CandidatePath); + const candidate = read(v653CandidatePath); + const v652Candidate = read(v652CandidatePath); const v652Publication = read(v652PublicationPath); const v651Candidate = read(v651CandidatePath); - const releaseNotes = read('docs/releases/v6.5.2.md'); + const v653ReleaseNotes = read('docs/releases/v6.5.3.md'); + const v652ReleaseNotes = read('docs/releases/v6.5.2.md'); const publication = read(v651PublicationPath); const v650Publication = read(v650PublicationPath); const v640Publication = read(v640PublicationPath); - expectV652CandidateEvidence(candidate); + expectV653CandidateEvidence(status, candidate); + expectV652CandidateEvidence(v652Candidate); expectV652PublishedEvidence(status, v652Publication); expectV651CandidateEvidence(v651Candidate); expectV651PublishedEvidence(status, publication); - expect(releaseNotes).toContain('passed all 14 release-verifier steps with 6,817 observed'); + expect(v653ReleaseNotes).toContain('release verifier passed all 14 steps with 6,829'); + 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('0052-persistent-git-object-sessions'); + expect(status).toContain('0053-git-object-session-coherence'); 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 fc21cc0..7c8fb2b 100644 --- a/test/unit/docs/release-truth.test.js +++ b/test/unit/docs/release-truth.test.js @@ -263,6 +263,21 @@ describe('persistent Git object session release documentation', () => { }); }); +describe('Git object session coherence release documentation', () => { + it('ships and links the v6.5.3 coherence contract', () => { + const readme = read('README.md'); + const upgrading = read('UPGRADING.md'); + const releaseNotes = read('docs/releases/v6.5.3.md'); + + expect(readme).toContain('[v6.5.3 Release Notes](./docs/releases/v6.5.3.md)'); + expect(upgrading).toContain('## v6.5.2 To v6.5.3'); + expect(upgrading).toContain('No application code changes are required'); + expect(releaseNotes).toContain('# git-cas v6.5.3 Release Notes'); + expect(releaseNotes).toMatch(/total Git\s+children fell from 558 to 401/); + expect(releaseNotes).toMatch(/changes no\s+public API/); + }); +}); + describe('advanced guide rendering', () => { it('keeps the table of contents rendered as Markdown links', () => { const advancedGuide = read('ADVANCED_GUIDE.md');