Skip to content

finding: SCIMMemberReferenceSchema.type admits 'Group' (RFC 7643 §4.2) but stable @better-auth/scim rejects it twice over — declaration-vs-contract fork, latent (zero runtime consumers) #11820

Description

@os-warren

Filed unassigned — recording, not claiming. Surfaced by the #11697 field-level parity measurement (card comment 5399511853, executed probe against a real constructed @better-auth/scim@1.7.1 plugin); filed by the spec PM seat so the fork survives #11697's closure. Awaiting first-touch triage.

Measured

  • Ours: SCIMMemberReferenceSchema.type (packages/spec/src/identity/scim.zod.ts) admits 'User' | 'Group' — RFC 7643 §4.2 canonical values — and the nested-group case is pinned green (packages/spec/src/identity/scim.test.ts:380, "should support nested groups").
  • Stable upstream: @better-auth/scim@1.7.1 rejects 'Group' twice over — a zod refine (dist/index.mjs:22) and a BAD_REQUEST/invalidValue throw (:4594) — and its own discovery document advertises canonicalValues: ['User']. Probe case C (nested group) was REJECTED by the real endpoint.

So published spec surface (with a rendered docs page) advertises a capability the shipped implementation answers with a 400. The divergence is latent, not live: SCIMGroupSchema has zero runtime consumers repo-wide and in objectui (docs pages only) — nothing routes group payloads through packages/spec today, and no leg of #11632 does.

The fork (from the measurement report, verbatim options)

  • A — keep 'User' | 'Group': RFC-faithful and portable to any SCIM peer; cost is docs advertising what our own deployment refuses.
  • B — narrow to 'User': declared = enforced; a generated app is stopped at authoring time rather than by the IdP; cost is a knowing RFC 7643 §4.2 divergence plus retiring the pinned nested-group case. If taken, it is its own Clause-② card with the RFC divergence recorded — never a rider.
  • C — defer until a downstream leg first makes this schema load-bearing; that leg's direction is itself the answer to "declaration or contract".

Measurement's recommendation: C, with B if the maintainer wants it closed now (the make-AI-metadata-hard-to-get-wrong axis favours B; the zero-consumer reading and startup scope discipline favour C).

Refs: #11697 (the measurement, comment 5399511853) · #11632 (SCIM epic) · #3653 (question A = implement).

Blocked-by: #11632


Triage: closed not_planned — North Star full-board re-grade (2026-09-19)

Path: none. All 22 identity-auth checklist items were read and not one tests SCIM (control: 96 items mention sign-in/login, so the instrument is live); enterprise IdP provisioning is not a step on the measured journey, and 「登录与身份」 means the application's own sign-in. The card itself records zero runtime consumers.

Nothing is lost. Closing does not delete this issue — body and thread stay readable and reopening is free. Maintainer-confirmed disposition; ⛔ this seat closes nothing on its own authority.


Generated by Claude Code

Activity

  1. claude commented on Aug 25, 2026

    @claude
    Contributor

    Concentrated triage batch: finding → pm:blocked + domain:spec, Task — declaration-vs-contract fork (spec admits RFC 7643 'Group', stable @better-auth/scim@1.7.1 rejects it twice over), latent with zero runtime consumers. The resolving fact is owned by the SCIM stable migration: whether the platform ships nested-group membership is decided there, so this card waits on it rather than forcing a premature narrowing.

    Blocked-by: #11632

    On unlock (the epic closes): re-measure probe case C against the migrated endpoint — if 'Group' is still rejected, narrowing SCIMMemberReferenceSchema.type is a Clause-② contract change and goes to the decision box with the probe reading; if the migration brought group membership, close this as resolved-by-upstream.


    Generated by Claude Code

  2. added theissue type on Aug 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions