CMDB is now multi-company; record the invariant and two testing lessons
Multi-Tenancy-Progress: CMDB marked done, with the two deferrals written down
- moving a CI between companies (and the shape it would take), and the
deliberate Network Mapper boundary where diagrams stay unfiltered.
CMDB page: a Multi-company section - one CI, one company, no shared CIs, what
that implies for parent/relationships/object_ref, what stays install-wide
(classes, properties, relationship types, icons) and why, and the move-to-
company gap.
Developer guide:
- new special case for a graph of inter-linking rows. The headline is that a
same-company invariant must bind an ALL-ACCESS actor too - a scope check
can't help when the actor legitimately reaches both sides - and that a link
leaks even when the far row is unreadable.
- ALWAYS INCLUDE A POSITIVE CONTROL. "Was it blocked?" assertions pass just as
happily when the request was broken as when it was refused. php://input is
empty under the CLI SAPI, so a whole write suite failed validation before
reaching any tenancy check and every isolation assertion went green - nine
checks proving nothing. The tell was the positive controls failing too.
- drive the real endpoint rather than a copy of its SQL, and why: parameter
ORDER (SELECT-subquery and JOIN...ON fragments bind before WHERE) is the bug
class a reimplementation can never catch.
Document the connection shape, the NULL-semantics trap and fresh-install drift
Multi-Tenancy-Developer-Guide:
- section 1 now documents THREE table shapes, not two. Connections (mailboxes,
messaging channels, web chat widgets) are a distinct shape where NULL means
shared intake, not Default-owned, and the list is deliberately install-wide.
Flags that using activeTenantFilter here would hide shared-intake channels
and break per-sender routing.
- notes the credentials exception to "caps guard writes not reads".
- adds analystCanAccessChannel / analystCanAssignTenant to the toolbox.
- verify section: N=1 and N=2 MUST run in separate processes because
tenantCount() memoises in a static; plus the scratch-database fixture
recipe, which doubles as a fresh-install test.
- checklist: name what NULL means; assert the two schema files agree; validate
a client-supplied company against the actor's access rather than existence.
Database-Verification-Developer-Guide: new section on the gap the index drift
guard doesn't cover — columns. Uses the asset_locations.tenant_id bug as the
worked example and explains why it survived review (development only ever
exercises the upgrade path, so fresh-install drift is invisible until someone
downloads it). Suggests extending the self-check to columns.
Multi-Tenancy-Progress: Knowledge and messaging/web chat marked done, with the
open tenant_channel_senders UI gap and the webchat routing asymmetry recorded.
Multi-Tenancy: locations are purely per-company (correct Settings/Progress/Dev Guide)
Multi-Tenancy: add Developer Guide (make a module company-aware); assets in Progress + Settings
Teams can grant company access (additive) — staff-access + Teams docs
Documented team → company access: additive grants unioned into
getAccessibleTenantIds, team default = grants nothing, effective access shown
on System → Analysts. Updated Multi-Tenancy-Staff-Access (new team-grant
section + reframed access as analyst-and-team), System.md Teams (Manage
companies), Multi-Tenancy-Progress (done), Multi-Tenancy-Settings (teams stay
global but can carry client grants).
Analysts + Teams now live under System, not Tickets → Settings
Documented the move: new System → Analysts / System → Teams sections in
System.md, removed the Analysts bullet from the Tickets settings list (with a
"moved to System" note), and repointed the analyst-management references in
Single-Sign-On, Multi-Tenancy-Progress and Multi-Tenancy-Staff-Access.
Multi-tenancy progress: Change Management now company-scoped (Phase 3)
Document 2026-06-27 work: portal SSO, multi-tenant SSO, System tools, Trash
- Single-Sign-On: self-service portal SSO (portal-aware callback, user_sso_identities,
auto-claim), multi-company company-owned providers + email-domain routing, providers
Company column.
- Self-Service-Portal: SSO sign-in for requesters.
- System: Help, Topology, Orphaned tickets, Debug Tools restructure + D003/D004.
- Tickets: manual-ticket send-from mailbox, Trash with restore (+ drag/right-click/empty).
- API-Reference: new endpoints.
- Multi-Tenancy-Progress: per-company SSO done; admin visibility tools.
Wiki end-of-session refresh: index status, progress (isolation/settings/analyst access done + deferred cross-module reads)
Add Multi-Tenancy-Isolation page: isolation model + the three-sweep hardening audit
Multi-tenancy settings: per-company add/hide (types+origins) + rationale for global-only settings
Multi-tenancy wiki: per-sender-address routing, freemail list, routing diagnostics (#563-567)
Multi-tenancy wiki: mark Phase 1 tickets + Phase 2 email routing as built
Progress tracker: count badges done; Phase 2 (pinned/shared mailboxes, domain
routing, triage queue, freemail handling) now complete bar outbound reply
identity. Email-routing + landing pages updated from 'planned' to 'built on the
multi-tenancy branch'. Parked ideas (routing visualiser, customisable freemail
list) noted.
Add Multi-tenancy progress tracker page