contract: WideFieldMask — backward-compatible >64-field masks (canonical form, repr-independent Eq/Hash)#651
Conversation
Add WideFieldMask alongside the untouched FieldMask (u64 presence mask) to represent classes with more than FieldMask::MAX_FIELDS (64) fields, e.g. Odoo account.move (109 fields). FieldMask itself is not modified in any way (no new derives, no changed method signatures, no representation change) so every existing FieldMask(u64)/EMPTY/FULL/with/has/from_positions/MAX_FIELDS call site keeps compiling and behaving identically. An internal Repr::Small(u64)|Repr::Wide(Box<[u64]>) swap inside FieldMask itself was considered and rejected: several call sites (ClassProjection::next, FieldMask::from_positions) rely on FieldMask: Copy for self-by-value method chaining, and a Box-bearing repr cannot be Copy - that would have silently broken existing callers, the exact footgun Ruling (c) forbids. WideFieldMask mirrors the FieldMask API shape (EMPTY, with, has, from_positions, count, is_empty, intersect, union, max_fields, full_for) and allocates only on demand: it stays in a zero-heap Small(u64) repr identical to FieldMask until a position >= 64 is set, then promotes once to a Wide(Box<[u64]>) chunk vector. Bit position N keeps the same logical field across both types and both tiers (N3 stability) - the widening only adds positions >= 64, never moves 0..63. Tests added (all in lance-graph-contract::class_view): u64_constructors_unchanged pins the untouched FieldMask API incl. Copy; wide_class_positions_beyond_64_are_representable sets/reads position 65 (mirrors the OGAR-side pin test's motivating case); small_mask_never_allocates asserts the Small repr for <=64-field masks; intersect_union_across_tiers covers Small/Wide and Wide/Wide folds; full_for_wide_class_emits_all covers a 109-field full mask; field_mask_promotes_into_wide_field_mask_losslessly covers the FieldMask -> WideFieldMask conversion. Every pre-existing test in the crate stays green unchanged (828 lib tests + existing integration/doc tests, all passing). Verified lance-graph-rbac, lance-graph-ontology, and lance-graph-arm-discovery (all internal FieldMask consumers) still compile and pass their full test suites unmodified. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…h (V-L P0) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Warning Review limit reached
Next review available in: 43 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the 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 configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
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. Comment |
What
L-1 of the criticals wave (operator ruling (c), 2026-07-06): widen the FieldMask ceiling past 64 fields without touching
FieldMaskitself —account.movehas 109 declared fields; today everything past bit 63 silently drops (X7/F14 blocker).Design (non-footgun, per ruling)
FieldMaskis byte-for-byte untouched — zero removed lines,Copy/const-fn/u64 semantics intact. Verified:git diff | grep '^-'shows only the two derive lines on the new type (see below). The enum-repr alternative (Repr::Small|WideinsideFieldMask) was evaluated and rejected:ClassProjection::next/from_positionsrely onFieldMask: Copy, and aBox-bearing repr would break exactly the way ruling (c) forbids.WideFieldMask:Repr::Small(u64)(bit-identical toFieldMask, allocation-free) promoting once toRepr::Wide(Box<[u64]>)at position ≥64. Bit N = the same logical N3 field across both reprs. LosslessFrom<FieldMask>; deliberately no lossy reverse conversion.intersect/unionresults trim trailing zero chunks and demote toSmallwhen they fit;PartialEq/Eq/Hashare hand-written over a trimmed chunk view, so semantically equal masks are equal and hash identically regardless of representation — the adversarial review reproduced the footgun (a.intersect(&b) != from_positions(same set)) before merge; regression test pins it.0x1000→0x1001reserved as last resort, unused).Doctrine alignment
docs/CLASSVIEW-FIELDVIEW-ASKAMA-BITMASK.md(OGAR): the u64/MAX_FIELDS=64mask was always documented as "the eventual expansion — to the class-conditioned shape, not a locked width".WideFieldMask::full_for(field_count)is exactly that class-conditioned shape. Note the same doctrine caps meaningful masks atFIELD_MASK_CAP = MAX_SIBLINGS_PER_TIER(256): a ≥256-field class is anOGAR-SOCsplit signal, not a mask-widening use case — consumers should treat WideFieldMask capacity beyond 256 as headroom, not license.Verification
cargo test -p lance-graph-contract— 829 passed, 0 failed (incl. 7 new: u64-pin, >64 representable, no-alloc small path, cross-tier intersect/union, full_for, lossless promote, canonical-form regression).cargo clippy -p lance-graph-contract --all-targets -- -D warnings— clean.cargo check/test -p lance-graph-rbac -p lance-graph-ontology+ arm-discovery — green with zero source changes (acceptance criterion feat: bump arrow 57, datafusion 51, lance 2 #1 of the ruling).Cross-repo
OGAR side ships separately (criticals-wave PR): interim loud-fail guard in
ogar-render-askama(>64 fields + partialFieldMask→Errinstead of silent drop) + falsifier #2 dual-target (askama↔jinja). OGAR adoption ofWideFieldMaskfollows as O-2-adjacent work; a fallibleTryFrom<WideFieldMask> for FieldMask(≤64 case) is named follow-up for RBAC'sPermissionSpec::projection.🤖 Generated with Claude Code
https://claude.ai/code/session_01Cg8DSUz1U4AvKqXiy9Xx2f
Generated by Claude Code