Skip to content

Resume exact materializations from retained git-cas roots#754

Merged
flyingrobots merged 1 commit into
mainfrom
v19-exact-materialization-resume
Jul 16, 2026
Merged

Resume exact materializations from retained git-cas roots#754
flyingrobots merged 1 commit into
mainfrom
v19-exact-materialization-resume

Conversation

@flyingrobots

Copy link
Copy Markdown
Member

Summary

  • represent every named materialization root with an explicit retained, empty, or unavailable posture
  • persist schema-v2, coordinate-keyed materialization descriptors and retained root bundles through the @git-stunts/git-cas CacheSet API
  • retain cold StateSession roots and reopen them on exact state-cache hits, including through a fresh runtime adapter
  • avoid replaying writer patches already covered by the exact snapshot and retained handle
  • flush StateSession roots only after successful reduction/projection, so failed reductions do not create partial unretained CAS artifacts
  • document both the delivered warm-resume behavior and the remaining graph-sized compatibility work

Why

Issue #738 requires warm materialization to resume from retained handles rather than repeatedly replaying the same causal prefix. The previous session bridge discarded the roots returned by StateSession.close(); exact snapshot hits therefore had no durable page-root basis to reopen.

This slice makes the node/edge trie roots durable and reconnects the exact-hit path to them. It is deliberately a partial delivery for #738, not issue closure.

Source evidence

  • Root availability is explicit and runtime-validated. [cite: src/domain/materialization/MaterializationRoot.ts#4-30@b96bd3e7d749ca946a2af7fa9d837cb2e56b8156]
  • The descriptor binds schema version, lane, state hash, causal coordinate, and all named root postures. [cite: src/infrastructure/adapters/GitCasMaterializationDescriptor.ts#12-79@b96bd3e7d749ca946a2af7fa9d837cb2e56b8156]
  • Retention and lookup use git-cas CacheSet; descriptor lane and coordinate mismatches fail closed. [cite: src/infrastructure/adapters/GitCasMaterializationStoreAdapter.ts#87-176@b96bd3e7d749ca946a2af7fa9d837cb2e56b8156]
  • Exact hits validate state hashes, reopen retained roots, reduce an empty patch source, and avoid republishing the snapshot. [cite: src/domain/services/controllers/MaterializeController.ts#296-353@b96bd3e7d749ca946a2af7fa9d837cb2e56b8156]
  • Session roots flush only after successful projection. [cite: src/domain/services/controllers/MaterializeSessionBridge.ts#34-90@b96bd3e7d749ca946a2af7fa9d837cb2e56b8156]
  • Real Git integration proves same-runtime and fresh-adapter retained-handle hits with no patch-chain load. [cite: test/integration/api/materialization.retainedResume.test.ts#27-65@b96bd3e7d749ca946a2af7fa9d837cb2e56b8156]
  • A dirty partial reduction is proven not to call the flushing close(). [cite: test/unit/domain/services/controllers/MaterializeController.stateSession.test.ts#197-225@b96bd3e7d749ca946a2af7fa9d837cb2e56b8156]

Code Lawyer

  • CAS ownership remains below the adapter boundary; lint:cas-invariants reports zero raw Git object-write violations.
  • Cache identity includes descriptor schema, lane, frontier, and ceiling.
  • Retained-handle and reconstructed-state hashes must agree.
  • Graft reports one internal module signature change, reduceSessionBackedState; its only source caller is MaterializeController. The built package-root declaration surface has zero changes or warnings.
  • Failed reductions do not flush partial roots.
  • Replace RuntimeHost full state with CAS-backed materialization handles #738 remains open. The normal result still loads a full snapshot, scans complete node/edge tries, constructs a full WarpState, and builds full adjacency. [cite: docs/topics/cas-first-memoized-materialization.md#144-161@b96bd3e7d749ca946a2af7fa9d837cb2e56b8156]

Validation

  • stable unit suite: 566 files, 6,982 passed, 2 skipped
  • full integration suite: 21 files, 96 passed
  • coverage: 578 files passed, 7,086 tests passed; 92.73% statements / 84.93% branches / 96.14% functions / 92.78% lines
  • focused retained-resume suite: 7 files, 97 passed
  • npm run typecheck
  • npm run lint, including source-size and git-cas ownership gates
  • IRONCLAD policy, consumer types, package declaration surface, docs topology, semgrep, anti-sludge, quarantine graduation
  • packed artifact smoke and npm pack dry run
  • pre-push link/static gates

Remaining #738 work

  • page properties, edge births, frontier, adjacency, provenance support, and Roaring indexes
  • make ordinary observers consume bounded support/page handles
  • remove resident full-state and full-view caches from RuntimeHost
  • replace the legacy WARP-owned full-snapshot cache lifecycle
  • add page-touch, work, age/size, timing, benchmark, and doctor instrumentation
  • close with constrained-memory proof

Refs #738

@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 46796035-2a08-4bdf-b069-c5421c5f9cc0

📥 Commits

Reviewing files that changed from the base of the PR and between c15a506 and b96bd3e.

📒 Files selected for processing (21)
  • CHANGELOG.md
  • docs/topics/cas-first-memoized-materialization.md
  • src/domain/RuntimeHost.ts
  • src/domain/materialization/MaterializationRoot.ts
  • src/domain/materialization/MaterializationRoots.ts
  • src/domain/services/controllers/MaterializeController.ts
  • src/domain/services/controllers/MaterializeCoordinateStrategy.ts
  • src/domain/services/controllers/MaterializeLiveStrategy.ts
  • src/domain/services/controllers/MaterializeSessionBridge.ts
  • src/domain/services/controllers/MaterializeStrategyRuntime.ts
  • src/domain/warp/RuntimeHostBoot.ts
  • src/infrastructure/adapters/GitCasMaterializationDescriptor.ts
  • src/infrastructure/adapters/GitCasMaterializationStoreAdapter.ts
  • test/helpers/InMemoryMaterializationStore.ts
  • test/integration/api/materialization.retainedResume.test.ts
  • test/integration/infrastructure/adapters/GitCasMaterializationStoreAdapter.integration.test.ts
  • test/unit/domain/materialization/MaterializationIdentity.test.ts
  • test/unit/domain/services/controllers/MaterializeController.snapshotCache.test.ts
  • test/unit/domain/services/controllers/MaterializeController.stateSession.test.ts
  • test/unit/domain/services/controllers/MaterializePatchStreamReducer.test.ts
  • test/unit/infrastructure/adapters/GitCasMaterializationStoreAdapter.test.ts
📜 Recent review details
⏰ Context from checks skipped due to timeout. (3)
  • GitHub Check: coverage-threshold
  • GitHub Check: test-node (22)
  • GitHub Check: preflight
🧰 Additional context used
📓 Path-based instructions (4)
src/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.{ts,tsx,js,jsx}: Do not introduce any, as any, as unknown as, unknown (outside adapters), Record<string, unknown> (outside adapters), *Like placeholder types, JSON.parse/JSON.stringify (outside adapters), fetch (outside adapters), process.env (outside adapters), @ts-ignore, or z.any() in core code; use validated boundary models and ports instead.
Use constructor-injected ports for external capabilities; do not rely on ambient dependencies for I/O, clocks, persistence, or entropy.
Do not create utils.ts, helpers.ts, misc.ts, or common.ts; name files after the actual concept they model.
Prefer one file per class, type, or object; if a file accumulates peer concepts, split it.
Keep helper corridors, fake shape trust, transitional duplication, and compile-time theater out of the codebase; runtime-honest TypeScript must reflect actual behavior.
No enum usage; prefer runtime-backed domain forms and unions.
Do not use boolean trap parameters; prefer named option objects or separate methods.
Avoid magic strings or numbers when a named constant should exist.
Keep domain bytes as Uint8Array; Buffer belongs in infrastructure adapters.

Files:

  • src/domain/services/controllers/MaterializeLiveStrategy.ts
  • src/domain/materialization/MaterializationRoot.ts
  • src/domain/services/controllers/MaterializeStrategyRuntime.ts
  • src/domain/services/controllers/MaterializeCoordinateStrategy.ts
  • src/domain/warp/RuntimeHostBoot.ts
  • src/domain/RuntimeHost.ts
  • src/infrastructure/adapters/GitCasMaterializationDescriptor.ts
  • src/domain/materialization/MaterializationRoots.ts
  • src/domain/services/controllers/MaterializeController.ts
  • src/domain/services/controllers/MaterializeSessionBridge.ts
  • src/infrastructure/adapters/GitCasMaterializationStoreAdapter.ts
src/domain/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

src/domain/**/*.{ts,tsx,js,jsx}: In src/domain/**, do not use Date.now(), new Date(), Date(), performance.now(), Math.random(), crypto.randomUUID(), crypto.getRandomValues(), setTimeout, setInterval, raw new Error(...)/new TypeError(...), or direct imports from Node built-ins; time, entropy, and external capabilities must enter through ports or parameters, and domain errors should extend WarpError.
Construct domain objects only in core when doing so establishes validated runtime truth; do not build infrastructure adapters, host APIs, persistence implementations, wall clocks, or entropy sources inside core.
Prefer discriminated unions and explicit result types instead of boolean-flag bags, and model expected failures as return values rather than exceptions.
src/domain/ must not import host APIs or Node-specific globals; hexagonal architecture boundaries are mandatory.
Domain code must not use the wall clock directly; time must enter through a port or parameter.

Files:

  • src/domain/services/controllers/MaterializeLiveStrategy.ts
  • src/domain/materialization/MaterializationRoot.ts
  • src/domain/services/controllers/MaterializeStrategyRuntime.ts
  • src/domain/services/controllers/MaterializeCoordinateStrategy.ts
  • src/domain/warp/RuntimeHostBoot.ts
  • src/domain/RuntimeHost.ts
  • src/domain/materialization/MaterializationRoots.ts
  • src/domain/services/controllers/MaterializeController.ts
  • src/domain/services/controllers/MaterializeSessionBridge.ts
src/domain/**/!(*.test).{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use explicit domain concepts with validated constructors, Object.freeze, and instanceof dispatch; domain objects should be runtime-backed nouns, not ad hoc shape bags.

Files:

  • src/domain/services/controllers/MaterializeLiveStrategy.ts
  • src/domain/materialization/MaterializationRoot.ts
  • src/domain/services/controllers/MaterializeStrategyRuntime.ts
  • src/domain/services/controllers/MaterializeCoordinateStrategy.ts
  • src/domain/warp/RuntimeHostBoot.ts
  • src/domain/RuntimeHost.ts
  • src/domain/materialization/MaterializationRoots.ts
  • src/domain/services/controllers/MaterializeController.ts
  • src/domain/services/controllers/MaterializeSessionBridge.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Do not use direct imports from src/infrastructure/** in src/domain/** or src/ports/**; depend on a port instead.
Do not use direct Node built-ins in src/domain/** or src/ports/**; use a port instead.

Files:

  • src/domain/services/controllers/MaterializeLiveStrategy.ts
  • src/domain/materialization/MaterializationRoot.ts
  • test/unit/domain/services/controllers/MaterializeController.snapshotCache.test.ts
  • src/domain/services/controllers/MaterializeStrategyRuntime.ts
  • src/domain/services/controllers/MaterializeCoordinateStrategy.ts
  • test/unit/domain/services/controllers/MaterializePatchStreamReducer.test.ts
  • test/integration/api/materialization.retainedResume.test.ts
  • test/helpers/InMemoryMaterializationStore.ts
  • src/domain/warp/RuntimeHostBoot.ts
  • test/unit/domain/materialization/MaterializationIdentity.test.ts
  • src/domain/RuntimeHost.ts
  • src/infrastructure/adapters/GitCasMaterializationDescriptor.ts
  • test/integration/infrastructure/adapters/GitCasMaterializationStoreAdapter.integration.test.ts
  • src/domain/materialization/MaterializationRoots.ts
  • src/domain/services/controllers/MaterializeController.ts
  • test/unit/domain/services/controllers/MaterializeController.stateSession.test.ts
  • src/domain/services/controllers/MaterializeSessionBridge.ts
  • test/unit/infrastructure/adapters/GitCasMaterializationStoreAdapter.test.ts
  • src/infrastructure/adapters/GitCasMaterializationStoreAdapter.ts
🧠 Learnings (1)
📚 Learning: 2026-03-08T19:50:17.519Z
Learnt from: flyingrobots
Repo: git-stunts/git-warp PR: 65
File: CHANGELOG.md:88-88
Timestamp: 2026-03-08T19:50:17.519Z
Learning: Follow the Keep a Changelog convention for CHANGELOG.md. Allow duplicate subheadings across versions (e.g., '### Added', '### Fixed'). Configure markdownlint MD024 with {"siblings_only": true} to avoid cross-version false positives.

Applied to files:

  • CHANGELOG.md
🪛 ast-grep (0.44.1)
test/integration/infrastructure/adapters/GitCasMaterializationStoreAdapter.integration.test.ts

[warning] Importing child_process exposes a command-execution surface; ensure any command/argument built from input is validated, and prefer execFile/spawn with an argument array over exec.
Context: import { execFile } from 'node:child_process';
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(detect-child-process-typescript)


[warning] Importing child_process exposes a command-execution surface; ensure any command/argument built from input is validated, and prefer execFile/spawn with an argument array over exec.
Context: import { execFile } from 'node:child_process';
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(detect-child-process-typescript)


[warning] Importing child_process exposes a command-execution surface; ensure any command/argument built from input is validated, and prefer execFile/spawn with an argument array over exec.
Context: import { execFile } from 'node:child_process';
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(detect-child-process-typescript)

🔇 Additional comments (21)
src/domain/materialization/MaterializationRoot.ts (1)

1-35: LGTM!

docs/topics/cas-first-memoized-materialization.md (1)

7-12: LGTM!

Also applies to: 23-23, 48-54, 76-93, 147-154

CHANGELOG.md (1)

69-74: LGTM!

test/integration/api/materialization.retainedResume.test.ts (1)

1-147: LGTM!

test/integration/infrastructure/adapters/GitCasMaterializationStoreAdapter.integration.test.ts (1)

12-12: LGTM!

Also applies to: 58-72, 205-222

test/unit/domain/materialization/MaterializationIdentity.test.ts (1)

4-4: LGTM!

Also applies to: 127-127, 140-162, 223-236

test/unit/domain/services/controllers/MaterializeController.stateSession.test.ts (1)

4-6: LGTM!

Also applies to: 20-20, 140-140, 177-177, 191-228, 263-310

src/domain/materialization/MaterializationRoots.ts (1)

2-2: LGTM!

Also applies to: 17-86

src/domain/services/controllers/MaterializeSessionBridge.ts (1)

6-8: LGTM!

Also applies to: 34-103, 124-161

src/domain/services/controllers/MaterializeController.ts (1)

24-24: LGTM!

Also applies to: 46-46, 56-60, 73-84, 90-118, 265-354, 409-421, 452-457

src/infrastructure/adapters/GitCasMaterializationDescriptor.ts (1)

1-222: LGTM!

src/infrastructure/adapters/GitCasMaterializationStoreAdapter.ts (1)

13-13: LGTM!

Also applies to: 27-34, 52-54, 106-110, 173-197, 216-218, 276-295

test/unit/domain/services/controllers/MaterializePatchStreamReducer.test.ts (1)

28-28: LGTM!

Also applies to: 209-220

test/unit/infrastructure/adapters/GitCasMaterializationStoreAdapter.test.ts (1)

4-4: LGTM!

Also applies to: 60-67, 76-98, 234-234, 275-300, 332-342, 519-546, 562-565, 574-593

src/domain/services/controllers/MaterializeCoordinateStrategy.ts (1)

116-118: LGTM!

src/domain/services/controllers/MaterializeLiveStrategy.ts (1)

258-264: LGTM!

src/domain/services/controllers/MaterializeStrategyRuntime.ts (1)

11-12: LGTM!

Also applies to: 41-42, 71-75

src/domain/RuntimeHost.ts (1)

291-291: LGTM!

Also applies to: 404-404

test/unit/domain/services/controllers/MaterializeController.snapshotCache.test.ts (1)

8-8: LGTM!

Also applies to: 136-136

src/domain/warp/RuntimeHostBoot.ts (1)

73-73: 🗄️ Data Integrity & Integration

No issue: materializations is already required and provided

RuntimeStorageProviderPort requires materializations, and GitCasRepositoryAdapter.createRuntimeStorageServices() supplies it.

			> Likely an incorrect or invalid review comment.
test/helpers/InMemoryMaterializationStore.ts (1)

42-47: 🎯 Functional Correctness

No issue: frontierEntries are already canonical.
MaterializationCoordinate.freezeFrontier() sorts entries by writerId, so coordinateKey() already produces a stable key here.

			> Likely an incorrect or invalid review comment.

📝 Walkthrough

Summary by CodeRabbit

  • New Features
    • Exact cached materializations can now resume across runtime restarts without replaying already-covered changes.
    • Retained materialization status is preserved, including partial, empty, and unavailable roots.
  • Bug Fixes
    • Failed state reductions no longer retain incomplete materialization data.
    • Repeated cache hits avoid unnecessary snapshot republishing and retention work.
  • Documentation
    • Clarified cache reuse behavior, retention states, lifecycle, and current limitations.

Walkthrough

Materialization now models root availability explicitly, retains coordinate-keyed descriptors through Git-CAS, and resumes exact cached snapshots by reopening retained roots without patch replay or duplicate snapshot publication. Tests cover partial roots, validation, failure handling, warm reuse, and fresh runtime adapters.

Changes

Retained materialization

Layer / File(s) Summary
Root and session contracts
src/domain/materialization/*, src/domain/services/controllers/MaterializeSessionBridge.ts
Materialization roots now carry retained, empty, or unavailable status, and session reduction converts root tokens into these values.
Controller exact-hit resume
src/domain/services/controllers/*, src/domain/RuntimeHost.ts, src/domain/warp/RuntimeHostBoot.ts
Exact snapshot paths attempt retained-root resume through the materialization store, returning retained handles and suppressing duplicate snapshot publication.
Git-CAS descriptor persistence
src/infrastructure/adapters/*, docs/topics/cas-first-memoized-materialization.md, CHANGELOG.md
Versioned descriptors encode coordinates and root statuses; only retained roots become bundle members, with strict decoding and rehydration validation.
Resume and storage validation
test/helpers/*, test/unit/*, test/integration/*
Tests verify root states, descriptor validation, partial-root retention, failed reduction handling, zero patch replay, and reuse across fresh runtime adapters.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related issues

Possibly related PRs

Sequence Diagram(s)

sequenceDiagram
  participant MaterializeLiveStrategy
  participant MaterializeController
  participant MaterializationStorePort
  participant StateSession
  MaterializeLiveStrategy->>MaterializeController: request exact snapshot resume
  MaterializeController->>MaterializationStorePort: findExact(coordinate)
  MaterializationStorePort-->>MaterializeController: retained roots
  MaterializeController->>StateSession: open session with retained roots
  StateSession-->>MaterializeController: projected state
  MaterializeController-->>MaterializeLiveStrategy: result without patch replay
Loading

Poem

A rabbit found roots in a Git-CAS burrow,
Reopened old branches without patchwork or worry.
Empty and waiting, retained ones in line,
Descriptors kept every coordinate sign.
Across fresh runtimes, the same bundles gleam—
No replaying the trail, just a cached-root dream.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately captures the main change: resuming exact materializations from retained git-cas roots.
Description check ✅ Passed The description is mostly complete, covering summary, issue reference, and validation, though it does not explicitly include the ADR checks section.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

Release Preflight

  • package version: 18.2.1
  • prerelease: false
  • npm dist-tag on release: latest
  • npm pack dry-run: passed
  • jsr publish dry-run: passed

If this PR is from a release/* branch and merges to main, Main Push Release Branch Check will run final preflight and create v18.2.1. A maintainer who is a JSR @git-stunts scope member must then dispatch the Release workflow manually.

@flyingrobots
flyingrobots merged commit 71a97c4 into main Jul 16, 2026
17 checks passed
@flyingrobots
flyingrobots deleted the v19-exact-materialization-resume branch July 16, 2026 16:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant