Skip to content

Comments

fix: preserve field names for single-element Cypher RETURN over Bolt …#3286

Merged
robfrank merged 3 commits intomainfrom
fix/bolt-tests
Jan 31, 2026
Merged

fix: preserve field names for single-element Cypher RETURN over Bolt …#3286
robfrank merged 3 commits intomainfrom
fix/bolt-tests

Conversation

@robfrank
Copy link
Collaborator

…protocol

When FinalProjectionStep unwraps single-element results (e.g., RETURN n), it stores the vertex directly as an element but loses the field name "n". This caused Bolt protocol to send vertex properties as field names instead of the RETURN clause field name.

Changes:

  • FinalProjectionStep: Store projection name in metadata when unwrapping
  • BoltNetworkExecutor: Use metadata to get correct field names for elements
  • BoltNetworkExecutor: Extract element values correctly for Bolt RECORD

This fixes 10+ failing Bolt integration tests where nodes/edges were returned as NULL because field names didn't match.

…protocol

When FinalProjectionStep unwraps single-element results (e.g., RETURN n),
it stores the vertex directly as an element but loses the field name "n".
This caused Bolt protocol to send vertex properties as field names instead
of the RETURN clause field name.

Changes:
- FinalProjectionStep: Store projection name in metadata when unwrapping
- BoltNetworkExecutor: Use metadata to get correct field names for elements
- BoltNetworkExecutor: Extract element values correctly for Bolt RECORD

This fixes 10+ failing Bolt integration tests where nodes/edges were
returned as NULL because field names didn't match.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @robfrank, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a critical issue in how single-element Cypher RETURN statements are handled over the Bolt protocol. Previously, when a query returned a single node or edge (e.g., RETURN n), the system would unwrap the element but lose its original field name. This led to incorrect serialization over Bolt, causing elements to appear as NULL. The changes introduce a mechanism to preserve the original projection name in metadata, which the Bolt network executor then uses to correctly identify and transmit the field names, ensuring accurate data representation for clients.

Highlights

  • Metadata Preservation: The FinalProjectionStep now stores the original projection name (e.g., 'n' for RETURN n) in metadata (_projectionName) when unwrapping single-element results (like vertices or edges). This ensures the field name is not lost during processing.
  • Bolt Protocol Integration: The BoltNetworkExecutor has been updated to utilize this new _projectionName metadata. It now correctly extracts field names for elements when sending data over the Bolt protocol, resolving issues where elements were previously returned as NULL due to missing field names.
  • Code Refactoring: A new private method, extractRecordValues, was introduced in BoltNetworkExecutor to centralize the logic for extracting values from a Result for Bolt records, handling both standard projections and single-element unwrapped results.
  • New Test Coverage: A new test, singleNodeHasProjectionNameMetadata, has been added to CypherResultFormatTest to verify that single-node returns correctly include the _projectionName metadata, ensuring the fix is robust.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@mergify
Copy link
Contributor

mergify bot commented Jan 31, 2026

🧪 CI Insights

Here's what we observed from your CI run for ebce707.

🟢 All jobs passed!

But CI Insights is watching 👀

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request effectively addresses an issue where field names were lost for single-element Cypher RETURN statements over the Bolt protocol. The approach of storing the projection name in the result metadata in FinalProjectionStep and then consuming it in BoltNetworkExecutor is a solid solution. The code changes are clear, and the addition of a new test case in CypherResultFormatTest is great for ensuring this fix is covered. I've made a few suggestions to replace the hardcoded metadata key "_projectionName" with the newly introduced FinalProjectionStep.PROJECTION_NAME_METADATA constant to improve maintainability.

// This happens for queries like "MATCH (n) RETURN n" where the vertex is
// returned directly but we need to preserve the field name "n" for Bolt protocol
if (firstResult.isElement()) {
final Object projectionName = firstResult.getMetadata("_projectionName");
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

To improve maintainability and avoid magic strings, it's recommended to use the FinalProjectionStep.PROJECTION_NAME_METADATA constant. This ensures that if the metadata key is ever updated, the change is reflected everywhere it's used. You can use the fully qualified name as suggested or add an import for FinalProjectionStep.

Suggested change
final Object projectionName = firstResult.getMetadata("_projectionName");
final Object projectionName = firstResult.getMetadata(com.arcadedb.query.opencypher.executor.steps.FinalProjectionStep.PROJECTION_NAME_METADATA);


// Check if this is an unwrapped element result
// (single vertex/edge returned directly from RETURN clause)
if (result.isElement() && result.getMetadata("_projectionName") != null) {
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Similar to the previous comment, using the FinalProjectionStep.PROJECTION_NAME_METADATA constant here instead of a hardcoded string will make the code more robust and easier to maintain.

Suggested change
if (result.isElement() && result.getMetadata("_projectionName") != null) {
if (result.isElement() && result.getMetadata(com.arcadedb.query.opencypher.executor.steps.FinalProjectionStep.PROJECTION_NAME_METADATA) != null) {

assertThat(results).hasSize(2);
for (final Result r : results) {
assertThat(r.isElement()).isTrue();
assertThat(r.getMetadata("_projectionName")).isEqualTo("n");
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

For consistency and to prevent potential issues if the key changes, it's best to use the FinalProjectionStep.PROJECTION_NAME_METADATA constant in tests as well. You can add an import for com.arcadedb.query.opencypher.executor.steps.FinalProjectionStep to shorten the line.

Suggested change
assertThat(r.getMetadata("_projectionName")).isEqualTo("n");
assertThat(r.getMetadata(com.arcadedb.query.opencypher.executor.steps.FinalProjectionStep.PROJECTION_NAME_METADATA)).isEqualTo("n");

@claude
Copy link

claude bot commented Jan 31, 2026

Code Review - PR #3286

Thank you for this fix! This addresses an important issue with field name preservation in Bolt protocol for single-element Cypher RETURN statements. Overall, the implementation is solid and well-documented. Here's my detailed feedback:

✅ Strengths

  1. Clear Problem Definition: The PR description and code comments clearly explain the issue - single-element results lose field names during unwrapping, causing Bolt to send NULL values.

  2. Appropriate Solution: Using metadata to preserve the projection name is a clean approach that doesn't break existing functionality.

  3. Good Test Coverage: The new singleNodeHasProjectionNameMetadata test directly validates the fix.

  4. Code Refactoring: The introduction of extractRecordValues() method improves code maintainability by eliminating duplication.

  5. Documentation: Excellent inline comments explaining the purpose and behavior, especially in extractFieldNames() and extractRecordValues().

🔍 Issues & Suggestions

1. Magic String Duplication (Minor Issue)

The metadata key "_projectionName" is hardcoded in two places in BoltNetworkExecutor.java (lines 806 and 831), but defined as a constant PROJECTION_NAME_METADATA in FinalProjectionStep.java:120.

Recommendation: Import and use the constant to avoid potential bugs from typos:

// In BoltNetworkExecutor.java imports:
import com.arcadedb.query.opencypher.executor.steps.FinalProjectionStep;

// Line 806:
final Object projectionName = firstResult.getMetadata(FinalProjectionStep.PROJECTION_NAME_METADATA);

// Line 831:
if (result.isElement() && result.getMetadata(FinalProjectionStep.PROJECTION_NAME_METADATA) != null) {

This follows DRY principles and makes refactoring safer. The constant is public, so this is the intended usage pattern.

2. Edge Case Consideration (Question)

What happens when a query returns multiple elements with the same projection name? For example:

MATCH (n) RETURN n LIMIT 100

Looking at the code, extractFieldNames() only peeks at the first result, so this should work correctly - all results get the same field name "n". However, it would be good to verify this with a test case.

3. Test Coverage Gap (Suggestion)

The test singleNodeHasProjectionNameMetadata validates metadata at the engine level, but there's no integration test showing the end-to-end Bolt behavior. Consider adding a test in BoltProtocolIT.java or BoltMultiLabelIT.java that:

  • Executes MATCH (n) RETURN n over Bolt
  • Verifies the response contains the correct field name "n"
  • Verifies the node is not NULL

This would provide regression protection at the protocol level where the original bug manifested.

4. Potential Null Handling (Minor)

In extractRecordValues() line 833:

values.add(BoltStructureMapper.toPackStreamValue(result.getElement().orElse(null)));

The .orElse(null) suggests elements could theoretically be absent. Should this be validated or logged? The isElement() check on line 831 suggests the element must exist, so this might be defensive programming, but worth clarifying.

📊 Code Quality Assessment

  • Readability: ⭐⭐⭐⭐⭐ Excellent comments and clear logic
  • Correctness: ⭐⭐⭐⭐½ Solid implementation, minor constant reference issue
  • Test Coverage: ⭐⭐⭐⭐ Good unit test, could benefit from integration test
  • Performance: ⭐⭐⭐⭐⭐ No performance concerns (metadata is lightweight)
  • Security: ⭐⭐⭐⭐⭐ No security issues identified
  • Maintainability: ⭐⭐⭐⭐½ Very good, would be perfect with constant reference

🎯 Recommendation

APPROVE with minor suggestions. The core fix is correct and addresses the stated problem. The magic string duplication is the only real issue, and it's minor. The suggested improvements (constant usage, additional integration test) would make this even more robust but aren't blockers.

📝 Checklist from CLAUDE.md

✅ Problem clearly stated
✅ Solution approach documented
✅ Test case added
✅ Code follows existing style (single-line if statements without braces where appropriate)
✅ No unnecessary dependencies added
✅ No security hazards introduced
✅ Performance impact minimal

Great work on the fix! The 10+ failing Bolt integration tests should now pass. 🚀


Review performed by Claude Code (Sonnet 4.5) following ArcadeDB project guidelines from CLAUDE.md

@codacy-production
Copy link

codacy-production bot commented Jan 31, 2026

Coverage summary from Codacy

See diff coverage on Codacy

Coverage variation Diff coverage
+0.03% 90.91%
Coverage variation details
Coverable lines Covered lines Coverage
Common ancestor commit (8c23ab7) 129696 71674 55.26%
Head commit (ebce707) 129810 (+114) 71780 (+106) 55.30% (+0.03%)

Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: <coverage of head commit> - <coverage of common ancestor commit>

Diff coverage details
Coverable lines Covered lines Diff coverage
Pull request (#3286) 22 20 90.91%

Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: <covered lines added or modified>/<coverable lines added or modified> * 100%

See your quality gate settings    Change summary preferences

Use column aliases in OpenCypher RETURN clause (AS name, AS height)
and access results by column name instead of numeric index. This
aligns with the Bolt protocol test patterns and the current OpenCypher
result format.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@claude
Copy link

claude bot commented Jan 31, 2026

Code Review - PR #3286

Summary

This PR fixes a critical issue where single-element Cypher RETURN queries (e.g., RETURN n) were losing field names when transmitted over the Bolt protocol, causing 10+ integration test failures. The solution stores projection names in metadata and uses them to correctly format Bolt RECORD messages.

Positive Aspects ✓

  1. Clean Architecture: The solution properly separates concerns - FinalProjectionStep (engine) stores metadata, BoltNetworkExecutor (protocol) consumes it. This follows the layered architecture pattern.

  2. Well-Documented Code: Excellent inline comments explaining the "why" behind the changes, especially around the metadata usage pattern.

  3. Test Coverage: Added regression test singleNodeHasProjectionNameMetadata() validates the core behavior at the engine level.

  4. Code Refactoring: Extracted extractRecordValues() method reduces duplication and improves readability in BoltNetworkExecutor.

  5. Consistent Patterns: Uses metadata for cross-layer communication, which aligns with existing usage throughout the query executor (17 files, 65 occurrences).

  6. PostgreSQL Test Update: The Cypher test improvements in PostgresWJdbcIT.java (using column aliases and named access) align with best practices.

Issues & Recommendations

1. Magic String - Use Constant Reference (Medium Priority)

// BoltNetworkExecutor.java:806, 831
final Object projectionName = firstResult.getMetadata("_projectionName");

Issue: Hard-coded string "_projectionName" instead of referencing FinalProjectionStep.PROJECTION_NAME_METADATA.

Risk: Typos won't be caught at compile time, violates DRY principle.

Fix:

import com.arcadedb.query.opencypher.executor.steps.FinalProjectionStep;

// Then use:
final Object projectionName = firstResult.getMetadata(FinalProjectionStep.PROJECTION_NAME_METADATA);
if (result.isElement() && result.getMetadata(FinalProjectionStep.PROJECTION_NAME_METADATA) != null)

2. Missing Integration Test (High Priority)

According to the PR description, this "fixes 10+ failing Bolt integration tests."

Issue: While CypherResultFormatTest validates engine-level behavior, there's no Bolt-specific integration test in this PR demonstrating the fix works end-to-end over the Bolt protocol.

Recommendation: Add a test in BoltProtocolIT.java that:

  • Executes MATCH (n:Person) RETURN n over Bolt
  • Validates the RECORD message has the correct field name "n"
  • Validates the vertex is properly serialized as a BoltNode

Example skeleton:

@Test
void singleElementReturnPreservesFieldName() {
  // Execute: MATCH (n:Person) RETURN n
  // Assert: result field name is "n", not vertex property names
  // Assert: value is a BoltNode with Person label
}

3. Edge Case: Multi-Element Returns (Low Priority)

Question: Does MATCH (n:Person), (m:Company) RETURN n, m work correctly?

The code only handles requestedProperties.size() == 1 in FinalProjectionStep.java:133. Multi-element returns won't get metadata, which seems correct, but should be validated.

Recommendation: Add a test case for multi-element returns to ensure no regression.

4. Null Safety (Low Priority)

// BoltNetworkExecutor.java:833
values.add(BoltStructureMapper.toPackStreamValue(result.getElement().orElse(null)));

Question: Can result.getElement() ever return Optional.empty() when result.isElement() is true and metadata is set?

If not, consider using .orElseThrow() for fail-fast behavior and clearer contract. If yes, ensure the null handling is intentional.

5. Code Style - Curly Braces (Minor)

Per CLAUDE.md guidelines:

"if statements with only one child sub-statement don't require a curly brace open/close, keep it simple"

// BoltNetworkExecutor.java:807-809 - could be simplified
if (projectionName instanceof String name) {
  return List.of(name);
}

This is fine as-is, but the existing codebase may prefer:

if (projectionName instanceof String name)
  return List.of(name);

Check consistency with the rest of BoltNetworkExecutor.java.

Performance Considerations ✓

  • Metadata storage: Negligible overhead (single string per result)
  • Metadata lookup: O(1) map access
  • No new allocations: Uses existing ResultInternal.metadata map

No performance concerns identified.

Security Considerations ✓

  • No user input directly used in metadata
  • Projection names come from parsed Cypher AST
  • No injection risks identified

Test Coverage Summary

  • ✅ Unit test: CypherResultFormatTest.singleNodeHasProjectionNameMetadata()
  • ✅ Improved: PostgresWJdbcIT.cypher() uses named columns
  • ❌ Missing: Bolt protocol integration test (see recommendation Bump gremlin.version from 3.4.10 to 3.5.1 #2)

Compliance with CLAUDE.md

  • ✅ Follows existing code style
  • ✅ No new dependencies
  • ✅ Reuses existing components (ResultInternal.metadata)
  • ✅ Test-first approach (regression test added)
  • ⚠️ Action needed: Run connected Bolt tests to ensure nothing else broke

Final Recommendation

Approve with minor changes:

  1. Must fix: Replace magic strings with constant reference (Issue build support #1)
  2. Strongly recommended: Add Bolt integration test (Issue Bump gremlin.version from 3.4.10 to 3.5.1 #2)
  3. Nice to have: Address edge cases and null safety (Issues Bump slf4j-simple.version from 1.7.31 to 1.7.32 #3, Bump mongo-java-driver from 3.12.4 to 3.12.10 #4)

The core solution is sound and well-architected. Once the constant reference is fixed and integration test is added, this will be production-ready.


Generated by Claude Code review agent

@claude
Copy link

claude bot commented Jan 31, 2026

Code Review: Fix Bolt Protocol Field Names for Cypher RETURN

Summary

This PR addresses a critical issue where the Bolt protocol was losing field names when returning single elements (vertices/edges) from Cypher queries like MATCH (n) RETURN n. The fix introduces metadata to preserve projection names through the query execution pipeline.


Positive Aspects ✅

  1. Clean Architecture: The metadata-based approach is elegant and non-intrusive. Using PROJECTION_NAME_METADATA constant ensures consistency.

  2. Good Test Coverage: The new singleNodeHasProjectionNameMetadata() test validates the fix at the engine level, and the PR description mentions fixing 10+ failing Bolt integration tests.

  3. Focused Changes: The modifications are minimal and targeted, touching only the necessary components (FinalProjectionStep, BoltNetworkExecutor).

  4. Documentation: Excellent inline comments explaining why the metadata is needed, particularly in BoltNetworkExecutor:806-811 and FinalProjectionStep:116-119.

  5. Code Style: Follows ArcadeDB conventions - proper use of final, clear variable naming, appropriate use of single-statement if blocks without braces.


Issues & Concerns 🔍

1. Test Coverage - Missing Bolt Integration Test Verification (HIGH PRIORITY)

The PR description claims it "fixes 10+ failing Bolt integration tests," but I don't see evidence of:

  • Which specific Bolt tests were failing
  • Verification that those tests now pass
  • New Bolt integration tests that validate the fix end-to-end

Recommendation:

  • Run the Bolt integration tests (mvn test -pl bolt) and document which tests now pass
  • Consider adding a dedicated Bolt integration test that validates field names for RETURN n queries
  • Example test case:
@Test
void returnNodePreservesFieldName() {
  try (Driver driver = getDriver()) {
    try (Session session = driver.session(SessionConfig.forDatabase(getDatabaseName()))) {
      session.run("CREATE (p:Person {name: 'Alice'})");
      final Result result = session.run("MATCH (n:Person) RETURN n");
      final Record record = result.next();
      assertThat(record.keys()).containsExactly("n");
      assertThat(record.get("n").asNode()).isNotNull();
    }
  }
}

2. Potential Edge Case - Multiple Single-Element Projections (MEDIUM)

What happens with queries like MATCH (a), (b) RETURN a, b? This would have 2 projections, each being a single element. The current code only unwraps when requestedProperties.size() == 1 (FinalProjectionStep:133), so this should be fine, but it's worth testing.

Recommendation: Add a test case to CypherResultFormatTest.java:

@Test
void returnMultipleSingleNodesIsProjection() {
  // MATCH (a), (b) RETURN a, b should return projection with both nodes
  final ResultSet result = database.query("opencypher", 
    "MATCH (a:Person), (b:Person) WHERE a.name = 'Alice' AND b.name = 'Bob' RETURN a, b");
  final Result r = result.next();
  assertThat(r.isProjection()).isTrue();
  assertThat(r.getPropertyNames()).containsExactlyInAnyOrder("a", "b");
}

3. PostgreSQL Wire Protocol Test Changes (LOW)

The changes in PostgresWJdbcIT.java:

  • Lines 324-326: Formatting changes (triple-quoted strings) are fine but inconsistent with line 328
  • Lines 329-338: Changed from index-based (rs.getString(1)) to name-based (rs.getString("name")) access and added explicit AS aliases

These changes are good practices, but they seem to be working around a different issue rather than being part of this fix. The query was changed from RETURN person.name, person.height to RETURN person.name AS name, person.height AS height.

Question: Was this PostgreSQL test actually affected by the Bolt fix, or was it failing for a different reason? If the latter, it might warrant a separate commit/PR.

4. Import Organization (LOW - Style)

BoltNetworkExecutor.java lines 20-47 show explicit import expansion. While this is valid Java, it differs from the wildcard import style used elsewhere in the codebase. This appears to be an IDE auto-formatting artifact.

Recommendation: Check if this matches project import conventions. The CLAUDE.md doesn't specify import style, but consistency is preferable.

5. Memory Overhead (LOW - Performance)

Adding metadata to every single-element result adds a small memory overhead (HashMap allocation in ResultInternal:355). For large result sets, this could accumulate.

Analysis: Given that:

  • Only applies to single-element returns (common but not dominant)
  • Metadata map is lazily allocated
  • The alternative (wrapping in projection) would use similar memory

This is acceptable, but worth noting for future optimization if needed.


Security Considerations 🔒

No security issues identified. The metadata key is a compile-time constant, not user-controlled, preventing injection risks.


Performance Considerations ⚡

  1. Positive: The extractRecordValues() method (BoltNetworkExecutor:847) extracts value extraction logic, reducing duplication and making the code more maintainable.

  2. Neutral: The metadata check (result.getMetadata(PROJECTION_NAME_METADATA) != null) adds minimal overhead (single map lookup) per record.

  3. Potential Issue: extractFieldNames() now has two potential return paths for elements - one with metadata, one without (falling back to property names). Ensure this doesn't cause confusion when elements are returned without going through FinalProjectionStep.


Code Quality Suggestions 📝

Minor: Metadata Constant Visibility

The constant PROJECTION_NAME_METADATA is public in FinalProjectionStep but only used by BoltNetworkExecutor (and potentially other wire protocols). Consider:

  • Adding a comment indicating this is part of the wire protocol contract
  • Or moving it to a shared constants class if other protocols need it

Minor: Null Safety

BoltNetworkExecutor:854 calls result.getElement().orElse(null) which could return null. Verify that BoltStructureMapper.toPackStreamValue(null) handles this gracefully.


Testing Checklist (per CLAUDE.md) ✓

Based on project guidelines, please verify:

  • Code compiles without errors
  • All affected tests pass (needs verification - see Issue build support #1)
  • New test case added (CypherResultFormatTest.singleNodeHasProjectionNameMetadata)
  • Regression test for Bolt protocol (recommended - see Issue build support #1)
  • Code style follows conventions (single-statement ifs, final keywords, etc.)
  • No System.out debug statements (verified)
  • Tests use preferred syntax (assertThat().isTrue() style)

Recommendations Summary

Before Merging:

  1. Run and document Bolt integration test results
  2. Add Bolt-specific integration test for this fix
  3. Clarify PostgreSQL test changes - separate fix or related?
  4. Add test for multiple single-element projections edge case

Nice to Have:
5. Consistent import style in BoltNetworkExecutor
6. Document metadata constant as part of wire protocol contract


Verdict

The core fix is solid and well-implemented. The metadata approach is clean and the changes are focused. However, the PR would benefit from stronger integration test verification before merging, particularly demonstrating that the claimed "10+ failing Bolt tests" now pass.

Recommendation: Approve with minor revisions - primarily adding test verification and addressing the test coverage gaps noted above.

Great work on isolating and fixing this tricky protocol issue! 🎯

@robfrank robfrank merged commit 20bdabf into main Jan 31, 2026
18 of 21 checks passed
robfrank added a commit that referenced this pull request Feb 17, 2026
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