Skip to content

Adopt persistent Git object sessions and close them safely#764

Merged
flyingrobots merged 8 commits into
mainfrom
perf/persistent-cas-sessions
Jul 19, 2026
Merged

Adopt persistent Git object sessions and close them safely#764
flyingrobots merged 8 commits into
mainfrom
perf/persistent-cas-sessions

Conversation

@flyingrobots

@flyingrobots flyingrobots commented Jul 19, 2026

Copy link
Copy Markdown
Member

Summary

  • consume published @git-stunts/git-cas@6.5.3 session coherence with @git-stunts/plumbing@3.2.0
  • keep repository-scoped Git object sessions alive across immutable history and CAS work
  • add idempotent GitStorage.close() and async disposal, with explicit ownership for history, internally-created CAS, and materialization leases
  • close those owners at application, CLI, migration, Deno, BATS, and integration-test boundaries
  • document the measured process topology and the caller lifecycle contract

Measured checkpoint

The controlled 128-node retained-materialization comparison reduced process creation from 558 to 401 children (28.1%), cat-file from 80 to 4, and mktree from 82 to 1. Median materialization time moved from 14.24 s to 12.72 s.

The three downstream registry-artifact runs produced 398 workload Git children, or 401 including repository setup. Their diagnostic wall times were 7.02 s, 7.18 s, and 6.67 s. These downstream timings remain non-gating because that run did not capture process-tree CPU/RSS or reproduce the old timing harness.

Validation

  • stable pre-push suite: 7,098 unit tests passed; 2 skipped across 573 files
  • controlled broad Node rerun: 7,304 tests passed; 2 skipped across 603 passing files and 1 skipped file
  • full integration directory: 101 tests passed across 21 files
  • Deno hosted command: 18 tests passed twice with no leaked-child errors
  • BATS: 110 of 110 passed with the local CI-equivalent CLI shim
  • build, source/test/consumer type checks, publication-surface checks, and Git signature checks passed
  • ESLint, Markdown, docs topology, Semgrep, source-backed reference, source-size, CAS ownership, contamination, quarantine, and audit gates passed
  • npm production audit reports 0 vulnerabilities
  • Graft reports no removed exports or signature-breaking public changes

Review posture

The branch has three signed commits and is based directly on current origin/main. The final code-lawyer pass found and corrected two issues before this update: cleanup could mask CLI binding failure, and canonical examples did not consistently close persistent storage. No unresolved review finding remains.

Scope and issues

This consumes the fix for git-stunts/git-cas#94. Compatibility with narrow third-party plumbing fakes is deliberately deferred to git-stunts/git-cas#98 instead of triggering another git-cas release.

This advances #738, #758, and #759, but does not close them: retained RuntimeHost materialization, the bounded-memory contract, and committed CPU/RSS benchmark gates remain separate work.

@flyingrobots

Copy link
Copy Markdown
Member Author

Self-code review

@codex please confirm this review posture.

Severity Count Finding
Critical 0 None
High 0 None
Medium 0 None
Low 0 None
Markdown/style 0 Markdownlint, code-sample lint, docs topology, links, and source-backed citation gates passed

Reviewed origin/main..785adbebf for intent, logic, behavioral regression, API impact, dependency provenance, fixture determinism, documentation accuracy, and repository policy compliance. Graft classified the four files as docs/config/test only, found no structural break, and reported no exported API change.

The only golden-value change was independently reproduced under git-cas 6.5.0, 6.5.2, and 6.5.3, then traced to PACKAGE_VERSION -> CasService.formatVersion -> Manifest.toJSON() -> manifest-tree OID. Full unit and integration suites are green locally.

@coderabbitai

coderabbitai Bot commented Jul 19, 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: 35 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

Run ID: 3f2874b5-2fb0-4009-8342-42d3c216e1e4

📥 Commits

Reviewing files that changed from the base of the PR and between 855b0cb and a3e345e.

📒 Files selected for processing (2)
  • bin/cli/commands/mcp.ts
  • test/unit/cli/commands/mcp-lifecycle.test.ts
📝 Walkthrough

Walkthrough

Adds idempotent Git/CAS storage closure and async disposal, wires cleanup through CLI, migration, fixture, and test boundaries, upgrades git-cas and plumbing, refreshes a manifest golden value, and documents persistent-session behavior and explicit storage shutdown.

Changes

Storage lifecycle management

Layer / File(s) Summary
Adapter close contracts and ownership
src/application/WarpStorage.ts, src/infrastructure/adapters/*
Adapters now track owned resources, expose idempotent close() and async disposal, remove closed materializations, validate inputs, and reject operations after closure.
GitStorage orchestration
storage.ts
GitStorage validates history before CAS creation, injects cleanup into the public handle, and aggregates open or close failures.
CLI and application boundary cleanup
bin/cli/*, bin/warp-graph.ts, test/bats/*
CLI storage and MCP command resources are tracked, completed, and closed across normal completion and failure paths.
Migration and test teardown
scripts/v18.0.0/..., test/helpers/..., test/integration/..., test/runtime/..., test/type-check/...
Migration flows, fixtures, harnesses, and compile-only examples close runtime resources before temporary-directory removal, with lifecycle behavior covered by tests.

git-cas 6.5.3 adoption

Layer / File(s) Summary
Dependency upgrade and golden validation
package.json, test/unit/scripts/v18-v17-public-read-legacy-reading-builder.test.ts
Dependency ranges and the expected git-cas-stamped manifest value are updated.
Performance behavior and consumer checkpoint
docs/topics/git-perf.md
Documentation separates historical process-per-object measurements from persistent sessions and records v6.5.3 diagnostic results and benchmark scope.
Storage lifecycle documentation
README.md, ARCHITECTURE.md, CHANGELOG.md, docs/topics/*, docs/migrations/v19/README.md, docs/TECHNICAL_TEARDOWN.md
Examples and reference material describe explicit storage closure, async disposal, and non-destructive resource release.

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

Possibly related issues

Possibly related PRs

Poem

A rabbit closes stores with care,
While Git and CAS release the air.
Sessions persist, then safely sleep,
Tests tidy paths in burrows deep.
v6.5.3 hops along! 🐇

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.43% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: persistent Git object sessions and safer shutdown.
Description check ✅ Passed Mostly matches the template: it includes Summary, issue refs, Validation, and scope; only the ADR checklist section is omitted.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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[bot]
coderabbitai Bot previously approved these changes Jul 19, 2026
@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 changed the title Adopt git-cas v6.5.3 persistent object sessions Adopt persistent Git object sessions and close them safely Jul 19, 2026
@flyingrobots

Copy link
Copy Markdown
Member Author

Final self-code review

@codex please confirm this final review posture for origin/main..23018c9df604a900c7f043031026d00f21c04c5d.

Severity Open Disposition
Critical 0 None
High 0 None
Medium 0 One primary-error masking path found during review and fixed in 23018c9df
Low 0 Incomplete lifecycle examples found during review and fixed in 23018c9df
Markdown/style 0 Markdownlint, code-sample, docs-topology, and source-backed-reference gates pass

Evidence

  • The published dependencies are pinned to git-cas 6.5.3 and plumbing 3.2.0. [cite: package.json#120-121@23018c9df604a900c7f043031026d00f21c04c5d]
  • Public storage shutdown is idempotent and supports async disposal. [cite: src/application/WarpStorage.ts#17-25@23018c9df604a900c7f043031026d00f21c04c5d]
  • The repository adapter owns only the CAS facade it constructs, tracks materialization owners, closes them before CAS, and fails closed for new services. [cite: src/infrastructure/adapters/GitCasRepositoryAdapter.ts#85-100@23018c9df604a900c7f043031026d00f21c04c5d] [cite: src/infrastructure/adapters/GitCasRepositoryAdapter.ts#204-273@23018c9df604a900c7f043031026d00f21c04c5d]
  • History closes its delegated git-cas persistence session idempotently. [cite: src/infrastructure/adapters/GitTimelineHistoryAdapter.ts#118-142@23018c9df604a900c7f043031026d00f21c04c5d]
  • GitStorage closes repository and history in ownership order and preserves both open and cleanup failures. [cite: storage.ts#16-75@23018c9df604a900c7f043031026d00f21c04c5d]
  • CLI storage is centrally tracked, closed on ordinary/error/signal exits, and preserves concurrent cleanup failures. [cite: bin/cli/shared.ts#33-77@23018c9df604a900c7f043031026d00f21c04c5d] [cite: bin/warp-graph.ts#73-157@23018c9df604a900c7f043031026d00f21c04c5d]

Verification

  • 7,098 stable unit tests passed; 2 skipped.
  • 7,304 tests passed in the controlled broad Node rerun; 2 skipped.
  • 101 full integration tests passed.
  • 18 Deno tests passed twice without leaked-child diagnostics.
  • 110 of 110 BATS tests passed.
  • All pre-push static, type, publication, documentation, source-size, and CAS-boundary gates passed.
  • Graft reports no removed exports or signature-breaking changes.
  • All three branch commits have valid signatures from James Ross <james@flyingrobots.dev>.

No unresolved issue remains from the final self-review.

@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: 5

🤖 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
`@scripts/v18.0.0/migrations/graph-model/GraphModelMigrationScratchRuntimeReplayer.ts`:
- Around line 138-147: Aggregate cleanup failures across all three sites instead
of allowing nested finally blocks to mask earlier errors: in
scripts/v18.0.0/migrations/graph-model/GraphModelMigrationScratchRuntimeReplayer.ts
lines 138-147, retain the replay failure and collect runtime storage close,
persistence close, and repository removal failures before throwing an
AggregateError after every cleanup attempt; in test/bats/helpers/seed-setup.ts
lines 66-71, collect failures from both close operations and report them
together; in test/runtime/deno/helpers.ts lines 80-87, collect close and removal
failures and report them together.

In `@src/infrastructure/adapters/GitCasMaterializationStoreAdapter.ts`:
- Line 222: Update GitCasMaterializationStoreAdapter’s materialization entry
points, especially openWorkspace() and retain(), to reject new operations once
close() has started, not only after `#closed` is set. Use the existing close
state/promise to guard these methods before any externally owned CAS writes
occur, while preserving normal behavior before closure begins.

In `@test/integration/api/materialization.retainedResume.test.ts`:
- Around line 34-39: Update the afterEach teardown to use Promise.allSettled for
all providers in providers, ensuring every provider.close() settles before
proceeding. Perform repo?.cleanup() after all closes have settled, then
aggregate and propagate any provider-close failures after cleanup completes.

In
`@test/integration/infrastructure/adapters/GitCasMaterializationStoreAdapter.integration.test.ts`:
- Around line 67-106: Ensure the acquisition created by reopened.acquireExact in
the test is always released, including when assertions or later operations fail.
Move acquisition.release into a finally block that runs before reopened.close,
while preserving the existing nested teardown order and avoiding release when
acquisition was never created.

In `@test/unit/infrastructure/adapters/GitCasRepositoryAdapter.test.ts`:
- Around line 196-201: Remove the direct services.materializations.close() call
from the repository closure test, while retaining the spy setup and repeated
repository.close() calls. Assert that repository.close() itself invokes the
materialization cleanup exactly once.
🪄 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: 5d2de608-f9e6-4769-867a-d145b9f6cb1f

📥 Commits

Reviewing files that changed from the base of the PR and between 785adbe and 23018c9.

📒 Files selected for processing (36)
  • ARCHITECTURE.md
  • CHANGELOG.md
  • README.md
  • bin/cli/shared.ts
  • bin/warp-graph.ts
  • docs/TECHNICAL_TEARDOWN.md
  • docs/migrations/v19/README.md
  • docs/topics/getting-started.md
  • docs/topics/querying.md
  • docs/topics/reference.md
  • scripts/v18.0.0/migrations/graph-model/GraphModelMigrationScratchRuntimeReplayer.ts
  • scripts/v18.0.0/migrations/graph-model/V17RestoredPublicReadLegacyReadingBuilder.ts
  • src/application/WarpStorage.ts
  • src/infrastructure/adapters/GitCasMaterializationStoreAdapter.ts
  • src/infrastructure/adapters/GitCasRepositoryAdapter.ts
  • src/infrastructure/adapters/GitTimelineHistoryAdapter.ts
  • storage.ts
  • test/bats/helpers/seed-setup.ts
  • test/bats/helpers/setup.bash
  • test/helpers/WarpGraphTestRepositories.ts
  • test/integration/WarpGraph.integration.test.ts
  • test/integration/api/checkpoint.test.ts
  • test/integration/api/helpers/setup.ts
  • test/integration/api/materialization.retainedResume.test.ts
  • test/integration/application/GitStorage.integration.test.ts
  • test/integration/domain/orset/trie/TrieCursor.flush.integration.test.ts
  • test/integration/infrastructure/adapters/GitCasMaterializationStoreAdapter.integration.test.ts
  • test/integration/infrastructure/adapters/GitCasTrieStoreAdapter.integration.test.ts
  • test/integration/infrastructure/adapters/GitCasWarpStateCacheAdapter.retention.integration.test.ts
  • test/runtime/deno/helpers.ts
  • test/type-check/v19-consumer.ts
  • test/type-check/v19-first-use.ts
  • test/type-check/v19-subpaths.ts
  • test/unit/application/WarpStorageRegistry.test.ts
  • test/unit/infrastructure/adapters/GitCasRepositoryAdapter.test.ts
  • test/unit/infrastructure/adapters/GitGraphAdapter.gitCasPersistence.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (3)
  • GitHub Check: test-node (22)
  • GitHub Check: preflight
  • GitHub Check: coverage-threshold
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{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/integration/application/GitStorage.integration.test.ts
  • test/type-check/v19-subpaths.ts
  • test/integration/api/checkpoint.test.ts
  • test/type-check/v19-consumer.ts
  • test/unit/infrastructure/adapters/GitGraphAdapter.gitCasPersistence.test.ts
  • test/integration/infrastructure/adapters/GitCasTrieStoreAdapter.integration.test.ts
  • test/helpers/WarpGraphTestRepositories.ts
  • scripts/v18.0.0/migrations/graph-model/GraphModelMigrationScratchRuntimeReplayer.ts
  • test/integration/api/helpers/setup.ts
  • test/integration/domain/orset/trie/TrieCursor.flush.integration.test.ts
  • test/unit/application/WarpStorageRegistry.test.ts
  • test/runtime/deno/helpers.ts
  • test/unit/infrastructure/adapters/GitCasRepositoryAdapter.test.ts
  • src/infrastructure/adapters/GitTimelineHistoryAdapter.ts
  • test/integration/WarpGraph.integration.test.ts
  • src/application/WarpStorage.ts
  • test/bats/helpers/seed-setup.ts
  • test/type-check/v19-first-use.ts
  • bin/warp-graph.ts
  • bin/cli/shared.ts
  • test/integration/infrastructure/adapters/GitCasWarpStateCacheAdapter.retention.integration.test.ts
  • test/integration/api/materialization.retainedResume.test.ts
  • storage.ts
  • scripts/v18.0.0/migrations/graph-model/V17RestoredPublicReadLegacyReadingBuilder.ts
  • src/infrastructure/adapters/GitCasMaterializationStoreAdapter.ts
  • test/integration/infrastructure/adapters/GitCasMaterializationStoreAdapter.integration.test.ts
  • src/infrastructure/adapters/GitCasRepositoryAdapter.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/GitTimelineHistoryAdapter.ts
  • src/application/WarpStorage.ts
  • src/infrastructure/adapters/GitCasMaterializationStoreAdapter.ts
  • src/infrastructure/adapters/GitCasRepositoryAdapter.ts
🧠 Learnings (1)
📚 Learning: 2026-03-08T19:50:17.519Z
Learnt from: flyingrobots
Repo: git-stunts/git-warp PR: 65
File: CHANGELOG.md:88-88
Timestamp: 2026-03-08T19:50:17.519Z
Learning: Follow the Keep a Changelog convention for CHANGELOG.md. Allow duplicate subheadings across versions (e.g., '### Added', '### Fixed'). Configure markdownlint MD024 with {"siblings_only": true} to avoid cross-version false positives.

Applied to files:

  • CHANGELOG.md
🪛 ast-grep (0.44.1)
test/integration/api/materialization.retainedResume.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)


[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)

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)


[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 (33)
ARCHITECTURE.md (1)

123-125: LGTM!

CHANGELOG.md (1)

22-23: LGTM!

Also applies to: 55-57, 78-81

README.md (1)

107-112: LGTM!

docs/TECHNICAL_TEARDOWN.md (1)

187-190: LGTM!

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

88-90: LGTM!

docs/topics/getting-started.md (1)

158-164: LGTM!

docs/topics/querying.md (1)

117-125: LGTM!

docs/topics/reference.md (1)

97-97: LGTM!

Also applies to: 195-195

src/application/WarpStorage.ts (1)

1-25: LGTM!

storage.ts (1)

16-74: LGTM!

test/integration/application/GitStorage.integration.test.ts (1)

20-33: LGTM!

test/type-check/v19-consumer.ts (1)

142-143: LGTM!

test/type-check/v19-first-use.ts (1)

11-15: LGTM!

Also applies to: 37-38

test/type-check/v19-subpaths.ts (1)

34-34: LGTM!

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

104-104: LGTM!

Also applies to: 134-142

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

72-96: LGTM!

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

33-33: LGTM!

Also applies to: 75-119, 207-274

test/helpers/WarpGraphTestRepositories.ts (1)

18-22: LGTM!

test/integration/WarpGraph.integration.test.ts (1)

39-47: LGTM!

test/integration/domain/orset/trie/TrieCursor.flush.integration.test.ts (1)

52-56: LGTM!

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

33-45: LGTM!

Also applies to: 220-233, 252-289

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

20-24: LGTM!

test/integration/infrastructure/adapters/GitCasWarpStateCacheAdapter.retention.integration.test.ts (1)

110-119: LGTM!

bin/cli/shared.ts (1)

33-46: LGTM!

Also applies to: 51-76

bin/warp-graph.ts (1)

8-8: LGTM!

Also applies to: 80-86, 131-141

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

131-132: LGTM!

Also applies to: 160-161, 181-190

test/bats/helpers/setup.bash (1)

63-91: LGTM!

test/integration/api/checkpoint.test.ts (1)

23-35: LGTM!

test/integration/api/helpers/setup.ts (1)

69-77: LGTM!

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

70-70: LGTM!

Also applies to: 87-87, 104-104, 124-124, 148-148, 264-294

test/unit/application/WarpStorageRegistry.test.ts (1)

1-1: LGTM!

Also applies to: 17-22, 47-57

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

119-119: LGTM!

Also applies to: 142-142, 202-210

test/unit/infrastructure/adapters/GitGraphAdapter.gitCasPersistence.test.ts (1)

248-258: LGTM!

Comment thread src/infrastructure/adapters/GitCasMaterializationStoreAdapter.ts Outdated
Comment thread test/integration/api/materialization.retainedResume.test.ts
Comment thread test/unit/infrastructure/adapters/GitCasRepositoryAdapter.test.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.

coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 19, 2026
@flyingrobots

Copy link
Copy Markdown
Member Author

Post-review verification

@codex please confirm this review posture for origin/main..b3b9753074a090b76699d7713f297e3128591238.

Severity Open Disposition
Critical 0 None
High 0 None
Medium 0 Both CodeRabbit major findings fixed in b3b975307
Low 0 Two teardown findings fixed; repository test finding verified already covered
Markdown/style 0 Full pre-push documentation and static gates passed

Evidence

  • Materialization entry points fail closed as soon as shutdown begins, before external CAS work. [cite: src/infrastructure/adapters/GitCasMaterializationStoreAdapter.ts#99-127@b3b9753074a090b76699d7713f297e3128591238] [cite: src/infrastructure/adapters/GitCasMaterializationStoreAdapter.ts#214-229@b3b9753074a090b76699d7713f297e3128591238]
  • Replay and teardown failures are retained while every cleanup action is attempted. [cite: scripts/v18.0.0/migrations/graph-model/GraphModelMigrationScratchRuntimeReplayer.ts#111-165@b3b9753074a090b76699d7713f297e3128591238]
  • The closure-start race has direct regression coverage for workspace, retention, and exact acquisition. [cite: test/unit/infrastructure/adapters/GitCasMaterializationStoreAdapter.lifecycle.test.ts#19-44@b3b9753074a090b76699d7713f297e3128591238]

Verification

  • CodeRabbit approved the current head.
  • Zero unresolved review threads.
  • Graft reports zero breaking changes and no removed exports.
  • Coverage: 7,227 passed, 2 skipped; 92.90% lines.
  • Integration: 101/101.
  • BATS: 110/110 using the branch CLI.
  • Deno: 18/18.
  • Full pre-push stable unit shards and every static/publication/documentation gate passed.
  • Commit signature is valid for James Ross <james@flyingrobots.dev>.

No unresolved issue remains from this self-review.

@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

Copy link
Copy Markdown
Member Author

Final self-code review

@codex please confirm this review posture for origin/main..855b0cb11.

File / lines Severity Infraction Mitigation prompt Resolution
src/infrastructure/adapters/GitCasMaterializationStoreAdapter.ts:113-140,305-325; GitCasMaterializationWorkspaceOwner.ts:24-90 High Active or in-flight git-cas workspaces could outlive repository shutdown, race CAS closure, or leak a raw staging workspace when wrapper construction failed. Track pending and active workspaces under one idempotent owner; reject opens after closure; release raw and wrapped workspaces; aggregate cleanup failures. Fixed in 91f499f11; race, release, and dual-failure tests added.
bin/warp-graph.ts:83-122,155-160; bin/cli/lifecycle.ts:4-22 High Long-running command cleanup and storage cleanup could run concurrently, allowing commands to touch already-closed persistent sessions. Drain the command first, close storage second, make shutdown idempotent, and preserve both failures. Fixed in 91f499f11; ordered-shutdown tests pass.
bin/cli/commands/mcp.ts:38-99; bin/cli/shared.ts:219-240 Medium MCP had no normal EOF completion contract, could abandon pending dispatches, and the built layout looked for dist/package.json. Treat EOF/close as completion, await pending dispatches, expose one completion promise, and locate package root from source or dist. Fixed in 91f499f11; built CLI EOF/version BATS case passes.
scripts/v18.0.0/migrations/graph-model/V17RestoredPublicReadLegacyReadingBuilder.ts:79-240; GraphModelMigrationScratchRuntimeReplayer.ts:106-163 Medium Migration scratch runtimes did not reliably close persistent CAS/history sessions, and cleanup could mask the primary migration failure. Own partial initialization explicitly; close repository then history; remove temporary repositories last; aggregate all failures. Fixed across 527a078e2 and 91f499f11; migration/unit shards pass.
src/infrastructure/adapters/GitCasMaterializationStoreAdapter.ts:132-228; OperationCleanup.ts:1-19 Medium finally cleanup could overwrite the causal promotion or legacy-cleanup failure. Run operation and cleanup sequentially; return success only after cleanup; preserve either single failure or both in order. Fixed in 91f499f11; helper is 100% covered.
test/integration/api/querybuilder.test.ts:17-114 Medium Seven tests rebuilt and materialized the same immutable graph independently, causing full-suite hook timeouts and obscuring product regressions. Build one immutable fixture per suite, clean it once, and retain typed result assertions. Fixed in 91f499f11; isolated runtime fell from about 39.4 s to 6.8 s; full integration is 101/101.
docs/topics/reference.md:195 Low Source-backed CLI line evidence was stale after the entry-point lifecycle additions. Regenerate the canonical source-backed reference and rerun docs topology. Fixed in 855b0cb11; docs topology, Markdown, and links pass.

Verdict

  • Critical: 0
  • High: 2 found, 2 resolved
  • Medium: 4 found, 4 resolved
  • Low: 1 found, 1 resolved
  • Unresolved: 0
  • Graft: 52 files classified, zero breaking changes
  • Publication surface: 0 errors, 0 warnings
  • Evidence: 7,241 coverage-gate tests; 101 integration tests; 111 local CLI acceptance tests; 18 Deno tests; all stable pre-push shards; lint, type, CAS ownership, docs, links, and source-size gates green

@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

🤖 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 `@bin/cli/commands/mcp.ts`:
- Around line 43-57: Attach an error handler to the readline interface created
in the MCP command, ensuring stdin/readline errors are propagated into the
existing completion and close lifecycle rather than becoming unhandled events.
Update the flow around trackMcpLines and the returned close function so storage
and other cleanup still execute when an error occurs.
🪄 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: 9e2274c6-652b-48e7-bf46-03fe71554374

📥 Commits

Reviewing files that changed from the base of the PR and between 23018c9 and 855b0cb.

📒 Files selected for processing (25)
  • bin/cli/commands/mcp.ts
  • bin/cli/lifecycle.ts
  • bin/cli/shared.ts
  • bin/warp-graph.ts
  • docs/topics/reference.md
  • scripts/v18.0.0/migrations/graph-model/GraphModelMigrationScratchRuntimeReplayer.ts
  • scripts/v18.0.0/migrations/graph-model/V17RestoredPublicReadLegacyReadingBuilder.ts
  • src/infrastructure/adapters/GitCasMaterializationStoreAdapter.ts
  • src/infrastructure/adapters/GitCasMaterializationStoreValidation.ts
  • src/infrastructure/adapters/GitCasMaterializationWorkspace.ts
  • src/infrastructure/adapters/GitCasMaterializationWorkspaceOwner.ts
  • src/infrastructure/adapters/OperationCleanup.ts
  • test/bats/cli-mcp.bats
  • test/bats/helpers/seed-setup.ts
  • test/integration/api/materialization.retainedResume.test.ts
  • test/integration/api/querybuilder.test.ts
  • test/integration/infrastructure/adapters/GitCasMaterializationStoreAdapter.integration.test.ts
  • test/runtime/deno/helpers.ts
  • test/unit/application/WarpStorageRegistry.test.ts
  • test/unit/cli/lifecycle.test.ts
  • test/unit/infrastructure/adapters/GitCasMaterializationStoreAdapter.lifecycle.test.ts
  • test/unit/infrastructure/adapters/GitCasMaterializationWorkspaceOwner.test.ts
  • test/unit/infrastructure/adapters/GitCasRepositoryAdapter.test.ts
  • test/unit/infrastructure/adapters/GitGraphAdapter.gitCasPersistence.test.ts
  • test/unit/infrastructure/adapters/OperationCleanup.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (3)
  • GitHub Check: test-node (22)
  • GitHub Check: coverage-threshold
  • GitHub Check: preflight
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{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:

  • bin/cli/lifecycle.ts
  • test/unit/infrastructure/adapters/OperationCleanup.test.ts
  • src/infrastructure/adapters/OperationCleanup.ts
  • test/unit/infrastructure/adapters/GitGraphAdapter.gitCasPersistence.test.ts
  • test/unit/cli/lifecycle.test.ts
  • test/runtime/deno/helpers.ts
  • test/integration/api/querybuilder.test.ts
  • test/unit/infrastructure/adapters/GitCasRepositoryAdapter.test.ts
  • test/bats/helpers/seed-setup.ts
  • test/unit/infrastructure/adapters/GitCasMaterializationWorkspaceOwner.test.ts
  • test/unit/application/WarpStorageRegistry.test.ts
  • src/infrastructure/adapters/GitCasMaterializationStoreValidation.ts
  • src/infrastructure/adapters/GitCasMaterializationWorkspaceOwner.ts
  • scripts/v18.0.0/migrations/graph-model/GraphModelMigrationScratchRuntimeReplayer.ts
  • bin/cli/shared.ts
  • src/infrastructure/adapters/GitCasMaterializationWorkspace.ts
  • test/unit/infrastructure/adapters/GitCasMaterializationStoreAdapter.lifecycle.test.ts
  • scripts/v18.0.0/migrations/graph-model/V17RestoredPublicReadLegacyReadingBuilder.ts
  • bin/cli/commands/mcp.ts
  • test/integration/infrastructure/adapters/GitCasMaterializationStoreAdapter.integration.test.ts
  • test/integration/api/materialization.retainedResume.test.ts
  • bin/warp-graph.ts
  • src/infrastructure/adapters/GitCasMaterializationStoreAdapter.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/OperationCleanup.ts
  • src/infrastructure/adapters/GitCasMaterializationStoreValidation.ts
  • src/infrastructure/adapters/GitCasMaterializationWorkspaceOwner.ts
  • src/infrastructure/adapters/GitCasMaterializationWorkspace.ts
  • src/infrastructure/adapters/GitCasMaterializationStoreAdapter.ts
🪛 ast-grep (0.44.1)
bin/cli/shared.ts

[warning] 221-221: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use.
Context: fs.readFileSync(path.join(packageRoot, 'package.json'), 'utf8')
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(detect-non-literal-fs-filename-typescript)

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)

test/integration/api/materialization.retainedResume.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)

🔇 Additional comments (26)
src/infrastructure/adapters/GitCasMaterializationStoreAdapter.ts (1)

11-14: LGTM!

Also applies to: 26-36, 84-86, 113-141, 220-230, 232-246, 306-312, 322-328, 358-363

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

1-50: LGTM!

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

44-45: LGTM!

Also applies to: 47-51, 64-64, 137-137

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

1-92: LGTM!

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

1-19: LGTM!

docs/topics/reference.md (1)

97-97: LGTM!

Also applies to: 195-195

test/bats/helpers/seed-setup.ts (1)

66-81: LGTM!

bin/cli/lifecycle.ts (1)

1-22: LGTM!

test/unit/cli/lifecycle.test.ts (1)

1-41: LGTM!

bin/warp-graph.ts (1)

31-45: LGTM!

Also applies to: 86-121, 155-167

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

109-165: LGTM!

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

82-105: LGTM!

Also applies to: 139-192, 209-247

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

35-47: LGTM!

Also applies to: 276-291, 320-327

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

22-48: LGTM!

Also applies to: 70-111

test/runtime/deno/helpers.ts (1)

79-95: LGTM!

bin/cli/commands/mcp.ts (2)

1-5: LGTM!

Also applies to: 13-17, 24-37, 86-98


59-84: 🗄️ Data Integrity & Integration

MCP dispatch is read-only
The registered MCP tools only read graph state, and McpGraphReadSurface exposes no mutation methods, so per-line concurrent dispatch here doesn’t create a write race.

			> Likely an incorrect or invalid review comment.
bin/cli/shared.ts (1)

33-46: LGTM!

Also applies to: 51-70, 219-224, 229-241

test/bats/cli-mcp.bats (1)

1-56: LGTM!

test/integration/api/querybuilder.test.ts (1)

1-20: LGTM!

Also applies to: 46-139

test/unit/application/WarpStorageRegistry.test.ts (1)

1-1: LGTM!

Also applies to: 17-22, 46-67

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

119-119: LGTM!

Also applies to: 142-142, 195-218

test/unit/infrastructure/adapters/GitGraphAdapter.gitCasPersistence.test.ts (1)

247-267: LGTM!

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

1-11: LGTM!

Also applies to: 22-128

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

1-108: LGTM!

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

1-58: LGTM!

Comment thread bin/cli/commands/mcp.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.

@flyingrobots
flyingrobots merged commit 4ebf810 into main Jul 19, 2026
17 checks passed
@flyingrobots
flyingrobots deleted the perf/persistent-cas-sessions branch July 19, 2026 21:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant