Skip to content

fix(identity): per-user-agent id convention (u+sha10) + shortest-unambiguous handles - #930

Merged
lilyshen0722 merged 2 commits into
mainfrom
fix/guide-identity-convention
Aug 13, 2026
Merged

fix(identity): per-user-agent id convention (u+sha10) + shortest-unambiguous handles#930
lilyshen0722 merged 2 commits into
mainfrom
fix/guide-identity-convention

Conversation

@lilyshen0722

Copy link
Copy Markdown
Contributor

Sam's two flags on the migrated Guide identity, answered as one convention:

The id itself: u<24-hex-ObjectId> was the 2am privacy fix, not a convention. The convention for per-user agents is now u + first 10 hex of sha256(userId) — short, signup-derivable, and opaque (the ObjectId no longer survives into any identity tier; the fleet review measured it leaking through instanceId, username, AND the collision-suffixed displayName). Migration (--dry supported) normalizes both legacy forms: long-form memory envelopes are renamed (single-owner by construction), shared default envelopes remain quarantine-only.

Whether anyone sees it: they shouldn't. The backend's mention map already resolves a bare agentName whenever a pod has exactly one installation of it — but the typeahead and the delivery hint preferred instanceId, which post-fork meant "Try @u6a7d154a0ec237d4b15dd286". Both now apply the same shortest-unambiguous rule: @guide everywhere, instanceId handles only when two instances of one agent genuinely share a pod.

Post-merge: run the migration on dev (normalizes the smoke install), then verify @guide typeahead live.

Tests pin the convention shape and distinctness; typecheck clean both tiers; frontend jest in CI.

🤖 Generated with Claude Code

https://claude.ai/code/session_01XeUH4HVDsDHYPsHJthXjB8

lilyshen0722 and others added 2 commits August 13, 2026 00:42
…biguous mention handles

Sam on the first migrated identity: "that guide agent id is that long? will
this be our convention????" No. Two fixes, one convention:

1. instanceId = u + sha256(userId).slice(0,10) — short enough for a handle,
   derivable at signup, and OPAQUE: the raw ObjectId no longer survives into
   any identity tier (the first cut leaked it through instanceId, username,
   and the collision-suffixed displayName; fleet review measured all three).
   Migration normalizes both legacy forms — long-form envelopes are renamed
   (single-owner by construction), shared 'default' envelopes stay
   quarantine-only.

2. The hash should also never be SEEN: the typeahead and delivery hint now
   apply the backend's own shortest-unambiguous rule (bare agentName resolves
   whenever a pod has exactly one installation of it — mention map line 195).
   "@guide" is the handle in every workspace; instanceId handles surface only
   when two instances of one agent actually share a pod — the case they were
   built for. Without this, the fork regressed the #914 hint into
   "Try @u6a7d154a0ec237d4b15dd286".

Tests pin the convention shape (u+10hex, raw userId absent) and distinctness.
Typecheck clean both tiers.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XeUH4HVDsDHYPsHJthXjB8
…ceIds always

CI caught my shortest-unambiguous rule regressing the moltbot case: for
openclaw agents the instanceId ("aria") IS the identity and agentName is the
runtime label we never surface — the rule would have suggested "@openclaw".
The distinction that actually matters is opacity, and the new convention
makes it detectable: isOpaqueInstanceToken (u+sha10 + legacy long form)
falls back to agentName; every human-chosen instanceId stays the handle.
Both directions pinned in the hint suite (@aria stays; @guide never shows
the token).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XeUH4HVDsDHYPsHJthXjB8
@lilyshen0722
lilyshen0722 merged commit 0cfec6a into main Aug 13, 2026
11 checks passed
@lilyshen0722
lilyshen0722 deleted the fix/guide-identity-convention branch August 13, 2026 07:59
lilyshen0722 added a commit that referenced this pull request Aug 13, 2026
…ffixes (#934)

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.


Claude-Session: https://claude.ai/code/session_01XeUH4HVDsDHYPsHJthXjB8

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant