Skip to content

fix(identity): opaque per-user tokens never surface in displayName suffixes - #934

Merged
lilyshen0722 merged 1 commit into
mainfrom
fix/opaque-token-displayname-suffix
Aug 13, 2026
Merged

fix(identity): opaque per-user tokens never surface in displayName suffixes#934
lilyshen0722 merged 1 commit into
mainfrom
fix/opaque-token-displayname-suffix

Conversation

@lilyshen0722

Copy link
Copy Markdown
Contributor

Why

Spotted while verifying the reaction-strip fix (#933): the smoke user's Guide renders as "Guide (U0da521ab41)" in every chat byline. The inline collision resolver (resolveCollisionFreeDisplayName) treats the opaque per-user token like any other instanceId — and since every user's Guide is displayName "Guide" by design, every user's Guide except the very first gets the token suffixed into its human-facing label. That's the exact leak the #930 identity convention exists to prevent, at the third of the four name sources.

What

  • Inline resolver: opaque tokens (convention u+10hex, or the legacy long form) exit before the peer query — bare name kept. Per-user agents are pod-scoped; two users' same-named agents never co-render in v1. If a shared-pod surface someday needs disambiguation, the honest label is the owner ("Sam's Guide"), not the token — noted for ADR-020.
  • Offline dedup script: opaque-token agents excluded from grouping entirely (neither receive nor force a suffix). Regex kept byte-identical across all three copies (resolver / script / V2PodChat) with cross-references in comments.
  • strip-opaque-displayname-suffixes.ts: one-shot repair for rows written before the fix. Only strips a suffix that is exactly the humanization of the row's own token — a legit human suffix ("Pixel (Pixel-Demo)") cannot match. --dry supported. Will run on dev post-deploy (1 known row).

Proof

Collision-resolver suite extended: opaque convention token + legacy long form both keep the bare name against a colliding canonical peer; all 12 tests pass locally.

Historical PG username snapshots keep their old labels — those are frozen at post time by design; new messages resolve clean after the sweep.

🤖 Generated with Claude Code

https://claude.ai/code/session_01XeUH4HVDsDHYPsHJthXjB8

…ffixes

Every user's Guide is displayName "Guide" by design, so the inline
collision resolver suffixed each one after the first with its own opaque
instance token — "Guide (U0da521ab41)" in every chat byline (observed
live 2026-08-13). That is the exact leak the #930 identity convention
exists to prevent, at the third of the four name sources.

- resolveCollisionFreeDisplayName: opaque tokens (convention u+10hex or
  legacy long form) keep the bare name — per-user agents are pod-scoped,
  so same-named agents of different users never co-render; a future
  shared-pod surface should disambiguate by OWNER, not token (ADR-020).
- offline dedup script: opaque-token agents excluded from grouping
  entirely (neither receive nor force a suffix); regex kept identical.
- strip-opaque-displayname-suffixes.ts: one-shot repair for rows written
  before the fix — only strips a suffix exactly matching the row's own
  humanized token, --dry supported.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XeUH4HVDsDHYPsHJthXjB8
@lilyshen0722
lilyshen0722 merged commit 2caafbd into main Aug 13, 2026
11 checks passed
@lilyshen0722
lilyshen0722 deleted the fix/opaque-token-displayname-suffix branch August 13, 2026 09:12
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