Motivation
After #5001 (PR #5059) added Bolt 5.x version-gated wire encoding, the PackStreamStructure accessors getFieldCount() and getSignature() are inconsistent with writeTo() on the version-gated structures:
BoltNode / BoltRelationship / BoltUnboundRelationship: getFieldCount() returns the Bolt 4.x base count (3 / 5 / 3) while writeTo() emits 4 / 8 / 4 when the negotiated major is >= 5 (adding element_id fields).
BoltDateTimeStructure: getSignature() returns the legacy 'F'/'f' signature while writeTo() emits the UTC 'I'/'i' signature on Bolt 5.0+.
This is inert today and was verified during review: PackStreamWriter serializes structures exclusively through writeTo() and never consults getFieldCount()/getSignature(); the only self-consumer of the writeStructureHeader(getSignature(), getFieldCount()) idiom is BoltPointStructure.writeTo (a version-invariant struct). The version-gated structs already document, on each accessor, that writeTo() is authoritative.
It remains a latent footgun: any future serialization path that calls writeStructureHeader(getSignature(), getFieldCount()) for a version-gated struct would emit a header/body mismatch on a 5.x connection and corrupt the stream. The accessors cannot be made version-correct because they are no-arg interface methods with no access to the negotiated version (only writeTo() has it, via the writer). Raised repeatedly by Claude and Gemini reviews on PR #5059; deferred out of that PR because it is a serialization-layer refactor, not a protocol-negotiation change.
Proposed design
Make writeTo() the sole authority for structure header emission:
- Remove
getSignature() and getFieldCount() from the PackStreamStructure interface.
- Inline the signature + field count directly in each
writeTo():
BoltPointStructure.writeTo (currently the only caller of the idiom) inlines its own version-invariant signature/field count.
- The other implementers (
BoltNode, BoltRelationship, BoltUnboundRelationship, BoltPath, BoltTemporalStructure, BoltDateTimeStructure) drop the two now-unused overrides; their writeTo() already writes the header directly.
- Update
BoltStructureTest assertions that currently read getFieldCount() / getSignature() to assert on the serialized wire bytes instead (the header byte + signature already asserted for the 5.x cases), or drop those assertions where redundant.
Acceptance criteria
Dependencies
Follow-up to #5001 (PR #5059). Related to the Bolt certification epic #4882 / tracking issue #4890.
Effort estimate
S
Motivation
After #5001 (PR #5059) added Bolt 5.x version-gated wire encoding, the
PackStreamStructureaccessorsgetFieldCount()andgetSignature()are inconsistent withwriteTo()on the version-gated structures:BoltNode/BoltRelationship/BoltUnboundRelationship:getFieldCount()returns the Bolt 4.x base count (3 / 5 / 3) whilewriteTo()emits 4 / 8 / 4 when the negotiated major is >= 5 (addingelement_idfields).BoltDateTimeStructure:getSignature()returns the legacy'F'/'f'signature whilewriteTo()emits the UTC'I'/'i'signature on Bolt 5.0+.This is inert today and was verified during review:
PackStreamWriterserializes structures exclusively throughwriteTo()and never consultsgetFieldCount()/getSignature(); the only self-consumer of thewriteStructureHeader(getSignature(), getFieldCount())idiom isBoltPointStructure.writeTo(a version-invariant struct). The version-gated structs already document, on each accessor, thatwriteTo()is authoritative.It remains a latent footgun: any future serialization path that calls
writeStructureHeader(getSignature(), getFieldCount())for a version-gated struct would emit a header/body mismatch on a 5.x connection and corrupt the stream. The accessors cannot be made version-correct because they are no-arg interface methods with no access to the negotiated version (onlywriteTo()has it, via the writer). Raised repeatedly by Claude and Gemini reviews on PR #5059; deferred out of that PR because it is a serialization-layer refactor, not a protocol-negotiation change.Proposed design
Make
writeTo()the sole authority for structure header emission:getSignature()andgetFieldCount()from thePackStreamStructureinterface.writeTo():BoltPointStructure.writeTo(currently the only caller of the idiom) inlines its own version-invariant signature/field count.BoltNode,BoltRelationship,BoltUnboundRelationship,BoltPath,BoltTemporalStructure,BoltDateTimeStructure) drop the two now-unused overrides; theirwriteTo()already writes the header directly.BoltStructureTestassertions that currently readgetFieldCount()/getSignature()to assert on the serialized wire bytes instead (the header byte + signature already asserted for the 5.x cases), or drop those assertions where redundant.Acceptance criteria
PackStreamStructureno longer exposesgetSignature()/getFieldCount();writeTo()is the only header contract.boltunit + real-driver ITs.mvn -pl bolt verifygreen.Dependencies
Follow-up to #5001 (PR #5059). Related to the Bolt certification epic #4882 / tracking issue #4890.
Effort estimate
S