One login, two companies: invite, accept, switch, fresh load, remove

Stage evidence for board row ui-s-b (PR #14396). A brand-new test person was invited into two TEST companies through the back office and accepted the second company's invite in a real browser. They moved between the companies with the real switcher, and a fresh load kept each pick. Staff then removed them from one company, and that company's access ended. Captured 2026-09-30 from a local dev server pointed at propflow-stage. No production system was read or written.

Result

✓ staff invite one new person into two companies through the back office
✓ the person accepts the second company invite in a real browser   (landed /dashboard, standing in A)
✓ the real switcher moves the person between companies, and a fresh load keeps the pick   (B → A → B)
✓ removing the person from one company ends that access and keeps the other
4 passed   exit 0

At every stop the run checks four things. The server names the picked company. It resolves that company's own Person. That company's building is served and the other company's building is not. A direct read of the other company's building by id is refused. After each switch, the same checks run again from a new browser that carries only the sign-in cookie, with no selection cookie and nothing in the URL. So the pick is held on the server.

1 · The switcher, open, offering both companies

This is the account menu of the invited person, standing in company A ("Dev Persona Started Co (TEST)"). The Company group lists both companies, and the check mark is on the one they are in. The next click is the real switch to "Module Gate Probe (TEST)".

switcher-open-before-B.png
Fresh loads, removal, the falsifier, cleanup, and what was not covered

2 · Fresh load after switching to B

The Properties page is loaded again with no company in the URL. The rail names Module Gate Probe, the only building listed is Module Gate Probe's own, and the account row shows B's Person ("Switch Proof B (TEST)").

fresh-load-in-B.png

3 · Switching back to A, then a fresh load

switcher-open-before-A.png
fresh-load-in-A.png

4 · After staff remove the person from B

The removal happened while the person was standing in B. After a reload they stand in A, and A's building is the only one served. The account menu no longer has a Company group, because one company is left. Picking B through the product is refused, and B's building by id is refused.

after-remove-menu.png

Falsifier: the test fails when the fix is taken out

The membership-scoped Person resolution was swapped back to the old single-Person read in the running app, then restored. The run failed where it should:

✘ "this company's building is served"
  Expected: "module-gate-probe-1"   Received: ["dev-persona-started-building"]

The screen said company B, but the data served was company A's. That is the cross-company exposure the row's ruling names.

Cleanup, read back

All the test people from seven runs were removed from both stage tables. That includes runs that failed while the spec was being built. A sweep of propflow-stage (about 1.67 million items) and propflow-auth-stage found 134 rows before removal and 0 after. It matched on the test address prefix plus every user and Person id the runs created. The same sweep, pointed at the staff login's address, finds 9 rows. That positive control shows the sweep can find rows when they exist.

Not covered, and found along the way

PropFlow Docs