Skip to content

docs(plan): ship raw-handle-export-contract — fold into §Packages and archive - #1908

Merged
tato123 merged 1 commit into
mainfrom
docs/ship-raw-handle-export-contract
Aug 22, 2026
Merged

docs(plan): ship raw-handle-export-contract — fold into §Packages and archive#1908
tato123 merged 1 commit into
mainfrom
docs/ship-raw-handle-export-contract

Conversation

@tato123

@tato123 tato123 commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator

Ships raw-handle-export-contract: folds it into ARCHITECTURE.md §Packages, adds the diagram edge it was missing, and archives the change file under its ticket's merge date.

Precondition — every ticket merged

The change file states it maps 1:1 to a single ticket, so the milestone precondition is one row:

Ticket PR Merged
#1900 spell the OPAQUE_FD texture export in the wheel #1905 2026-08-22

Archive date is #1905's merge date, 2026-08-22.

Step 1 — the REMOVED gate

$ bash .claude/scripts/ship-change-removed-gate.sh docs/plan/changes/raw-handle-export-contract.md
note: docs/plan/changes/raw-handle-export-contract.md declares no '- REMOVED:' bullets — nothing to verify.
EXIT: 0

This is the change's own declared shape, not an omission — its ## REMOVED section reads "Nothing. No REMOVED: bullets; the ship gate has nothing to verify gone." The change was additive spelling over plan text #1903 had already merged, so nothing in the tree retires with it. Re-run against the archived path is identical.

Step 2 — the fold

The §Packages raw-handle entry is marked [raw-handle-export-contract — SHIPPED #1900] with three verify: markers.

Most of what this change built was already written into the entry by the align that decided it (#1903) — Full-only minting, the use bound, allocation-not-frame semantics, and the full field list the typed export carries. The fold therefore adds only the three contract facts the entry did not state, each verified against the shipped code:

  • An export is taken from a resolved surface, never from a name. The fd reaches a helper at checkout (SCM_RIGHTS), so a texture acquired but not yet resolved is refused telling the caller to resolve its surface id first, and every other refusal names the flavour's own door.
  • The recipe travels because a raw allocation is consumed as an image — a linear buffer mapping over tiled memory yields block-linear bytes, never pixels. That is why tiling, usage and the mip/layer/sample counts sit on the export object instead of being the importer's guess.
  • A successful import pins the payload past the exporter destroying the source texture. This is the useful direction of the entry's existing "the surface-id lifetime guarantees end at export", and it has a test.

The OPEN zero-copy-per-frame entry is untouched — it is its own align, and out of scope by the change's own statement.

The section header drops the archived change and stays IN-FLIGHT (→ importable-python-library).

Every marker resolves to a real test target, checked with cargo metadata and by name:

  • opaque_fd_wheel_export_foreign_consumer::a_wheel_exported_opaque_fd_read_by_a_foreign_process_shows_the_kernels_pixels — a second VkDevice in a genuinely foreign process, driven only by the exported bundle
  • opaque_fd_image_consumer_rhi_round_trip::an_exported_opaque_fd_pins_the_payload_past_source_texture_teardown — the audit addendum probe
  • test_device_exchange.py::test_a_texture_handle_round_trips_across_the_process_boundary — carries the metadata and refusal assertions; requires_gpu, so rig-only, never CI

Step 3 — the diagram

system.mmd gains a helper --> pkgs edge for the Full-gated raw fd. Neither #1903 (the plan text) nor #1904 (the change file) touched the diagram, so this DECIDED entry was unrepresented against the plan's own opening rule that "every DECIDED entry is represented in the diagram". The existing pkgs --> helper arrow covers only the inbound direction — a third-party package exposing handles to Python. The export is the outbound one.

Verification

cargo run -p xtask -- check-all-source-gates — all 10 source-walking gates pass.

Spot-checked that the change's non-plan claims actually landed: README.md:251-252 now names both export_dma_buf and export_opaque_fd as ctx.gpu_full_access methods (the doc-rot bullet), and test_device_exchange.py:279 asserts the redirect names export_opaque_fd.

🤖 Generated with Claude Code

… archive

The change maps 1:1 to #1900, closed 2026-08-22 by PR #1905, so the
milestone precondition is one ticket and it is merged. The removal gate has
nothing to verify: the change declares no REMOVED bullets, by design — this
was additive spelling over plan text #1903 had already merged.

The §Packages raw-handle entry is marked SHIPPED. Most of what the change
built was already written there by the align, so the fold adds only the
three contract facts the entry did not state:

- An export is taken from a resolved surface, never from a name. The fd
  reaches a helper at checkout, so an acquired-but-unresolved texture is
  refused telling the caller to resolve its surface id first, and every
  other refusal names the flavour's own door.
- The recipe travels because a raw allocation is consumed as an image. A
  linear buffer mapping over tiled memory yields block-linear bytes, never
  pixels — the reason tiling, usage and the mip/layer/sample counts are on
  the export object rather than being the importer's guess.
- A successful import pins the payload past the exporter destroying the
  texture it came from, which is the useful direction of "the surface-id
  lifetime guarantees end at export".

The OPEN zero-copy-per-frame entry is untouched — it is its own align.

The system diagram gains the helper→packages edge. Neither #1903 nor #1904
drew this contract, so the entry was unrepresented against the plan's own
rule that every DECIDED entry appears in the diagram.

Refs #1900

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

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

Next review available in: 35 minutes

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

Wait for the limit to reset, then comment @coderabbitai review or push new commits to the PR.

An organization admin can change what happens after included review limits in Billing.

How do review limits work?

CodeRabbit enforces per-developer PR review limits within each organization.

For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: dc555155-fd8e-4d3f-b003-41eec72a300a

📥 Commits

Reviewing files that changed from the base of the PR and between 059464b and 21b756f.

📒 Files selected for processing (3)
  • docs/plan/ARCHITECTURE.md
  • docs/plan/changes/archive/2026-08-22-raw-handle-export-contract.md
  • docs/plan/diagrams/system.mmd

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.

@tato123
tato123 merged commit d6b12a7 into main Aug 22, 2026
5 checks passed
@tato123
tato123 deleted the docs/ship-raw-handle-export-contract branch August 22, 2026 19:54
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