fix: retain bounded materialization roots#755
Conversation
📝 WalkthroughWalkthroughState sessions now support bounded dirty-page checkpointing through renewable CAS-backed workspaces. Materialization reduction carries explicit coordinates, accepts final retention witnesses, and releases workspaces on failure or empty results. Trie rebasing and ancestor rebinding preserve reopened checkpoint state. ChangesBounded session checkpointing
CAS workspace retention
Materialization orchestration
Validation and regression coverage
Estimated code review effort: 4 (Complex) | ~60 minutes Possibly related PRs
Sequence Diagram(s)sequenceDiagram
participant MaterializeStrategy
participant MaterializeController
participant MaterializeSessionBridge
participant MaterializationWorkspace
participant StateSession
MaterializeStrategy->>MaterializeController: reduce patches with coordinate
MaterializeController->>MaterializeSessionBridge: reduceSessionBackedState
MaterializeSessionBridge->>MaterializationWorkspace: open workspace
MaterializeSessionBridge->>StateSession: open with workspace
StateSession->>MaterializationWorkspace: checkpoint dirty roots
StateSession-->>MaterializeSessionBridge: prepared close roots
MaterializeController->>MaterializationWorkspace: accept final retention
MaterializationWorkspace-->>MaterializeController: retained materialization
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches📝 Generate docstrings
Comment |
Release Preflight
If this PR is from a |
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
test/helpers/InMemoryMaterializationStore.ts (1)
1-1: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDuplicated
StorageRetentionWitnessconstruction for workspace-checkpoint doubles. Both sites hand-roll the same "cache-set"/"pinned" witness shape for a workspace checkpoint; extracting one shared factory would remove the drift risk if the witness contract changes.
test/helpers/InMemoryMaterializationStore.ts#L114-129: exportworkspaceRetentionWitness(or a parameterizedbuildCacheSetRetentionWitness(handle, { policy, namespace, generation })) so it can be imported by other test doubles instead of being reimplemented.test/unit/domain/orset/session/StateSession.test.ts#L454-482: replaceRecordingWorkspace.checkpoint's inlineStorageRetentionWitness/StorageRetentionRootconstruction with the shared exported helper fromtest/helpers/InMemoryMaterializationStore.ts.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@test/helpers/InMemoryMaterializationStore.ts` at line 1, Extract the shared workspace checkpoint StorageRetentionWitness construction from InMemoryMaterializationStore into an exported helper, such as workspaceRetentionWitness or a parameterized factory preserving handle, policy, namespace, and generation. Update RecordingWorkspace.checkpoint in StateSession.test.ts to use this helper instead of constructing StorageRetentionWitness and StorageRetentionRoot inline, keeping the existing witness values unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/domain/services/controllers/MaterializeController.ts`:
- Around line 266-299: Update _buildResult so
params.reduced.workspace?.release() cannot replace an exception raised by the
try block; preserve and rethrow the original operation error while isolating any
release failure, and retain release behavior when the main operation succeeds.
In `@src/domain/services/controllers/MaterializeSessionBridge.ts`:
- Around line 108-112: Update the catch block in MaterializeSessionBridge to
preserve the original caught error when workspace.release() fails: attempt
cleanup without allowing its exception to replace raw, then rethrow raw. Apply
the same error-preserving cleanup pattern to the other shared call sites
referenced by the consolidated comment.
In `@src/infrastructure/adapters/GitCasMaterializationWorkspace.ts`:
- Around line 104-183: Update release() to perform best-effort cleanup without
throwing lease-health errors: preserve the release and cache-removal work, but
prevent `#assertLeaseHealthy`() failures from escaping during cleanup. Keep lease
health available through the existing state/error mechanisms rather than masking
the original failure.
In `@test/unit/domain/orset/session/StateSession.test.ts`:
- Around line 454-482: The RecordingWorkspace.checkpoint implementation
duplicates the retention-witness construction already provided by
workspaceRetentionWitness in InMemoryMaterializationStore. Reuse that shared
helper for the returned StorageRetentionWitness, supplying the test checkpoint
handle and generation values as needed, while preserving the existing checkpoint
recording and test-specific identifiers.
---
Outside diff comments:
In `@test/helpers/InMemoryMaterializationStore.ts`:
- Line 1: Extract the shared workspace checkpoint StorageRetentionWitness
construction from InMemoryMaterializationStore into an exported helper, such as
workspaceRetentionWitness or a parameterized factory preserving handle, policy,
namespace, and generation. Update RecordingWorkspace.checkpoint in
StateSession.test.ts to use this helper instead of constructing
StorageRetentionWitness and StorageRetentionRoot inline, keeping the existing
witness values unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 21ec0d15-31d3-4442-a29a-5377d6a9243a
📒 Files selected for processing (31)
CHANGELOG.mdsrc/domain/orset/session/StateSession.tssrc/domain/orset/shadow/ShadowTrieORSet.tssrc/domain/orset/trie/TrieCursor.tssrc/domain/services/controllers/MaterializeController.tssrc/domain/services/controllers/MaterializeCoordinateStrategy.tssrc/domain/services/controllers/MaterializeLiveStrategy.tssrc/domain/services/controllers/MaterializeSessionBridge.tssrc/domain/services/controllers/MaterializeStrategyRuntime.tssrc/domain/warp/RuntimeHostBoot.tssrc/infrastructure/adapters/GitCasMaterializationStoreAdapter.tssrc/infrastructure/adapters/GitCasMaterializationWorkspace.tssrc/ports/MaterializationStorePort.tssrc/ports/MaterializationWorkspacePort.tstest/helpers/InMemoryGitCasFacade.tstest/helpers/InMemoryMaterializationStore.tstest/integration/api/materialization.retainedResume.test.tstest/integration/infrastructure/adapters/GitCasMaterializationStoreAdapter.integration.test.tstest/unit/domain/WarpGraph.autoCheckpoint.test.tstest/unit/domain/WarpGraph.patchCount.test.tstest/unit/domain/WarpGraph.test.tstest/unit/domain/WarpGraph.versionVector.test.tstest/unit/domain/orset/session/StateSession.test.tstest/unit/domain/orset/trie/TrieCursor.test.tstest/unit/domain/services/controllers/MaterializeController.stateSession.test.tstest/unit/domain/services/controllers/MaterializeController.test.tstest/unit/domain/services/controllers/MaterializePatchStreamReducer.test.tstest/unit/domain/warp/hydrateCheckpointIndex.regression.test.tstest/unit/infrastructure/adapters/GitCasMaterializationStoreAdapter.test.tstest/unit/infrastructure/adapters/GitCasMaterializationWorkspace.test.tstest/unit/scripts/v18-graph-model-migration-command-cli.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
- GitHub Check: test-node (22)
- GitHub Check: preflight
🧰 Additional context used
📓 Path-based instructions (5)
src/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{ts,tsx,js,jsx}: Do not introduceany,as any,as unknown as,unknown(outside adapters),Record<string, unknown>(outside adapters),*Likeplaceholder types,JSON.parse/JSON.stringify(outside adapters),fetch(outside adapters),process.env(outside adapters),@ts-ignore, orz.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 createutils.ts,helpers.ts,misc.ts, orcommon.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 asUint8Array;Bufferbelongs in infrastructure adapters.
Files:
src/ports/MaterializationWorkspacePort.tssrc/domain/orset/shadow/ShadowTrieORSet.tssrc/domain/services/controllers/MaterializeCoordinateStrategy.tssrc/domain/services/controllers/MaterializeStrategyRuntime.tssrc/ports/MaterializationStorePort.tssrc/domain/orset/trie/TrieCursor.tssrc/domain/services/controllers/MaterializeSessionBridge.tssrc/infrastructure/adapters/GitCasMaterializationWorkspace.tssrc/infrastructure/adapters/GitCasMaterializationStoreAdapter.tssrc/domain/services/controllers/MaterializeLiveStrategy.tssrc/domain/warp/RuntimeHostBoot.tssrc/domain/orset/session/StateSession.tssrc/domain/services/controllers/MaterializeController.ts
src/ports/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
In
src/ports/**, do not import Node built-ins orsrc/infrastructure/**; ports must stay abstract and depend only on boundary-safe types.
Files:
src/ports/MaterializationWorkspacePort.tssrc/ports/MaterializationStorePort.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,js,jsx}: Do not use direct imports fromsrc/infrastructure/**insrc/domain/**orsrc/ports/**; depend on a port instead.
Do not use direct Node built-ins insrc/domain/**orsrc/ports/**; use a port instead.
Files:
src/ports/MaterializationWorkspacePort.tssrc/domain/orset/shadow/ShadowTrieORSet.tssrc/domain/services/controllers/MaterializeCoordinateStrategy.tstest/unit/domain/services/controllers/MaterializeController.test.tstest/unit/domain/services/controllers/MaterializePatchStreamReducer.test.tstest/unit/domain/WarpGraph.patchCount.test.tstest/unit/domain/WarpGraph.versionVector.test.tstest/unit/domain/WarpGraph.autoCheckpoint.test.tstest/integration/api/materialization.retainedResume.test.tssrc/domain/services/controllers/MaterializeStrategyRuntime.tstest/unit/infrastructure/adapters/GitCasMaterializationWorkspace.test.tstest/unit/infrastructure/adapters/GitCasMaterializationStoreAdapter.test.tstest/helpers/InMemoryMaterializationStore.tssrc/ports/MaterializationStorePort.tstest/integration/infrastructure/adapters/GitCasMaterializationStoreAdapter.integration.test.tstest/unit/scripts/v18-graph-model-migration-command-cli.test.tssrc/domain/orset/trie/TrieCursor.tssrc/domain/services/controllers/MaterializeSessionBridge.tssrc/infrastructure/adapters/GitCasMaterializationWorkspace.tstest/unit/domain/services/controllers/MaterializeController.stateSession.test.tstest/unit/domain/orset/session/StateSession.test.tssrc/infrastructure/adapters/GitCasMaterializationStoreAdapter.tstest/unit/domain/orset/trie/TrieCursor.test.tssrc/domain/services/controllers/MaterializeLiveStrategy.tstest/unit/domain/warp/hydrateCheckpointIndex.regression.test.tstest/helpers/InMemoryGitCasFacade.tssrc/domain/warp/RuntimeHostBoot.tssrc/domain/orset/session/StateSession.tstest/unit/domain/WarpGraph.test.tssrc/domain/services/controllers/MaterializeController.ts
src/domain/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/domain/**/*.{ts,tsx,js,jsx}: Insrc/domain/**, do not useDate.now(),new Date(),Date(),performance.now(),Math.random(),crypto.randomUUID(),crypto.getRandomValues(),setTimeout,setInterval, rawnew 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 extendWarpError.
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/orset/shadow/ShadowTrieORSet.tssrc/domain/services/controllers/MaterializeCoordinateStrategy.tssrc/domain/services/controllers/MaterializeStrategyRuntime.tssrc/domain/orset/trie/TrieCursor.tssrc/domain/services/controllers/MaterializeSessionBridge.tssrc/domain/services/controllers/MaterializeLiveStrategy.tssrc/domain/warp/RuntimeHostBoot.tssrc/domain/orset/session/StateSession.tssrc/domain/services/controllers/MaterializeController.ts
src/domain/**/!(*.test).{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use explicit domain concepts with validated constructors,
Object.freeze, andinstanceofdispatch; domain objects should be runtime-backed nouns, not ad hoc shape bags.
Files:
src/domain/orset/shadow/ShadowTrieORSet.tssrc/domain/services/controllers/MaterializeCoordinateStrategy.tssrc/domain/services/controllers/MaterializeStrategyRuntime.tssrc/domain/orset/trie/TrieCursor.tssrc/domain/services/controllers/MaterializeSessionBridge.tssrc/domain/services/controllers/MaterializeLiveStrategy.tssrc/domain/warp/RuntimeHostBoot.tssrc/domain/orset/session/StateSession.tssrc/domain/services/controllers/MaterializeController.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/unit/infrastructure/adapters/GitCasMaterializationWorkspace.test.ts
[warning] 353-353: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(${field} dependency, 'u')
Note: [CWE-1333] Inefficient Regular Expression Complexity
(regexp-from-variable)
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)
[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 (36)
test/helpers/InMemoryGitCasFacade.ts (1)
51-51: LGTM!Also applies to: 105-107, 295-295, 323-323, 341-352
test/integration/infrastructure/adapters/GitCasMaterializationStoreAdapter.integration.test.ts (1)
16-20: LGTM!Also applies to: 87-154, 164-170, 181-187, 298-348
test/unit/domain/orset/trie/TrieCursor.test.ts (1)
120-125: LGTM!test/unit/infrastructure/adapters/GitCasMaterializationStoreAdapter.test.ts (1)
17-17: LGTM!Also applies to: 77-123, 519-519
test/unit/infrastructure/adapters/GitCasMaterializationWorkspace.test.ts (1)
1-492: LGTM!test/unit/domain/WarpGraph.test.ts (1)
634-638: LGTM!test/unit/domain/WarpGraph.versionVector.test.ts (1)
137-148: LGTM!test/unit/domain/warp/hydrateCheckpointIndex.regression.test.ts (1)
42-42: LGTM!Also applies to: 61-70
test/unit/scripts/v18-graph-model-migration-command-cli.test.ts (1)
28-28: LGTM!Also applies to: 75-81, 114-114, 151-151, 187-187
test/helpers/InMemoryMaterializationStore.ts (1)
15-129: LGTM!test/integration/api/materialization.retainedResume.test.ts (1)
9-12: LGTM!Also applies to: 84-95, 115-144
test/unit/domain/orset/session/StateSession.test.ts (1)
132-361: LGTM! Thorough coverage of bounded checkpointing, terminal-flush gating on a witnessed retention, null-witness handling, prepareClose failure recovery, and bounded-compaction rejection — all consistent with theStateSessioncontract shown in context.test/unit/domain/services/controllers/MaterializeController.stateSession.test.ts (1)
107-199: LGTM! Release-on-failure/empty/legacy-cache-disabled coverage is well aligned withMaterializeController._buildResult'sfinally { workspace?.release() }and_resolveMaterializationpromotion path.Also applies to: 202-367, 404-404, 440-440
CHANGELOG.md (1)
53-92: LGTM! Changelog entries accurately describe the workspace retention/checkpoint-gating/ancestor-rebinding behavior exercised by the accompanying tests.test/unit/domain/WarpGraph.autoCheckpoint.test.ts (1)
387-392: LGTM!Also applies to: 425-430, 526-529
test/unit/domain/WarpGraph.patchCount.test.ts (1)
138-163: LGTM!test/unit/domain/services/controllers/MaterializeController.test.ts (1)
81-113: LGTM!Also applies to: 245-251
test/unit/domain/services/controllers/MaterializePatchStreamReducer.test.ts (1)
49-49: LGTM!Also applies to: 174-194
src/domain/orset/session/StateSession.ts (3)
6-73: LGTM!Also applies to: 84-122, 157-215, 223-464
216-221: 🗄️ Data Integrity & Integration
close()isn’t used on the workspace-backed path here. This flow goes throughprepareClose()andaccept(witness), so the retention-loss concern doesn’t apply.> Likely an incorrect or invalid review comment.
154-176: 🩺 Stability & AvailabilityNo concurrent flush path here. The current call sites await each
StateSessionmutation sequentially, so overlapping#flushAndRetain()calls aren’t reachable on this path.> Likely an incorrect or invalid review comment.src/domain/orset/shadow/ShadowTrieORSet.ts (1)
79-96: LGTM!src/domain/orset/trie/TrieCursor.ts (2)
594-594: Correct ancestor-rebind fix.Adding the explicit
#rebindParentBranch(args.parentPath, args.nibble)after the recursive descend fixes the previously-missing propagation of dirty markers up through intermediate branch levels when inserting into an already-existing branch chain — without it, only the immediate leaf-level parent got rebinded, leaving ancestor branches pointing at stale child OIDs after a flush.
70-70: LGTM!Also applies to: 197-216
src/ports/MaterializationStorePort.ts (1)
3-18: LGTM!src/infrastructure/adapters/GitCasMaterializationStoreAdapter.ts (1)
23-28: LGTM!Also applies to: 39-45, 90-107
src/domain/warp/RuntimeHostBoot.ts (1)
341-350: LGTM!Scoping
pageCacheper session-open (rather than sharing one instance across all opens) is a reasonable correctness-oriented choice givenPageCacheis mutable session state.src/ports/MaterializationWorkspacePort.ts (1)
1-31: LGTM!src/infrastructure/adapters/GitCasMaterializationWorkspace.ts (2)
1-102: LGTM!Also applies to: 185-372
248-268: 🗄️ Data Integrity & Integration
parseRoot()already produces a valid bundle member input.BundleMemberInputacceptsApplicationHandleInput, andApplicationHandleInputincludesBundleHandleInput, which acceptsstring.> Likely an incorrect or invalid review comment.src/domain/services/controllers/MaterializeController.ts (2)
44-68: LGTM!Also applies to: 111-122
301-465: LGTM!src/domain/services/controllers/MaterializeCoordinateStrategy.ts (1)
37-37: LGTM!Also applies to: 65-66, 145-145
src/domain/services/controllers/MaterializeLiveStrategy.ts (1)
32-64: LGTM!Also applies to: 131-131, 175-186, 259-259
src/domain/services/controllers/MaterializeSessionBridge.ts (1)
6-9: LGTM!Also applies to: 30-32, 39-107, 114-126
src/domain/services/controllers/MaterializeStrategyRuntime.ts (1)
10-13: LGTM!Also applies to: 48-81
Release Preflight
If this PR is from a |
Summary
Issue
Refs #738
Refs #734
This is a partial implementation of #738. It bounds mutated dirty pages, not total process memory. Full ORSet projection and bounded observer execution remain unfinished, and #738 remains incomplete and open.
Storage invariants
Periodic flushes cannot forget dirty pages before git-cas confirms anchored workspace retention. Terminal flushes cannot be accepted before final materialization retention. [cite:
src/domain/orset/session/StateSession.ts#198-270@960159a02404fae2dfffaa13f4ac34ab72e76f09] [cite:src/domain/orset/session/StateSession.ts#411-466@960159a02404fae2dfffaa13f4ac34ab72e76f09]Workspace checkpoint, lease renewal, promotion, and release are serialized; release waits for promotion, while renewal remains active during long final retention. [cite:
src/infrastructure/adapters/GitCasMaterializationWorkspace.ts#95-245@960159a02404fae2dfffaa13f4ac34ab72e76f09]Workspace keys are operation-unique, while final materializations remain coordinate-keyed through the existing git-cas CacheSet. [cite:
src/infrastructure/adapters/GitCasMaterializationStoreAdapter.ts#90-126@960159a02404fae2dfffaa13f4ac34ab72e76f09]The controller promotes final roots before accepting the prepared session and always releases its temporary workspace. [cite:
src/domain/services/controllers/MaterializeController.ts#264-349@960159a02404fae2dfffaa13f4ac34ab72e76f09] [cite:src/domain/services/controllers/MaterializeSessionBridge.ts#49-114@960159a02404fae2dfffaa13f4ac34ab72e76f09]Failure-unwind cleanup cannot replace the original operation failure, even if cleanup diagnostics themselves fail; successful operations still surface release failures. [cite:
src/domain/services/controllers/MaterializationWorkspaceCleanup.ts#4-24@3ecb818dba0060c61ff6bbd9fe24a3e0f7625644] [cite:src/domain/services/controllers/MaterializeController.ts#289-294@3ecb818dba0060c61ff6bbd9fe24a3e0f7625644] [cite:src/domain/services/controllers/MaterializeSessionBridge.ts#111-113@3ecb818dba0060c61ff6bbd9fe24a3e0f7625644]A recorded lease-renewal failure remains fail-closed for checkpoint/promotion, while release still removes the temporary cache root. [cite:
src/infrastructure/adapters/GitCasMaterializationWorkspace.ts#174-182@3ecb818dba0060c61ff6bbd9fe24a3e0f7625644]Live materialization captures its frontier even when the legacy snapshot cache is disabled. [cite:
src/domain/services/controllers/MaterializeLiveStrategy.ts#30-76@960159a02404fae2dfffaa13f4ac34ab72e76f09]Reopened deep trie writes propagate changed descendant handles through every ancestor. [cite:
src/domain/orset/trie/TrieCursor.ts#561-595@960159a02404fae2dfffaa13f4ac34ab72e76f09]Performance
On a fresh tiny repository, the safe path improved from approximately 7.44s to 2.39s by eliminating the redundant terminal workspace publication/removal. Existing query and traversal integrations again pass their original 10s hook limit.
Test plan
npm run test:coverage:ci: 580 files passed, 1 skipped; 7,116 tests passed, 2 skipped; 92.79% linesADR checks