Skip to content

Classify v19 writes with admission outcomes - #768

Merged
flyingrobots merged 3 commits into
mainfrom
v19/write-admission-receipts
Jul 20, 2026
Merged

Classify v19 writes with admission outcomes#768
flyingrobots merged 3 commits into
mainfrom
v19/write-admission-receipts

Conversation

@flyingrobots

@flyingrobots flyingrobots commented Jul 20, 2026

Copy link
Copy Markdown
Member

Summary

  • replace generic write statuses with a closed derived | plural | conflict | obstruction admission union
  • require a distinct typed witness, explicit evaluation binding, and residual posture for every write result
  • capture the exact graph or strand basis while exposing only storage-neutral evidence handles
  • keep runtime failures outside causal outcomes and keep admission distinct from later settlement

Issue

Refs #712
Refs #765

This is the write-admission child slice of the broader v19 Runtime, Lane, and Observation public API goalpost. It does not close #712.

Semantics

  • derived and plural are admitted outcomes with different causal topology
  • conflict and obstruction remain operationally distinct and carry different recovery evidence
  • plurality is a lawful terminal posture and is not automatically linearized
  • draft writes retain derived and plural admissions; conflict and obstruction do not append
  • public evidence handles reveal no Git object IDs, patch journals, or other substrate identities
  • malformed input, process failures, and implementation defects reject outside the causal union

Test plan

  • Full stable unit suite through the pre-push hook: 7,129 passed, 2 skipped
  • Focused admission/write suite: 64 passed
  • Git storage integration target
  • Node 22, Bun, and Deno CI matrix
  • Coverage threshold
  • Lint, Semgrep, type, consumer, and public-surface firewalls
  • Documentation topology, Markdown, links, and code samples
  • Release preflight, npm pack dry-run, and JSR publish dry-run

ADR checks

  • This PR does not implement ADR 2 without satisfying ADR 3
  • Persisted op formats are unchanged; an ADR 3 readiness issue is not required for this slice
  • Wire compatibility is unchanged; canonical-only wire behavior remains unchanged
  • Schema constants are unchanged; patch and checkpoint namespaces remain distinct

Review

The branch received a clean second self-review after correcting three first-pass findings. CodeRabbit completed an assertive review; its remaining inline maintainability request is addressed in the follow-up commit.

@flyingrobots

Copy link
Copy Markdown
Member Author

Self-code review

Severity Open Resolved during review
Critical 0 0
High 0 0
Medium 0 1
Low 0 2

The first pass found and corrected three issues in e14665799: plural draft admissions were not being retained, an internal field name still encoded the obsolete accepted-status vocabulary, and whitespace-only projection bases were not rejected.

The clean follow-up pass reviewed the complete origin/main...HEAD diff for semantic phase separation, illegal union states, substrate leakage, exact basis binding, runtime-failure handling, draft behavior, public export drift, documentation consistency, and test coverage. I found zero remaining actionable findings. The intentional root-surface change is semver-major and belongs to the v19 cutover.

@codex please confirm the branch has no remaining actionable correctness, contract, or documentation findings.

@coderabbitai

coderabbitai Bot commented Jul 20, 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: 40 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: 89549da6-beee-4091-9fe1-e34aa3edb2da

📥 Commits

Reviewing files that changed from the base of the PR and between e146657 and 582c4ff.

📒 Files selected for processing (1)
  • src/domain/api/WriteAdmissionRuntime.ts
📝 Walkthrough

Walkthrough

The PR replaces legacy write receipt outcome strings with a closed AdmissionOutcome union, typed witnesses, immutable runtime projections, causal-basis tracking, and admission-aware write classification. Read and join receipts retain separate transitional outcome aliases.

Changes

Admission outcome migration

Layer / File(s) Summary
Admission contracts and receipt validation
src/domain/api/AdmissionOutcome.ts, src/domain/api/AdmissionOutcomeRuntime.ts, src/domain/api/ReceiptOutcome.ts, src/domain/api/WriteReceipt.ts, index.ts
Defines derived, plural, conflict, and obstruction outcomes with typed witnesses; projects immutable runtime outcomes; separates read/join statuses; and validates typed write outcomes.
Causal basis and coordinate capture
src/domain/services/admission/*, src/domain/services/PatchBuilder.ts, src/domain/services/controllers/PatchController.ts, src/domain/services/strand/*
Captures immutable patch causal basis metadata and computes deterministic graph, checkpoint, and strand evaluation coordinates.
Write admission classification
src/domain/api/WriteAdmissionRuntime.ts, src/domain/api/WriteRuntime.ts, src/domain/api/DraftTimelineRuntime.ts, test/unit/domain/WriteRuntime.test.ts, test/unit/domain/WarpFacade.test.ts
Prepares write evaluations, creates derived or obstructed admissions, maps selected failures to structured witnesses, and updates draft receipt handling.
Consumer migration and validation
README.md, docs/**, test/type-check/v19-consumer.ts, test/integration/**, test/unit/domain/**, test/unit/scripts/**
Updates examples, migration documentation, diagnostics, integration checks, type-consumer checks, and the locked root export contract.

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

Possibly related issues

Possibly related PRs

Poem

A rabbit hops through outcomes four,
With typed witnesses at the door.
Derived or blocked, each path is clear,
Causal clues are held quite near.
Old receipt strings fade from sight—
Admission guides the write tonight.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 8.47% 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
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.
Title check ✅ Passed The title clearly summarizes the main change: classifying v19 writes with admission outcomes.
Description check ✅ Passed The description includes Summary, Issue, Test plan, ADR checks, and a review note, matching the template well.

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.

@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 `@src/domain/api/WriteAdmissionRuntime.ts`:
- Around line 124-135: Introduce a named constant for the intent kinds that do
not require a bounded basis coordinate, and update
resolveEvaluationCoordinateRef to check membership in that constant instead of
hardcoding 'node.add' and 'edge.add'. Preserve the existing fallback behavior
for all other intent kinds.
🪄 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: 6b7b208a-b072-45ac-a105-1eab3ce1fe17

📥 Commits

Reviewing files that changed from the base of the PR and between 54d0c25 and e146657.

📒 Files selected for processing (35)
  • CHANGELOG.md
  • README.md
  • docs/migrations/v19/README.md
  • docs/topics/api/README.md
  • docs/topics/getting-started.md
  • docs/topics/reference.md
  • docs/topics/supported-outcome-settlement.md
  • index.ts
  • src/domain/api/AdmissionOutcome.ts
  • src/domain/api/AdmissionOutcomeRuntime.ts
  • src/domain/api/ApiRuntimeContext.ts
  • src/domain/api/DraftTimelineRuntime.ts
  • src/domain/api/JoinReceipt.ts
  • src/domain/api/ReadReceipt.ts
  • src/domain/api/ReceiptOutcome.ts
  • src/domain/api/WriteAdmissionRuntime.ts
  • src/domain/api/WriteReceipt.ts
  • src/domain/api/WriteRuntime.ts
  • src/domain/services/PatchBuilder.ts
  • src/domain/services/admission/BoundedIntentGuardReader.ts
  • src/domain/services/admission/GraphCoordinateRef.ts
  • src/domain/services/admission/PatchBuilderCausalBasis.ts
  • src/domain/services/controllers/PatchController.ts
  • src/domain/services/strand/StrandPatchService.ts
  • src/domain/services/strand/createStrandCoordinator.ts
  • test/integration/application/GitStorage.integration.test.ts
  • test/type-check/v19-consumer.ts
  • test/unit/domain/AdmissionOutcomeRuntime.test.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/domain/WriteRuntime.test.ts
  • test/unit/domain/services/controllers/StrandController.host-interface.test.ts
  • test/unit/scripts/v19-public-api-boundary.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/unit/domain/services/controllers/StrandController.host-interface.test.ts
  • test/integration/application/GitStorage.integration.test.ts
  • src/domain/api/ApiRuntimeContext.ts
  • src/domain/services/strand/createStrandCoordinator.ts
  • src/domain/services/admission/PatchBuilderCausalBasis.ts
  • src/domain/api/DraftTimelineRuntime.ts
  • src/domain/api/ReceiptOutcome.ts
  • test/unit/domain/AdmissionOutcomeRuntime.test.ts
  • index.ts
  • src/domain/services/admission/GraphCoordinateRef.ts
  • src/domain/api/AdmissionOutcome.ts
  • src/domain/services/controllers/PatchController.ts
  • src/domain/api/ReadReceipt.ts
  • test/unit/domain/WarpFacade.test.ts
  • src/domain/api/AdmissionOutcomeRuntime.ts
  • src/domain/api/JoinReceipt.ts
  • test/unit/domain/WriteRuntime.test.ts
  • test/type-check/v19-consumer.ts
  • test/unit/domain/ReceiptOutcome.test.ts
  • test/unit/domain/ReceiptDiagnostics.test.ts
  • src/domain/api/WriteRuntime.ts
  • src/domain/api/WriteAdmissionRuntime.ts
  • test/unit/domain/DraftTimelineRuntime.test.ts
  • src/domain/services/strand/StrandPatchService.ts
  • src/domain/services/PatchBuilder.ts
  • src/domain/api/WriteReceipt.ts
  • test/unit/scripts/v19-public-api-boundary.test.ts
  • src/domain/services/admission/BoundedIntentGuardReader.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/services/strand/createStrandCoordinator.ts
  • src/domain/services/admission/PatchBuilderCausalBasis.ts
  • src/domain/api/DraftTimelineRuntime.ts
  • src/domain/api/ReceiptOutcome.ts
  • src/domain/services/admission/GraphCoordinateRef.ts
  • src/domain/api/AdmissionOutcome.ts
  • src/domain/services/controllers/PatchController.ts
  • src/domain/api/ReadReceipt.ts
  • src/domain/api/AdmissionOutcomeRuntime.ts
  • src/domain/api/JoinReceipt.ts
  • src/domain/api/WriteRuntime.ts
  • src/domain/api/WriteAdmissionRuntime.ts
  • src/domain/services/strand/StrandPatchService.ts
  • src/domain/services/PatchBuilder.ts
  • src/domain/api/WriteReceipt.ts
  • src/domain/services/admission/BoundedIntentGuardReader.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/services/strand/createStrandCoordinator.ts
  • src/domain/services/admission/PatchBuilderCausalBasis.ts
  • src/domain/api/DraftTimelineRuntime.ts
  • src/domain/api/ReceiptOutcome.ts
  • src/domain/services/admission/GraphCoordinateRef.ts
  • src/domain/api/AdmissionOutcome.ts
  • src/domain/services/controllers/PatchController.ts
  • src/domain/api/ReadReceipt.ts
  • src/domain/api/AdmissionOutcomeRuntime.ts
  • src/domain/api/JoinReceipt.ts
  • src/domain/api/WriteRuntime.ts
  • src/domain/api/WriteAdmissionRuntime.ts
  • src/domain/services/strand/StrandPatchService.ts
  • src/domain/services/PatchBuilder.ts
  • src/domain/api/WriteReceipt.ts
  • src/domain/services/admission/BoundedIntentGuardReader.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/services/strand/createStrandCoordinator.ts
  • src/domain/services/admission/PatchBuilderCausalBasis.ts
  • src/domain/api/DraftTimelineRuntime.ts
  • src/domain/api/ReceiptOutcome.ts
  • src/domain/services/admission/GraphCoordinateRef.ts
  • src/domain/api/AdmissionOutcome.ts
  • src/domain/services/controllers/PatchController.ts
  • src/domain/api/ReadReceipt.ts
  • src/domain/api/AdmissionOutcomeRuntime.ts
  • src/domain/api/JoinReceipt.ts
  • src/domain/api/WriteRuntime.ts
  • src/domain/api/WriteAdmissionRuntime.ts
  • src/domain/services/strand/StrandPatchService.ts
  • src/domain/services/PatchBuilder.ts
  • src/domain/api/WriteReceipt.ts
  • src/domain/services/admission/BoundedIntentGuardReader.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
🔇 Additional comments (37)
src/domain/api/AdmissionOutcome.ts (1)

1-95: LGTM!

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

22-22: LGTM!

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

1-14: LGTM!

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

6-12: LGTM!

Also applies to: 36-36

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

3-25: LGTM!

Also applies to: 39-42, 47-52, 60-61

index.ts (1)

29-57: LGTM!

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

1-122: LGTM!

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

4-21: LGTM!

Also applies to: 30-37, 96-126, 145-155

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

126-146: 🗄️ Data Integrity & Integration

reason is already a closed object with only family and code, so the spread is harmless.

			> Likely an incorrect or invalid review comment.
src/domain/api/ReadReceipt.ts (1)

6-12: LGTM!

Also applies to: 35-35

src/domain/services/admission/GraphCoordinateRef.ts (1)

1-49: LGTM!

src/domain/services/admission/PatchBuilderCausalBasis.ts (1)

1-30: LGTM!

src/domain/services/PatchBuilder.ts (1)

40-40: LGTM!

Also applies to: 61-62, 115-124

src/domain/services/admission/BoundedIntentGuardReader.ts (1)

7-12: LGTM!

Also applies to: 60-69

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

41-41: LGTM!

Also applies to: 154-157

src/domain/services/strand/StrandPatchService.ts (1)

20-20: LGTM!

Also applies to: 42-50, 245-245, 254-264, 343-347

src/domain/services/strand/createStrandCoordinator.ts (1)

59-59: LGTM!

test/unit/domain/services/controllers/StrandController.host-interface.test.ts (1)

30-30: LGTM!

src/domain/api/WriteAdmissionRuntime.ts (3)

1-22: LGTM!

Also applies to: 64-122, 137-171, 185-211


47-62: 🎯 Functional Correctness

No return-type change needed. AdmissionClassifier.classify(DerivationWitness) already returns DerivedAdmission; PluralAdmission is produced from PluralityWitness, not this path.

			> Likely an incorrect or invalid review comment.

173-207: 🎯 Functional Correctness

writerId and participantId are intentionally separate
participantId binds the admission to runtime.writerId; writerId is used for patch-journal and publication refs.

			> Likely an incorrect or invalid review comment.
src/domain/api/WriteRuntime.ts (1)

3-25: LGTM!

Also applies to: 36-181, 197-252

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

234-255: LGTM!

docs/topics/reference.md (1)

39-82: LGTM!

docs/topics/supported-outcome-settlement.md (1)

19-20: LGTM!

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

26-26: LGTM!

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

11-32: LGTM!

Also applies to: 59-60, 77-77, 88-103, 130-137

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

6-18: LGTM!

Also applies to: 57-57, 81-84, 164-168, 178-188

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

9-51: LGTM!

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

1-182: LGTM!

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

263-263: LGTM!

Also applies to: 279-306, 366-377, 572-572

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

20-20: LGTM!

Also applies to: 52-99, 114-114, 161-161, 188-197, 283-283

CHANGELOG.md (1)

14-16: LGTM!

README.md (1)

90-91: LGTM!

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

18-18: LGTM!

Also applies to: 119-137, 258-261, 284-284, 300-325

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

332-336: LGTM!

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

55-73: LGTM!

Comment thread src/domain/api/WriteAdmissionRuntime.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 dbc8651 into main Jul 20, 2026
17 checks passed
@flyingrobots
flyingrobots deleted the v19/write-admission-receipts branch July 20, 2026 08:39
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.

Goalpost: v19 Runtime, Lane, and Observation public API

1 participant