Skip to content

fix(yes-core): accept any RFC 9562 UUID version, not only v4 (2.1.1) - #37

Merged
aroeczek merged 5 commits into
mainfrom
fix/types-uuid-accept-v7
Aug 22, 2026
Merged

fix(yes-core): accept any RFC 9562 UUID version, not only v4 (2.1.1)#37
aroeczek merged 5 commits into
mainfrom
fix/types-uuid-accept-v7

Conversation

@aroeczek

Copy link
Copy Markdown
Contributor

Same bug as yousty-eventsourcing 17.0.2, in the other gem family

pg_eventstore 3.0.0 generates event ids with SecureRandom.uuid_v7 (moved off the database's gen_random_uuid(), which always produced v4). Those ids reach the gem as causation_id / correlation_id, and Types::UUID pinned the version nibble to 4, so TransactionDetails.new raises Dry::Struct::Error — the handler fails and the subscription dies once its restarts are exhausted.

apprenticeship_presentation died exactly that way in production on 2026-08-22, via the same bug in yousty-eventsourcing.

Why fix it here too, now

company_manager and application_management_system are exposed through this gem. They have not been hit yet only because the specific handlers have not fired — and 🔴 the failed_subscription_notifier is still unmerged here (#36), so a death in those two services would be silent. No Sentry alert, just a subscription quietly not processing.

The change

Version nibble becomes [1-8] instead of a hard-coded 4. Still a real constraint — the variant nibble must remain 8/9/a/b per RFC 9562.

case before after
v4
v7
bad variant / bad version / not-a-uuid

Specs cover all of the above. Version → 2.1.1, root CHANGELOG entry, and a pg_eventstore compatibility note in the yes-core README.

Based on origin/main, so it is independent of the open #36 branch.

Same bug as yousty-eventsourcing 17.0.2, in the other gem family. pg_eventstore
3.0.0 moved event-id generation off the database's gen_random_uuid() (always v4) to
SecureRandom.uuid_v7, and those ids reach us as causation_id / correlation_id. The
v4-pinned pattern makes TransactionDetails.new raise Dry::Struct::Error, which fails
the handler and kills the subscription once its restarts run out.

apprenticeship_presentation died that way in production on 2026-08-22 through
yousty-eventsourcing. company_manager and application_management_system are exposed
through this gem and have not been hit yet only because the specific handlers have
not fired -- worth fixing before they do, particularly since the
failed_subscription_notifier is still unmerged here (#36), so a death in those two
services would be SILENT.

Version is now [1-8] rather than a hard-coded 4. Still a real constraint: variant
nibble stays 8/9/a/b per RFC 9562. Specs cover v4/v7, non-UUID, bad variant and bad
version. README gains the pg_eventstore compatibility note.

Based on origin/main so it is independent of the open #36 branch.
CI failed at "Set up Ruby" with bundle exit 16 across all five jobs -- a
lockfile/gemspec mismatch, not a test failure: bumping only yes-core to 2.1.1 left
every committed Gemfile.lock pinning yes-core (2.1.0), which bundler refuses in
frozen mode.

Following the convention the 2.1.0 release used (b9b418d), which bumped all five
version files together and updated the lockfiles: lib/yes, yes-auth,
yes-command-api and yes-read-api go to 2.1.1 alongside yes-core, and the yes-*
entries in all five Gemfile.lock files are updated to match.

Only yes-core has a functional change; the others move for version lockstep.
PR #36 added the failed-subscription notifier without a CHANGELOG entry, and it is
now part of this release. Worth pairing explicitly: the UUID fix addresses a bug
that KILLS subscriptions, and the notifier is what tells you when one has died --
yes-core services had neither until now.
This repository is public. The 2.1.1 notes and the code comments named internal
services, an internal ticket id and a private sibling gem -- none of which mean
anything to an outside reader, and none of which we should be publishing.

Removed from CHANGELOG, types.rb, railtie.rb and failed_subscription_notifier.rb.
The technical substance is unchanged and arguably clearer: what the bug is, what it
breaks, and what the constraint still enforces, described in terms of pg_eventstore
and this gem's own behaviour.

Note CHANGELOG.md:98 (a 2.0.0-era entry) still names the private gem. Left alone
rather than rewriting released notes -- worth a separate decision.
@aroeczek
aroeczek merged commit 2ee5675 into main Aug 22, 2026
5 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.

1 participant