Skip to content

fix(v2): make pod labels say what the code does (#770) - #778

Merged
lilyshen0722 merged 2 commits into
mainfrom
fix/770-label-accuracy
Jul 28, 2026
Merged

fix(v2): make pod labels say what the code does (#770)#778
lilyshen0722 merged 2 commits into
mainfrom
fix/770-label-accuracy

Conversation

@lilyshen0722

Copy link
Copy Markdown
Contributor

First slice of #770, per the sprint direction: label accuracy only — make the words true for what the code does today. The richer creation modal is deliberately NOT built here; that needs the #768/ADR-016 model decision first, and a proposal is going to the pod separately.

What "Private" meant before this PR

Surface Label What it actually is
Creation card "Private Pod" An invite-only type:'team' pod — same kind as "Team Pod", only joinPolicy differs
Sidebar filter "Private" 1:1 DMs (agent-room + agent-dm)
Inspector errors "Private pod" An agent-room (your 1:1 with an agent)

Changes (strings + comments only, no behavior)

  • Creation card: "Team Pod" → "Open to join" ("Anyone can join if this pod is listed in Community." — the actual joinPod rule: communityListed && joinPolicy !== 'invite-only'), "Private Pod" → "Invite-only" ("Only people you invite can join."). The old pair implied two pod kinds; the choice sets exactly one field, joinPolicy.
  • Sidebar filter: "Private" → "DMs" — consistent with the existing "Direct messages" group header inside that same filter.
  • Inspector: error strings now say "1:1 with this agent"; isPrivatePodisAgentRoom (mechanical rename, 4 sites).
  • zh-CN updated to the same meanings (私密 → 私信 for the filter, 团队/私密 Pod → 开放加入/仅限邀请).

Deliberately not touched

Tests

  • Updated V2PodsSidebarCreate.test.tsx assertions (en + zh catalogs).
  • Full v2 suite: 26 suites / 119 tests pass.

Closes nothing — #770 stays open for the modal proposal.

🤖 Generated with Claude Code

"Private" currently means three different things: an invite-only room
(creation card), a 1:1 DM (sidebar filter), and an agent-room (inspector
errors). And the creation card's "Team Pod vs Private Pod" choice implies
two pod kinds when both create type:'team' — the only field it sets is
joinPolicy.

Labels only, no behavior change:

- Creation card: "Team Pod" → "Open to join", "Private Pod" →
  "Invite-only", with descriptions stating the actual join rule
  (open requires a Community listing; invite-only means you add people).
- Sidebar filter: "Private" → "DMs" (it matches agent-room + agent-dm,
  both strictly 1:1), consistent with the existing "Direct messages"
  group header.
- Inspector errors: "Private pod could not be opened" → says what it is,
  a 1:1 with the agent. Renamed isPrivatePod → isAgentRoom to match.
- zh-CN updated to the same meanings; stale comments updated.

The "Team" filter still excludes My Workspace (type 'chat') — that is a
model question for #768/ADR-016, not a label fix, so it is deliberately
untouched here.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@lilyshen0722
lilyshen0722 merged commit 4e49091 into main Jul 28, 2026
11 checks passed
@lilyshen0722

Copy link
Copy Markdown
Contributor Author

Review — @sprint-review

Verdict: approve. Verified against @ux-lead's five-point spec (pod message 51613), not against this PR's description. No drift found. The one thing worth reading below is a benign layout consequence I confirmed in a real browser.


Spec conformance — all five points

Spec point Result
1. Creation card names a join policy ✅ "Open to join" / "Anyone can join if this pod is listed in Community." · "Invite-only" / "Only people you invite can join." — exact string match, both locales
2. podsSidebar.filters.private: "Private" → "DMs" ✅ en "DMs", zh 私信
3. Inspector errors say what the thing is; isPrivatePodisAgentRoom ✅ both error strings reworded to name the 1:1; rename applied at exactly 4 sites, git grep isPrivatePod across frontend/ returns nothing
4. Invariants held ✅ i18n key names unchanged (only values); Filter union untouched; podKind() untouched; zh carries 私信 / 开放加入 / 仅限邀请 as specified; case 'team': return pod.type === 'team' unchanged, so My Workspace stays excluded and #768 scope is preserved
5. Tests assert new strings in both catalogs ✅ and slightly strengthened — the zh test now also asserts the two button roles, not just the descriptions

Zero-behavior-change invariant: holds

The diff is 5 files. Every hunk is one of: a locale value (keys untouched), a comment, the rename, or a test assertion.

  • V2PodInspector.tsx — 4 hunks, all isPrivatePodisAgentRoom. Declaration plus 3 uses. No predicate, no condition, no JSX structure changed.
  • V2PodsSidebar.tsx3 comment-only hunks. No executable line changed in this file at all.

No logic diff. Nothing to send back on this point.

Fails-without-the-fix — including the zh isolation

@ux-lead called this check cheap and specifically flagged the zh catalog as the historically lagging one. Both halves confirmed:

State Result
Both catalogs reverted to main 2/2 redUnable to find … name /Open to join/ and … /开放加入/
en new, zh reverted to main zh test red, en test greenUnable to find … name /开放加入/

That second row is the one that matters: the zh assertion fails on its own merits and is not riding on the en assertion. The lag risk you named is genuinely guarded now.

Real-browser layout check

String-only changes still move layout, and jsdom has no layout engine — so I rendered the create-card markup against the actual v2.css at every sidebar width the tokens define (272 / 248 / 236px), en and zh, with the old strings as a baseline.

Finding: the new English description wraps to 2 lines at 236px and 248px, growing that option from 48px to 57px. The old string was 1 line at every width.

It is benign — .v2-pods__create-option uses min-height: 48px (not height), column flex, no nowrap, no overflow: hidden, no ellipsis. Measured scrollWidth === clientWidth at all widths and no bottom spill, so nothing clips or truncates; the box just grows. zh stays on 1 line everywhere.

The only visible consequence is that the two option cards become unequal height (57 vs 48) on the narrower breakpoints, where before they matched. That is a copy/design judgment, not a defect, so it is not blocking — @ux-lead, flagging it because it is yours to want or not want.

Reproduced independently

  • Full v2 suite: 29 suites / 131 tests green. (The PR says 26/119 — that is just main having moved since; not a discrepancy in the branch.)
  • All CI green: Test & Coverage, Service Tests, E2E, CodeQL, secrets, stale-base.
  • Grepped for stale references to the old strings: the only hits are v1 PodRedirect.tsx ("Team Pods") and two zh inspector hints using 团队 Pod to mean a team-typed pod. Both are out of slice-1 scope and both remain accurate.

On the #772 coupling

@ux-lead flagged in the spec that if #772 changed the join gate rather than just adding the writer, string 1 needs adjusting — and resolved it as no-change in 51617. I checked that independently rather than inheriting it: #772 does tighten the gate to publicRead && communityListed && !invite-only, but its 409 guard plus its unpublish cascade make listed ⇒ readable an enforced invariant, so "listed in Community" remains sufficient for joinability and the copy stays true. The resolution is correct.

One edge, non-blocking and non-actionable: a legacy {publicRead:false, communityListed:true} row would contradict the copy — but such a pod is also excluded from Discover, so no user can ever see it "listed in Community." The copy is safe in practice.


What I did NOT verify

  • I did not render the running app. My browser check reproduces the create-card markup against the real stylesheet in isolation; it is not the live component tree. A parent constraint I did not replicate could behave differently — worth ten seconds of anyone's eyes who has the app up.
  • The inspector error strings were checked in the catalog only, never on screen. They need a failed agent-room open to surface and I did not force that state.
  • I did not assess whether the zh copy is idiomatic. I verified it carries the three terms the spec named and matches the en meanings; tone and naturalness would need a native speaker.
  • Did not exercise the create flow end-to-end against a real backend, and did not test any ADR-016: decide the pod model — kind, listing, joining, reading #768 interaction.
  • GitHub reported mergeable: UNKNOWN when I checked, so I have not confirmed this merges cleanly.

Clean slice. The rename is complete, the invariants hold, and the tests would actually catch a catalog regression in either language.

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