Skip to content

fix(scim): push Stop for runs a directory sync ends, after its transaction commits - #9104

Merged
waleedlatif1 merged 2 commits into
stagingfrom
fix/stop-delivery-convention
Oct 16, 2026
Merged

waleedlatif1 merged 2 commits into
stagingfrom
fix/stop-delivery-convention

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

  • A directory sync that withdrew a workspace grant (withdrawGrant) or demoted an org admin (setOrganizationRole) recorded Stop for the user's live Chat runs but dropped the returned runs, so nothing pushed the Stop; the run ended only on the worker's next run-control read
  • ProjectionDelta now carries stoppedRuns; withdrawGrant and setOrganizationRole return the runs they stopped
  • One convention: the transaction owner delivers with deliverRunStops strictly after commit — group writes (withGroupWrite), SCIM user PUT/PATCH (writeUser), and the batched reconcile per committed batch (reconcile job, mapping changes). A rolled-back write or batch delivers nothing
  • Member removal, member transfer and external-collaborator removal results carry stoppedRuns as a required field (no more ?? [] at callers), returned from inside the transaction so a retried attempt can never surface runs from a rolled-back one
  • Provisioning's projection cannot withdraw (a new directory record has no provenance), so it delivers nothing; noted inline

Not in this PR:

  • The ban path (disableUserResources) still relies on run control: delivering from it (statically or lazily) pulls the delivery graph into every page via lib/auth/auth.ts and exceeds the module-count baseline on 11 page entries. Needs a separate decision
  • The four internal-admin role writes that bypass changeMemberRoleTx are unchanged (tracked separately)

Type of Change

  • Bug fix

Testing

  • New integration tests (real Postgres + Redis, stub worker): directory group removal and directory demotion push Stop for the live run after commit (both fail on staging); a group write that rolls back after stopping a run pushes nothing; the batched reconcile pushes nothing for a rolled-back batch and pushes once the batch commits (fails on staging)
  • Verified the batch rollback test catches a delivery of rolled-back work
  • Affected SCIM, membership and member-manager unit tests pass

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@vercel

vercel Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
docs Skipped Skipped Oct 16, 2026 3:31am UTC

Request Review

@cubic-dev-ai cubic-dev-ai Bot 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.

3 issues found across 17 files

Confidence score: 3/5

  • reconcile-user.ts can stop runs for a workspace that receives a new grant in the same reconciliation: the stop is collected before plan.apply and canceled only after access is restored. Make the stop decision account for grants applied in that reconciliation.
  • removal-stops-runs.integration.ts only seeds two users, so it misses whether Stops from a committed batch survive a later batch rollback. Seed more than 25 users and fail a grant in the second batch.
  • removal-stops-runs.integration.ts uses a fixed 200 ms delay to check rollback behavior, so a late asynchronous Stop can arrive after the assertion. Use a deterministic delivery barrier or await delivery.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/sim/lib/mothership/request/application/removal-stops-runs.integration.ts">

<violation number="1" location="apps/sim/lib/mothership/request/application/removal-stops-runs.integration.ts:713">
P3: The rollback checks use a fixed 200 ms delay, so a delayed asynchronous Stop can arrive after the assertion and make the regression test pass. Replace the wall-clock sleep with a deterministic delivery barrier or awaitable worker observation.</violation>

<violation number="2" location="apps/sim/lib/mothership/request/application/removal-stops-runs.integration.ts:738">
P2: This supplies only two users, so reconciliation uses one batch and never tests whether Stops from an earlier committed batch survive a later batch rollback. Seed more than 25 users and fail a grant in the second batch to cover that guarantee.</violation>
</file>

<file name="apps/sim/ee/scim/lib/projection/reconcile-user.ts">

<violation number="1" location="apps/sim/ee/scim/lib/projection/reconcile-user.ts:379">
P2: Role demotion runs before `plan.apply`, so a run in a workspace receiving a new grant is collected here while access is temporarily absent, then canceled after commit despite restored access. Filter Stops against the final grants.</violation>
</file>

Turn on auto-fix | Re-trigger cubic

Comment thread apps/sim/lib/mothership/request/application/removal-stops-runs.integration.ts Outdated
Comment thread apps/sim/ee/scim/lib/projection/reconcile-user.ts Outdated
Comment thread apps/sim/lib/mothership/request/application/removal-stops-runs.integration.ts Outdated
@greptile-apps

greptile-apps Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Critical impact] This PR appears safe to merge; no new actionable issues were found.

Summary

This PR pushes Stop for Chat runs whose workspace access ends during directory sync.

  • Directory syncs push Stops when a change ends a user's workspace access.
  • Membership changes return the runs they stopped for callers to deliver.

Diagram

sequenceDiagram
    participant Caller as Group write, user write, or batch
    participant DB as Database transaction
    participant Worker
    Caller->>DB: Change directory grants
    DB->>DB: Check final access and record Stops
    alt Transaction commits
        DB-->>Caller: Return stopped runs
        Caller->>Worker: Deliver Stops
    else Transaction rolls back
        DB-->>Caller: Throw error
        Note over Caller,Worker: No Stops delivered
    end
Loading

Reviews (3) · Last reviewed commit: "fix(scim): judge directory stops against..." · Reviewed by Greptile

Comment thread apps/sim/ee/scim/lib/projection/reconcile-user.ts Outdated
Comment thread apps/sim/lib/mothership/request/application/removal-stops-runs.integration.ts Outdated
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptileai review

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cubic-dev-ai review

@cubic-dev-ai

cubic-dev-ai Bot commented Oct 16, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai review

@waleedlatif1 I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-ai Bot 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.

No issues found across 20 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Turn on auto-fix | Re-trigger cubic

…ction commits

A directory sync that withdrew a workspace grant or demoted an organization
admin recorded Stop for the user's live Chat runs but never pushed it, so the
runs ended only on the worker's next run-control read.

- Projection deltas carry the runs their withdrawals stopped; withdrawGrant and
  setOrganizationRole return them instead of dropping them
- Group writes and user updates deliver them once their transaction commits;
  the batched reconcile delivers each batch after it commits, so a rolled-back
  batch delivers nothing
- Member removal, transfer and external-collaborator removal results carry
  stoppedRuns as a required field, returned from inside the transaction
- A reconciliation pass that demotes an admin or withdraws a grant while granting the same workspace back no longer stops the run there: access is checked once after every withdrawal and grant
- Fix the readonly skipped result that failed type-check
- Cover a committed batch delivering when a later batch rolls back, and observe rollback deliveries deterministically
@waleedlatif1
waleedlatif1 force-pushed the fix/stop-delivery-convention branch from fc60e9d to 8c1efe3 Compare October 16, 2026 03:31
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptileai review

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cubic-dev-ai review

@cubic-dev-ai

cubic-dev-ai Bot commented Oct 16, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai review

@waleedlatif1 I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-ai Bot 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.

No issues found across 20 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Turn on auto-fix | Re-trigger cubic

@waleedlatif1
waleedlatif1 merged commit e7076a9 into staging Oct 16, 2026
53 checks passed
@waleedlatif1
waleedlatif1 deleted the fix/stop-delivery-convention branch October 16, 2026 03:47

This branch was previously deployed

1 inactive deployment
Preview — 8c1efe35 Deployed Oct 16, 2026 by vercel[bot]
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