Skip to content

Seal Git substrate out of v19 receipts and evidence - #745

Merged
flyingrobots merged 4 commits into
mainfrom
v19-storage-neutral-receipts
Jul 14, 2026
Merged

Seal Git substrate out of v19 receipts and evidence#745
flyingrobots merged 4 commits into
mainfrom
v19-storage-neutral-receipts

Conversation

@flyingrobots

Copy link
Copy Markdown
Member

Closes #743

Summary

  • replace root-facing write, read, and join substrate identifiers with opaque, storage-neutral Evidence handles
  • make Tick.id a deterministic opaque identifier while retaining its internal coordinate binding
  • retain exact write/read/join provenance in a storage-authorized diagnostics registry
  • require explicit storage context for inspectReceipt()
  • add an AST-based gate over the transitive emitted root declaration graph
  • update first-use docs, migration guidance, conformance tests, and consumer type proofs

This is an intentional breaking API change for the eventual v19.0.0 release.

Source evidence

  • Public evidence contains only opaque basis/support handles and an optional public tick. [cite: src/domain/api/Evidence.ts#3-13@d5b4b47ded6303235fa4314dd22e76e93abecb01]
  • Write receipts require evidence and no longer expose a patch identifier. [cite: src/domain/api/WriteReceipt.ts#16-31@d5b4b47ded6303235fa4314dd22e76e93abecb01]
  • Join receipts require or optionally carry evidence and no longer expose patch arrays. [cite: src/domain/api/JoinReceipt.ts#18-40@d5b4b47ded6303235fa4314dd22e76e93abecb01]
  • Read receipts use the same storage-neutral evidence contract. [cite: src/domain/api/ReadReceipt.ts#18-35@d5b4b47ded6303235fa4314dd22e76e93abecb01]
  • Tick identity is derived through the opaque-ID runtime boundary. [cite: src/domain/api/TickRuntime.ts#48-57@d5b4b47ded6303235fa4314dd22e76e93abecb01]
  • Exact substrate provenance is storage-bound, immutable, and single-assignment. [cite: src/application/ReceiptProvenanceRegistry.ts#13-64@d5b4b47ded6303235fa4314dd22e76e93abecb01]
  • Diagnostics require the issuing storage handle and recover exact object identities. [cite: diagnostics.ts#11-90@d5b4b47ded6303235fa4314dd22e76e93abecb01]
  • The publication check executes the transitive declaration vocabulary gate. [cite: scripts/check-dts-surface.ts#212-235@d5b4b47ded6303235fa4314dd22e76e93abecb01]
  • The gate walks emitted declaration imports and rejects Git/CAS vocabulary in reachable identifiers and literals. [cite: scripts/v19-root-declaration-gate.ts#30-83@d5b4b47ded6303235fa4314dd22e76e93abecb01]

Validation

  • npm run test:local: 577 files passed, 1 skipped; 7,374 tests passed, 2 skipped
  • npm run test:coverage:ci: 588 files passed, 1 skipped; 7,419 tests passed, 2 skipped; 92.62% line threshold met
  • npx vitest run test/integration: 19 files, 98 tests passed
  • PATH="$PWD/bin:$PATH" bats test/bats/: 110 tests passed
  • npm run typecheck:surface: zero errors and zero warnings
  • source/test/consumer type checks, lint, Markdown, docs topology, source-backed references, contamination map, CAS invariants, and link checks passed
  • npm pack --dry-run passed the full prepack pipeline
  • IRONCLAD pre-push firewall passed all gates
  • Graft export analysis reports the expected v19 major impact: Evidence and EvidenceHandle added; ReadEvidence removed

@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 1 minute

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: bae2fde1-59ec-4938-b51a-84804991f3f9

📥 Commits

Reviewing files that changed from the base of the PR and between 15e8989 and 888216a.

📒 Files selected for processing (5)
  • src/application/ReceiptProvenanceRegistry.ts
  • src/domain/api/ApiRuntimeContext.ts
  • src/domain/api/EvidenceRuntime.ts
  • test/unit/domain/DraftTimelineRuntime.test.ts
  • test/unit/domain/ReceiptDiagnostics.test.ts
📝 Walkthrough

Walkthrough

The v19 API replaces direct receipt substrate identifiers with opaque evidence handles, threads runtime context through receipt-producing operations, and adds storage-aware provenance diagnostics. Public exports, documentation, declaration checks, and tests are updated for the new contracts.

Changes

Receipt evidence and provenance

Layer / File(s) Summary
Evidence and receipt contracts
src/domain/api/ApiRuntimeContext.ts, src/domain/api/Evidence.ts, src/domain/api/*Receipt.ts
Receipts use immutable Evidence; accepted outcomes require evidence while rejected outcomes expose reasons without substrate identifiers.
Runtime evidence generation
src/application/ReceiptProvenanceRegistry.ts, src/domain/api/EvidenceRuntime.ts, src/domain/api/TickRuntime.ts
Runtime contexts create opaque IDs, bind receipt provenance, generate operation-specific evidence, and create opaque tick IDs.
Timeline operation integration
src/application/openWarp.ts, src/domain/api/*Runtime.ts
Timeline, read, write, and join flows receive runtime context and bind provenance when constructing receipts.
Storage-aware diagnostics
diagnostics.ts
inspectReceipt requires storage, resolves provenance, exposes substrate details, validates operation matches, and derives object IDs from provenance.
Public boundary and migration updates
index.ts, scripts/*, docs/topics/*, docs/migrations/v19/*
Evidence types are exported, direct substrate fields are removed from public guidance, and emitted declarations are checked for forbidden vocabulary.

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

Possibly related PRs

Sequence Diagram(s)

sequenceDiagram
  participant Timeline
  participant RuntimeContext
  participant Receipt
  participant Diagnostics
  participant Storage
  Timeline->>RuntimeContext: create evidence and bind provenance
  RuntimeContext->>Receipt: store opaque evidence
  Diagnostics->>Storage: resolve provenance for receipt
  Storage-->>Diagnostics: return substrate provenance
  Diagnostics-->>Timeline: return inspection details
Loading

Poem

I’m a rabbit with receipts tucked neat,
Opaque little handles, wonderfully sweet.
Git stays below while evidence takes flight,
Storage reveals what diagnostics write.
Hop through the timeline, secure and bright!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 2.86% 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 concisely summarizes the main v19 API hardening change around sealing Git substrate out of receipts and evidence.
Description check ✅ Passed It includes a summary, linked issue reference, and validation notes, which is mostly aligned with the required template.
Linked Issues check ✅ Passed The code and docs implement the storage-neutral receipts, opaque ticks, diagnostics, and declaration gate requested by #743.
Out of Scope Changes check ✅ Passed The remaining changes are tests, docs, and gates directly supporting the v19 API hardening; no unrelated scope stands out.

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

@flyingrobots

Copy link
Copy Markdown
Member Author

Self-review at d5b4b47ded6303235fa4314dd22e76e93abecb01

Verdict: clean; no open findings.

I reviewed the complete base-to-head diff for public API leakage, receipt/evidence correlation, provenance authorization and immutability, live-versus-historical read semantics, declaration-gate completeness, architecture quarantine, tests, docs, and migration impact.

Findings resolved before this final pass

  • The first implementation briefly put JSON canonicalization and an unknown helper boundary in domain code. I moved opaque-ID construction into the application runtime context, narrowed the error handling at its caller, and regenerated the contamination map. The committed diff preserves the repository's existing 1/2/0/0 quarantine baseline with no new exception. [cite: src/application/ReceiptProvenanceRegistry.ts#15-33@d5b4b47ded6303235fa4314dd22e76e93abecb01]
  • The public evidence model now contains only opaque handles and an optional tick; it cannot expose Git/CAS object identities. [cite: src/domain/api/Evidence.ts#3-13@d5b4b47ded6303235fa4314dd22e76e93abecb01]
  • Raw write/read/join identities remain available only through explicit, storage-authorized diagnostics. Provenance is single-assignment, immutable, receipt-bound, and rejected for the wrong storage instance. [cite: src/application/ReceiptProvenanceRegistry.ts#13-64@d5b4b47ded6303235fa4314dd22e76e93abecb01] [cite: diagnostics.ts#40-90@d5b4b47ded6303235fa4314dd22e76e93abecb01]
  • The root declaration check follows the full local emitted declaration graph and rejects forbidden substrate vocabulary transitively, including plural and objectId forms. [cite: scripts/v19-root-declaration-gate.ts#30-83@d5b4b47ded6303235fa4314dd22e76e93abecb01]

Validation

  • npm run test:local: 577 files passed, 1 skipped; 7,374 tests passed, 2 skipped.
  • npm run test:coverage:ci: 588 files passed, 1 skipped; 7,419 tests passed, 2 skipped; 92.62% line coverage threshold met.
  • npx vitest run test/integration: 19 files and 98 tests passed.
  • PATH="$PWD/bin:$PATH" bats test/bats/: 110/110 passed.
  • Source/test/consumer typechecks, lint, docs, declaration surface, contamination map, package dry-run, commit hook, and push hook all passed.
  • Graft's export analysis classifies the intended removals/additions as a major-version surface change.

The API break is intentional for v19: storage-neutral receipts replace raw substrate identities at root, while diagnostics retain exact operator visibility behind explicit storage authority.

@flyingrobots

Copy link
Copy Markdown
Member Author

Code Lawyer review at d5b4b47ded6303235fa4314dd22e76e93abecb01

Disposition: clean; no blocking contract defect and no unresolved issue.

Vocabulary and public-boundary law

The v19 root contract speaks in timelines, intents, readings, receipts, ticks, and opaque evidence handles. Git/CAS vocabulary and raw object identities are absent from receipt/evidence declarations; operator substrate details live in /diagnostics. [cite: src/domain/api/Evidence.ts#3-13@d5b4b47ded6303235fa4314dd22e76e93abecb01] [cite: diagnostics.ts#11-37@d5b4b47ded6303235fa4314dd22e76e93abecb01]

Provenance and authorization law

A runtime may bind provenance to a receipt once. Inspection requires the same opaque storage authority that issued it; unissued receipts and cross-storage inspection fail closed with stable error codes. Returned provenance is frozen, and join identity arrays are defensively copied before freezing. [cite: src/application/ReceiptProvenanceRegistry.ts#13-64@d5b4b47ded6303235fa4314dd22e76e93abecb01]

Settlement law

Receipt outcomes remain the control-flow axis. Accepted writes require evidence and prohibit a reason; unaccepted writes require a reason and prohibit evidence. The removed patchSha field therefore cannot survive through an alternate settlement variant. [cite: src/domain/api/WriteReceipt.ts#16-28@d5b4b47ded6303235fa4314dd22e76e93abecb01] [cite: src/domain/api/WriteReceipt.ts#78-95@d5b4b47ded6303235fa4314dd22e76e93abecb01]

Temporal identity law

A public Tick carries an opaque digest-derived ID, while its coordinate remains runtime-private in a WeakMap. Tick use is constrained to the issuing timeline/runtime and fails closed on mismatch. [cite: src/domain/api/TickRuntime.ts#12-45@d5b4b47ded6303235fa4314dd22e76e93abecb01] [cite: src/domain/api/TickRuntime.ts#48-57@d5b4b47ded6303235fa4314dd22e76e93abecb01]

Enforcement law

The boundary is mechanically enforced against the emitted root declaration closure, not merely the hand-written barrel. The AST gate follows local import/export/import-type edges and rejects forbidden singular, plural, and compound substrate vocabulary. [cite: scripts/v19-root-declaration-gate.ts#30-83@d5b4b47ded6303235fa4314dd22e76e93abecb01] [cite: scripts/v19-root-declaration-gate.ts#95-169@d5b4b47ded6303235fa4314dd22e76e93abecb01]

The intentional breaking surface is correctly classified as semver-major by Graft. Documentation and migration material describe diagnostics as the explicit escape hatch rather than preserving a second storage-bearing root contract.

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

Caution

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

⚠️ Outside diff range comments (3)
index.ts (1)

6-10: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Module doc comment is stale relative to the new root Evidence export.

The header says formal read, evidence, and support machinery lives under @git-stunts/git-warp/advanced, but line 21 now exports Evidence/EvidenceHandle directly from root. This contradicts the doc's stated boundary and could confuse consumers about where opaque evidence types live. Update the comment to reflect that Evidence/EvidenceHandle are first-use root types, reserving advanced for Optic/Witness/coordinate capture only.

📝 Proposed doc fix
- * Storage adapters live under `@git-stunts/git-warp/storage`; formal read,
- * evidence, and support machinery lives under `@git-stunts/git-warp/advanced`;
- * operator inspection tools live under `@git-stunts/git-warp/diagnostics`.
+ * Storage adapters live under `@git-stunts/git-warp/storage`; formal optic,
+ * coordinate, and witness machinery lives under `@git-stunts/git-warp/advanced`;
+ * operator inspection tools live under `@git-stunts/git-warp/diagnostics`.

Also applies to: 21-21

🤖 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 `@index.ts` around lines 6 - 10, Update the module header comment near the root
exports to state that Evidence and EvidenceHandle are first-use types exported
from the root package, and limit the advanced package description to Optic,
Witness, and coordinate-capture machinery. Keep the existing storage and
diagnostics boundaries unchanged.
src/domain/api/DraftTimelineRuntime.ts (1)

117-187: 🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win

TOCTOU race in joinDraftTimeline
await rejectedJoinPrecondition(...) yields before state.joining = true, so two back-to-back calls can both pass the guard and commit the same intents. Split the synchronous guard check from async rejection receipt creation so the in-progress flag is set before any await.

🤖 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/domain/api/DraftTimelineRuntime.ts` around lines 117 - 187, The
asynchronous rejectedJoinPrecondition check in joinDraftTimeline allows
concurrent calls to pass before state.joining is set. Split the synchronous
state validation from rejectedJoin receipt creation, set state.joining before
the first await, and preserve the existing rejection reasons and results for
joined, joining, failed, and empty-intent states.
src/domain/api/WriteRuntime.ts (1)

36-73: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Post-commit receipt creation can still fail the write.

commit() completes before createWriteEvidence() and context.bindReceipt(), so a failure there leaves the patch applied but reports a write error instead of a receipt. Split receipt binding from the commit path or add a recovery path for the already-committed write.

🤖 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/domain/api/WriteRuntime.ts` around lines 36 - 73, Update
executeIntentWrite and acceptedWriteReceipt so failures during post-commit
evidence creation or receipt binding cannot report the already-applied write as
failed. Separate commit completion from receipt construction/binding, or add
recovery that returns a valid receipt for the committed patch while preserving
operational failure handling for errors occurring before commit.
🤖 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/v19-root-declaration-gate.ts`:
- Around line 5-20: Update the compound-vocabulary validation in the root
declaration gate to inspect each adjacent token pair rather than only
tokens.join(''). Use FORBIDDEN_COMPOUNDS for every pair, so identifiers such as
rootObjectId, sourceObjectIds, and readObjectIdHex are rejected while preserving
the existing FORBIDDEN_TOKENS checks.

In `@src/application/ReceiptProvenanceRegistry.ts`:
- Around line 20-23: Update createOpaqueId to replace JSON.stringify with
delimiter-based serialization of the namespace and parts, using the existing
parts type of readonly (string | number)[] and preserving the current hash input
semantics without introducing JSON APIs in application code.

In `@src/domain/api/Evidence.ts`:
- Around line 9-15: Update the default export for the Evidence type in
Evidence.ts to use a type-only default re-export, replacing the value-style
export while preserving the existing Evidence type definition and default import
contract.

In `@src/domain/api/EvidenceRuntime.ts`:
- Around line 77-83: Extract undefined handling into a shared
freezeOptionalEvidence helper alongside freezeEvidence, delegating defined
values to freezeEvidence. Update the constructors in
src/domain/api/JoinReceipt.ts:37-60, src/domain/api/ReadReceipt.ts:34-59, and
src/domain/api/WriteReceipt.ts:30-55 to use the helper with their existing field
names, replacing each inline ternary.
- Around line 16-97: Define shared named constants for the opaque-id namespaces
used by createWriteEvidence, createJoinEvidence, createReadEvidence, and
createReadSupport, including write, join, read, patch, and index. Replace every
corresponding raw namespace literal passed to createHandle with the appropriate
constant, such as EVIDENCE_NAMESPACE.PATCH, while preserving the existing handle
inputs and ordering.

In `@test/unit/domain/ReceiptDiagnostics.test.ts`:
- Around line 14-24: Extract the duplicate createBoundedReadBasis helper from
ReceiptDiagnostics.test.ts and WarpFacade.test.ts into a shared test helper
module, then import and reuse that single implementation in both tests. Preserve
its existing parameters, runtime setup, materialization, and checkpoint
behavior.

---

Outside diff comments:
In `@index.ts`:
- Around line 6-10: Update the module header comment near the root exports to
state that Evidence and EvidenceHandle are first-use types exported from the
root package, and limit the advanced package description to Optic, Witness, and
coordinate-capture machinery. Keep the existing storage and diagnostics
boundaries unchanged.

In `@src/domain/api/DraftTimelineRuntime.ts`:
- Around line 117-187: The asynchronous rejectedJoinPrecondition check in
joinDraftTimeline allows concurrent calls to pass before state.joining is set.
Split the synchronous state validation from rejectedJoin receipt creation, set
state.joining before the first await, and preserve the existing rejection
reasons and results for joined, joining, failed, and empty-intent states.

In `@src/domain/api/WriteRuntime.ts`:
- Around line 36-73: Update executeIntentWrite and acceptedWriteReceipt so
failures during post-commit evidence creation or receipt binding cannot report
the already-applied write as failed. Separate commit completion from receipt
construction/binding, or add recovery that returns a valid receipt for the
committed patch while preserving operational failure handling for errors
occurring before commit.
🪄 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: 4f41f44c-2df6-47b8-91b8-f1c2b0420425

📥 Commits

Reviewing files that changed from the base of the PR and between a7976ad and d5b4b47.

📒 Files selected for processing (32)
  • diagnostics.ts
  • docs/migrations/v19/README.md
  • docs/topics/api/README.md
  • docs/topics/getting-started.md
  • docs/topics/querying.md
  • docs/topics/reference.md
  • index.ts
  • scripts/check-dts-surface.ts
  • scripts/v19-root-declaration-gate.ts
  • src/application/ReceiptProvenanceRegistry.ts
  • src/application/openWarp.ts
  • src/domain/api/ApiRuntimeContext.ts
  • src/domain/api/DraftTimelineRuntime.ts
  • src/domain/api/Evidence.ts
  • src/domain/api/EvidenceRuntime.ts
  • src/domain/api/JoinReceipt.ts
  • src/domain/api/ReadReceipt.ts
  • src/domain/api/ReadingRuntime.ts
  • src/domain/api/TickRuntime.ts
  • src/domain/api/TimelineRuntime.ts
  • src/domain/api/TimelineViewRuntime.ts
  • src/domain/api/WriteReceipt.ts
  • src/domain/api/WriteRuntime.ts
  • test/conformance/v18FirstUseOpticsHonesty.test.ts
  • test/type-check/v19-consumer.ts
  • test/type-check/v19-subpaths.ts
  • test/unit/domain/DraftTimelineRuntime.test.ts
  • test/unit/domain/ReceiptDiagnostics.test.ts
  • test/unit/domain/ReceiptOutcome.test.ts
  • test/unit/domain/WarpFacade.test.ts
  • test/unit/scripts/v19-public-api-boundary.test.ts
  • test/unit/scripts/v19-root-declaration-gate.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (3)
  • GitHub Check: preflight
  • GitHub Check: test-node (22)
  • GitHub Check: coverage-threshold
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{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/v19-root-declaration-gate.test.ts
  • index.ts
  • src/domain/api/ApiRuntimeContext.ts
  • src/domain/api/Evidence.ts
  • test/type-check/v19-subpaths.ts
  • src/application/ReceiptProvenanceRegistry.ts
  • src/application/openWarp.ts
  • src/domain/api/TickRuntime.ts
  • src/domain/api/ReadReceipt.ts
  • test/unit/scripts/v19-public-api-boundary.test.ts
  • src/domain/api/WriteRuntime.ts
  • src/domain/api/EvidenceRuntime.ts
  • test/type-check/v19-consumer.ts
  • src/domain/api/ReadingRuntime.ts
  • src/domain/api/TimelineViewRuntime.ts
  • test/conformance/v18FirstUseOpticsHonesty.test.ts
  • test/unit/domain/ReceiptOutcome.test.ts
  • scripts/check-dts-surface.ts
  • test/unit/domain/WarpFacade.test.ts
  • src/domain/api/JoinReceipt.ts
  • test/unit/domain/DraftTimelineRuntime.test.ts
  • diagnostics.ts
  • test/unit/domain/ReceiptDiagnostics.test.ts
  • src/domain/api/DraftTimelineRuntime.ts
  • src/domain/api/TimelineRuntime.ts
  • scripts/v19-root-declaration-gate.ts
  • src/domain/api/WriteReceipt.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/api/ApiRuntimeContext.ts
  • src/domain/api/Evidence.ts
  • src/application/ReceiptProvenanceRegistry.ts
  • src/application/openWarp.ts
  • src/domain/api/TickRuntime.ts
  • src/domain/api/ReadReceipt.ts
  • src/domain/api/WriteRuntime.ts
  • src/domain/api/EvidenceRuntime.ts
  • src/domain/api/ReadingRuntime.ts
  • src/domain/api/TimelineViewRuntime.ts
  • src/domain/api/JoinReceipt.ts
  • src/domain/api/DraftTimelineRuntime.ts
  • src/domain/api/TimelineRuntime.ts
  • src/domain/api/WriteReceipt.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/api/ApiRuntimeContext.ts
  • src/domain/api/Evidence.ts
  • src/domain/api/TickRuntime.ts
  • src/domain/api/ReadReceipt.ts
  • src/domain/api/WriteRuntime.ts
  • src/domain/api/EvidenceRuntime.ts
  • src/domain/api/ReadingRuntime.ts
  • src/domain/api/TimelineViewRuntime.ts
  • src/domain/api/JoinReceipt.ts
  • src/domain/api/DraftTimelineRuntime.ts
  • src/domain/api/TimelineRuntime.ts
  • src/domain/api/WriteReceipt.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/api/ApiRuntimeContext.ts
  • src/domain/api/Evidence.ts
  • src/domain/api/TickRuntime.ts
  • src/domain/api/ReadReceipt.ts
  • src/domain/api/WriteRuntime.ts
  • src/domain/api/EvidenceRuntime.ts
  • src/domain/api/ReadingRuntime.ts
  • src/domain/api/TimelineViewRuntime.ts
  • src/domain/api/JoinReceipt.ts
  • src/domain/api/DraftTimelineRuntime.ts
  • src/domain/api/TimelineRuntime.ts
  • src/domain/api/WriteReceipt.ts
🔇 Additional comments (32)
diagnostics.ts (1)

5-28: LGTM!

Also applies to: 37-61, 63-71, 73-89

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

4-13: LGTM!

Also applies to: 26-65, 66-88, 90-113, 114-136, 137-150, 152-168

test/conformance/v18FirstUseOpticsHonesty.test.ts (1)

4-4: LGTM!

Also applies to: 130-130, 188-188, 202-210

docs/topics/querying.md (1)

100-108: LGTM!

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

4-7: LGTM!

Also applies to: 20-33, 74-80, 95-116, 130-160

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

15-15: LGTM!

Also applies to: 139-139, 295-297, 361-361, 422-423, 437-437, 452-458, 564-570

index.ts (1)

21-21: LGTM!

Also applies to: 53-53

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

12-23: LGTM! The added @ts-expect-error assertions correctly verify patchSha, patchShas, and checkpointSha are no longer exposed, consistent with the opaque Evidence/EvidenceHandle contract.

Also applies to: 80-81, 114-122, 134-134

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

8-16: LGTM! InspectReceiptOptions/ReceiptSubstrateInspection usage and the @ts-expect-error for missing storage context match the inspectReceipt contract in diagnostics.ts.

Also applies to: 28-40

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

39-44: LGTM! Migration guidance is consistent with the opaque evidence contract and storage-required diagnostics.

Also applies to: 111-111, 229-266, 286-286, 307-318, 330-332

docs/topics/api/README.md (1)

119-119: LGTM! The new "Opaque Evidence" section and updated examples correctly describe the storage-neutral evidence handle contract.

Also applies to: 162-183, 263-263, 281-281, 413-418, 433-433

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

50-58: LGTM!

Also applies to: 83-83

docs/topics/reference.md (1)

39-85: LGTM!

Also applies to: 149-159

scripts/check-dts-surface.ts (1)

18-18: LGTM!

Also applies to: 224-238, 262-262, 363-366, 433-433

test/unit/scripts/v19-public-api-boundary.test.ts (2)

31-32: LGTM!

Also applies to: 63-64, 202-202, 242-244


12-13: 🗄️ Data Integrity & Integration

No issue with the Evidence export
src/domain/api/Evidence.ts exports Evidence as the default type, so export type { default as Evidence, EvidenceHandle } in index.ts is valid.

			> Likely an incorrect or invalid review comment.
test/unit/scripts/v19-root-declaration-gate.test.ts (1)

17-49: LGTM!

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

9-13: LGTM!

Also applies to: 15-42, 69-89, 91-106, 108-134

src/domain/api/ApiRuntimeContext.ts (1)

1-27: LGTM!

src/domain/api/ReadingRuntime.ts (1)

9-16: LGTM!

Also applies to: 28-48, 69-94, 180-209

src/domain/api/DraftTimelineRuntime.ts (1)

3-5: LGTM on the evidence/context-threading changes outside the guard flow (state shape, createDraftTimeline, previewDraftJoin, writeDraftIntent's SHA capture/validation, joinResult/acceptedJoinReceipt/unacceptedJoinReceipt) — these correctly thread context and match the createJoinEvidence contract and existing tests.

Also applies to: 15-15, 32-61, 79-83, 108-108, 203-233, 263-315

src/application/ReceiptProvenanceRegistry.ts (1)

1-19: LGTM on the binding/resolution/freeze logic (outside the flagged JSON.stringify call).

Also applies to: 24-65

src/domain/api/TickRuntime.ts (1)

4-4: LGTM!

Also applies to: 14-34, 48-58

src/application/openWarp.ts (1)

7-7: LGTM!

Also applies to: 25-40, 50-50

src/domain/api/TimelineRuntime.ts (1)

3-3: LGTM!

Also applies to: 17-43

src/domain/api/TimelineViewRuntime.ts (1)

2-24: LGTM!

src/domain/api/Evidence.ts (1)

1-6: LGTM!

src/domain/api/JoinReceipt.ts (1)

4-5: LGTM!

Also applies to: 18-30, 90-99, 107-114

src/domain/api/ReadReceipt.ts (1)

3-4: LGTM!

Also applies to: 18-30, 94-98

src/domain/api/WriteReceipt.ts (1)

3-4: LGTM!

Also applies to: 16-28, 78-95

src/domain/api/EvidenceRuntime.ts (1)

99-151: LGTM!

src/domain/api/WriteRuntime.ts (1)

13-23: LGTM!

Comment thread scripts/v19-root-declaration-gate.ts
Comment thread src/application/ReceiptProvenanceRegistry.ts
Comment thread src/domain/api/Evidence.ts
Comment thread src/domain/api/EvidenceRuntime.ts
Comment thread src/domain/api/EvidenceRuntime.ts
Comment thread test/unit/domain/ReceiptDiagnostics.test.ts Outdated
@flyingrobots

Copy link
Copy Markdown
Member Author

Final-head review addendum at 15e898964df3abe720c95a4218f36df3783f27dc

Self-review: clean. Code Lawyer: no open contract defect. CodeRabbit disposition: eight valid findings fixed; one compiler-proven false positive rejected. All six inline threads have explicit replies and are resolved.

Outside-diff findings

  • The root module contract now identifies opaque Evidence as a first-use root type and limits /advanced to formal optic, coordinate, and witness machinery. [cite: index.ts#8-11@15e898964df3abe720c95a4218f36df3783f27dc]
  • Join preconditions are synchronous, joining is set before the first await, and finally clears it. The regression starts both joins back-to-back before awaiting either and proves only one commit occurs. [cite: src/domain/api/DraftTimelineRuntime.ts#124-184@15e898964df3abe720c95a4218f36df3783f27dc] [cite: test/unit/domain/DraftTimelineRuntime.test.ts#60-100@15e898964df3abe720c95a4218f36df3783f27dc]
  • Writes reserve opaque recovery evidence before mutation. After commit, canonical hashing may fall back to an honest basis with empty support, while exact raw provenance remains bound for diagnostics. I applied the same settlement rule to accepted and partially committed joins. [cite: src/domain/api/WriteRuntime.ts#38-87@15e898964df3abe720c95a4218f36df3783f27dc] [cite: src/domain/api/EvidenceRuntime.ts#40-77@15e898964df3abe720c95a4218f36df3783f27dc] [cite: test/unit/domain/DraftTimelineRuntime.test.ts#102-173@15e898964df3abe720c95a4218f36df3783f27dc]

Inline findings

  • Opaque-ID hashing now uses typed, length-prefixed framing, avoiding both delimiter ambiguity and string/number collisions without JSON APIs. [cite: src/application/ReceiptProvenanceRegistry.ts#15-45@15e898964df3abe720c95a4218f36df3783f27dc] [cite: test/unit/domain/ReceiptDiagnostics.test.ts#14-25@15e898964df3abe720c95a4218f36df3783f27dc]
  • The declaration gate checks adjacent token pairs and the fixture covers embedded objectId variants. [cite: scripts/v19-root-declaration-gate.ts#47-84@15e898964df3abe720c95a4218f36df3783f27dc] [cite: test/unit/scripts/v19-root-declaration-gate.test.ts#17-65@15e898964df3abe720c95a4218f36df3783f27dc]
  • Evidence protocol tags are named, optional evidence freezing is centralized, and the bounded-read setup is shared between tests. [cite: src/domain/api/EvidenceRuntime.ts#16-127@15e898964df3abe720c95a4218f36df3783f27dc] [cite: test/helpers/BoundedReadBasis.ts#5-18@15e898964df3abe720c95a4218f36df3783f27dc]
  • type Evidence = ...; export default Evidence; is valid TypeScript split declaration/default-export syntax. It is accepted by source, test, consumer, emitted-declaration, Node, Bun, and Deno compilation and emits no runtime value. The review claim confused it with the invalid inline form export default type Evidence = ...; no change was warranted.

Final-head validation

  • Stable suite: 577 files passed, 1 skipped; 7,377 tests passed, 2 skipped.
  • Coverage: 588 files passed, 1 skipped; 7,422 tests passed, 2 skipped; 92.62% line threshold met.
  • Integration: 19 files and 98 tests passed.
  • Full lint, source/test/consumer typechecks, emitted surface, Semgrep, docs topology, source-backed reference, CAS invariant, and contamination baseline all passed.
  • The pre-push IRONCLAD firewall reran all static gates and the complete stable suite and authorized the push.
  • Graft reports no breaking change in the review-fix commit; its added exports are internal sibling-module/test helpers and do not change the package root declaration graph.

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

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/domain/api/EvidenceRuntime.ts`:
- Around line 40-45: Update createWriteRecoveryEvidence and the corresponding
recovery helper to derive recovery evidence IDs from a storage-scoped uniqueness
source, such as a storage-scoped port or injected runtime nonce, instead of
keying nextRecoverySequence solely from ApiRuntimeContext. Ensure reopening the
same worldline cannot regenerate an identical recovery handle for the same
inputs, while preserving the existing recovery evidence behavior.

In `@test/unit/domain/ReceiptDiagnostics.test.ts`:
- Around line 14-24: Update the test case around createApiRuntimeContext and
createOpaqueId to include a duplicate invocation with the same typed input, then
assert the resulting IDs are equal. Preserve the existing distinct-input
collision assertions while also verifying deterministic ID generation.
🪄 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: acf711b0-8323-49b8-9a3c-988b5df4b78b

📥 Commits

Reviewing files that changed from the base of the PR and between d5b4b47 and 15e8989.

📒 Files selected for processing (15)
  • docs/topics/reference.md
  • index.ts
  • scripts/v19-root-declaration-gate.ts
  • src/application/ReceiptProvenanceRegistry.ts
  • src/domain/api/DraftTimelineRuntime.ts
  • src/domain/api/EvidenceRuntime.ts
  • src/domain/api/JoinReceipt.ts
  • src/domain/api/ReadReceipt.ts
  • src/domain/api/WriteReceipt.ts
  • src/domain/api/WriteRuntime.ts
  • test/helpers/BoundedReadBasis.ts
  • test/unit/domain/DraftTimelineRuntime.test.ts
  • test/unit/domain/ReceiptDiagnostics.test.ts
  • test/unit/domain/WarpFacade.test.ts
  • test/unit/scripts/v19-root-declaration-gate.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (3)
  • GitHub Check: coverage-threshold
  • GitHub Check: test-node (22)
  • GitHub Check: preflight
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{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/BoundedReadBasis.ts
  • index.ts
  • test/unit/scripts/v19-root-declaration-gate.test.ts
  • src/application/ReceiptProvenanceRegistry.ts
  • src/domain/api/WriteReceipt.ts
  • src/domain/api/ReadReceipt.ts
  • src/domain/api/JoinReceipt.ts
  • src/domain/api/WriteRuntime.ts
  • scripts/v19-root-declaration-gate.ts
  • test/unit/domain/ReceiptDiagnostics.test.ts
  • src/domain/api/EvidenceRuntime.ts
  • src/domain/api/DraftTimelineRuntime.ts
  • test/unit/domain/DraftTimelineRuntime.test.ts
  • test/unit/domain/WarpFacade.test.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/application/ReceiptProvenanceRegistry.ts
  • src/domain/api/WriteReceipt.ts
  • src/domain/api/ReadReceipt.ts
  • src/domain/api/JoinReceipt.ts
  • src/domain/api/WriteRuntime.ts
  • src/domain/api/EvidenceRuntime.ts
  • src/domain/api/DraftTimelineRuntime.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/api/WriteReceipt.ts
  • src/domain/api/ReadReceipt.ts
  • src/domain/api/JoinReceipt.ts
  • src/domain/api/WriteRuntime.ts
  • src/domain/api/EvidenceRuntime.ts
  • src/domain/api/DraftTimelineRuntime.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/api/WriteReceipt.ts
  • src/domain/api/ReadReceipt.ts
  • src/domain/api/JoinReceipt.ts
  • src/domain/api/WriteRuntime.ts
  • src/domain/api/EvidenceRuntime.ts
  • src/domain/api/DraftTimelineRuntime.ts
🔇 Additional comments (15)
index.ts (1)

8-11: LGTM!

Also applies to: 22-22, 54-54

docs/topics/reference.md (1)

32-85: LGTM!

Also applies to: 152-159

scripts/v19-root-declaration-gate.ts (1)

65-76: LGTM!

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

17-35: LGTM!

Also applies to: 49-50, 90-92, 102-170

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

19-19: LGTM!

test/unit/scripts/v19-root-declaration-gate.test.ts (1)

23-57: LGTM!

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

11-11: LGTM!

Also applies to: 26-168

test/helpers/BoundedReadBasis.ts (1)

1-18: LGTM!

src/domain/api/JoinReceipt.ts (1)

5-5: LGTM!

Also applies to: 35-57

src/domain/api/ReadReceipt.ts (1)

4-4: LGTM!

Also applies to: 34-56, 91-95

src/domain/api/WriteReceipt.ts (1)

4-4: LGTM!

Also applies to: 19-19, 30-60

src/application/ReceiptProvenanceRegistry.ts (1)

15-75: LGTM!

src/domain/api/EvidenceRuntime.ts (1)

16-38: LGTM!

Also applies to: 47-66, 76-127

src/domain/api/WriteRuntime.ts (1)

4-5: LGTM!

Also applies to: 21-23, 38-86

src/domain/api/DraftTimelineRuntime.ts (1)

5-6: LGTM!

Also applies to: 15-80, 124-359

Comment thread src/domain/api/EvidenceRuntime.ts
Comment thread test/unit/domain/ReceiptDiagnostics.test.ts
@flyingrobots

flyingrobots commented Jul 14, 2026

Copy link
Copy Markdown
Member Author

Final-review follow-up at 888216a66b7761214ada9e6a768acd12b3900e12

Self-review: clean. Code Lawyer: clean; recovery handles now satisfy uniqueness across reopened contexts without weakening deterministic canonical IDs, exposing storage vocabulary, or persisting mutable metadata. Graft: no exported API changes and no breaking changes.

Both final CodeRabbit findings were valid and are fixed:

  • Recovery identity reservation is now application-owned and storage-scoped: one CSPRNG epoch plus a monotonic sequence is shared by every API context over the same opaque WarpStorage. [cite: src/application/ReceiptProvenanceRegistry.ts#13-50@888216a66b7761214ada9e6a768acd12b3900e12]
  • Domain evidence construction consumes only the opaque reserved token. [cite: src/domain/api/EvidenceRuntime.ts#128-143@888216a66b7761214ada9e6a768acd12b3900e12]
  • The internal runtime capability makes that ownership explicit. [cite: src/domain/api/ApiRuntimeContext.ts#20-27@888216a66b7761214ada9e6a768acd12b3900e12]
  • Tests prove both typed-input determinism and uniqueness across reopened contexts sharing one storage. [cite: test/unit/domain/ReceiptDiagnostics.test.ts#14-38@888216a66b7761214ada9e6a768acd12b3900e12]

Validation: focused 15/15; stable 577 files passed, 1 skipped / 7,378 tests passed, 2 skipped; coverage 588 files passed, 1 skipped / 7,423 tests passed, 2 skipped / 92.62% lines; integration 19/19 files, 98/98 tests; lint, source size, CAS invariants, Semgrep, contamination ratchet, source/test/consumer types, publication surface, source-backed docs, policy, and the complete IRONCLAD pre-push firewall all green. Both new review threads have explicit replies and are resolved.

@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.

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.

Seal Git substrate out of v19 receipts, ticks, and evidence

1 participant