Skip to content

Fix HLC UUID node id contract#73

Merged
dexcompiler merged 4 commits into
mainfrom
codex/71-hlc-node-id-contract
May 14, 2026
Merged

Fix HLC UUID node id contract#73
dexcompiler merged 4 commits into
mainfrom
codex/71-hlc-node-id-contract

Conversation

@dexcompiler
Copy link
Copy Markdown
Owner

Summary

  • constrain HlcGuidFactory node IDs to the 14-bit range recoverable from RFC-compatible UUIDv7 values
  • expose HlcGuidFactory.MaxNodeId and reject unsupported IDs instead of silently losing the top two bits
  • add C# boundary tests and an F# property that generated HLC UUIDs preserve supported node IDs
  • document the node-id range in README, the HLC guide, DI extension docs, and cluster registry docs

Root cause

The HLC UUIDv7 encoding stores the node ID in bytes 8-9, but byte 8 also carries the RFC UUID variant bits. That leaves 14 recoverable node-id bits. The public contract previously accepted any ushort, allowing values above 0x3FFF to be truncated in generated GUIDs.

Validation

  • dotnet test tests/Clockworks.Tests.csproj --filter HlcGuidFactoryNodeIdTests -v minimal
  • dotnet test property-tests/Clockworks.PropertyTests.fsproj --filter "HlcGuidFactory UUID preserves supported node id" -v minimal
  • dotnet test Clockworks.sln -v minimal -m:1

Fixes #71

@dexcompiler dexcompiler marked this pull request as ready for review May 14, 2026 21:34
@dexcompiler dexcompiler changed the title [codex] Fix HLC UUID node id contract Fix HLC UUID node id contract May 14, 2026
@dexcompiler
Copy link
Copy Markdown
Owner Author

@copilot do a careful review this pr

Copy link
Copy Markdown
Contributor

Copilot AI commented May 14, 2026

@copilot do a careful review this pr

Reviewed carefully. The core logic, encoding/decoding math, and tests are all correct. I found and fixed two gaps (commit 8cc3979):

  1. HlcClusterRegistry.RegisterNode was missing an <exception> XML doc tag — the method propagates ArgumentOutOfRangeException from the HlcGuidFactory constructor when nodeId > MaxNodeId, but that wasn't documented.

  2. CHANGELOG — the [Unreleased] section was empty despite this being a breaking change (previously values above 0x3FFF were silently truncated; now they throw). Added an entry under ### Changed.

Everything else checked out:

  • MaxNodeId = 0x3FFF constant is correct (14-bit max; variant bits consume the top 2 bits of bytes 8-9)
  • The encoding (WriteUInt16BigEndian then OR-in VariantRfc4122 | (byte & 0x3F)) and decoding ((byte[8] & 0x3F) << 8 | byte[9]) are symmetric and correct at the boundary
  • The ArgumentOutOfRangeException is thrown with the right paramName and actualValue
  • C# boundary tests cover the max-valid and first-invalid cases
  • F# property masks the generated uint16 with &&& MaxNodeId to stay in the valid range and verifies round-trip fidelity for all 100 inputs

Resolve #73 changelog conflict after release workflow updates.
@dexcompiler dexcompiler merged commit ca25a0c into main May 14, 2026
6 checks passed
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.

Bug: align HlcGuidFactory node-id contract with 14-bit UUID encoding

2 participants