A renewals deep link to one building makes the top bar name it

Cookie retirement, part 1: the deep link moves the company selection, and a one-building selection is the building filter

24 Sept 2026 · branch origin/fix/deep-link-building-rides-the-selection · captured against propflow-stage · at 8d9ee410f9

Data note. Every name and balance below comes from propflow-stage, which is anonymized by construction (ADR-0097/0110 — phones in the impossible +1000 NPA, emails @example.test). The identical capture against prod would carry real tenants' names and balances and is not safe to attach anywhere, which is why the generator refuses to run against one.

1 · Before (main): the deep link names a building the top bar never shows

One company picked in the top-left corner, then a renewals link that names one of its buildings (?propertyId=). On main, WorkspaceScopeSync writes the single-building cookie, but since #11041 the building picker reads the selection, so the trigger keeps saying All Properties over a page scoped to one building.

Asserted in the captured DOM — All Properties. The trigger's all-state text is on screen with the page scoped to one building.

Before (main): the deep link names a building the top bar never shows
Provenance. Captured from commit bf48e22b07 plus uncommitted changes, read from the worktree the server was started from (/Users/miniclaw/code/PropFlow/propflowai-p11-building-picker) — the server could not report its own commit, so this is the weaker of the two sources. That commit is already merged into origin/main.

2 · After (this PR): the top bar names the deep-linked building

The same start. WorkspaceScopeSync now puts org=<its company>&prop=<it> on the address for one hop, keeping propertyId. The middleware records the selection and SelectionProvider cleans the two keys off. The trigger names Birch Row, and every building-filter consumer follows because a one-building selection is the building filter (buildingFilterOf).

Asserted in the captured DOM — Birch Row. The trigger names the deep-linked building. The address after cleanup is recorded by the companion probe below.

After (this PR): the top bar names the deep-linked building

What this checks and what it does not

Stage data (anonymized by construction), smoke user, one company picked by cookie. The address bar is not in the DOM, so a companion Playwright probe (same two servers, same start state) read every picker trigger and the final address after the page settled:

BEFORE (main bf48e22b07)  /leasing/renewals?propertyId=appfolio-9002  triggers: Fixture Property Co || All Properties
AFTER  (#11587 8d9ee410f9) /leasing/renewals?propertyId=appfolio-9002  triggers: Fixture Property Co || Birch Row

The building trigger is the second one. On both, SelectionProvider has removed org/prop and kept the page's own propertyId. Suites that pin the rule without a browser: WorkspaceScopeSync.test.tsx, building-filter-of.test.ts, PmsInspectorClient.nav-scope.test.tsx, one-building-selection-is-the-building-filter.dom.test.tsx.

PropFlow Docs