Skip to content

[default values] Handshake and drop read-bridge overlays on the server - #678

Open
cbb330 wants to merge 4 commits into
chbush/read-bridge-policy-rampfrom
chbush/read-bridge-sanitize-on-write
Open

[default values] Handshake and drop read-bridge overlays on the server#678
cbb330 wants to merge 4 commits into
chbush/read-bridge-policy-rampfrom
chbush/read-bridge-sanitize-on-write

Conversation

@cbb330

@cbb330 cbb330 commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

Summary

Depends on #674 (policy), stacked on #668#645. #679 (ReadBridge.apply) restacks on this PR.

Read-bridge overlays must not persist. This PR puts the drop on the server before apply lands, so there is no deployable cut where overlays are applied but not stripped.

Default-aware clients send initial-default on stamped field-ids (the handshake). The server gates Type 1 / Type 2, then strips those keys before Iceberg commit. Unstamped ids keep the writer's defaults.

Until #679, apply is still a no-op; PUTs only carry initial-default if the writer set it. The server is already safe: drop is a no-op when the handshake is absent, and Type 2 fail-closes unaware rewrites on ramped tables.

How strip protection works

Gate When Result
Type 1 Ramped table; a previously stamped field-id is still in the schema but missing from incoming stamps 400 COLUMN_DEFAULT_REMOVED
Type 2 Ramped rewrite (replace / overwrite on main) while previous stamps are nonempty 400 COLUMN_DEFAULT_REWRITE unless each remaining id's initial-default JSON equals the stamp
Unusable Ramped write; source throw / unreadable schema / unreadable snapshots 400 COLUMN_DEFAULT_UNUSABLE
Drop After gates pass Remove initial-default on stamped ids (same findParents("id") walk as the client)

Unramped tables are a no-op. GET resolve() still fail-opens; only the write path is fail-closed. Awareness is JsonNode.equals against the stamped config, not key presence.

OSS never parses ASL. ColumnDefaultsSource is the seam (NONE in OSS); LinkedIn fills it. Type 1 compares stamped field-id sets from the resolver.

Changes

  • New Features — ReadBridgeStripProtection.prepare on PUT table / snapshots
  • Internal API Changes — resolver write APIs stampedColumnDefaults / isRampedForCommit
  • Tests — unit Type 1/2/unusable, mock bean for MockTablesApplication, HTTP e2e that GET initialDefault() is null after overlay PUT

Testing Done

  • Added new tests for the changes made.
  • Updated existing tests to reflect the changes made.
  • Local (Java 17): ./gradlew :services:tables:test --tests '*ReadBridgeStripProtectionTest' --tests '*ReadBridgeConfigResolverTest' --tests '*ReadBridgeColumnDefaultE2ETest'

Additional Information

  • Large PR broken into smaller PRs, and PR plan linked in the description.

Stack

  1. #645 — substrate (seam + encode + decode hook)
  2. #668 — decode off Iceberg’s retry path
  3. #674 — policy / ramp in OpenHouse
  4. This PR — handshake on PUT, Type 1/2, drop before persist
  5. #679ReadBridge.apply (merge after this PR)
  6. #681 — Spark catalog itest (overlay)

Rollback Plan

Revert this PR. After #679, clients send overlays; without the server drop they persist in Iceberg metadata.

@cbb330
cbb330 force-pushed the chbush/read-bridge-sanitize-on-write branch 5 times, most recently from ff60798 to a5571f8 Compare August 13, 2026 02:48
@cbb330
cbb330 force-pushed the chbush/read-bridge-policy-ramp branch from ab56db9 to d5faa07 Compare August 13, 2026 05:42
@cbb330
cbb330 force-pushed the chbush/read-bridge-sanitize-on-write branch from f05903f to 9d1bb96 Compare August 13, 2026 05:42
@cbb330
cbb330 marked this pull request as ready for review August 13, 2026 06:05
@cbb330
cbb330 force-pushed the chbush/read-bridge-policy-ramp branch from d5faa07 to b0fbf21 Compare August 13, 2026 06:10
@cbb330
cbb330 force-pushed the chbush/read-bridge-sanitize-on-write branch from 253129c to 7c005b2 Compare August 13, 2026 06:10
@cbb330
cbb330 force-pushed the chbush/read-bridge-sanitize-on-write branch from 7c005b2 to a93119a Compare August 13, 2026 22:27
@cbb330 cbb330 changed the title [default values] Sanitize read-bridge overlays before commit [default values] Handshake and drop read-bridge overlays on the server Aug 13, 2026
@cbb330
cbb330 changed the base branch from chbush/read-bridge-policy-ramp to chbush/read-bridge-apply August 13, 2026 22:27
@cbb330
cbb330 force-pushed the chbush/read-bridge-sanitize-on-write branch from a93119a to 4ad3f14 Compare August 13, 2026 22:35
@cbb330
cbb330 changed the base branch from chbush/read-bridge-apply to chbush/read-bridge-policy-ramp August 13, 2026 22:35
@cbb330
cbb330 force-pushed the chbush/read-bridge-policy-ramp branch from b0fbf21 to ea956d9 Compare August 13, 2026 23:55
cbb330 added 2 commits August 13, 2026 16:55
Default-aware clients must send the overlay on the wire; the server uses it to
block unaware overwrite/replace, rejects dropping a live default, then strips
stamped keys before persist.
Type 1/2 only run when the table is ramped. Awareness is JSON
equality with the stamp, not key presence. Write-path source and
parse failures are 400; a bug stays 500. HTTP e2e proves overlays
do not persist.
@cbb330
cbb330 force-pushed the chbush/read-bridge-sanitize-on-write branch from 4ad3f14 to b8a8a8b Compare August 13, 2026 23:56
cbb330 added 2 commits August 13, 2026 21:43
Those tests belong on the apply PR. This PR is the server handshake
and drop; the client still does not overlay until apply lands.
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