You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
plugin-auth: a SCIM group push grants nothing — no projection maps a group to a role or permission set, though last-admin-guard counts it a live write shape #30959
Filing gate: (b) a contract gap with a named consumer, measured by the cloud#3667 dev on a real licensed objectos-ee serve (report on objectstack-ai/cloud#3667, Enterprise SCIM leaver lifecycle; draft PR objectstack-ai/cloud#3672). Platform gaps go to the platform (「平台的问题应该在平台处理」, objectstack#30765); the maintainer gave Enterprise work priority (「cloud 多了几个企业版的任务,优先处理」). Consumer: objectstack-ai/cloud#3667 (live Okta / Entra ID provisioning).
Measured (cloud pin 2ffdb649 on the serve; objectstack 6ddf827236 read)
SCIM POST /api/v1/auth/scim/v2/Groups with the user as a member → 201. The user's sys_user_permission_set rows and sys_member.role are unchanged (cloud#3672 parks this as it.skip).
packages/plugins/plugin-auth/src/auth-manager-plugin-list.ts:798 calls scim({ connections, authentication, identity }) with no projection, so @better-auth/scim's group membership touches nothing in the platform's grant model.
last-admin-guard.ts names a SCIM group-mapping change as a write shape it guards, which describes a mapping that does not exist.
Expected
A declared mapping from a SCIM group (by displayName or externalId, per connection or per organization; the lane decides) to an organization role and/or permission sets. Membership add and remove apply and revoke the grant.
Grants go through the existing assignment doors (assignable-set boundary, last-admin guard), not around them. A mapping that would drop the last admin is refused as the guard refuses other shapes.
Each grant change writes the audit row the assignment door already writes, attributed to the SCIM connection.
Acceptance
Tests: push a mapped group with a member → the set is granted; remove the member → revoked; an unmapped group grants nothing; a mapping that would remove the last admin → refused as a SCIM 403.
Dedupe (2026-11-06): SCIM group role mapping → 21 hits (#27314 open is the bridges epic, a different surface; the rest closed); scim projection → 47 hits, top 4 closed and unrelated. None covers this gap.
This answers domain:server#4's ask (6687238315). A SCIM group push creates the group and its members but grants no role and no permission set. Triage re-read main: auth-manager-plugin-list.ts passes scim({ connections: [], authentication, … }) with no projection. last-admin-guard.ts (L36, L121, L600) still speaks of a SCIM group mapping that nothing implements, and its refusal text sends an operator to a mapping that does not exist.
For the implementing lane: whether the mapping is a spec key or a settings row is the lane's design. A spec key brings the spec lane's review. The card already requires the existing assignment doors, the assignable-set boundary and the last-admin guard; a mapping that went around them would widen a security boundary.
Claim: PM loop round 1 · 2026-11-06T14:48Z
Session: session_016WV4czvZykUqhYxYXSSDt4
Account: os-elon-musk (the seat's linked user as GET /user answers it; the card's assignee)
Branch: the card thread's designated claude/project-thread-* branch, re-posted in a whole claim once the thread reports it
Worktree: objectstack-issue-30959
Domain: domain:server
Seat: domain:server#4
File surface: the SCIM wiring and a group projection in packages/plugins/plugin-auth/src/** (auth-manager-plugin-list.ts, scim-connection-service.ts, a new projection module, last-admin-guard.ts only where it names the SCIM mapping shape); the existing role and permission-set assignment doors it calls (read, or a caller face exposed with no new judgment); their tests and dogfood; content/docs/** sentences on SCIM provisioning; one root .changeset/ file. ⛔ packages/spec/**: if the mapping needs a published key, schema or settings key, the dev stops after measuring and the seat takes the design choice to the maintainer and files the domain:spec sub-card. ⛔ ui/**, skills/** (stop on breach; explain in the report)
Container & model: L, mode:thread, model: default, effort: xhigh (p1)
Clause-②: yes (widening) (provisional: a SCIM group push starts granting roles and permission sets; the dev measures and reports the arm)
Metadata-protocol: none (provisional; added only through the spec sub-card)
Responsibility: n/a — capability gap with a named consumer (objectstack-ai/cloud#3667), not a regression
Thread-read: 6687271791
Premise: card body (Enterprise priority, 「cloud 多了几个企业版的任务,优先处理」) and triage 6687271791 (p1 kept).
A declared mapping from a SCIM group (by displayName or externalId) to an organization role and/or permission sets. Adding a member grants, removing one revokes, and an unmapped group grants nothing.
Every grant goes through the existing assignment doors (assignable-set boundary, last-admin guard) and writes their audit row, attributed to the SCIM connection. A mapping change that would drop the last admin is refused as a SCIM 403.
Whether the mapping is a spec key or a settings row is measured first and decided before any build.
Serial constraints cleared: no open PR touches packages/plugins/plugin-auth (searched at claim); the dev re-reads open PRs on it at branch start
Contract review owed (a widening of a security boundary: a new grant path) before the queue.
Claim: PM loop round 1 (whole claim re-posted with the branch) · 2026-11-06T14:52Z
Session: session_016WV4czvZykUqhYxYXSSDt4
Account: os-elon-musk (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/project-thread-qta161
Dev session: session_016WV4cwCnS3MmnAfNkXm8MS (card thread)
Worktree: objectstack-issue-30959
Domain: domain:server
Seat: domain:server#4
File surface: the SCIM wiring and a group projection in packages/plugins/plugin-auth/src/** (auth-manager-plugin-list.ts, scim-connection-service.ts, a new projection module, last-admin-guard.ts only where it names the SCIM mapping shape); the existing role and permission-set assignment doors it calls (read, or a caller face exposed with no new judgment); their tests and dogfood; content/docs/** sentences on SCIM provisioning; one root .changeset/ file. ⛔ packages/spec/**: if the mapping needs a published key, schema or settings key, the dev stops after measuring and the seat takes the design choice to the maintainer and files the domain:spec sub-card. ⛔ ui/**, skills/** (stop on breach; explain in the report)
Container & model: L, mode:thread, model: default, effort: xhigh (p1)
Clause-②: yes (widening) (provisional: a SCIM group push starts granting roles and permission sets; the dev measures and reports the arm)
Metadata-protocol: none (provisional; added only through the spec sub-card)
Responsibility: n/a — capability gap with a named consumer (objectstack-ai/cloud#3667), not a regression
Thread-read: 6687271791
Premise: card body (Enterprise priority, 「cloud 多了几个企业版的任务,优先处理」) and triage 6687271791 (p1 kept).
A declared mapping from a SCIM group (by displayName or externalId) to an organization role and/or permission sets. Adding a member grants, removing one revokes, and an unmapped group grants nothing.
Every grant goes through the existing assignment doors (assignable-set boundary, last-admin guard) and writes their audit row, attributed to the SCIM connection. A mapping change that would drop the last admin is refused as a SCIM 403.
Whether the mapping is a spec key or a settings row is measured first and decided before any build.
Serial constraints cleared: no open PR touches packages/plugins/plugin-auth (searched at claim); the dev re-reads open PRs on it at branch start
Contract review owed (a widening of a security boundary: a new grant path) before the queue.
Parked · 2026-11-06T15:06Z · section 1 measured (/mnt/project-files/server-lane-seat4/30959/section1-measurements.md). The build is serial behind two sibling cards that edit the same files (scim-connection-service.ts, auth-manager-plugin-list.ts). This card rides #30960's SCIM write attribution (svc:scim:<connection>) instead of building its own. The storage of the mapping, and whether an IdP group may confer admin standing, are with the maintainer on a decision card. ADR-0134 D4 ("no group→role mapping in V1") needs an amendment, so the PR will be Tier H. The claim (6687734014) and the card thread stand.
Release: claim 6687734014 · 2026-11-06T16:25Z · server seat 4 is signing off on the maintainer's word, and this card has not started building. It stays pm:blocked (Blocked-by: #30960, Blocked-by: #30958). The assignee is removed, so the next seat claims it fresh.
Handoff for that seat:
Section 1 is measured: /mnt/project-files/server-lane-seat4/30959/section1-measurements.md (project files; the summary is in the parked note above).
Still open, for the maintainer: where the mapping lives (recommended: a per-connection platform-object row, sets only) and whether an IdP group may confer admin standing (recommended: no in V1). The seat's decision card on this was withdrawn at sign-off, so the next seat re-asks.
Owed: an ADR-0134 D4 amendment ("no group→role mapping in V1"), a fable-tier surface, so the PR is Tier H. One platform-object-names constant in spec needs the spec lane's nod.
Activity
objectstack-fleet commentedon Nov 6, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: audit · p1 kept ·
domain:server· 2026-11-06T14:31Z⛔ Not a claim.
domain:server#4's ask (6687238315). A SCIM group push creates the group and its members but grants no role and no permission set. Triage re-readmain:auth-manager-plugin-list.tspassesscim({ connections: [], authentication, … })with no projection.last-admin-guard.ts(L36, L121, L600) still speaks of a SCIM group mapping that nothing implements, and its refusal text sends an operator to a mapping that does not exist.domain:server(plugin-auth), followed byrepo:cloudfor cloud#3667.pm:queue.Generated by Claude Code
objectstack-fleet commentedon Nov 6, 2026
domain:server#4 · os-elon-musk · session_016WV4czvZykUqhYxYXSSDt4
Claim: PM loop round 1 · 2026-11-06T14:48Z
Session:
session_016WV4czvZykUqhYxYXSSDt4Account:
os-elon-musk(the seat's linked user asGET /useranswers it; the card's assignee)Branch: the card thread's designated
claude/project-thread-*branch, re-posted in a whole claim once the thread reports itWorktree:
objectstack-issue-30959Domain:
domain:serverSeat:
domain:server#4File surface: the SCIM wiring and a group projection in
packages/plugins/plugin-auth/src/**(auth-manager-plugin-list.ts,scim-connection-service.ts, a new projection module,last-admin-guard.tsonly where it names the SCIM mapping shape); the existing role and permission-set assignment doors it calls (read, or a caller face exposed with no new judgment); their tests and dogfood;content/docs/**sentences on SCIM provisioning; one root.changeset/file. ⛔packages/spec/**: if the mapping needs a published key, schema or settings key, the dev stops after measuring and the seat takes the design choice to the maintainer and files thedomain:specsub-card. ⛔ui/**,skills/**(stop on breach; explain in the report)Container & model:
L,mode:thread,model: default,effort: xhigh(p1)Clause-②: yes (widening) (provisional: a SCIM group push starts granting roles and permission sets; the dev measures and reports the arm)
Metadata-protocol: none (provisional;
addedonly through the spec sub-card)Responsibility: n/a — capability gap with a named consumer (objectstack-ai/cloud#3667), not a regression
Thread-read: 6687271791
Premise: card body (Enterprise priority, 「cloud 多了几个企业版的任务,优先处理」) and triage 6687271791 (p1 kept).
displayNameorexternalId) to an organization role and/or permission sets. Adding a member grants, removing one revokes, and an unmapped group grants nothing.Serial constraints cleared: no open PR touches
packages/plugins/plugin-auth(searched at claim); the dev re-reads open PRs on it at branch startContract review owed (a widening of a security boundary: a new grant path) before the queue.
objectstack-fleet commentedon Nov 6, 2026
domain:server#4 · os-elon-musk · session_016WV4czvZykUqhYxYXSSDt4
Claim: PM loop round 1 (whole claim re-posted with the branch) · 2026-11-06T14:52Z
Session:
session_016WV4czvZykUqhYxYXSSDt4Account:
os-elon-musk(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/project-thread-qta161Dev session:
session_016WV4cwCnS3MmnAfNkXm8MS(card thread)Worktree:
objectstack-issue-30959Domain:
domain:serverSeat:
domain:server#4File surface: the SCIM wiring and a group projection in
packages/plugins/plugin-auth/src/**(auth-manager-plugin-list.ts,scim-connection-service.ts, a new projection module,last-admin-guard.tsonly where it names the SCIM mapping shape); the existing role and permission-set assignment doors it calls (read, or a caller face exposed with no new judgment); their tests and dogfood;content/docs/**sentences on SCIM provisioning; one root.changeset/file. ⛔packages/spec/**: if the mapping needs a published key, schema or settings key, the dev stops after measuring and the seat takes the design choice to the maintainer and files thedomain:specsub-card. ⛔ui/**,skills/**(stop on breach; explain in the report)Container & model:
L,mode:thread,model: default,effort: xhigh(p1)Clause-②: yes (widening) (provisional: a SCIM group push starts granting roles and permission sets; the dev measures and reports the arm)
Metadata-protocol: none (provisional;
addedonly through the spec sub-card)Responsibility: n/a — capability gap with a named consumer (objectstack-ai/cloud#3667), not a regression
Thread-read: 6687271791
Premise: card body (Enterprise priority, 「cloud 多了几个企业版的任务,优先处理」) and triage 6687271791 (p1 kept).
displayNameorexternalId) to an organization role and/or permission sets. Adding a member grants, removing one revokes, and an unmapped group grants nothing.Serial constraints cleared: no open PR touches
packages/plugins/plugin-auth(searched at claim); the dev re-reads open PRs on it at branch startContract review owed (a widening of a security boundary: a new grant path) before the queue.
objectstack-fleet commentedon Nov 6, 2026
domain:server#4 · os-elon-musk · session_016WV4czvZykUqhYxYXSSDt4
Parked · 2026-11-06T15:06Z · section 1 measured (
/mnt/project-files/server-lane-seat4/30959/section1-measurements.md). The build is serial behind two sibling cards that edit the same files (scim-connection-service.ts,auth-manager-plugin-list.ts). This card rides #30960's SCIM write attribution (svc:scim:<connection>) instead of building its own. The storage of the mapping, and whether an IdP group may confer admin standing, are with the maintainer on a decision card. ADR-0134 D4 ("no group→role mapping in V1") needs an amendment, so the PR will be Tier H. The claim (6687734014) and the card thread stand.Blocked-by: #30960
Blocked-by: #30958
objectstack-fleet commentedon Nov 6, 2026
domain:server#4 · os-elon-musk · session_016WV4czvZykUqhYxYXSSDt4
Release: claim 6687734014 · 2026-11-06T16:25Z · server seat 4 is signing off on the maintainer's word, and this card has not started building. It stays
pm:blocked(Blocked-by: #30960,Blocked-by: #30958). The assignee is removed, so the next seat claims it fresh.Handoff for that seat:
/mnt/project-files/server-lane-seat4/30959/section1-measurements.md(project files; the summary is in the parked note above).externalId, thendisplayName. Ride plugin-auth: SCIM-driven writes leave sys_audit_log rows with actor, user_id and metadata null, so no audit row names the SCIM connection that acted #30960's SCIM write attribution (svc:scim:<connection>); don't build a second one.platform-object-namesconstant in spec needs the spec lane's nod.