Bite 30E — Session and Tenant Selection Refactor - RodrigoMattosoSilveira/EnterpriseRemoteSystems GitHub Wiki

Bite 30E — Session and Tenant Selection Refactor

Deterministic Manual Verification Checklist Before Promotion

Issue: Bite #30E — Session and Tenant Selection Refactor
Branch: 712-bite-30e-session-and-tenant-selection-refactor


0. Testing Standard for Bite 30E

This checklist is intentionally fixture-driven and deterministic.

For the remainder of Bite 30E, use these terms consistently:

Person ID
Authentication Account ID
Login

Tenant ID
Actor ID
Actor Key
Membership ID

Delegated Role

Relationship terminology:

Authentication Account
  -> Tenant Actor
      -> same-tenant Person–Tenant Membership

If an API returns actorRecordId, treat it as:

actorRecordId (Actor ID)

It is the same persisted authz_actors.id.


1. Automated Prerequisite

Before beginning manual testing:

  • All migrations apply successfully.
  • make local-check passes.
  • Full Vitest suite passes.
  • Full Playwright suite passes.

2. Seed the Bite 30E Manual-Test Identities

Use the Bite 30E seed script created for this test cycle.

From the project root:

cd /Users/rodrigosilveira/projects/EnterpriseRemoteSystems

Stop the backend before running the seed script because it writes directly to SQLite.

Then run:

python3 scripts/seed-bite30e-manual-test-identities.py

Default credentials:

Identity A
Login: [email protected]

Identity B
Login: [email protected]

Identity C
Login: [email protected]

Identity D
Login: [email protected]

Password for all four:
Manual-30C-Password!

Default tenant names:

Tenant A: Byte 28A Manual Test
Tenant B: default

If the default fixture batch has already been used and you need a fresh set:

python3 scripts/seed-bite30e-manual-test-identities.py \
  --batch retry1

In that case, use the logins and IDs printed by that run instead of the default values shown above.


3. Fixture Manifest — Fill This Once From the Seed Output

The seed script prints all values needed by the tests below.

Copy the output here before starting.

Tenant A

Tenant A Name:
Byte 28A Manual Test

Tenant A ID: b16647b4-82a3-4d4e-99d0-c15ede05840b
________________________________________

In the current local test data this has commonly been:

b16647b4-82a3-4d4e-99d0-c15ede05840b

Use the value printed by the seed script as authoritative.

Tenant B

Tenant B Name: Default Tenant
default

Tenant B ID: default
________________________________________

Identity A — Multi-Tenant Ordinary Account

Expected shape:

one ACTIVE Authentication Account
-> two ACTIVE tenant Actors
-> two ACTIVE same-tenant Memberships
-> no delegated Roles

Record:

Login: [email protected]
Password: Manual-30C-Password!
Person ID:
________________________________________

Authentication Account ID:
________________________________________

Tenant A ID:
________________________________________

Tenant A Actor ID:
________________________________________

Tenant A Actor Key:
________________________________________

Tenant A Membership ID:
________________________________________

Tenant B ID:
________________________________________

Tenant B Actor ID:
________________________________________

Tenant B Actor Key:
________________________________________

Tenant B Membership ID:
________________________________________

Testing rule: Identity A is stable. Do not deactivate or otherwise mutate its Actors or Memberships during Bite 30E manual testing.


Identity B — Person-Only Account

Expected shape:

one ACTIVE Authentication Account
-> exactly one ACTIVE tenant Actor
-> exactly one ACTIVE same-tenant Membership
-> no delegated Roles
-> no Collaborator Journey

Record:

Login:
[email protected]

Password:
Manual-30C-Password!

Person ID:
________________________________________

Authentication Account ID:
________________________________________

Tenant ID:
________________________________________

Actor ID:
________________________________________

Actor Key:
________________________________________

Membership ID:
________________________________________

Testing rule: Identity B is stable. Do not add delegated Roles or create a Collaborator Journey for it.


Identity C — Single-Tenant Account

Expected shape:

one ACTIVE Authentication Account
-> exactly one ACTIVE tenant Actor
-> exactly one ACTIVE same-tenant Membership
-> exactly one usable tenant

Record:

Login:
[email protected]

Password:
Manual-30C-Password!

Person ID:
________________________________________

Authentication Account ID:
________________________________________

Tenant ID:
________________________________________

Actor ID:
________________________________________

Actor Key:
________________________________________

Membership ID:
________________________________________

Testing rule: Identity C is stable. It exists only to verify the single-tenant session/selection experience.


Identity D — Disposable Multi-Tenant Account

Expected shape:

one ACTIVE Authentication Account
-> two ACTIVE tenant Actors
-> two ACTIVE same-tenant Memberships
-> no delegated Roles
-> safe for Actor deactivate/reactivate tests

Record:

Login:
[email protected]

Password:
Manual-30C-Password!

Person ID:
________________________________________

Authentication Account ID:
________________________________________

Tenant A ID:
________________________________________

Tenant A Actor ID:
________________________________________

Tenant A Actor Key:
________________________________________

Tenant A Membership ID:
________________________________________

Tenant B ID:
________________________________________

Tenant B Actor ID:
________________________________________

Tenant B Actor Key:
________________________________________

Tenant B Membership ID:
________________________________________

Testing rule: Identity D is the only identity intentionally mutated during the destructive session/Actor tests.


4. Canonical DevTools Scripts

Use these exact snippets throughout the checklist.

Script A — Show Current Account Session

Open DevTools → Console and run:

fetch("/api/v1/auth/session", {
  credentials: "include",
  cache: "no-store"
})
  .then(async (r) => ({
    status: r.status,
    body: await r.json()
  }))
  .then(console.log);

Expected for a valid ACTIVE Authentication Account:

status: 200

Script B — Show Current Actor for an Exact Tenant

Replace <TENANT-ID> with the exact ID from the Fixture Manifest:

fetch("/api/v1/authz/current-actor", {
  credentials: "include",
  cache: "no-store",
  headers: {
    "X-Tenant-ID": "<TENANT-ID>"
  }
})
  .then(async (r) => ({
    status: r.status,
    body: await r.json()
  }))
  .then(console.log);

Record/compare:

tenantId
actorRecordId (Actor ID)
actorKey
scope
roleCodes

Journey 1 — Identity A: Multi-Tenant Session and Actor Resolution

Do Tests 1–4 consecutively. Log in only once.


Test 1 — Identity A Authenticates Once at Account Level

Test Data

Login:
[email protected]

Password:
Manual-30C-Password!

Use the exact Identity A IDs from the Fixture Manifest.

Starting State

  • Identity A Authentication Account is ACTIVE.
  • Tenant A Actor is ACTIVE.
  • Tenant A Membership is ACTIVE.
  • Tenant B Actor is ACTIVE.
  • Tenant B Membership is ACTIVE.
  • Browser is signed out.

Procedure

  1. Open:

    http://localhost:5173/login
    
  2. Sign in using Identity A.

  3. Do not sign out.

  4. Open DevTools → Console.

  5. Run Script A — Show Current Account Session.

Expected UI

  • Login succeeds.
  • ERS does not ask which Actor should authenticate.
  • ERS does not ask for a second login for Tenant A or Tenant B.
  • Tenant selection is available after authentication.

Expected API

GET /api/v1/auth/session
-> HTTP 200

Pass

✔︎ PASS only if the Authentication Account is authenticated independently of which tenant Actor will later be selected.

Promotion Blocker

FAIL if:

  • ERS requires Actor-specific credentials;
  • ERS requires separate credentials for each tenant;
  • Account authentication fails even though the Authentication Account is ACTIVE.

Test 2 — Identity A Selects Tenant A and Resolves Exactly Actor A

Starting State

Identity A remains logged in from Test 1.

Test Data

Use:

Tenant A Name:
Byte 28A Manual Test

Tenant A ID:
<Identity A Tenant A ID>

Expected Actor ID:
<Identity A Tenant A Actor ID>

Expected Actor Key:
<Identity A Tenant A Actor Key>

Procedure

  1. In the header Tenant selector, select:

    Byte 28A Manual Test
    
  2. Open DevTools → Console.

  3. Run Script B with:

    X-Tenant-ID = <Identity A Tenant A ID>
    
  4. Compare the returned values with the Fixture Manifest.

Expected UI

  • Header shows Tenant A selected.
  • No Login screen appears.
  • [ x No password prompt appears.

Expected API

status:
200

tenantId:
<Identity A Tenant A ID>

actorRecordId (Actor ID):
<Identity A Tenant A Actor ID>

actorKey:
<Identity A Tenant A Actor Key>

scope:
TENANT

Pass

✔︎ PASS only if the returned Actor ID and Actor Key exactly match Identity A's Tenant A Actor.

Promotion Blocker

FAIL if:

  • Tenant A resolves Identity A's Tenant B Actor;
  • Tenant A resolves any unrelated Actor;
  • another login is required.

Test 3 — Identity A Switches Tenant A → Tenant B Without Reauthentication

Starting State

Identity A is logged in and Tenant A is currently selected.

Test Data

Tenant B Name:
default

Tenant B ID:
<Identity A Tenant B ID>

Expected Actor ID:
<Identity A Tenant B Actor ID>

Expected Actor Key:
<Identity A Tenant B Actor Key>

Procedure

  1. In the header Tenant selector, change:

    Byte 28A Manual Test
    

    to:

    default
    
  2. Do not sign out.

  3. Do not enter a password.

  4. Run Script B with:

    X-Tenant-ID = <Identity A Tenant B ID>
    
  5. Compare the result to the Fixture Manifest.

Expected UI

  • Header shows Tenant B selected.
  • No Login screen appears.
  • No password prompt appears.

Expected API

status:
200

tenantId:
<Identity A Tenant B ID>

actorRecordId (Actor ID):
<Identity A Tenant B Actor ID>

actorKey:
<Identity A Tenant B Actor Key>

scope:
TENANT

The Actor must be different from Tenant A:

Tenant A Actor ID != Tenant B Actor ID

Pass

✔︎ PASS only if the Account remains logged in and Tenant B resolves exactly Identity A's Tenant B Actor.

Promotion Blocker

FAIL if:

  • another login is required;
  • Tenant A Actor remains effective;
  • an unrelated Actor becomes effective;
  • Authentication Account changes.

Test 4 — Identity A Switches Back and Does Not Leak Tenant Data

Starting State

Identity A is logged in and Tenant B is selected.

Procedure

Part A — Verify data changes with tenant

  1. While Tenant B is selected, open:

    People
    
  2. Note one recognizable record or count belonging to Tenant B.

  3. Change the header Tenant selector to:

    Byte 28A Manual Test
    
  4. Remain on/open:

    People
    
  5. Watch the UI while the tenant changes.

Part B — Verify Actor resolution

  1. Run Script B with:

    X-Tenant-ID = <Identity A Tenant A ID>
    

Expected UI

  • Tenant-B People data is not presented as Tenant-A data.
  • Tenant-B records do not remain actionable after the switch.
  • Tenant-A data loads for Tenant A.
  • No Login screen appears.

Expected API

tenantId:
<Identity A Tenant A ID>

actorRecordId (Actor ID):
<Identity A Tenant A Actor ID>

actorKey:
<Identity A Tenant A Actor Key>

Expected sequence:

Tenant A -> Actor A
Tenant B -> Actor B
Tenant A -> Actor A

Promotion Blocker

FAIL if:

  • Tenant-B data remains actionable under Tenant A;
  • Actor B remains effective after selecting Tenant A;
  • the browser requires another login.

Journey 2 — Identity B: Person-Only Intrinsic Access


Test 5 — Person-Only Account Selects Its Tenant Without a Delegated Role

Test Data

Login:
[email protected]

Password:
Manual-30C-Password!

Expected Tenant ID:
<Identity B Tenant ID>

Expected Actor ID:
<Identity B Actor ID>

Expected Actor Key:
<Identity B Actor Key>

Delegated Roles:
NONE

Collaborator Journey:
NONE

Starting State

  • Identity A has been signed out.
  • Identity B Authentication Account is ACTIVE.
  • Identity B Actor is ACTIVE.
  • Identity B Membership is ACTIVE.
  • Identity B has no delegated Roles.

Procedure

  1. Open:

    http://localhost:5173/login
    
  2. Login as Identity B.

  3. Select its available tenant if the selector requires a choice.

  4. Open the normal Person self-service landing area.

  5. Run Script B using Identity B's Tenant ID.

Expected UI

  • Login succeeds.
  • Identity B can select/use its tenant.
  • Person self-service is available.
  • Tenant Administrator workspace is not available.
  • Earnings/Expenses operator workspaces are not available merely because the user authenticated.

Expected API

status:
200

tenantId:
<Identity B Tenant ID>

actorRecordId (Actor ID):
<Identity B Actor ID>

actorKey:
<Identity B Actor Key>

Pass

[x] PASS only if tenant selection works with zero delegated Roles.

Promotion Blocker

FAIL if:

  • ERS requires PERSON or another delegated Role merely to select the tenant;
  • operator/admin authority appears without a delegated Role;
  • the Account cannot authenticate because it has no delegated Role.

Journey 3 — Identity C: Single-Tenant Experience


Test 6 — Single-Tenant Account Has Exactly One Usable Tenant Context

Test Data

Login:
[email protected]

Password:
Manual-30C-Password!

Expected Tenant ID:
<Identity C Tenant ID>

Expected Actor ID:
<Identity C Actor ID>

Expected Actor Key:
<Identity C Actor Key>

Starting State

  • Identity B has been signed out.
  • Identity C Authentication Account is ACTIVE.
  • Identity C has exactly one ACTIVE tenant Actor.
  • Identity C has exactly one ACTIVE same-tenant Membership.

Procedure

  1. Login as Identity C.

  2. Inspect the header Tenant selector.

  3. Confirm there is exactly one usable tenant.

  4. Open People or another permitted landing page.

  5. Refresh the browser.

  6. Run Script B using Identity C's Tenant ID.

Expected UI

  • Exactly one usable tenant is available.
  • ERS does not present nonexistent Tenant A/Tenant B choices.
  • Browser refresh does not lose the valid tenant context.
  • No multi-tenant workflow is forced onto the user unnecessarily.

Expected API

status:
200

tenantId:
<Identity C Tenant ID>

actorRecordId (Actor ID):
<Identity C Actor ID>

actorKey:
<Identity C Actor Key>

Promotion Blocker

FAIL if:

  • unrelated tenants appear;
  • refresh resolves a different Actor;
  • the user is forced to select among tenant contexts that do not exist for the Account.

Journey 4 — Identity D: Actor Deactivation and Session Independence

Do Tests 7–11 consecutively.

Identity D is intentionally disposable.


Test 7 — Establish Identity D Baseline

Test Data

Login:
[email protected]

Password:
Manual-30C-Password!

Tenant A Actor ID:
<Identity D Tenant A Actor ID>

Tenant B Actor ID:
<Identity D Tenant B Actor ID>

Starting State

Verify in Authorization → Actors:

Identity D Tenant A Actor = ACTIVE
Identity D Tenant B Actor = ACTIVE

Procedure

  1. Sign out Identity C.

  2. Login as Identity D.

  3. Select Tenant A.

  4. Run Script B for Tenant A.

  5. Select Tenant B.

  6. Run Script B for Tenant B.

Expected

Tenant A:

actorRecordId (Actor ID):
<Identity D Tenant A Actor ID>

Tenant B:

actorRecordId (Actor ID):
<Identity D Tenant B Actor ID>

And:

Tenant A Actor ID != Tenant B Actor ID
  • Both tenant contexts work before destructive testing begins.

Test 8 — Deactivate Only Identity D Tenant A Actor

Starting State

Identity D is still authenticated.

Procedure

  1. Open a second browser context/window as Application Administrator.

  2. Navigate to:

    Authorization
    
  3. In Actors, search for Identity D.

  4. Locate the Actor whose Actor ID is exactly:

    <Identity D Tenant A Actor ID>
    
  5. Verify its Actor Key is:

    <Identity D Tenant A Actor Key>
    
  6. Click:

    Deactivate
    
  7. Do not deactivate Identity D's Tenant B Actor.

  8. Return to Identity D's browser session.

Expected Administrator UI

  • Tenant A Actor becomes inactive.
  • Tenant B Actor remains ACTIVE.
  • Identity D Authentication Account remains ACTIVE.

Test 9 — Inactive Tenant A Actor Returns 403 but Account Session Remains 200

Starting State

Identity D Tenant A Actor is inactive.

Identity D's browser session has not been deliberately signed out.

Procedure

Part A — Test Tenant A Actor resolution

Run Script B using:

<Identity D Tenant A ID>

Expected

HTTP 403

error.code:
tenant_actor_unavailable

Part B — Test Account session

Run Script A.

Expected

HTTP 200

Pass

[X] PASS only if both statements are true:

Tenant A Actor unavailable -> 403 tenant_actor_unavailable

Authentication Account session -> still valid -> 200

Promotion Blocker

FAIL if:

  • Actor deactivation produces Account-level 401;
  • the Authentication Account session is destroyed;
  • ERS silently substitutes Tenant B Actor for Tenant A.

Test 10 — Tenant B Remains Fully Usable After Tenant A Actor Is Deactivated

Starting State

Identity D Tenant A Actor is inactive.

Identity D Tenant B Actor remains ACTIVE.

Procedure

  1. Select:

    Tenant B / default
    
  2. Open a permitted Tenant-B page.

  3. Run Script B with:

    <Identity D Tenant B ID>
    

Expected UI

  • Tenant B remains available.
  • No re-login is required.
  • Tenant-B page functions normally.

Expected API

status:
200

actorRecordId (Actor ID):
<Identity D Tenant B Actor ID>

actorKey:
<Identity D Tenant B Actor Key>

Promotion Blocker

FAIL if deactivating Tenant A Actor also destroys Tenant B access.


Test 11 — Reactivate Tenant A Actor and Restore the Original Context

Procedure

  1. As Application Administrator, return to:

    Authorization → Actors
    
  2. Locate:

    <Identity D Tenant A Actor ID>
    
  3. Reactivate that Actor.

  4. Return to Identity D's browser.

  5. Refresh/re-evaluate tenant selection.

  6. Select Tenant A.

  7. Run Script B for Identity D Tenant A.

Expected

status:
200

actorRecordId (Actor ID):
<Identity D Tenant A Actor ID>

actorKey:
<Identity D Tenant A Actor Key>
  • The same original Actor ID is restored.
  • The same original Actor Key is restored.
  • Authentication Account ID remains unchanged.
  • Membership ID remains unchanged.
  • No duplicate Actor is created.
  • No duplicate Authentication Account is created.

Journey 5 — Identity D: No Active Tenant Actor Still Does Not Mean No Account

This is destructive. Perform it only after Test 11 succeeds.


Test 12 — ACTIVE Account With No Active Tenant Actors Can Still Authenticate

Starting State

Identity D is back to its original state after Test 11.

Procedure

Part A — Deactivate both tenant Actors

As Tenant Administrator:

  1. Deactivate:

    <Identity D Tenant A Actor ID>
    
  2. Deactivate:

    <Identity D Tenant B Actor ID>
    
  3. Verify the Authentication Account itself remains ACTIVE.

Part B — Establish a fresh login

  1. Sign Identity D out.

  2. Open:

    http://localhost:5173/login
    

[x] 6. Login again using:

[email protected]
Manual-30C-Password!

[x] 7. Run Script A.

Expected UI

  • Authentication succeeds.
  • ERS presents a No Tenant Access / limited-access state or equivalent.
  • No tenant application workspace is available.
  • Sign Out remains available.

Expected API

GET /api/v1/auth/session
-> HTTP 200

Pass

[x] PASS only if ERS distinguishes:

ACTIVE Authentication Account

from:

no currently usable tenant Actor

Promotion Blocker

FAIL if:

  • ERS reports invalid login/password solely because both tenant Actors are inactive;
  • Account authentication returns 401;
  • ERS silently invents or borrows a tenant Actor.

Test 13 — Restore Identity D After Destructive Tests

Do not leave the fixture damaged.

Procedure

As Application Administrator:

  1. Reactivate Identity D Tenant A Actor.

  2. Reactivate Identity D Tenant B Actor.

  3. Verify both are ACTIVE.

  4. Login as Identity D again if needed.

  5. Run Script B for Tenant A.

  6. Run Script B for Tenant B.

Expected

Tenant A:

Actor ID:
<original Identity D Tenant A Actor ID>

Tenant B:

Actor ID:
<original Identity D Tenant B Actor ID>
  • Original Actors were restored.
  • No replacement Actors were created.
  • Original Membership IDs remain unchanged.

[x] Journey 6 — Session Cache and Application-Administrator Regression


[x] Test 14 — New Login Does Not Reuse the Previous Account's Tenant/Actor State

Starting State

Identity D has been restored.

Procedure

  1. Login as Identity A.

  2. Select Tenant B.

  3. Open:

    People
    
  4. Run Script B and confirm Identity A Tenant B Actor.

  5. Sign out.

  6. Login as Identity C.

  7. Open:

    People
    
  8. Run Script B using Identity C's Tenant ID.

Expected

  • Identity A Tenant-B data does not remain displayed as Identity C data.
  • Identity A Actor does not survive the new login.
  • Tenant choices belong only to Identity C.
  • Current Actor is exactly Identity C's Actor.

Promotion Blocker

FAIL if a new Authentication Account inherits the prior Account's tenant data, Actor, or tenant selection in a way that grants incorrect access.


Test 15 — Application Administrator Remains Application-Scoped

Test Data

Use the normal local Application Administrator Authentication Account.

Starting State

Sign out the ordinary user.

Procedure

  1. Login as Application Administrator.

  2. Open DevTools → Console.

  3. Run Script B using Tenant A ID.

  4. Record:

    actorRecordId (Actor ID)
    actorKey
    scope
    roleCodes
    
  5. Run Script B using Tenant B ID.

  6. Compare the two results.

Expected

Both requests resolve the same Application Administrator Actor.

Expected authority:

scope:
APPLICATION

roleCodes:
includes APPLICATION_ADMIN

Verify:

  • Application Administrator remains application-scoped.
  • Tenant selection does not manufacture a tenant Actor for the Application Administrator.
  • Tenant selection does not convert APPLICATION_ADMIN into TENANT_ADMIN.
  • The same application Actor remains effective.

Do not use this test to enforce Bite 30H's later Application Administrator tenant-data-isolation behavior.


5. Final Browser/Network Sanity Check

During the journeys above, keep DevTools available.

Verify:

  • No unexpected JavaScript exception occurs.
  • No unexpected 500 response occurs.
  • 403 tenant_actor_unavailable occurs only when intentionally requesting a tenant whose Account-owned Actor is unavailable.
  • No authentication loop occurs.
  • No previous tenant's data remains actionable after switching tenants.
  • No previous Account's data remains actionable after signing out and logging in as another Account.

6. Final Backend Log Sanity Check

After completing manual testing, review backend output.

Verify:

  • No panic.
  • No unexpected internal API error.
  • No valid tenant selection resolves the wrong Actor.
  • No tenant Actor is borrowed from another tenant.
  • Deactivating a tenant Actor does not unexpectedly invalidate the Authentication Account session.

7. Promotion Gate

Bite 30E is ready for promotion only if all of the following pass:

  • Test 1 — Identity A authenticates once at Account level.
  • Test 2 — Tenant A resolves exactly Identity A Actor A.
  • Test 3 — Tenant B resolves exactly Identity A Actor B without re-login.
  • Test 4 — Switching back restores Actor A and does not leak tenant data.
  • Test 5 — Person-only Identity B selects its tenant without delegated Roles.
  • Test 6 — Identity C has exactly one usable tenant context.
  • Test 7 — Identity D baseline has two distinct usable tenant Actors.
  • Test 8 — Only Identity D Tenant A Actor is deactivated.
  • Test 9 — inactive tenant Actor returns 403 tenant_actor_unavailable while Account session remains 200.
  • Test 10 — Identity D Tenant B remains usable.
  • Test 11 — reactivation restores the original Tenant A Actor.
  • Test 12 — ACTIVE Account with zero active tenant Actors can still authenticate.
  • Test 13 — Identity D is restored to its original fixture state.
  • Test 14 — a new login does not inherit the previous Account's cached tenant/Actor context.
  • Test 15 — Application Administrator remains APPLICATION-scoped.
  • No unexpected 500, authentication loop, or cross-tenant data exposure occurs.

8. Promotion-Blocking Defects

Do not promote Bite 30E if any of these occur:

  • Tenant A resolves Tenant B Actor.
  • Tenant B resolves Tenant A Actor.
  • Switching tenants requires another login.
  • Switching tenants changes the Authentication Account.
  • Tenant-specific data remains actionable after switching to another tenant.
  • ERS borrows an Actor from another tenant.
  • Deactivating one tenant Actor invalidates the whole Authentication Account session.
  • Deactivating Tenant A Actor destroys Tenant B access.
  • An ACTIVE Account cannot authenticate solely because it has no active tenant Actor.
  • Person-only Identity B requires a delegated Role merely to select its tenant.
  • Identity C exposes more than its one valid tenant context.
  • Reactivating an Actor creates a replacement instead of restoring the original Actor.
  • A new login inherits the previous Account's Actor or tenant data.
  • Application Administrator becomes tenant-scoped.
  • Any unexpected server 500 occurs during a valid Bite 30E journey.
  • Any cross-tenant data exposure is observed.

If every Promotion Gate item passes, Bite 30E is ready for promotion.

⚠️ **GitHub.com Fallback** ⚠️