Skip to content

Register the Pub/Sub split agent identifiers: per-side flags and per-language families - #361

Open
umair-ably wants to merge 2 commits into
mainfrom
pubsub-per-side-agents
Open

umair-ably wants to merge 2 commits into
mainfrom
pubsub-per-side-agents

Conversation

@umair-ably

@umair-ably umair-ably commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Registers both kinds of agent identifier introduced by the PDR-091b package split, in two commits:

Commit 1 — the cross-SDK side flags (versionless)

ably-pubsub-device / ably-pubsub-server are the same two strings stamped by every language (ably-js#2293, ably-java#1233, ably-ruby#453). Versionless, per the review discussion below: under lockstep versioning a side-flag version always duplicates the SDK entry beside it, and across SDKs it cannot say version-of-what — so, like browser, the entry is a pure flag. Entry shape follows browser exactly (versioned: false, no source/product, hence the runtime type branch — flag if you'd prefer a dedicated type). The matching SDK-side change is implemented in ably-js#2297; java/ruby mirror it before their splits merge.

Commit 2 — the per-language family identifiers (versioned)

Each SDK's identifier follows its repo rename in the new major: ably-pubsub-js, -java, -go, -python, -ruby, -php, -dotnet, -flutter, -dart, -cocoa, -swift, -rust. Because the flip happens exactly at the split and maintenance branches are never touched, the identifier alone partitions the fleet — old identifier ⇒ legacy-package traffic, new ⇒ new-package traffic — so migration tracking and legacy EOL enforcement become a string match. Wire shape:

ably-pubsub-js/3.0.0 nodejs/22.3.0 ably-pubsub-server

Details: each new entry sits beside its legacy counterpart, which stays registered (the old packages stamp the old identifiers through their maintenance year, and those entries carry their eventual EOL sunsets). Names/types mirror the legacy entries; ably-pubsub-flutter stays a wrapper over the Java/Cocoa cores; ably-pubsub-dart and ably-pubsub-rust have no legacy pub-sub entry and are registered fresh against their existing repos. One known wrinkle, deliberate: old and new identifiers share a source repo, so fetch-agent-releases will associate that repo's releases with both entries — sunsets are authored per entry, so this only affects the best-effort release CSV.

The full convention (including what each SDK owner does and the registry-before-release ordering) is proposed as a comment on PDR-091b2.

Verified: npm run validate:agents (93 agents), npx jest test/agents.test.js (2 passing), prettier --check clean.

🤖 Generated with Claude Code

@umair-ably umair-ably changed the title Register the ably-js per-side Pub/Sub package agents Register the cross-SDK per-side Pub/Sub agents Sep 1, 2026
@umair-ably
umair-ably force-pushed the pubsub-per-side-agents branch from c65f88a to a90c69e Compare September 1, 2026 17:01
@lmars

lmars commented Sep 1, 2026

Copy link
Copy Markdown
Member

Each package stamps its own version, and each SDK's own agent entry (ably-js/x.y.z, ably-java/x.y.z, …) travels alongside, so SDK identity and support status stay carried by the existing per-SDK entries — the side entry declares the side.

I don't think this is right.

The version string is the version of the entry it is tied to, so for example the agent string ably-js/2.0.1 nodejs/22.23.2, that means the client is using version 2.0.1 of ably-js and 22.23.2 of Node.js.

You're proposing here that ably-pubsub-device will get a version, but what version will it be? In the example above, if it's 2.0.1 because that's the SDK version, then I think the entry needs to be ably-pubsub-js-device (i.e. it has "js" in it to imply it's the device constructor from version 2.0.1 of ably-js, not some other SDK).

But I question whether it should have a version, and instead it's a versionless entry to indicate server/device, a bit like browser is versionless to indicate the client is connecting from a browser?

@lmars

lmars commented Sep 1, 2026

Copy link
Copy Markdown
Member

These are (I believe) the registry's first multi-repo identifiers

There are existing agent entries not tied to any repo, like linux, jre, and browser.

PDR-091b splits every Pub/Sub SDK into per-side packages whose
factories stamp a side-declaring agent entry so that MAU
classification never has to guess which side a connection is on. The
identifiers are shared across languages: ably/ably-pubsub-js#2293,
ably/ably-pubsub-java#1233 and ably/ably-pubsub-ruby#453 all stamp the same
ably-pubsub-device / ably-pubsub-server strings, alongside the SDK's
own versioned agent entry.

The entries are versionless, like browser: under lockstep versioning a
side-flag version would always duplicate the SDK entry beside it, and
across SDKs a bare ably-pubsub-device/1.2.3 cannot say 1.2.3 of what.
Version-of-what stays the SDK entry's job; the side entry is a pure
flag. They carry no source or product for the same reason browser
carries none: they are emitted by many repos and attribute no package.

Register both so the realtime system classifies them as known agents
rather than by their -device/-server suffix alone.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@umair-ably
umair-ably force-pushed the pubsub-per-side-agents branch from a90c69e to accd376 Compare September 2, 2026 09:07
@umair-ably

Copy link
Copy Markdown
Contributor Author

Both points taken — updated the PR accordingly.

Versionless it is. You're right that the version answered the wrong question: under the lockstep policy it always duplicated the SDK entry beside it, and cross-SDK it couldn't say version-of-what. The entries are now versioned: false, pure flags like browser, and the SDK implementations will stop stamping a version before they merge (ably-js change is queued; ably-java#1233 / ably-ruby#453 will match).

On the ably-pubsub-js-device alternative: we'd rather not fold the side into per-language identifiers — it's the same design question the registry already answered for ably-js itself, which covers Node/browser/RN with one versioned identifier plus separate context flags (browser, nodejs, react-native) rather than ably-js-browser identifiers. Family identifier + orthogonal flag keeps the two axes (which code / which side) independently queryable, avoids ~13 per-side identifiers whose versions would track identical core code, and keeps the -server suffix rule intact as the fallback.

And yes, "first multi-repo identifiers" was wronglinux/jre/browser are exactly the precedent. Following it dissolved the source question entirely: no source/product, which puts these in the schema's runtime branch. That type name is a stretch for a side marker — it's just the closest existing "context flag" shape. Shout if you'd prefer wrapper+source or a dedicated type and I'll switch.

umair-ably added a commit to ably/ably-pubsub-js that referenced this pull request Sep 2, 2026
The ably-pubsub-device / ably-pubsub-server agent identifiers are
shared by every Pub/Sub SDK (ably-java and ably-ruby stamp the same
strings), so a version on them cannot say what it versions — and under
lockstep releasing it only ever duplicated the SDK's own agent entry
sent alongside. Per the review of ably/ably-common#361, the side
entries become pure flags, like the core's browser entry:

  ably-js/2.29.0 nodejs/22.3.0 ably-pubsub-server

getAgentString now emits a bare identifier for a nullish agents value
(previously it produced the invalid token 'name/undefined'; the
Record<string, string | undefined> type always sanctioned versionless
entries, but no code path emitted them correctly). Entries with
versions are emitted exactly as before, so versioned attribution from
layered SDKs (chat-js/x.y.z, react-hooks/x.y.z) is unchanged.

optionsWithSideAgent loses its version parameter, the factories stop
importing their package.json version, and the wire tests
(pubsub_side_agent.test.js, the UTS side_modes self-test) now assert
the bare token and fail on any versioned form of the flag.

Marked breaking because the wire value changes: a released version had
stamped ably-pubsub-device/<version>, and anything matching on the
versioned form must match the bare identifier instead.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
umair-ably added a commit to ably/ably-pubsub-ruby that referenced this pull request Sep 2, 2026
Matches the entry's registration in the ably-common agents registry
(ably/ably-common#361): the side entry is a pure flag, like browser.
Under lockstep versioning a version on the flag always duplicates the
ably-ruby entry beside it, which keeps carrying identity, version and
support status. Wire shape:

  ably-ruby/2.0.0 ruby/3.3.0 ably-pubsub-server

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Under PDR-091b every SDK's agent identifier follows its repo rename in
the new major: ably-js -> ably-pubsub-js and so on. Because the flip
happens exactly at the package split and the maintenance branches are
never touched, the identifier alone partitions the fleet - the old
identifier is legacy-package traffic, the new one is new-package
traffic - so migration tracking and legacy EOL enforcement become a
string match.

Each entry sits beside its legacy counterpart, which stays registered:
the old packages keep stamping the old identifiers through their
maintenance year, and those entries are where their EOL sunsets will
live. Names and types mirror the legacy entries (ably-pubsub-flutter
stays a wrapper over the Java/Cocoa cores). ably-pubsub-dart and
ably-pubsub-rust have no legacy pub-sub entry to shadow and are
registered fresh against their existing repos.

Known wrinkle, deliberate: old and new identifiers share a source
repo, so fetch-agent-releases will associate that repo's releases with
both entries. Sunsets are authored per entry, so this only affects the
best-effort release CSV.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@umair-ably umair-ably changed the title Register the cross-SDK per-side Pub/Sub agents Register the Pub/Sub split agent identifiers: per-side flags and per-language families Sep 2, 2026
@umair-ably
umair-ably requested review from AndyTWF and lmars September 2, 2026 11:43
umair-ably added a commit to ably/ably-pubsub-java that referenced this pull request Sep 2, 2026
The family identifier follows the package split, per the agent
identifier convention proposed on PDR-091b2 and registered in
ably/ably-common#361: because it flips exactly at the split and the
maintenance branch is never touched, the identifier alone partitions
the fleet - ably-java/* is legacy-package traffic, ably-pubsub-java/*
is new-package traffic. It names the family rather than any one
published artifact; the side a client declares travels as the separate
versionless entry stamped by the door packages:

  ably-pubsub-java/2.0.0 jre/17.0.12 ably-pubsub-server

Requires the ably-pubsub-java registry entry (ably/ably-common#361)
before any release from this branch. Mirrors ably/ably-pubsub-js#2297.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
umair-ably added a commit to ably/ably-pubsub-ruby that referenced this pull request Sep 2, 2026
The family identifier follows the package split, per the agent
identifier convention proposed on PDR-091b2 and registered in
ably/ably-common#361: because it flips exactly at the split and the
maintenance branch is never touched, the identifier alone partitions
the fleet - ably-ruby/* is legacy-gem traffic, ably-pubsub-ruby/* is
new-package traffic. It names the family rather than any one published
gem; the side a client declares travels as the separate versionless
entry stamped by the server factories:

  ably-pubsub-ruby/2.0.0 ruby/3.3.0 ably-pubsub-server

Requires the ably-pubsub-ruby registry entry (ably/ably-common#361)
before any release from this branch. Mirrors ably/ably-pubsub-js#2297 and
ably/ably-pubsub-java#1233.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ttypic pushed a commit to ably/ably-pubsub-js that referenced this pull request Sep 15, 2026
The ably-pubsub-device / ably-pubsub-server agent identifiers are
shared by every Pub/Sub SDK (ably-java and ably-ruby stamp the same
strings), so a version on them cannot say what it versions — and under
lockstep releasing it only ever duplicated the SDK's own agent entry
sent alongside. Per the review of ably/ably-common#361, the side
entries become pure flags, like the core's browser entry:

  ably-js/2.29.0 nodejs/22.3.0 ably-pubsub-server

getAgentString now emits a bare identifier for a nullish agents value
(previously it produced the invalid token 'name/undefined'; the
Record<string, string | undefined> type always sanctioned versionless
entries, but no code path emitted them correctly). Entries with
versions are emitted exactly as before, so versioned attribution from
layered SDKs (chat-js/x.y.z, react-hooks/x.y.z) is unchanged.

optionsWithSideAgent loses its version parameter, the factories stop
importing their package.json version, and the wire tests
(pubsub_side_agent.test.js, the UTS side_modes self-test) now assert
the bare token and fail on any versioned form of the flag.

Marked breaking because the wire value changes: a released version had
stamped ably-pubsub-device/<version>, and anything matching on the
versioned form must match the bare identifier instead.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ttypic pushed a commit to ably/ably-pubsub-js that referenced this pull request Sep 15, 2026
The ably-pubsub-device / ably-pubsub-server agent identifiers are
shared by every Pub/Sub SDK (ably-java and ably-ruby stamp the same
strings), so a version on them cannot say what it versions — and under
lockstep releasing it only ever duplicated the SDK's own agent entry
sent alongside. Per the review of ably/ably-common#361, the side
entries become pure flags, like the core's browser entry:

  ably-js/2.29.0 nodejs/22.3.0 ably-pubsub-server

getAgentString now emits a bare identifier for a nullish agents value
(previously it produced the invalid token 'name/undefined'; the
Record<string, string | undefined> type always sanctioned versionless
entries, but no code path emitted them correctly). Entries with
versions are emitted exactly as before, so versioned attribution from
layered SDKs (chat-js/x.y.z, react-hooks/x.y.z) is unchanged.

optionsWithSideAgent loses its version parameter, the factories stop
importing their package.json version, and the wire tests
(pubsub_side_agent.test.js, the UTS side_modes self-test) now assert
the bare token and fail on any versioned form of the flag.

Marked breaking because the wire value changes: a released version had
stamped ably-pubsub-device/<version>, and anything matching on the
versioned form must match the bare identifier instead.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@lmars lmars left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

A minor comment regarding URLs, but otherwise LGTM

Comment thread protocol/agents.json
"identifier": "ably-pubsub-js",
"versioned": true,
"type": "sdk",
"source": "https://github.com/ably/ably-js",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should this be https://github.com/ably/ably-pubsub-js? Similar for all the other sources added in this PR.

ttypic pushed a commit to ably/ably-pubsub-java that referenced this pull request Sep 16, 2026
The family identifier follows the package split, per the agent
identifier convention proposed on PDR-091b2 and registered in
ably/ably-common#361: because it flips exactly at the split and the
maintenance branch is never touched, the identifier alone partitions
the fleet - ably-java/* is legacy-package traffic, ably-pubsub-java/*
is new-package traffic. It names the family rather than any one
published artifact; the side a client declares travels as the separate
versionless entry stamped by the door packages:

  ably-pubsub-java/2.0.0 jre/17.0.12 ably-pubsub-server

Requires the ably-pubsub-java registry entry (ably/ably-common#361)
before any release from this branch. Mirrors ably/ably-pubsub-js#2297.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants