Skip to content

Add one-shot v18-to-v19 retained-substrate migration#788

Merged
flyingrobots merged 22 commits into
mainfrom
v19-v18-substrate-migration
Jul 26, 2026
Merged

Add one-shot v18-to-v19 retained-substrate migration#788
flyingrobots merged 22 commits into
mainfrom
v19-v18-substrate-migration

Conversation

@flyingrobots

@flyingrobots flyingrobots commented Jul 26, 2026

Copy link
Copy Markdown
Member

Summary

  • Add a mandatory one-shot v18-to-v19 retained-substrate migrator with non-mutating rehearsal, atomic promotion, recovery refs, and idempotent resume.
  • Keep legacy readers under scripts/v18-to-v19/; the v19 runtime accepts current git-cas handles only and fails closed before retained-state access.
  • Pin git-cas@6.5.5, batch retained index pages, and verify reopen, append, bounded public reading, receipt, checkpoint, and content behavior.

Issue

Closes #786. Advances #739.

v18 stores can retain blob-backed state that v19's tree-backed boundary correctly rejects; an API-only migration can therefore strand an active writer.

Test plan

  • Pre-push firewall: lint, typecheck, policy, consumer surface, documentation topology, Markdown, source-size, storage-ownership, and 7,141 passing unit tests / 2 intentional skips.
  • Local integration suite: 110 passing tests.
  • Clean Linux Node 22.23.1 with registry @git-stunts/git-cas@6.5.5 and no configured Git identity: all 6 migration/finalization proofs pass, including the published-v18 2 MiB fixture.
  • Full worktree-pinned CLI BATS suite: 112 passing tests.
  • npm pack --dry-run: 1.29 MiB packed / 6.02 MiB unpacked; largest published file 423 KiB.
  • Tracked migration fixtures remain 16 KiB and 2.1 MiB; no repository file exceeds 10 MiB. The 1.8 GiB Think proof remains disposable /tmp evidence and is not tracked or packaged.
  • Prior disposable heavy proof: 11,708 retained commits reached verified-dry-run in 32m15.74s.

ADR checks

  • This PR does not implement ADR 2 without satisfying ADR 3
  • Persisted domain op formats are unchanged; this migrates storage envelopes, so no ADR 3 readiness issue is required
  • Wire op compatibility is unchanged; canonical-only ops remain rejected on the wire pre-cutover
  • Patch and checkpoint schema namespaces remain distinct

@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@flyingrobots, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 31 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 1a54d4a5-14bd-4645-88dd-afb193e19eae

📥 Commits

Reviewing files that changed from the base of the PR and between adde959 and f0c4061.

📒 Files selected for processing (3)
  • src/infrastructure/adapters/SubstrateVersionGate.ts
  • test/unit/infrastructure/adapters/GitCasRepositoryAdapter.test.ts
  • test/unit/infrastructure/adapters/SubstrateVersionGate.test.ts
📝 Walkthrough

Walkthrough

Adds a one-shot git-warp-v18-to-v19 migration CLI with dry-run verification, v18 patch/checkpoint translation, scratch replay, compare-and-swap promotion, recovery refs, and idempotent reruns. The v19 runtime now gates unmigrated substrates and uses current git-cas handles.

Changes

Retained-substrate migration

Layer / File(s) Summary
Migration planning and conversion
scripts/v18-to-v19/*, scripts/migrations/v17.0.0/*
Inventories retained refs, validates legacy commits and checkpoints, translates patches and retained state, rewrites writer chains, and prepares disposable verified repositories.
Promotion and runtime boundary
scripts/v18-to-v19/V18MigrationCommand.ts, scripts/v18-to-v19/V18MigrationFinalizer.ts, src/infrastructure/adapters/SubstrateVersionGate.ts, src/infrastructure/adapters/GitCasRepositoryAdapter.ts
Runs dry-run or apply flows, promotes refs atomically with recovery refs, detects concurrent movement, and blocks v19 access until the substrate marker exists.
Current storage contracts and staging
src/ports/*, src/infrastructure/adapters/*
Removes production legacy-read paths, requires current git-cas patch/checkpoint formats, simplifies materialization loading, and adds batched index-page staging.
Fixtures, documentation, and validation
fixtures/v18/*, README.md, docs/*, test/*, package.json
Adds deterministic retained-substrate fixtures, CLI documentation and packaging, migration proofs, runtime-boundary tests, and updated current-handle fixtures.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI as migrate.ts
  participant Plan as planV18ToV19Migration
  participant Scratch as prepareV18MigrationScratch
  participant Finalizer as finalizeV18Migration
  participant Git as Git refs
  CLI->>Plan: inventory repository and writer chains
  Plan->>Scratch: prepare disposable translated refs
  Scratch->>Scratch: verify reopen, read, append, and receipts
  CLI->>Finalizer: apply verified migration
  Finalizer->>Git: compare-and-swap promoted refs and recovery refs
  Finalizer->>CLI: return migration report
Loading

Possibly related PRs

Poem

A rabbit hops through refs so bright,
Turning old blobs into handles right.
Scratch paws test each writer’s trail,
Recovery carrots guard the rail.
“Already current!” we cheer with glee—
V19 now bounds the tree!

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The PR also changes performance-gating code and tests that are unrelated to the v18-to-v19 migration objectives. Split the performance-related GatePerformance, PerformanceEnvironment, and PerformanceModel changes into a separate PR.
Docstring Coverage ⚠️ Warning Docstring coverage is 15.69% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes implement the required one-shot migrator, keep legacy decoding under scripts/v18-to-v19, and add fail-closed, CAS-guarded migration and verification flows.
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding a one-shot v18-to-v19 retained-substrate migration.
Description check ✅ Passed The description matches the template with Summary, Issue, Test plan, and completed ADR checks, including same-repository issue references.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 27

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/infrastructure/adapters/GitCasStrandStoreAdapter.ts (1)

52-63: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicate "must target a publication commit" check — extract a shared helper.

readDescriptor (Lines 57-63) and retainedDescriptorParent (Lines 133-140) implement the identical readObjectType(...) !== 'commit' guard with the same StrandError message/code, just with different context payloads. Extracting a small shared helper avoids the two call sites drifting out of sync.

♻️ Proposed helper extraction
+async function requireCommitObjectType(
+  history: StrandHistory,
+  oid: string,
+  context: Record<string, unknown>,
+): Promise<void> {
+  const objectType = await history.readObjectType(oid);
+  if (objectType !== 'commit') {
+    throw new StrandError('strand descriptor ref must target a publication commit', {
+      code: 'E_STRAND_CORRUPT',
+      context: { ...context, objectType },
+    });
+  }
+}
+
   override async readDescriptor(graphName: string, strandId: string): Promise<Uint8Array | null> {
     const revision = await this.#history.readRef(buildStrandRef(graphName, strandId));
     if (revision === null) {
       return null;
     }
-    const objectType = await this.#history.readObjectType(revision);
-    if (objectType !== 'commit') {
-      throw new StrandError('strand descriptor ref must target a publication commit', {
-        code: 'E_STRAND_CORRUPT',
-        context: { graphName, strandId, revision, objectType },
-      });
-    }
+    await requireCommitObjectType(this.#history, revision, { graphName, strandId, revision });
     const node = await this.#history.getNodeInfo(revision);

Also applies to: 130-140

🤖 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 `@src/infrastructure/adapters/GitCasStrandStoreAdapter.ts` around lines 52 -
63, Extract the duplicated commit-type validation from readDescriptor and
retainedDescriptorParent into a shared private helper in
GitCasStrandStoreAdapter. Have the helper call readObjectType, throw the same
StrandError message and E_STRAND_CORRUPT code when the target is not a commit,
and preserve each caller’s graphName, strandId, revision, and objectType context
payload.
🤖 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 `@fixtures/v18/retained-substrate-medium/generate.mjs`:
- Around line 6-11: Pin the fixture generator’s `@git-stunts/plumbing` dependency
to version 3.0.3, matching the recorded version in README.md and manifest.json,
and update package-lock.json accordingly. Add a fail-fast lockfile validation
for the generate.mjs project so generation stops when `@git-stunts/plumbing`
resolves to any other version.
- Line 13: Update the repositoryPath initialization to use Node’s fileURLToPath
conversion on the repository URL instead of reading URL.pathname, then continue
passing the resulting filesystem path as cwd.

In `@README.md`:
- Around line 67-68: Pin every documented git-warp-v18-to-v19 invocation to the
explicit `@git-stunts/git-warp`@18.2.1 package version, including the rehearsal
and promotion examples in README.md lines 67-68 and
docs/migrations/v19/README.md lines 25-29 and 44-49; preserve each command’s
existing arguments and --apply behavior.

In `@scripts/migrations/v17.0.0/CheckpointMaterializationMigration.ts`:
- Around line 27-51: Update the workspace cleanup around promotion in the
migration flow so a rejection from workspace.release() cannot replace or obscure
the successfully returned MaterializationHandle. Reuse the existing
completeWithCleanup-style helper or equivalent cleanup handling, aggregating
release errors with an earlier failure and surfacing standalone cleanup failures
without losing the promoted result.

In `@scripts/v18-to-v19/migrate.ts`:
- Around line 126-130: Update the main() rejection handler to preserve nested
failure diagnostics: include Error.cause details and AggregateError.errors when
formatting the error, rather than printing only error.message. Ensure
verification and rollback failures remain visible for manual recovery while
retaining the existing stderr output and exit-code behavior.

In `@scripts/v18-to-v19/V18MigrationFinalizer.ts`:
- Around line 167-201: Replace the raw JSON.parse and Buffer decoding in
readRetainedPayloadOids with textDecode(bytes) passed to
parseV18RetainedStateCacheJson, then retain the existing collectPayloadOids
recursive walk so passthrough fields are still discovered. Import and consume
the exported parser from V18RetainedSubstrateFixtureJsonAdapter; make no direct
changes to that adapter.

In `@scripts/v18-to-v19/V18MigrationGit.ts`:
- Around line 58-61: Attach an error handler to child.stdin before the
options.input write in the migration flow, and route stdin write/stream errors
through the existing promise rejection path so they become V18MigrationGitError
rather than uncaught exceptions. Preserve the current stdin.end behavior and
ensure this covers large-input commands such as commit-tree and hash-object.

In `@scripts/v18-to-v19/V18MigrationScratch.ts`:
- Line 48: Make the scratch root configurable in the migration flow: update the
options handling and both scratch-repository creation sites around scratchPath
to use the explicit scratchRoot option when provided, falling back to tmpdir()
otherwise. Ensure the selected root is passed to mkdtemp for both repositories.

In `@scripts/v18-to-v19/V18PatchTranslator.ts`:
- Around line 158-176: Update `#rewriteOperation` to explicitly reject any
operation whose key is '_content' but whose value is not a string, instead of
returning it unchanged; preserve the existing translation for string content
values and BlobValue oid references, and fail with the same established error
behavior used by translateV18CheckpointState for this invalid legacy shape.
- Around line 178-196: Update `#contentHandles` caching in
`#translateContentReference` and translatedContentHandle to include the encrypted
mode in the lookup and storage key, such as a combined reference-and-encrypted
key. Ensure encrypted and plaintext references receive separate handles while
preserving checkpoint translation lookups.

In `@scripts/v18-to-v19/V18RetainedSubstrateFixtureRestore.ts`:
- Around line 98-101: Replace the capped gitText/runGit reads in
V18RetainedSubstrateFixtureRestore, including the calls around the retained
state-cache read and lines 124–133, with the existing v18MigrationGitText helper
from V18MigrationGit.ts. Preserve the current git arguments and parsing behavior
while routing large blob reads through the streaming implementation.

In `@src/infrastructure/adapters/CborCheckpointStoreAdapter.ts`:
- Around line 142-165: Update loadCheckpoint and the related materialization
snapshot reader flow to reuse layout.materialization returned by `#readLayout`
instead of calling read(layout.bundleHandle) and decoding the basis again. Add
or use a basis-consuming resolve method in GitCasMaterializationSnapshotReader
that performs only the remaining materialization work, then build CheckpointData
from that resolved result while preserving provenanceIndex handling.

In `@src/infrastructure/adapters/CborIndexPageBatchStager.ts`:
- Around line 34-39: Update the post-push flush condition in the batch staging
flow to use >= for both this.#batch.length and this.#batchBytes against their
respective maximums. Ensure oversized pages also flush immediately, while
preserving the existing flush behavior for batches that reach either limit.

In `@src/infrastructure/adapters/CurrentCheckpointStorageValidation.ts`:
- Around line 24-27: Update the PersistenceError message in
CurrentCheckpointStorageValidation so the checkpoint version is separated from
“unsupported storage:” by a space, preserving readable output such as “storage:
v18”; include the relevant v18→v19 migration command guidance if the nearby
unsupportedCheckpointSchema message establishes that convention.

In `@src/infrastructure/adapters/GitCasRepositoryAdapter.ts`:
- Around line 114-141: Update GitCasRepositoryAdapter.createSeekCursorStore to
call this._substrateVersionGate.ensure(timelineName) before creating or reading
the SeekCursorStore. Preserve the existing store construction behavior after the
check, ensuring unmigrated substrates are rejected before git-cas access.

In `@src/infrastructure/adapters/SubstrateVersionGate.ts`:
- Around line 29-38: Update SubstrateVersionGate.ensure so a rejected promise
from `#ensureOnce` is removed from `#checks`, allowing later calls to retry
transient failures. Preserve successful promise caching and only delete the
entry if it still references the failed check, avoiding removal of a newer
concurrent entry.

In `@src/infrastructure/adapters/TrailerCommitMessageCodecAdapter.ts`:
- Around line 243-247: Update the CheckpointCommitMessage.bundleHandle
declaration in CommitMessageCodecPort to use non-nullable BundleHandle instead
of BundleHandle | null, matching checkpointCommitMessageSchema and
encodeCheckpoint’s runtime requirement.
- Around line 331-343: The encodePatchMessage function currently hand-builds the
manifest-tree AssetHandle string, duplicating git-cas grammar. Replace this
construction with the `@git-stunts/git-cas` AssetHandle formatter/API, preserving
the existing oid, hashAlgorithm, and manifest-tree values; if no formatter is
available, centralize the prefix and format components in named constants before
constructing AssetHandle.

In `@src/ports/CommitMessageCodecPort.ts`:
- Line 17: Remove the redundant PatchStorageRoute alias and isGitCasPatchStorage
guard; use GitCasAssetPatchStorage directly throughout the affected commit
message codec flow. If runtime validation is required, change the guard’s input
type to an untrusted shape rather than the already-narrow
GitCasAssetPatchStorage type.

In `@test/helpers/FixturePatchJournal.ts`:
- Around line 86-92: Extract the duplicated fixturePatchKey normalization logic
into a shared helper module named for the concept, then remove the local
implementations and import the shared helper in
test/helpers/FixturePatchJournal.ts lines 86-92 and
test/helpers/WarpGraphMockPersistence.ts lines 158-164. Preserve the existing
GitCasAssetHandle.parse OID extraction and raw-handle fallback behavior at both
sites.

In `@test/helpers/InMemoryGitCasFacade.ts`:
- Around line 360-383: Update `#putPageBatch` to read the staged page size
directly from result.size, matching the flat StagedPage returned by `#putPage` and
existing direct property access elsewhere; preserve the batch byte-limit
validation and returned staged-page collection.

In `@test/integration/scripts/v18-to-v19-medium-fixture.test.ts`:
- Around line 93-102: Remove the duplicated readFixtureRefs helper and reuse the
existing shared ref-map helper used by v18-to-v19-command.test.ts and
v18-to-v19-scratch.test.ts. Update this test’s callers to preserve the required
null-handling behavior without maintaining a third implementation.

In `@test/unit/infrastructure/adapters/CborCheckpointStoreAdapter.test.ts`:
- Around line 483-495: Update the “rejects retired checkpoint envelopes” test
around loadCheckpoint to assert the specific retired or legacy-version error
code/message, following the file’s existing rejection-pattern conventions,
rather than accepting any thrown error.

In `@test/unit/scripts/v18-to-v19-command.test.ts`:
- Around line 153-166: Remove the duplicate readHeads helper from
v18-to-v19-command.test.ts and reuse the existing shared ref-map helper used by
the related v18-to-v19 tests. Update the test references/imports as needed while
preserving the missing-ref error behavior and frozen result contract.

In `@test/unit/scripts/v18-to-v19-scratch.test.ts`:
- Around line 245-251: Remove the duplicate collect helper from the scratch test
and reuse the existing shared collect implementation from
v18-to-v19-writer-chain.test.ts, updating imports or references as needed while
preserving the current async-byte aggregation behavior.
- Around line 231-243: Remove the duplicate readHeads helper from this test and
reuse the consolidated ref-map helper already defined in
v18-to-v19-command.test.ts, preserving the existing ref-to-commit mapping
behavior and callers.

In `@test/unit/scripts/v18-to-v19-writer-chain.test.ts`:
- Around line 132-138: Remove the duplicate collect helper from
v18-to-v19-writer-chain.test.ts and reuse the existing shared collect
implementation from v18-to-v19-scratch.test.ts, preserving the current
byte-aggregation behavior.

---

Outside diff comments:
In `@src/infrastructure/adapters/GitCasStrandStoreAdapter.ts`:
- Around line 52-63: Extract the duplicated commit-type validation from
readDescriptor and retainedDescriptorParent into a shared private helper in
GitCasStrandStoreAdapter. Have the helper call readObjectType, throw the same
StrandError message and E_STRAND_CORRUPT code when the target is not a commit,
and preserve each caller’s graphName, strandId, revision, and objectType context
payload.
🪄 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 Plus

Run ID: 3c5dd943-ede0-48bc-96e1-f522fc118e12

📥 Commits

Reviewing files that changed from the base of the PR and between b97d86e and 4e29563.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (104)
  • CHANGELOG.md
  • README.md
  • docs/migrations/v19/README.md
  • docs/topics/reference.md
  • fixtures/v18/retained-substrate-golden/README.md
  • fixtures/v18/retained-substrate-golden/manifest.json
  • fixtures/v18/retained-substrate-golden/v18-retained-substrate.bundle
  • fixtures/v18/retained-substrate-medium/README.md
  • fixtures/v18/retained-substrate-medium/generate.mjs
  • fixtures/v18/retained-substrate-medium/manifest.json
  • fixtures/v18/retained-substrate-medium/v18-medium-retained-substrate.bundle
  • package.json
  • scripts/migrations/v17.0.0/CheckpointMaterializationMigration.ts
  • scripts/migrations/v17.0.0/LegacyCheckpointArtifactAdapter.ts
  • scripts/migrations/v17.0.0/LegacyCheckpointCommitMessageCodec.ts
  • scripts/migrations/v17.0.0/LegacyCheckpointFormat.ts
  • scripts/migrations/v17.0.0/LegacyCheckpointStorageReader.ts
  • scripts/migrations/v17.0.0/SubstrateMigrationCompatibilityPolicy.ts
  • scripts/migrations/v17.0.0/checkpoint-schema-upgrade.ts
  • scripts/migrations/v17.0.0/openCheckpointMigrationStore.ts
  • scripts/v18-to-v19/README.md
  • scripts/v18-to-v19/V18CheckpointMigrationCodec.ts
  • scripts/v18-to-v19/V18CheckpointSeed.ts
  • scripts/v18-to-v19/V18MigrationCommand.ts
  • scripts/v18-to-v19/V18MigrationFinalizer.ts
  • scripts/v18-to-v19/V18MigrationGit.ts
  • scripts/v18-to-v19/V18MigrationPlan.ts
  • scripts/v18-to-v19/V18MigrationProgress.ts
  • scripts/v18-to-v19/V18MigrationScratch.ts
  • scripts/v18-to-v19/V18MigrationScratchGraph.ts
  • scripts/v18-to-v19/V18PatchCommit.ts
  • scripts/v18-to-v19/V18PatchTranslator.ts
  • scripts/v18-to-v19/V18RetainedSubstrateFixtureRestore.ts
  • scripts/v18-to-v19/V18WriterChainRewriter.ts
  • scripts/v18-to-v19/adapters/V18RetainedSubstrateFixtureJsonAdapter.ts
  • scripts/v18-to-v19/migrate.ts
  • scripts/v18.0.0/migrations/graph-model/GraphModelMigrationSourceInventoryCollector.ts
  • scripts/v18.0.0/migrations/graph-model/V17PatchCommitMessageDecoder.ts
  • src/domain/services/codec/MessageCodecInternal.ts
  • src/domain/utils/RefLayout.ts
  • src/infrastructure/adapters/CborCheckpointStoreAdapter.ts
  • src/infrastructure/adapters/CborIndexPageBatchStager.ts
  • src/infrastructure/adapters/CborIndexShardWriter.ts
  • src/infrastructure/adapters/CborPatchJournalAdapter.ts
  • src/infrastructure/adapters/CheckpointCommitMessageBundleCodec.ts
  • src/infrastructure/adapters/CheckpointStorageFormatClassifier.ts
  • src/infrastructure/adapters/CurrentCheckpointStorageValidation.ts
  • src/infrastructure/adapters/GitCasAssetStorageAdapter.ts
  • src/infrastructure/adapters/GitCasAuditLogAdapter.ts
  • src/infrastructure/adapters/GitCasMaterializationSnapshotReader.ts
  • src/infrastructure/adapters/GitCasMaterializationWorkspace.ts
  • src/infrastructure/adapters/GitCasMaterializationWorkspaceValidation.ts
  • src/infrastructure/adapters/GitCasRepositoryAdapter.ts
  • src/infrastructure/adapters/GitCasStrandStoreAdapter.ts
  • src/infrastructure/adapters/GitTrustChainAdapter.ts
  • src/infrastructure/adapters/LegacyAnchorMessageDetectorAdapter.ts
  • src/infrastructure/adapters/SubstrateCompatibilityPolicy.ts
  • src/infrastructure/adapters/SubstrateVersionGate.ts
  • src/infrastructure/adapters/TrailerCommitMessageCodecAdapter.ts
  • src/ports/ArtifactStagingPort.ts
  • src/ports/CommitMessageCodecPort.ts
  • src/ports/PatchJournalPort.ts
  • test/benchmark/detachedReadBenchmark.fixture.ts
  • test/helpers/FixturePatchJournal.ts
  • test/helpers/InMemoryGitCasFacade.ts
  • test/helpers/MemoryRuntimeStorageAdapter.ts
  • test/helpers/WarpGraphMockPersistence.ts
  • test/integration/scripts/v18-to-v19-medium-fixture.test.ts
  • test/unit/domain/WarpGraph.checkpoint.test.ts
  • test/unit/domain/WarpGraph.patchesFor.test.ts
  • test/unit/domain/WarpGraph.test.ts
  • test/unit/domain/WarpGraph.versionVector.test.ts
  • test/unit/domain/services/MessageCodecModules.test.ts
  • test/unit/domain/services/WarpMessageCodec.test.ts
  • test/unit/domain/services/WarpMessageCodec.v3.test.ts
  • test/unit/domain/services/WormholeService.test.ts
  • test/unit/domain/services/v3-compatibility.test.ts
  • test/unit/domain/warp/RuntimeHostPortResolvers.test.ts
  • test/unit/infrastructure/CborIndexStoreAdapter.test.ts
  • test/unit/infrastructure/adapters/CborCheckpointStoreAdapter.test.ts
  • test/unit/infrastructure/adapters/CborIndexPageBatchStager.test.ts
  • test/unit/infrastructure/adapters/CborPatchJournalAdapter.test.ts
  • test/unit/infrastructure/adapters/GitCasAssetStorageAdapter.test.ts
  • test/unit/infrastructure/adapters/GitCasAuditLogAdapter.test.ts
  • test/unit/infrastructure/adapters/GitCasIntentStoreAdapter.test.ts
  • test/unit/infrastructure/adapters/GitCasMaterializationStoreAdapter.lifecycle.test.ts
  • test/unit/infrastructure/adapters/GitCasMaterializationWorkspace.test.ts
  • test/unit/infrastructure/adapters/GitCasMaterializationWorkspaceOwner.test.ts
  • test/unit/infrastructure/adapters/GitCasRepositoryAdapter.test.ts
  • test/unit/infrastructure/adapters/GitCasStrandStoreAdapter.test.ts
  • test/unit/infrastructure/adapters/GitTrustChainAdapter.test.ts
  • test/unit/infrastructure/adapters/SubstrateVersionGate.test.ts
  • test/unit/infrastructure/adapters/TrailerCommitMessageCodecAdapter.test.ts
  • test/unit/scripts/checkpoint-schema-upgrade.test.ts
  • test/unit/scripts/release-artifact-command.test.ts
  • test/unit/scripts/v18-checkpoint-migration-codec.test.ts
  • test/unit/scripts/v18-checkpoint-seed.test.ts
  • test/unit/scripts/v18-migration-progress.test.ts
  • test/unit/scripts/v18-to-v19-command.test.ts
  • test/unit/scripts/v18-to-v19-finalization.test.ts
  • test/unit/scripts/v18-to-v19-retained-substrate-fixture.test.ts
  • test/unit/scripts/v18-to-v19-scratch.test.ts
  • test/unit/scripts/v18-to-v19-writer-chain.test.ts
  • test/unit/scripts/v18-v17-public-read-legacy-reading-builder.test.ts
💤 Files with no reviewable changes (8)
  • src/infrastructure/adapters/CheckpointStorageFormatClassifier.ts
  • scripts/migrations/v17.0.0/SubstrateMigrationCompatibilityPolicy.ts
  • src/infrastructure/adapters/LegacyAnchorMessageDetectorAdapter.ts
  • test/unit/domain/services/v3-compatibility.test.ts
  • src/infrastructure/adapters/SubstrateCompatibilityPolicy.ts
  • src/infrastructure/adapters/CheckpointCommitMessageBundleCodec.ts
  • src/domain/services/codec/MessageCodecInternal.ts
  • src/infrastructure/adapters/CborPatchJournalAdapter.ts
👮 Files not reviewed due to content moderation or server errors (1)
  • fixtures/v18/retained-substrate-medium/v18-medium-retained-substrate.bundle
📜 Review details
⏰ Context from checks skipped due to timeout. (5)
  • GitHub Check: type-firewall
  • GitHub Check: coverage-threshold
  • GitHub Check: test-node (22)
  • GitHub Check: v19 base/head performance
  • GitHub Check: preflight
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{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:

  • test/unit/scripts/v18-migration-progress.test.ts
  • scripts/migrations/v17.0.0/LegacyCheckpointFormat.ts
  • scripts/v18-to-v19/V18MigrationScratchGraph.ts
  • test/unit/scripts/v18-checkpoint-seed.test.ts
  • test/unit/infrastructure/adapters/GitCasRepositoryAdapter.test.ts
  • test/unit/infrastructure/adapters/GitCasIntentStoreAdapter.test.ts
  • test/unit/scripts/release-artifact-command.test.ts
  • src/infrastructure/adapters/CborIndexPageBatchStager.ts
  • scripts/migrations/v17.0.0/LegacyCheckpointCommitMessageCodec.ts
  • test/unit/domain/WarpGraph.checkpoint.test.ts
  • test/unit/scripts/v18-to-v19-retained-substrate-fixture.test.ts
  • test/unit/infrastructure/adapters/CborIndexPageBatchStager.test.ts
  • src/domain/utils/RefLayout.ts
  • test/unit/scripts/v18-checkpoint-migration-codec.test.ts
  • scripts/migrations/v17.0.0/LegacyCheckpointArtifactAdapter.ts
  • test/unit/infrastructure/adapters/GitCasMaterializationWorkspaceOwner.test.ts
  • test/unit/scripts/v18-v17-public-read-legacy-reading-builder.test.ts
  • test/unit/domain/warp/RuntimeHostPortResolvers.test.ts
  • scripts/v18-to-v19/V18MigrationProgress.ts
  • test/unit/domain/WarpGraph.patchesFor.test.ts
  • src/infrastructure/adapters/SubstrateVersionGate.ts
  • src/ports/PatchJournalPort.ts
  • test/unit/infrastructure/adapters/GitCasMaterializationStoreAdapter.lifecycle.test.ts
  • scripts/v18.0.0/migrations/graph-model/GraphModelMigrationSourceInventoryCollector.ts
  • test/unit/domain/WarpGraph.versionVector.test.ts
  • test/integration/scripts/v18-to-v19-medium-fixture.test.ts
  • test/unit/infrastructure/CborIndexStoreAdapter.test.ts
  • scripts/v18.0.0/migrations/graph-model/V17PatchCommitMessageDecoder.ts
  • scripts/v18-to-v19/V18CheckpointMigrationCodec.ts
  • test/helpers/WarpGraphMockPersistence.ts
  • test/unit/domain/services/MessageCodecModules.test.ts
  • test/unit/scripts/v18-to-v19-writer-chain.test.ts
  • test/unit/domain/services/WarpMessageCodec.v3.test.ts
  • scripts/v18-to-v19/V18MigrationCommand.ts
  • test/unit/scripts/v18-to-v19-finalization.test.ts
  • src/infrastructure/adapters/GitCasMaterializationWorkspaceValidation.ts
  • test/unit/infrastructure/adapters/GitCasStrandStoreAdapter.test.ts
  • scripts/v18-to-v19/V18MigrationGit.ts
  • test/unit/domain/services/WormholeService.test.ts
  • src/infrastructure/adapters/CurrentCheckpointStorageValidation.ts
  • test/helpers/FixturePatchJournal.ts
  • scripts/v18-to-v19/migrate.ts
  • scripts/migrations/v17.0.0/openCheckpointMigrationStore.ts
  • test/unit/scripts/v18-to-v19-command.test.ts
  • test/unit/infrastructure/adapters/GitCasMaterializationWorkspace.test.ts
  • scripts/migrations/v17.0.0/CheckpointMaterializationMigration.ts
  • test/benchmark/detachedReadBenchmark.fixture.ts
  • test/unit/infrastructure/adapters/GitTrustChainAdapter.test.ts
  • test/helpers/InMemoryGitCasFacade.ts
  • test/unit/infrastructure/adapters/CborPatchJournalAdapter.test.ts
  • scripts/v18-to-v19/V18WriterChainRewriter.ts
  • scripts/v18-to-v19/V18RetainedSubstrateFixtureRestore.ts
  • src/infrastructure/adapters/GitCasRepositoryAdapter.ts
  • test/unit/domain/WarpGraph.test.ts
  • scripts/v18-to-v19/V18MigrationFinalizer.ts
  • src/infrastructure/adapters/GitCasAssetStorageAdapter.ts
  • scripts/v18-to-v19/V18MigrationScratch.ts
  • scripts/v18-to-v19/V18PatchCommit.ts
  • src/infrastructure/adapters/GitCasMaterializationWorkspace.ts
  • scripts/v18-to-v19/V18MigrationPlan.ts
  • scripts/v18-to-v19/V18PatchTranslator.ts
  • test/unit/infrastructure/adapters/SubstrateVersionGate.test.ts
  • src/ports/ArtifactStagingPort.ts
  • test/helpers/MemoryRuntimeStorageAdapter.ts
  • src/ports/CommitMessageCodecPort.ts
  • scripts/v18-to-v19/adapters/V18RetainedSubstrateFixtureJsonAdapter.ts
  • src/infrastructure/adapters/CborIndexShardWriter.ts
  • test/unit/infrastructure/adapters/GitCasAssetStorageAdapter.test.ts
  • src/infrastructure/adapters/GitCasMaterializationSnapshotReader.ts
  • test/unit/infrastructure/adapters/CborCheckpointStoreAdapter.test.ts
  • test/unit/infrastructure/adapters/TrailerCommitMessageCodecAdapter.test.ts
  • test/unit/domain/services/WarpMessageCodec.test.ts
  • scripts/v18-to-v19/V18CheckpointSeed.ts
  • scripts/migrations/v17.0.0/checkpoint-schema-upgrade.ts
  • src/infrastructure/adapters/GitCasStrandStoreAdapter.ts
  • scripts/migrations/v17.0.0/LegacyCheckpointStorageReader.ts
  • test/unit/scripts/checkpoint-schema-upgrade.test.ts
  • test/unit/scripts/v18-to-v19-scratch.test.ts
  • test/unit/infrastructure/adapters/GitCasAuditLogAdapter.test.ts
  • src/infrastructure/adapters/CborCheckpointStoreAdapter.ts
  • src/infrastructure/adapters/GitCasAuditLogAdapter.ts
  • src/infrastructure/adapters/GitTrustChainAdapter.ts
  • src/infrastructure/adapters/TrailerCommitMessageCodecAdapter.ts
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/infrastructure/adapters/CborIndexPageBatchStager.ts
  • src/domain/utils/RefLayout.ts
  • src/infrastructure/adapters/SubstrateVersionGate.ts
  • src/ports/PatchJournalPort.ts
  • src/infrastructure/adapters/GitCasMaterializationWorkspaceValidation.ts
  • src/infrastructure/adapters/CurrentCheckpointStorageValidation.ts
  • src/infrastructure/adapters/GitCasRepositoryAdapter.ts
  • src/infrastructure/adapters/GitCasAssetStorageAdapter.ts
  • src/infrastructure/adapters/GitCasMaterializationWorkspace.ts
  • src/ports/ArtifactStagingPort.ts
  • src/ports/CommitMessageCodecPort.ts
  • src/infrastructure/adapters/CborIndexShardWriter.ts
  • src/infrastructure/adapters/GitCasMaterializationSnapshotReader.ts
  • src/infrastructure/adapters/GitCasStrandStoreAdapter.ts
  • src/infrastructure/adapters/CborCheckpointStoreAdapter.ts
  • src/infrastructure/adapters/GitCasAuditLogAdapter.ts
  • src/infrastructure/adapters/GitTrustChainAdapter.ts
  • src/infrastructure/adapters/TrailerCommitMessageCodecAdapter.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/utils/RefLayout.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/utils/RefLayout.ts
src/ports/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

In src/ports/**, do not import Node built-ins or src/infrastructure/**; ports must stay abstract and depend only on boundary-safe types.

Files:

  • src/ports/PatchJournalPort.ts
  • src/ports/ArtifactStagingPort.ts
  • src/ports/CommitMessageCodecPort.ts
🧠 Learnings (2)
📚 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
📚 Learning: 2026-03-04T12:08:30.347Z
Learnt from: flyingrobots
Repo: git-stunts/git-warp PR: 63
File: package.json:126-126
Timestamp: 2026-03-04T12:08:30.347Z
Learning: Vitest 4 removes vite-node as a dependency and rewrites its pool system. Do not flag the absence of vite-node in package.json or lockfiles as an error for Vitest 4 projects. Use this as a general guideline: if a project uses Vitest 4, missing vite-node is expected and correct; only flag issues if there is evidence the project is not using Vitest 4 or if vite-node is explicitly required by the project.

Applied to files:

  • package.json
🪛 ast-grep (0.44.1)
test/unit/scripts/release-artifact-command.test.ts

[warning] 4: 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 {
spawnSync,
type SpawnSyncOptionsWithStringEncoding,
type SpawnSyncReturns,
} from 'node:child_process';
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(detect-child-process-typescript)

scripts/v18.0.0/migrations/graph-model/GraphModelMigrationSourceInventoryCollector.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)

test/integration/scripts/v18-to-v19-medium-fixture.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 { spawn } from 'node:child_process';
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(detect-child-process-typescript)

scripts/v18-to-v19/V18MigrationGit.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 { spawn } from 'node:child_process';
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(detect-child-process-typescript)

scripts/v18-to-v19/V18RetainedSubstrateFixtureRestore.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)

🪛 LanguageTool
fixtures/v18/retained-substrate-medium/README.md

[style] ~16-~16: This phrase is redundant. Consider writing “same”.
Context: ...h the published v18 public API with the same exact registry lock as the small golden fixtu...

(SAME_EXACT)

🪛 OpenGrep (1.25.0)
scripts/v18-to-v19/V18PatchCommit.ts

[ERROR] 142-142: Dynamic command passed to child_process.exec/execSync. Use child_process.execFile or spawn with an argument array instead.

(coderabbit.command-injection.exec-js)

scripts/v18-to-v19/adapters/V18RetainedSubstrateFixtureJsonAdapter.ts

[WARNING] 43-43: Sequelize.literal() with dynamic input can lead to SQL injection. Use parameterized queries or model methods instead.

(coderabbit.sql-injection.sequelize-literal)


[WARNING] 71-71: Sequelize.literal() with dynamic input can lead to SQL injection. Use parameterized queries or model methods instead.

(coderabbit.sql-injection.sequelize-literal)

src/infrastructure/adapters/TrailerCommitMessageCodecAdapter.ts

[WARNING] 110-110: Sequelize.literal() with dynamic input can lead to SQL injection. Use parameterized queries or model methods instead.

(coderabbit.sql-injection.sequelize-literal)

🔇 Additional comments (98)
CHANGELOG.md (1)

25-31: LGTM!

docs/topics/reference.md (1)

13-13: LGTM!

fixtures/v18/retained-substrate-golden/README.md (1)

1-55: LGTM!

fixtures/v18/retained-substrate-golden/manifest.json (1)

1-94: LGTM!

fixtures/v18/retained-substrate-golden/v18-retained-substrate.bundle (1)

1-28: LGTM!

fixtures/v18/retained-substrate-medium/README.md (1)

1-40: LGTM!

fixtures/v18/retained-substrate-medium/manifest.json (1)

1-80: LGTM!

package.json (1)

24-25: LGTM!

Also applies to: 97-97, 126-126

scripts/migrations/v17.0.0/LegacyCheckpointArtifactAdapter.ts (1)

1-5: LGTM!

scripts/migrations/v17.0.0/LegacyCheckpointCommitMessageCodec.ts (1)

1-67: LGTM!

scripts/migrations/v17.0.0/LegacyCheckpointFormat.ts (1)

1-1: LGTM!

scripts/migrations/v17.0.0/LegacyCheckpointStorageReader.ts (2)

1-149: LGTM!


186-198: LGTM!

scripts/migrations/v17.0.0/checkpoint-schema-upgrade.ts (1)

28-30: LGTM!

Also applies to: 96-101, 131-132

scripts/v18-to-v19/README.md (1)

1-74: LGTM!

scripts/v18-to-v19/V18MigrationCommand.ts (1)

1-141: LGTM!

scripts/v18-to-v19/V18MigrationFinalizer.ts (1)

1-166: LGTM!

Also applies to: 203-277

scripts/v18-to-v19/V18MigrationPlan.ts (1)

1-251: LGTM!

scripts/v18-to-v19/adapters/V18RetainedSubstrateFixtureJsonAdapter.ts (1)

1-88: LGTM!

scripts/v18-to-v19/migrate.ts (1)

1-125: LGTM!

scripts/migrations/v17.0.0/openCheckpointMigrationStore.ts (1)

6-12: LGTM!

Also applies to: 30-30

scripts/v18-to-v19/V18CheckpointMigrationCodec.ts (1)

11-51: LGTM!

scripts/v18-to-v19/V18CheckpointSeed.ts (1)

38-131: LGTM!

Also applies to: 133-219

scripts/v18-to-v19/V18MigrationGit.ts (1)

1-1: LGTM!

Also applies to: 30-45

scripts/v18-to-v19/V18MigrationProgress.ts (1)

1-34: LGTM!

scripts/v18-to-v19/V18MigrationScratch.ts (1)

40-119: LGTM!

Also applies to: 121-141, 143-219, 221-298

scripts/v18-to-v19/V18MigrationScratchGraph.ts (1)

10-50: LGTM!

scripts/v18-to-v19/V18PatchCommit.ts (2)

5-5: LGTM!

Also applies to: 39-49, 51-104, 106-139, 141-160, 162-184, 198-203


186-196: 🎯 Functional Correctness

Confirm retained v18 eg-lamport is strictly positive.

requirePositiveInteger rejects 0, so any retained v18 patch tagged with eg-lamport: 0 will fail this mandatory migration. Check the frozen v18 release path; if that value is possible, allow non-negative integers for eg-lamport while keeping eg-schema positive.

scripts/v18-to-v19/V18PatchTranslator.ts (2)

31-61: LGTM!

Also applies to: 63-101, 103-136, 225-240, 242-272


69-72: 🩺 Stability & Availability

No change needed: hydration constructs a new Patch instead of mutating the record.

hydrateDecodedPatch reads fields from the decoded object and passes them into the Patch constructor; it does not assign onto the frozen decoded patch or its ops, so the frozen input does not cause a runtime TypeError in hydration.

			> Likely an incorrect or invalid review comment.
scripts/v18-to-v19/V18RetainedSubstrateFixtureRestore.ts (1)

27-54: LGTM!

Also applies to: 56-66, 68-91, 93-115, 117-122

scripts/v18-to-v19/V18WriterChainRewriter.ts (1)

24-100: LGTM!

Also applies to: 102-112, 114-133, 135-164

test/integration/scripts/v18-to-v19-medium-fixture.test.ts (1)

15-92: LGTM!

Also applies to: 104-121

test/unit/domain/WarpGraph.checkpoint.test.ts (1)

448-451: LGTM!

test/unit/domain/WarpGraph.patchesFor.test.ts (1)

467-498: LGTM!

test/unit/domain/WarpGraph.test.ts (1)

440-442: LGTM!

Also applies to: 738-747

test/unit/domain/WarpGraph.versionVector.test.ts (1)

359-365: LGTM!

test/unit/scripts/v18-migration-progress.test.ts (1)

1-13: LGTM!

test/unit/scripts/v18-to-v19-command.test.ts (1)

33-150: LGTM!

test/unit/scripts/v18-to-v19-finalization.test.ts (1)

1-138: LGTM!

test/unit/scripts/v18-to-v19-retained-substrate-fixture.test.ts (1)

1-76: LGTM!

test/unit/scripts/v18-to-v19-scratch.test.ts (1)

46-208: LGTM!

test/unit/scripts/v18-to-v19-writer-chain.test.ts (1)

1-107: LGTM!

test/unit/scripts/v18-v17-public-read-legacy-reading-builder.test.ts (1)

52-52: LGTM!

test/unit/domain/services/MessageCodecModules.test.ts (1)

68-73: LGTM!

Also applies to: 85-87

test/unit/domain/services/WarpMessageCodec.test.ts (1)

15-16: LGTM!

Also applies to: 67-92, 130-130, 139-139, 166-167, 202-216

test/unit/domain/services/WarpMessageCodec.v3.test.ts (1)

153-155: LGTM!

Also applies to: 192-194, 214-216, 260-283, 316-316

test/unit/domain/services/WormholeService.test.ts (1)

284-284: LGTM!

Also applies to: 351-353

test/unit/domain/warp/RuntimeHostPortResolvers.test.ts (1)

4-4: LGTM!

Also applies to: 32-36

test/unit/infrastructure/CborIndexStoreAdapter.test.ts (1)

78-78: LGTM!

Also applies to: 310-311, 326-333

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

15-17: LGTM!

Also applies to: 43-50, 74-88, 198-212, 257-275, 567-569

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

1-64: LGTM!

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

1-1: LGTM!

Also applies to: 13-20, 29-30, 174-175

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

3-26: LGTM!

Also applies to: 83-110, 111-111

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

8-28: LGTM!

Also applies to: 71-85, 189-189

test/unit/scripts/v18-checkpoint-seed.test.ts (1)

1-60: LGTM!

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

17-17: LGTM!

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

104-106: LGTM!

test/unit/infrastructure/adapters/GitCasMaterializationWorkspace.test.ts (4)

20-40: LGTM!


57-81: LGTM!


155-169: LGTM!


42-55: 🎯 Functional Correctness

No change needed.

The empty page-batch assertion matches how InMemoryGitCasFacade represents an opened-but-unused workspace: no root checkpoint has run, so readWorkspaceRoots() is [].

			> Likely an incorrect or invalid review comment.
test/unit/infrastructure/adapters/GitCasMaterializationWorkspaceOwner.test.ts (1)

100-108: LGTM!

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

154-159: LGTM!

test/unit/infrastructure/adapters/GitCasStrandStoreAdapter.test.ts (3)

12-23: LGTM!


74-82: LGTM!


108-118: LGTM!

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

231-243: LGTM!

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

1-107: LGTM!

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

34-42: LGTM!

Also applies to: 66-66, 78-132, 145-164, 175-175, 194-198, 209-209

test/unit/scripts/checkpoint-schema-upgrade.test.ts (1)

36-41: LGTM!

Also applies to: 90-94, 380-380, 386-394, 459-464, 517-522

test/unit/scripts/v18-checkpoint-migration-codec.test.ts (1)

1-26: LGTM!

test/unit/scripts/release-artifact-command.test.ts (1)

42-45: 🎯 Functional Correctness

No change needed.

packEntries() consumes runNpmPackDryRun() as plain text, and the surrounding tests use npm notice ... headers before entries, matching --no-json output.

scripts/v18.0.0/migrations/graph-model/GraphModelMigrationSourceInventoryCollector.ts (1)

18-18: LGTM!

Also applies to: 113-117

scripts/v18.0.0/migrations/graph-model/V17PatchCommitMessageDecoder.ts (1)

1-49: LGTM!

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

11-14: LGTM!

Also applies to: 36-43, 63-120

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

37-52: LGTM!

Also applies to: 97-101, 104-118, 120-146

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

19-28: LGTM!

Also applies to: 86-116

test/helpers/InMemoryGitCasFacade.ts (1)

45-46: LGTM!

Also applies to: 84-84, 95-95, 111-115, 135-135, 176-179, 257-269

test/helpers/MemoryRuntimeStorageAdapter.ts (1)

37-51: LGTM!

Also applies to: 111-115, 133-134

test/benchmark/detachedReadBenchmark.fixture.ts (1)

3-3: 🎯 Functional Correctness

No change needed.

InMemoryBlobStorageAdapter already exposes store(content, options?), so simulatePatchCommit(assetStorage.store(patchBuffer)) is supported.

src/domain/utils/RefLayout.ts (1)

353-360: LGTM!

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

7-32: LGTM!

Also applies to: 52-52, 66-73, 92-93

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

1-43: LGTM!

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

188-198: LGTM!

Also applies to: 248-255

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

5-5: LGTM!

Also applies to: 26-26, 61-66, 109-109, 135-142, 159-162, 197-199, 228-229, 306-306

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

40-87: LGTM on the migration-detection and marker-verification logic itself.

src/ports/ArtifactStagingPort.ts (1)

9-27: LGTM!

Also applies to: 38-39

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

44-53: LGTM!

Also applies to: 65-136, 167-259

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

1-33: LGTM!

Also applies to: 40-94

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

1-23: LGTM!

Also applies to: 28-82

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

44-48: LGTM!

Also applies to: 67-102

src/infrastructure/adapters/TrailerCommitMessageCodecAdapter.ts (2)

100-112: Note: the static-analysis hint on Line 110 flagging Sequelize.literal() SQL injection is a false positive; this is z.literal from zod.

LGTM!

Source: Linters/SAST tools


15-15: LGTM!

Also applies to: 32-33, 85-90, 120-135, 161-185, 196-241, 256-282, 361-363

src/ports/PatchJournalPort.ts (1)

32-32: LGTM!

test/helpers/FixturePatchJournal.ts (1)

1-1: LGTM!

Also applies to: 43-43

test/helpers/WarpGraphMockPersistence.ts (1)

1-1: LGTM!

Also applies to: 149-156

Comment thread fixtures/v18/retained-substrate-medium/generate.mjs
Comment thread fixtures/v18/retained-substrate-medium/generate.mjs Outdated
Comment thread README.md Outdated
Comment thread scripts/migrations/v17.0.0/CheckpointMaterializationMigration.ts
Comment thread scripts/v18-to-v19/migrate.ts
Comment thread test/unit/scripts/v18-to-v19-command.test.ts Outdated
Comment thread test/unit/scripts/v18-to-v19-scratch.test.ts Outdated
Comment thread test/unit/scripts/v18-to-v19-scratch.test.ts Outdated
Comment thread test/unit/scripts/v18-to-v19-writer-chain.test.ts Outdated
@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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/infrastructure/adapters/CurrentCheckpointStorageValidation.ts (1)

23-36: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Restore the missing bundle-handle guard.

A current-version checkpoint with metadata.bundleHandle === null now passes null to readBasis; Line 89 of GitCasMaterializationSnapshotReader.ts then calls bundle.toString(), producing an untyped runtime failure instead of E_CHECKPOINT_MISSING_BUNDLE_HANDLE. Preserve the explicit persisted-metadata validation before returning.

🐛 Proposed fix
   if (metadata.checkpointVersion !== CHECKPOINT_STORAGE_FORMAT) {
     throw new PersistenceError(
       `Checkpoint ${checkpointSha} uses unsupported storage: `
         + `${metadata.checkpointVersion ?? '(unspecified)'}`,
       'E_CHECKPOINT_UNSUPPORTED_STORAGE',
       {
         context: {
           checkpointSha,
           storageVersion: metadata.checkpointVersion,
         },
       },
     );
   }
+  if (metadata.bundleHandle === null) {
+    throw new PersistenceError(
+      `Checkpoint ${checkpointSha} is missing its bundle handle`,
+      'E_CHECKPOINT_MISSING_BUNDLE_HANDLE',
+      { context: { checkpointSha } },
+    );
+  }
   return metadata.bundleHandle;
🤖 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 `@src/infrastructure/adapters/CurrentCheckpointStorageValidation.ts` around
lines 23 - 36, Update the validation flow before returning metadata.bundleHandle
to explicitly reject a null bundle handle with PersistenceError code
E_CHECKPOINT_MISSING_BUNDLE_HANDLE. Keep the existing checkpoint-version
validation and persisted-metadata context intact, and only return the handle
after both validations pass.
test/unit/infrastructure/adapters/CborCheckpointStoreAdapter.test.ts (1)

545-546: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Retain coverage for unsupported checkpoint storage.

The production path still rejects checkpointVersion !== CHECKPOINT_STORAGE_FORMAT, but removing the parameterized test leaves that compatibility gate without direct coverage. Restore or replace it with an assertion for E_CHECKPOINT_UNSUPPORTED_STORAGE; also keep a separate case for a missing bundle handle.

🤖 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/unit/infrastructure/adapters/CborCheckpointStoreAdapter.test.ts` around
lines 545 - 546, Restore or replace the parameterized coverage around the
checkpoint storage version guard so an unsupported checkpoint version asserts
E_CHECKPOINT_UNSUPPORTED_STORAGE. Keep a separate test case covering a missing
bundle handle, while preserving the existing causal-anchor coverage in the
checkpoint publication tests.
🤖 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/infrastructure/adapters/SubstrateVersionGate.ts`:
- Around line 87-90: Update the migration-required obstruction in
SubstrateVersionGate to name the recovery command explicitly, including
git-warp-v18-to-v19 (or the exact installed command) in the user-facing message
and/or context. Preserve the existing graphName details and
E_SUBSTRATE_MIGRATION_REQUIRED error code.

---

Outside diff comments:
In `@src/infrastructure/adapters/CurrentCheckpointStorageValidation.ts`:
- Around line 23-36: Update the validation flow before returning
metadata.bundleHandle to explicitly reject a null bundle handle with
PersistenceError code E_CHECKPOINT_MISSING_BUNDLE_HANDLE. Keep the existing
checkpoint-version validation and persisted-metadata context intact, and only
return the handle after both validations pass.

In `@test/unit/infrastructure/adapters/CborCheckpointStoreAdapter.test.ts`:
- Around line 545-546: Restore or replace the parameterized coverage around the
checkpoint storage version guard so an unsupported checkpoint version asserts
E_CHECKPOINT_UNSUPPORTED_STORAGE. Keep a separate test case covering a missing
bundle handle, while preserving the existing causal-anchor coverage in the
checkpoint publication tests.
🪄 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 Plus

Run ID: 123b73d6-fa00-4b5e-b33a-e02bc6b06fa1

📥 Commits

Reviewing files that changed from the base of the PR and between 4e29563 and adde959.

⛔ Files ignored due to path filters (2)
  • fixtures/v18/retained-substrate-medium/package-lock.json is excluded by !**/package-lock.json
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (53)
  • README.md
  • bin/cli/commands/info.ts
  • bin/cli/commands/materialize.ts
  • bin/cli/shared.ts
  • docs/migrations/v19/README.md
  • fixtures/v18/retained-substrate-medium/README.md
  • fixtures/v18/retained-substrate-medium/generate.mjs
  • fixtures/v18/retained-substrate-medium/package.json
  • package.json
  • scripts/migrations/v17.0.0/CheckpointMaterializationMigration.ts
  • scripts/migrations/v17.0.0/LegacyCheckpointCommitMessageCodec.ts
  • scripts/migrations/v17.0.0/LegacyCheckpointStorageReader.ts
  • scripts/performance/GatePerformance.ts
  • scripts/performance/PerformanceEnvironment.ts
  • scripts/v18-to-v19/README.md
  • scripts/v18-to-v19/V18MigrationCommand.ts
  • scripts/v18-to-v19/V18MigrationFinalizer.ts
  • scripts/v18-to-v19/V18MigrationGit.ts
  • scripts/v18-to-v19/V18MigrationPublicReadingVerification.ts
  • scripts/v18-to-v19/V18MigrationScratch.ts
  • scripts/v18-to-v19/V18PatchTranslator.ts
  • scripts/v18-to-v19/V18RetainedSubstrateFixtureRestore.ts
  • scripts/v18-to-v19/migrate.ts
  • src/domain/services/controllers/ForkController.ts
  • src/infrastructure/adapters/CborCheckpointStoreAdapter.ts
  • src/infrastructure/adapters/CborIndexPageBatchStager.ts
  • src/infrastructure/adapters/CurrentCheckpointStorageValidation.ts
  • src/infrastructure/adapters/GitCasMaterializationSnapshotReader.ts
  • src/infrastructure/adapters/GitCasRepositoryAdapter.ts
  • src/infrastructure/adapters/GitCasStrandStoreAdapter.ts
  • src/infrastructure/adapters/SubstrateVersionGate.ts
  • src/infrastructure/adapters/TrailerCommitMessageCodecAdapter.ts
  • src/ports/CommitMessageCodecPort.ts
  • src/ports/RuntimeStorageProviderPort.ts
  • test/helpers/FixturePatchJournal.ts
  • test/helpers/FixturePatchKey.ts
  • test/helpers/V18MigrationRefMap.ts
  • test/helpers/WarpGraphMockPersistence.ts
  • test/helpers/collectAsyncBytes.ts
  • test/integration/api/content-attachment.test.ts
  • test/integration/infrastructure/adapters/GitCasSeekCursorStoreAdapter.integration.test.ts
  • test/integration/scripts/v18-to-v19-medium-fixture.test.ts
  • test/unit/domain/services/WarpMessageCodec.test.ts
  • test/unit/domain/services/controllers/ForkController.test.ts
  • test/unit/domain/warp/RuntimeHostPortResolvers.test.ts
  • test/unit/infrastructure/adapters/CborCheckpointStoreAdapter.test.ts
  • test/unit/infrastructure/adapters/GitCasRepositoryAdapter.test.ts
  • test/unit/infrastructure/adapters/SubstrateVersionGate.test.ts
  • test/unit/scripts/PerformanceModel.test.ts
  • test/unit/scripts/v18-to-v19-command.test.ts
  • test/unit/scripts/v18-to-v19-scratch.test.ts
  • test/unit/scripts/v18-to-v19-writer-chain.test.ts
  • test/unit/scripts/v18-v17-public-read-legacy-reading-builder.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (5)
  • GitHub Check: type-firewall
  • GitHub Check: test-node (22)
  • GitHub Check: v19 base/head performance
  • GitHub Check: coverage-threshold
  • GitHub Check: preflight
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{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:

  • test/helpers/collectAsyncBytes.ts
  • scripts/performance/PerformanceEnvironment.ts
  • test/helpers/FixturePatchKey.ts
  • test/integration/infrastructure/adapters/GitCasSeekCursorStoreAdapter.integration.test.ts
  • src/domain/services/controllers/ForkController.ts
  • bin/cli/commands/info.ts
  • bin/cli/commands/materialize.ts
  • test/helpers/V18MigrationRefMap.ts
  • test/unit/scripts/v18-v17-public-read-legacy-reading-builder.test.ts
  • test/helpers/FixturePatchJournal.ts
  • test/integration/scripts/v18-to-v19-medium-fixture.test.ts
  • test/integration/api/content-attachment.test.ts
  • test/unit/domain/services/controllers/ForkController.test.ts
  • test/unit/domain/warp/RuntimeHostPortResolvers.test.ts
  • bin/cli/shared.ts
  • test/helpers/WarpGraphMockPersistence.ts
  • scripts/v18-to-v19/V18MigrationPublicReadingVerification.ts
  • test/unit/infrastructure/adapters/SubstrateVersionGate.test.ts
  • scripts/migrations/v17.0.0/LegacyCheckpointCommitMessageCodec.ts
  • test/unit/infrastructure/adapters/GitCasRepositoryAdapter.test.ts
  • src/ports/RuntimeStorageProviderPort.ts
  • src/infrastructure/adapters/SubstrateVersionGate.ts
  • test/unit/scripts/v18-to-v19-writer-chain.test.ts
  • scripts/v18-to-v19/migrate.ts
  • test/unit/scripts/v18-to-v19-scratch.test.ts
  • test/unit/scripts/v18-to-v19-command.test.ts
  • scripts/migrations/v17.0.0/CheckpointMaterializationMigration.ts
  • scripts/v18-to-v19/V18RetainedSubstrateFixtureRestore.ts
  • src/infrastructure/adapters/CborIndexPageBatchStager.ts
  • src/infrastructure/adapters/CurrentCheckpointStorageValidation.ts
  • test/unit/domain/services/WarpMessageCodec.test.ts
  • src/infrastructure/adapters/GitCasMaterializationSnapshotReader.ts
  • scripts/v18-to-v19/V18MigrationScratch.ts
  • src/infrastructure/adapters/GitCasStrandStoreAdapter.ts
  • test/unit/scripts/PerformanceModel.test.ts
  • src/infrastructure/adapters/CborCheckpointStoreAdapter.ts
  • scripts/v18-to-v19/V18MigrationCommand.ts
  • scripts/performance/GatePerformance.ts
  • scripts/v18-to-v19/V18MigrationFinalizer.ts
  • scripts/v18-to-v19/V18PatchTranslator.ts
  • scripts/migrations/v17.0.0/LegacyCheckpointStorageReader.ts
  • src/infrastructure/adapters/GitCasRepositoryAdapter.ts
  • scripts/v18-to-v19/V18MigrationGit.ts
  • test/unit/infrastructure/adapters/CborCheckpointStoreAdapter.test.ts
  • src/ports/CommitMessageCodecPort.ts
  • src/infrastructure/adapters/TrailerCommitMessageCodecAdapter.ts
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/ForkController.ts
  • src/ports/RuntimeStorageProviderPort.ts
  • src/infrastructure/adapters/SubstrateVersionGate.ts
  • src/infrastructure/adapters/CborIndexPageBatchStager.ts
  • src/infrastructure/adapters/CurrentCheckpointStorageValidation.ts
  • src/infrastructure/adapters/GitCasMaterializationSnapshotReader.ts
  • src/infrastructure/adapters/GitCasStrandStoreAdapter.ts
  • src/infrastructure/adapters/CborCheckpointStoreAdapter.ts
  • src/infrastructure/adapters/GitCasRepositoryAdapter.ts
  • src/ports/CommitMessageCodecPort.ts
  • src/infrastructure/adapters/TrailerCommitMessageCodecAdapter.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/ForkController.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/ForkController.ts
src/ports/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

In src/ports/**, do not import Node built-ins or src/infrastructure/**; ports must stay abstract and depend only on boundary-safe types.

Files:

  • src/ports/RuntimeStorageProviderPort.ts
  • src/ports/CommitMessageCodecPort.ts
🧠 Learnings (1)
📚 Learning: 2026-03-04T12:08:30.347Z
Learnt from: flyingrobots
Repo: git-stunts/git-warp PR: 63
File: package.json:126-126
Timestamp: 2026-03-04T12:08:30.347Z
Learning: Vitest 4 removes vite-node as a dependency and rewrites its pool system. Do not flag the absence of vite-node in package.json or lockfiles as an error for Vitest 4 projects. Use this as a general guideline: if a project uses Vitest 4, missing vite-node is expected and correct; only flag issues if there is evidence the project is not using Vitest 4 or if vite-node is explicitly required by the project.

Applied to files:

  • fixtures/v18/retained-substrate-medium/package.json
  • package.json
🪛 ast-grep (0.44.1)
test/integration/scripts/v18-to-v19-medium-fixture.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 { spawn } 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 { spawn } 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 { spawn } from 'node:child_process';
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(detect-child-process-typescript)

scripts/v18-to-v19/V18MigrationGit.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 { spawn } 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 (54)
src/infrastructure/adapters/CborCheckpointStoreAdapter.ts (1)

147-148: LGTM!

Also applies to: 189-203, 239-258

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

35-36: LGTM!

README.md (1)

61-75: LGTM!

docs/migrations/v19/README.md (1)

15-70: LGTM!

scripts/performance/GatePerformance.ts (1)

14-15: LGTM!

Also applies to: 42-43, 195-196

scripts/performance/PerformanceEnvironment.ts (1)

1-15: LGTM!

scripts/v18-to-v19/README.md (1)

1-73: LGTM!

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

67-104: LGTM!

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

16-16: LGTM!

Also applies to: 43-50, 74-88, 198-212, 260-275, 483-495, 568-570

test/unit/scripts/v18-v17-public-read-legacy-reading-builder.test.ts (1)

52-52: LGTM!

bin/cli/commands/info.ts (1)

115-115: LGTM!

bin/cli/commands/materialize.ts (1)

76-76: LGTM!

bin/cli/shared.ts (1)

137-149: LGTM!

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

153-153: LGTM!

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

84-84: LGTM!

Also applies to: 114-164, 194-203, 254-260

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

22-29: LGTM!

Also applies to: 41-67, 124-146

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

20-41: LGTM!

src/ports/RuntimeStorageProviderPort.ts (1)

47-48: LGTM!

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

87-87: LGTM!

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

111-112: LGTM!

fixtures/v18/retained-substrate-medium/README.md (1)

23-26: LGTM!

fixtures/v18/retained-substrate-medium/generate.mjs (1)

3-4: LGTM!

Also applies to: 14-30

fixtures/v18/retained-substrate-medium/package.json (1)

1-14: LGTM!

package.json (1)

126-126: LGTM!

scripts/v18-to-v19/V18MigrationFinalizer.ts (1)

2-3: LGTM!

Also applies to: 177-177

scripts/v18-to-v19/V18MigrationGit.ts (1)

44-63: LGTM!

scripts/v18-to-v19/V18RetainedSubstrateFixtureRestore.ts (1)

10-13: LGTM!

Also applies to: 125-132

test/helpers/V18MigrationRefMap.ts (1)

1-29: LGTM!

test/integration/scripts/v18-to-v19-medium-fixture.test.ts (1)

9-9: LGTM!

Also applies to: 33-34, 58-60

test/unit/scripts/v18-to-v19-command.test.ts (1)

14-18: LGTM!

Also applies to: 52-62, 85-85, 104-104

scripts/migrations/v17.0.0/CheckpointMaterializationMigration.ts (1)

29-45: Successful promotion is still discarded if release fails.

completeWithCleanup throws a workspace.release() failure even after workspace.promote() succeeds, so the caller loses the already-retained handle. This is the same unresolved failure mode from the prior review.

scripts/migrations/v17.0.0/LegacyCheckpointCommitMessageCodec.ts (1)

9-19: LGTM!

scripts/migrations/v17.0.0/LegacyCheckpointStorageReader.ts (1)

18-20: LGTM!

Also applies to: 202-209

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

1-1: LGTM!

Also applies to: 247-249, 342-346

src/ports/CommitMessageCodecPort.ts (1)

42-42: LGTM!

Also applies to: 51-51

test/helpers/FixturePatchJournal.ts (1)

13-13: LGTM!

Also applies to: 43-43

test/helpers/FixturePatchKey.ts (1)

1-9: LGTM!

test/helpers/WarpGraphMockPersistence.ts (1)

12-12: LGTM!

Also applies to: 150-150

test/integration/api/content-attachment.test.ts (1)

360-360: LGTM!

Also applies to: 383-383, 386-386, 409-409

test/unit/domain/services/WarpMessageCodec.test.ts (1)

129-129: LGTM!

test/unit/domain/warp/RuntimeHostPortResolvers.test.ts (1)

15-15: LGTM!

Also applies to: 52-52

scripts/v18-to-v19/V18MigrationCommand.ts (1)

36-36: LGTM!

Also applies to: 57-57

scripts/v18-to-v19/V18MigrationPublicReadingVerification.ts (1)

1-56: LGTM!

scripts/v18-to-v19/V18MigrationScratch.ts (2)

23-26: 🎯 Functional Correctness

Scratch root is now configurable.

Both scratch repositories (primary and verification) are created under the caller-supplied scratchRoot, falling back to tmpdir(). This resolves the earlier concern about ENOSPC risk when migrating multi-GiB stores on a constrained /tmp.

Also applies to: 41-47, 105-105


125-137: LGTM!

Also applies to: 202-226, 228-252

scripts/v18-to-v19/V18PatchTranslator.ts (1)

112-127: 🎯 Functional Correctness

Both previously flagged issues are fixed.

_content values that aren't strings now fail closed (Line 173-177) instead of passing through untranslated, and the content-handle cache is now keyed by (reference, encrypted) with an explicit ambiguous-encryption-mode check in translatedContentHandle (Line 112-127), preventing silent wrong-mode handle reuse.

Also applies to: 173-177, 190-209, 255-257

scripts/v18-to-v19/migrate.ts (2)

138-154: 🩺 Stability & Availability

Error-cause swallowing is fixed.

formatFailure now recursively surfaces AggregateError.errors and Error.cause (with circular-reference protection), so operators get the full diagnostic chain on the verification-failed/rollback-failed path instead of just the top-level message.


6-13: LGTM!

Also applies to: 27-27, 44-64, 81-81, 124-124

test/helpers/collectAsyncBytes.ts (1)

1-11: LGTM!

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

56-59: LGTM!

Also applies to: 127-130

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

12-65: LGTM!

Also applies to: 113-123

test/unit/scripts/PerformanceModel.test.ts (1)

170-192: LGTM!

test/unit/scripts/v18-to-v19-scratch.test.ts (1)

3-3: 📐 Maintainability & Code Quality

Duplicate helper comments resolved.

Local readHeads/collect implementations replaced with shared readRequiredV18MigrationRefMap/collectAsyncBytes helpers, and new coverage confirms scratchRoot is honored (dirname(prepared.scratchPath) === scratchRoot, Line 82).

Also applies to: 23-24, 64-64, 77-82, 91-91, 118-118, 163-163, 202-209

test/unit/scripts/v18-to-v19-writer-chain.test.ts (1)

20-20: 📐 Maintainability & Code Quality

Duplicate collect helper resolved via shared collectAsyncBytes import.

Also applies to: 96-100

Comment thread src/infrastructure/adapters/SubstrateVersionGate.ts
@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.

1 similar comment
@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 209eb86 into main Jul 26, 2026
18 checks passed
@flyingrobots
flyingrobots deleted the v19-v18-substrate-migration branch July 26, 2026 18:41
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.

Add one-shot v18-to-v19 retained substrate migration

1 participant