Skip to content

fix(cli): Make org identity canonical and forward-compatible#64

Merged
thecodedrift merged 2 commits into
mainfrom
fix/org-identity-forward-compat
Jul 14, 2026
Merged

fix(cli): Make org identity canonical and forward-compatible#64
thecodedrift merged 2 commits into
mainfrom
fix/org-identity-forward-compat

Conversation

@thecodedrift

Copy link
Copy Markdown
Member

Treats the Taskless organization UUID as the single canonical identity and makes the CLI forward-compatible with the server's coming identity cleanup — without changing any observable behavior today.

What & why

The whoami/token payload currently carries three org identifiers with no clear hierarchy: a Taskless UUID (id), a numeric GitHub org id (orgId), and a GitHub App installationId. This PR establishes id as the one identity we act on and contains the other two.

  • Stop consuming installationId. Dropped from the WhoamiOrg type and from the taskless rule meta --json output. It was already .optional() and documented as absent for public repos, so no consumer could rely on its presence. The CLI never used it and it shouldn't round-trip through us.
  • Namespace the GitHub org id. WhoamiOrg.orgId is now optional and a new githubOrgId?: number is added; consumers read githubOrgId ?? orgId and keep working across the server's rename. It's a convenience id, never an identity.
  • Identify on the canonical id. decodeOrgId prefers the token's id claim over the legacy numeric orgId, and PostHog now groups organizations on that canonical id.
  • Tolerate number | string on the legacy path only. The canonical WhoamiOrg.id stays a UUID string; decodeOrgId accepts either type since we can't promise what a legacy claim carries.

No behavior change today

Current tokens don't carry an id claim, so decodeOrgId falls back to the numeric orgId and PostHog grouping is byte-for-byte unchanged until the server starts minting id. The new path is dormant plumbing.

Assumption to confirm

The canonical JWT claim is assumed to be named id (matching the whoami field). It's safe either way — dormant until such a claim exists — but if the server will name it differently, that's a one-word change in decodeOrgId.

Versioning

Marked patch (0.10.2): no observable change now, and the only external surface touched is an already-optional --json field. Bump to minor if you'd rather flag the field removal more loudly.

367 tests pass; typecheck, eslint, prettier clean.

🤖 Generated with Claude Code

Treat the Taskless org UUID as the one canonical identity and prepare for the
server namespacing its identifiers.

- Drop installationId from the WhoamiOrg type and rule meta --json output; the
  CLI never used it and it should not round-trip through us.
- Make WhoamiOrg.orgId optional and add githubOrgId?: number so consumers read
  githubOrgId ?? orgId across the server's rename; it is a convenience id only.
- decodeOrgId now prefers the token's canonical id claim over the legacy numeric
  orgId, tolerating string|number on the legacy path; PostHog groups on that
  canonical id, falling back to the numeric claim until id claims are minted.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 14, 2026 04:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR makes the CLI treat the Taskless organization UUID as the canonical org identity and prepares the client for upcoming server-side org identity cleanup (while aiming to keep current behavior unchanged until tokens start carrying the new claim).

Changes:

  • Update JWT org-subject decoding to prefer a canonical id claim (with legacy orgId fallback) and update telemetry grouping to use that canonical subject.
  • Adjust the WhoamiOrg type to drop installationId and to be forward-compatible with a server rename from orgIdgithubOrgId.
  • Remove installationId from taskless rule meta --json output schema and update/add tests plus a changeset entry.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/cli/test/telemetry.test.ts Adds coverage ensuring telemetry groups by canonical id when present.
packages/cli/test/org.test.ts Updates whoami org fixtures to align with the new WhoamiOrg shape.
packages/cli/test/jwt.test.ts Expands decodeOrgId tests for canonical-claim precedence and new accepted types.
packages/cli/src/telemetry.ts Switches PostHog org grouping from legacy orgId to canonical org subject.
packages/cli/src/schemas/rules-meta.ts Drops installationId from the meta JSON output schema.
packages/cli/src/auth/org.ts Refines WhoamiOrg typing for forward-compat (githubOrgId ?? orgId) and removes installationId.
packages/cli/src/auth/jwt.ts Changes decodeOrgId to prefer the canonical id claim and return `string
.changeset/org-identity-forward-compat.md Documents the forward-compat identity changes as a patch release.

Comment thread packages/cli/src/auth/jwt.ts Outdated
Comment thread packages/cli/test/jwt.test.ts
Address review: decodeOrgId now validates the canonical id claim and the
legacy orgId claim independently — a valid id wins, an invalid (empty) id still
lets a valid orgId through, and a non-numeric orgId is rejected rather than
accepted as an identity (a numeric string is coerced).

When neither a matched org nor a token claim resolves, the canonical id falls
back to the nil UUID so the org subject and PostHog group are always a known,
stable value. resolveOrgSubject is therefore total; resolveIdentity no longer
throws on a token missing org info and instead sends the nil-UUID subject.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@thecodedrift
thecodedrift merged commit 2b5f618 into main Jul 14, 2026
4 checks passed
@thecodedrift
thecodedrift deleted the fix/org-identity-forward-compat branch July 14, 2026 05:06
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.

2 participants