feat: emit PENDING status on invitation resources - #184
Conversation
Point go.mod at the baton-sdk branch that adds UserTrait_Status_STATUS_PENDING and Status_RESOURCE_STATUS_PENDING so invitation resources can express a pending state. Kept as its own commit so swapping to a tagged SDK release is a single-commit change. Co-authored-by: c1-squire-dev[bot] <c1-squire-dev[bot]@users.noreply.github.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Invitation resources previously emitted STATUS_UNSPECIFIED via the
deprecated trait-level WithStatus option, because the SDK had no way to
express "pending" and NewUserTrait force-defaults an unset trait status
to ENABLED.
Now that the SDK has a PENDING value, emit it explicitly:
- resource level via the non-deprecated WithResourceStatus, matching
the accepted-member path in user.go
- trait level via WithDetailedStatus, which is still required to
override NewUserTrait's ENABLED default
Both levels carry the invitation_status value (pending acceptance vs
expired) as status details. Expired invitations stay PENDING rather than
getting a distinct enum value: an expired invite is still not a usable
account, and the details field preserves the distinction.
Co-authored-by: c1-squire-dev[bot] <c1-squire-dev[bot]@users.noreply.github.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
| // attributes. Expired invitations stay PENDING - they are still not a | ||
| // usable account - and carry the distinction in the status details. | ||
| resourceSdk.WithResourceProfile(profile), | ||
| resourceSdk.WithResourceStatus(v2.Status_RESOURCE_STATUS_PENDING, status), |
There was a problem hiding this comment.
🟡 Suggestion: docs/connector.mdx:26 still says "if an invitation is pending, the account status will be shown as Unspecified", which this change makes wrong. Update it to Pending in this PR so the docs don't lag the emitted status.
Separately, both status fields carry defined_only enum validation, so a reader still on the pre-PENDING proto descriptor would reject enum value 4 rather than fall back to unspecified. The PR description covers the c1-first rollout ordering, but nothing in the connector enforces it — worth confirming that ordering is tracked before this leaves draft, since there is no config gate to fall back to.
|
|
||
| require ( | ||
| github.com/conductorone/baton-sdk v0.24.6 | ||
| github.com/conductorone/baton-sdk v0.25.1-0.20260825204020-991ca45253a7 |
There was a problem hiding this comment.
🟡 Suggestion: two things on this bump.
- It pins an unreleased pseudo-version (
v0.25.1-0.20260825204020-991ca45253a7). The PR already commits to swapping to the tagged release before undrafting — flagging so it isn't lost. - The bump is scoped in the description to "adds the two PENDING enum values", but v0.24.6 → v0.25.x also changes runtime behavior the connector inherits: the default dotc1z storage engine flips from SQLite to Pebble for new files (
pkg/dotc1z/engine_registry.go,pkg/field/defaults.go), and the--diff-syncs/--base-sync-id/--applied-sync-idflags are removed along with diff-sync support. Nothing in this repo references those flags, so there is no build or CI break, but the storage-engine default change affects the artifact this connector produces and is worth calling out in the PR description and release notes rather than shipping silently.
Connector PR Review: feat: emit PENDING status on invitation resourcesBlocking Issues: 0 | Suggestions: 3 | Threads Resolved: 0 Review SummaryScanned the full PR diff for security and correctness: the connector change ( Security IssuesNone found. Correctness IssuesNone found. Suggestions
Prompt for AI agents |
What changes
Pending GitHub org invitations are modeled as a dedicated
invitationresource type. Until now they had no way to say "pending": the connector emittedUserTrait_Status_STATUS_UNSPECIFIEDthrough the deprecatedWithStatustrait option, with a//nolint:staticchecksuppression, because the SDK had no PENDING value andNewUserTraitforce-defaults an unset trait status toENABLED.The SDK now has that value, so invitations emit it explicitly:
WithResourceStatus(v2.Status_RESOURCE_STATUS_PENDING, <detail>), the same non-deprecated option the accepted-member path inuser.gouses.WithDetailedStatus(v2.UserTrait_Status_STATUS_PENDING, <detail>). Still needed: SDK mirroring runs trait → resource, not resource → trait, so setting only the resource status would leave the trait defaulted toENABLED. Both trait-status options remain deprecated in the SDK, so the//nolintstays, but its justification is now narrow and accurate.The
<detail>string is the existinginvitation_statusvalue, so consumers can tell the two flavors apart:RESOURCE_STATUS_PENDINGSTATUS_PENDINGinvitation_pending_acceptanceRESOURCE_STATUS_PENDINGSTATUS_PENDINGinvitation_expiredExpired invitations stay PENDING rather than getting a distinct enum value. An expired invite is still not a usable account, and the details field preserves the distinction without inventing new enum semantics.
What changes for consumers
Invitation resources move from
STATUS_UNSPECIFIEDtoSTATUS_PENDING, at both the trait and the resource level. Nothing else about the resource changes — profile, IDs, entitlements, grants, and provisioning are untouched.Dependency
Depends on ConductorOne/baton-sdk#1104, which adds
UserTrait_Status_STATUS_PENDING = 4andStatus_RESOURCE_STATUS_PENDING = 4.The SDK is currently pinned by pseudo-version (
v0.25.1-0.20260825204020-991ca45253a7) in its own commit, separate from the code change, so swapping to the tagged release before undrafting is a one-commit change.Rollout ordering
c1 should ship its PENDING handling before this connector releases. That handling treats explicit
UNSPECIFIEDas pending too, so the ordering is safe in both directions — a c1 that understands PENDING reads today'sUNSPECIFIEDinvitations correctly, and a connector emitting PENDING against a c1 that already handles it is a no-op change in behavior.Testing
pkg/connector/invitation_test.goasserts both status levels for both fixtures via a newrequireInvitationPendinghelper. Verified the trait-level assertion is load-bearing: removing theWithDetailedStatusline makes the trait status come back as1(ENABLED) instead of4(PENDING) while the resource level stays PENDING — exactly the trap the removed comment described — and three subtests fail.🤖 Generated with Claude Code