Skip to content

feat: add Value::same_scalar_data for comparing single values across variants - #5125

Merged
QuantumExplorer merged 4 commits into
v4.2-devfrom
claude/platform-value-same-scalar-data
Sep 28, 2026
Merged

QuantumExplorer merged 4 commits into
v4.2-devfrom
claude/platform-value-same-scalar-data

Conversation

@QuantumExplorer

@QuantumExplorer QuantumExplorer commented Sep 28, 2026 •

Copy link
Copy Markdown
Member

Basic explanation

What this does: It adds one method, Value::same_scalar_data, that answers "do these two single values hold the same data?" even when they are stored in different variants: the number 513 as a U64 and as a U16, or an identifier and the same 32 bytes. It works like the existing Value::equal_underlying_data, with two differences: a map, or an array of anything but U8 values, never matches (an array of U8s is the bytes it lists, as to_identifier_bytes reads it), and two floats must have exactly the same bits, so -0.0 and 0.0 are different. Nothing calls it yet. #5102, which is stacked on this pull request, uses it to compare the two sides of a refersTo propertyAgreement.

Example: there is no "before" for users, since the method is new. The difference from equal_underlying_data:

Values compared equal_underlying_data same_scalar_data
Float(-0.0) and Float(0.0) equal (== on f64) different (different bits)
Float(NaN) and the same Float(NaN) different equal (same bits)
U64(1_700_000_000_000) and Float(1.7e12) different equal (the integer read as a float)
Map([("a", U8(1))]) and Map([("a", U64(1))]) equal (recursive) different (not a single value)
Array([U64(1)]) and Array([U64(1)]) equal different (not a single value)
Array([U8(7); 32]) and Identifier([7; 32]) different equal (the bytes it lists)
U64(513) and U16(513) equal equal
Identifier([7; 32]) and Bytes32([7; 32]) equal equal
Text("") and Text("\0") different different

Value: Comparing two single values the way a document index sees them (floats by their bits) no longer needs a hand-written helper per caller, and the comparison lives next to equal_underlying_data where its sibling rules are.

Risks: None on its own: the method is new and has no caller in this pull request. equal_underlying_data is not touched, since shipped generations call it at every protocol version.

Issue being fixed or feature implemented

#5102 compares a propertyAgreement pair as two values rather than as two index keys. It added DocumentPropertyType::values_are_equal in dpp for that, which mostly repeats Value::equal_underlying_data. equal_underlying_data cannot serve directly: it recurses into maps and arrays, compares floats with == (so -0.0 equals 0.0, whose tree keys differ), and does not equate a float with an integer, while a document stores date and number properties as floats and a transition may carry one as an integer. It also cannot change, because the document replace transformer and proof verification call it at every protocol version. This adds the single-value comparison to platform-value under its own name, so #5102 can drop its dpp helper.

What was done?

Value::same_scalar_data(&self, other: &Value) -> bool in packages/rs-platform-value/src/eq.rs, next to equal_underlying_data:

  1. An Array on either side: equal only when both sides hold the same bytes, reading an array whose every element is a U8 as the bytes it lists (as to_identifier_bytes does) and any bytes-like variant as its bytes. A transition may carry an identifier or a byte array that way.
  2. A Map on either side: not equal.
  3. A Float on either side: both sides read as f64 through as_float (so an integer converts, rounding past 2^53 as storage does, which makes the comparison not transitive there) and compared with f64::to_bits. A non-number against a float is not equal.
  4. Anything else goes to equal_underlying_data, which for two single values compares bytes-like variants (Bytes, Bytes20, Bytes32, Bytes36, Identifier) by their bytes, integers by value through as_i128_unified (a U128 past i128::MAX equals only the same U128), and everything else with ==: two nulls are equal, a null equals nothing else, text compares as text, booleans as booleans.

The doc comment explains that floats compare by bits (so -0.0 and 0.0 differ, as their tree keys do; this is bit equality, not tree key equality, since the key encoding maps a few distinct bit patterns to one key) and that there is no size limit, unlike the 255 bytes of a tree key.

How Has This Been Tested?

Ten new tests in eq::same_scalar_data_tests, each checking both argument orders give the same answer:

  • should_not_equate_the_empty_string_with_a_nul_character
  • should_equate_the_same_integer_carried_at_different_widths (U64/U16, I64/I32, U8/I128)
  • should_equate_a_u128_past_i128_only_with_the_same_u128
  • should_equate_an_identifier_with_the_same_32_bytes (against Bytes32 and Bytes)
  • should_equate_equal_strings_and_byte_arrays_longer_than_a_tree_key (256 ASCII bytes, 70 emoji, 300 bytes)
  • should_compare_floats_by_their_bits (-0.0/0.0, NaN payloads, with the equal_underlying_data contrast)
  • should_read_an_integer_against_a_float_as_the_float_it_converts_to
  • should_never_equate_a_map_or_an_array_of_anything_but_bytes
  • should_read_an_array_of_u8_as_the_bytes_it_lists
  • should_equate_two_nulls_and_nothing_else_with_a_null
  • should_not_equate_values_of_different_kinds
cargo test -p platform-value --lib --tests          # 1060 + 239 + 3 passed
cargo test -p platform-value --all-features --doc   # 94 passed
cargo fmt --all
cargo clippy -p platform-value --tests -- -D warnings

Breaking Changes

None. The method is additive and changes no existing behaviour.

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have added "!" to the title and described breaking changes in the corresponding section if my code contains any
  • I have made corresponding changes to the documentation if needed
  • If I added or changed GroveDB structure, I described it in the area's structure.rs, regenerated grovedb-structure.json, and checked the structure viewer link posted on this pull request

For repository code-owners and collaborators only

  • I have assigned this pull request to a milestone

🤖 Generated with Claude Code

PR Hygiene · a410611

  • Bots — coderabbitai ✓ · thepastaclaw 1 thread unresolved — resolve it
  • Self-review — post /self-reviewed once the bots are done
  • Within your 5 open PRs
  • Build running
  • Approvals — you own every area touched; none needed

When every box is checked the PR Hygiene check passes and this can merge.

Summary by CodeRabbit

  • New Features
    • Added scalar value comparisons that support byte-based values, numeric integers, and bit-for-bit floats. Integer values can also be compared with floats after conversion. Arrays are treated as byte data only when every element is an unsigned 8-bit value; maps and other arrays do not match through this comparison.
  • Bug Fixes
    • Property agreements now compare stored values directly, including values longer than 255 bytes. Empty strings no longer match strings containing a NUL character, while identical empty strings agree.

…variants

`Value::same_scalar_data` is `equal_underlying_data` for single values:
bytes-like variants compare by their bytes, integers by value at any width,
and anything else with `==`. It differs in two ways. A map or an array on
either side never matches. When either side is a float, both are read as
`f64` (an integer converting as `to_float` does) and compared by bits, so
`-0.0` is not `0.0` and a NaN equals the same NaN, as a float's tree key
tells them apart.

`equal_underlying_data` is left as it is: shipped generations call it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added this to the v4.2.0 milestone Sep 28, 2026
@coderabbitai

coderabbitai Bot commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: dashpay/platform/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 7b13e67c-6fd4-4b68-879a-6855bc473667

📥 Commits

Reviewing files that changed from the base of the PR and between b6f0a21 and a410611.

📒 Files selected for processing (9)
  • book/src/contract-keywords/refers-to.md
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document/document_reference_validation/v0/mod.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/agreement_values.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/mod.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_common/data_contract_reference_validation/v0/mod.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/mod.rs
  • packages/rs-drive-abci/tests/supporting_files/contract/reference-validation/reference-validation-contract-agreement-long-values.json
  • packages/rs-platform-value/src/eq.rs
  • packages/rs-platform-version/src/version/v14.rs

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The change adds Value::same_scalar_data and uses it to compare property-agreement values instead of encoded index keys. It also adds registration and ABCI pipeline tests, plus updates to the contract keyword documentation and v14 change notes.

Changes

Property Agreement Comparison

Layer / File(s) Summary
Scalar comparison rules
packages/rs-platform-value/src/eq.rs
Adds same_scalar_data with type-specific comparison rules. Tests cover numeric conversion, byte-like values, floats, scalar values, and containers.
Agreement validation and pipeline tests
packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document/document_reference_validation/v0/mod.rs, packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/*, packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_common/data_contract_reference_validation/v0/mod.rs
Document reference validation uses same_scalar_data. ABCI pipeline tests cover matching and mismatching long strings, empty strings, and NUL strings.
Registration and documented rules
packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/mod.rs, packages/rs-drive-abci/tests/supporting_files/contract/reference-validation/reference-validation-contract-agreement-long-values.json, book/src/contract-keywords/refers-to.md, packages/rs-platform-version/src/version/v14.rs
Adds a registration test and contract fixture for long values. Updates the property-agreement documentation and v14 change notes with the comparison rules.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Feature

Suggested reviewers: thepastaclaw

Merge Risk: ⚪ Minimal · up to a4106

The property-agreement change is mergeable after normal checks; no actionable issue remains from this review.

Security Architecture Review

Security architecture risk: 🔵 Low · up to a4106

The new rule changes which document values can satisfy a reference agreement. Contract type checks and the existing mismatch and identity checks remain in place, and no new authorization bypass was established. Input normalization and behavior across protocol upgrades remain incompletely verified.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The affected security decision is whether a document write satisfies a declared reference agreement, including agreements used as a writer-identity gate. The evidence does not establish a broader service or infrastructure privilege change.

Trust Boundaries and Controls

  • observed — The new comparator is a leaf equality check: the surrounding validator still obtains the referenced document and rejects missing-on-one-side or unequal agreement values. Contract registration constrains which properties may be paired.

Resilience and Maintainability Implications

  • inferred — Numeric comparisons involving a float inherit integer-to-f64 rounding, so distinct integer representations can compare equal to one float. Matching-kind registration is counterevidence to an unrestricted cross-type bypass, but the inspected sources do not settle every runtime representation or its comparison with the former key-encoding rule.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding Value::same_scalar_data to compare single values across variants.
Docstring Coverage ✅ Passed Docstring coverage is 96.15% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 26 functions across 7 files. (2 skipped: 2 …
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.
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

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 github-actions Bot added the waiting-bots Waiting for the review bots to report on this head label Sep 28, 2026
@thepastaclaw

thepastaclaw commented Sep 28, 2026 •

Copy link
Copy Markdown
Collaborator

🕓 Queued for automated review — 3rd in line, estimated start in ~30 min (commit a410611)
Estimated review time once started: ~1.0 h (two-phase automated review; median of recent runs).

  • Request priority review — click to move this review to the front of the queue.

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Final validation — Phase 1 + Phase 2

The additive helper has no production callers and leaves existing comparison behavior unchanged; no blocking issues were found. Verification identified an inaccurate tree-key equivalence claim, an avoidable allocation, and overlapping documentation/test gaps around integer rounding. All 10 targeted same_scalar_data tests passed at the exact reviewed head.

🟡 3 suggestion(s)

Review provenance

Source: reviewer 1: glm-5.3-flash (agent: phase1-reviewer, role: general); reviewer 2: glm-5.3-flash (agent: phase1-reviewer, role: architecture-layering); reviewer 3: glm-5.3-flash (agent: phase1-reviewer, role: rust-quality); reviewer 4: glm-5.3-flash (agent: phase1-reviewer, role: security-auditor); reviewer 5: gpt-6-astra (agent: phase2-reviewer, role: general); reviewer 6: gpt-6-astra (agent: phase2-reviewer, role: architecture-layering); reviewer 7: gpt-6-astra (agent: phase2-reviewer, role: rust-quality); reviewer 8: gpt-6-astra (agent: phase2-reviewer, role: security-auditor); final verifier: gpt-6-astra (agent: astra-verifier, role: final-verifier)

  • Triage: low by gpt-6-astra (effort low) — The diff adds a small, self-contained Value::same_scalar_data method with extensive tests, reuses existing conversions and equality logic, and introduces no callers or changes to existing consensus behavior.
  • Phase 1 reviewers: glm-5.3-flash — general (completed, effort high); agent phase1-reviewer, glm-5.3-flash — architecture-layering (completed, effort high); agent phase1-reviewer, glm-5.3-flash — rust-quality (completed, effort high); agent phase1-reviewer, glm-5.3-flash — security-auditor (completed, effort high); agent phase1-reviewer
  • Phase 1 model: glm-5.3-flash — zai quota: 5h 95% left, weekly 99% left; passed over gemini-3.8-flash-high (antigravity below 15% reserve: weekly 13% left, 5h 100% left)
  • Fresh verifier: gpt-6-astra — final-verifier; agent astra-verifier
  • Phase 2 reviewers: gpt-6-astra — general (completed, effort medium); agent phase2-reviewer, gpt-6-astra — architecture-layering (completed, effort medium); agent phase2-reviewer, gpt-6-astra — rust-quality (completed, effort medium); agent phase2-reviewer, gpt-6-astra — security-auditor (completed, effort medium); agent phase2-reviewer
🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.

In `packages/rs-platform-value/src/eq.rs`:
- [SUGGESTION] packages/rs-platform-value/src/eq.rs:229-233: Do not claim float bits exactly match document index keys
  The claimed equivalence does not hold for every float accepted by this helper. Signed zeros actually produce distinct keys, contrary to the original review's counterexample. However, DocumentPropertyType::encode_float branches on val < 0.0, so negative NaNs take the sign-bit-XOR branch instead of the complement branch. Consequently, f64::from_bits(0xfff8000000000000), a negative NaN, and f64::from_bits(0x8007ffffffffffff), a negative finite subnormal, both encode as 0x7ff8000000000000 even though same_scalar_data rejects the pair. Document this API as bit-level equality rather than exact tree-key equivalence, and update the matching test comment and PR explanation. This does not require changing the existing encoder or the helper's intentionally documented bitwise semantics.
- [SUGGESTION] packages/rs-platform-value/src/eq.rs:253-256: Use as_float to avoid constructing discarded errors
  Comparing a Float against a nonnumeric scalar calls to_float on that scalar, allocating the String inside Error::StructureError before immediately discarding the error. The existing as_float accessor has the same numeric variants and casts but returns None without allocating. Using it preserves every comparison result while avoiding unnecessary error construction in this boolean predicate.
- [SUGGESTION] packages/rs-platform-value/src/eq.rs:478-486: Pin integer rounding and document its nontransitive comparison
  The integer/float tests exercise only exactly representable integers, leaving the explicitly documented rounding behavior untested. Add assertions showing that U64(2^53 + 1) matches Float(2^53) but does not match U64(2^53). Both integers match that float, so also state in the API documentation that the comparison is not transitive. Boundary assertions can cover I128(i128::MIN) against Float(-2.0f64.powi(127)) and U128(u128::MAX) against Float(2.0f64.powi(128)), with an infinity contrast. The original proposed I128 assertion used -2^63; that is incorrect because i128::MIN is -2^127.

Comment thread packages/rs-platform-value/src/eq.rs Outdated
Comment thread packages/rs-platform-value/src/eq.rs
Comment thread packages/rs-platform-value/src/eq.rs
@github-actions

github-actions Bot commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Your move: thepastaclaw left review threads unresolved; resolve them.
Full checklist in the description.

@github-actions github-actions Bot added waiting-self-review Waiting for the author to post /self-reviewed bot-review-skipped A required review bot did not report; it was skipped by the window or by a person. and removed waiting-bots Waiting for the review bots to report on this head labels Sep 28, 2026
A transition may carry an identifier or a byte array as an array of U8
values, which to_identifier_bytes already reads as those bytes. Treating
every array as a container refused such a value against the same bytes
stored as an identifier. An array whose every element is a U8 now
compares as its bytes; any other array, and any map, still never
matches.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added waiting-bots Waiting for the review bots to report on this head and removed waiting-self-review Waiting for the author to post /self-reviewed bot-review-skipped A required review bot did not report; it was skipped by the window or by a person. labels Sep 28, 2026
@github-actions

github-actions Bot commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Your move: thepastaclaw left review threads unresolved; resolve them.
Full checklist in the description.

@github-actions github-actions Bot added waiting-self-review Waiting for the author to post /self-reviewed and removed waiting-bots Waiting for the review bots to report on this head labels Sep 28, 2026
…uality

- read both sides with as_float, which returns None instead of building
  an error that is thrown away
- describe the float rule as bit equality: the tree key encoding maps a
  few distinct bit patterns to one key, so the two are not the same
- note that rounding past 2^53 makes the integer/float comparison not
  transitive, and pin it with a test, including the i128::MIN and
  u128::MAX boundaries and an infinity contrast

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added waiting-bots Waiting for the review bots to report on this head and removed waiting-self-review Waiting for the author to post /self-reviewed labels Sep 28, 2026
QuantumExplorer added a commit that referenced this pull request Sep 28, 2026
Value::same_scalar_data now reads an array of U8 values as the bytes it
lists (#5125), as the index key comparison did, so a moderation charter
application that writes its target contract that way agrees with the
stored identifier again. Note 56, the check's comment and the book say
so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-review — Final validation — Phase 1 + Phase 2

Verified the complete diff at a27bd29: the additive helper leaves existing comparison behavior unchanged, and all three prior findings are fixed. One non-blocking performance suggestion remains in the array comparison path; no blocking issues were found. Local validation passed 1,304 unit/integration tests, 94 all-feature documentation tests, and clippy with warnings denied; the working tree remains unchanged.

🟡 1 suggestion(s)

Review provenance

Source: reviewer 1: glm-5.3-flash (agent: phase1-reviewer, role: general); reviewer 2: glm-5.3-flash (agent: phase1-reviewer, role: architecture-layering); reviewer 3: glm-5.3-flash (agent: phase1-reviewer, role: rust-quality); reviewer 4: gpt-6-astra (agent: phase2-reviewer, role: general); reviewer 5: gpt-6-astra (agent: phase2-reviewer, role: architecture-layering); reviewer 6: gpt-6-astra (agent: phase2-reviewer, role: rust-quality); reviewer 7: gpt-6-astra (agent: phase2-reviewer, role: general); reviewer 8: gpt-6-astra (agent: phase2-reviewer, role: architecture-layering); reviewer 9: gpt-6-astra (agent: phase2-reviewer, role: rust-quality); final verifier: gpt-6-astra (agent: astra-verifier, role: final-verifier)

  • Triage: low by gpt-6-astra (effort low) — The diff adds a small, self-contained comparison helper in rs-platform-value/src/eq.rs with extensive edge-case tests and no callers or changes to existing consensus behavior.
  • Phase 1 reviewers: glm-5.3-flash — general (completed, effort high); agent phase1-reviewer, glm-5.3-flash — architecture-layering (completed, effort high); agent phase1-reviewer, glm-5.3-flash — rust-quality (completed, effort high); agent phase1-reviewer
  • Phase 1 model: glm-5.3-flash — zai quota: 5h 99% left, weekly 97% left; passed over gemini-3.8-flash-high (antigravity below 15% reserve: weekly 13% left, 5h 100% left)
  • Fresh final gate: an independent Phase-2 review ran after iterative findings were reconciled
  • Fresh verifier: gpt-6-astra — final-verifier; agent astra-verifier
  • Phase 2 reviewers: gpt-6-astra — general (completed, effort medium); agent phase2-reviewer, gpt-6-astra — architecture-layering (completed, effort medium); agent phase2-reviewer, gpt-6-astra — rust-quality (completed, effort medium); agent phase2-reviewer, gpt-6-astra — general (completed, effort medium); agent phase2-reviewer, gpt-6-astra — architecture-layering (completed, effort medium); agent phase2-reviewer, gpt-6-astra — rust-quality (completed, effort medium); agent phase2-reviewer
🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.

In `packages/rs-platform-value/src/eq.rs`:
- [SUGGESTION] packages/rs-platform-value/src/eq.rs:258-267: Compare array bytes without materializing both operands
  When either operand is an Array, held_bytes collects each valid U8 array into a Vec and copies any bytes-like counterpart into another Vec solely for comparison. This uses temporary memory proportional to both inputs and traverses complete valid inputs even when their lengths or first bytes differ. Because this API explicitly supports arbitrarily long values, the overhead is not limited to fixed-size identifiers. Split array/array and array/bytes comparisons, check lengths first, and compare borrowed elements directly while requiring each array element to be Value::U8. This preserves the documented semantics without temporary buffers and permits early rejection. Returning Cow for bytes-like operands would avoid their copies, but would still leave the array allocation.

Comment on lines +258 to +267
fn held_bytes(value: &Value) -> Option<Vec<u8>> {
match value {
Value::Array(items) => items
.iter()
.map(|item| match item {
Value::U8(byte) => Some(*byte),
_ => None,
})
.collect(),
_ => value.as_bytes_slice().ok().map(<[u8]>::to_vec),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Suggestion: Compare array bytes without materializing both operands

When either operand is an Array, held_bytes collects each valid U8 array into a Vec and copies any bytes-like counterpart into another Vec solely for comparison. This uses temporary memory proportional to both inputs and traverses complete valid inputs even when their lengths or first bytes differ. Because this API explicitly supports arbitrarily long values, the overhead is not limited to fixed-size identifiers. Split array/array and array/bytes comparisons, check lengths first, and compare borrowed elements directly while requiring each array element to be Value::U8. This preserves the documented semantics without temporary buffers and permits early rejection. Returning Cow for bytes-like operands would avoid their copies, but would still leave the array allocation.

source: glm-5.3-flash (phase1-reviewer: general, architecture-layering, rust-quality); gpt-6-astra (phase2-reviewer: rust-quality)

…V14) (#5102)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

📖 Book Preview built successfully.

Download the preview from the workflow artifacts.
To view locally: download the artifact, unzip, and open index.html.

Updated at 2026-09-28T17:49:51.584Z

@github-actions

Copy link
Copy Markdown
Contributor

Your move: thepastaclaw left review threads unresolved; resolve them.
Full checklist in the description.

@github-actions github-actions Bot added waiting-self-review Waiting for the author to post /self-reviewed and removed waiting-bots Waiting for the review bots to report on this head labels Sep 28, 2026

@QuantumExplorer QuantumExplorer left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved

@QuantumExplorer
QuantumExplorer merged commit b40e4db into v4.2-dev Sep 28, 2026
47 of 49 checks passed
@QuantumExplorer
QuantumExplorer deleted the claude/platform-value-same-scalar-data branch September 28, 2026 18:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

waiting-self-review Waiting for the author to post /self-reviewed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants