# One product, two audiences

The company that built Connect uses it to run its own business, from the same code a customer gets. There is no operator-only feature and no customer-only feature. What differs is commercial: a customer's use is bounded by their plan's allowances, and the operator has no plan and no allowances. Two platform administration screens are the only deliberate exception.

- **Status:** Available
- **Audience:** both
- **Last verified:** 2026-09-10
- **Canonical:** https://connectbyjbrh.com/docs/product/owner-and-customer/

## One feature set

Every capability Connect has is reachable by the operator's workspace and by a customer's. If a screen, a button or an endpoint exists for one audience it exists for the other, over the same implementation — the relationship console, the mailbox console, the channel console and the workspace console are each one body with two thin routers on top.

That shape is a rule learned the hard way rather than a preference. A reduced copy built for one audience has drifted every single time it has been built here: the Phone screen once carried a customer view with no Behaviour or Voice settings, which nobody noticed until somebody looked at the other audience's screen in a browser.

## Two doors onto one body

|  | The operator's workspace | A customer's workspace |
|---|---|---|
| Session | Ordinary operator session | Customer session, marked as such |
| Workspace | The operator's own | One workspace per customer |
| Path a browser calls | The operator paths | The customer facade paths |
| How it gets there | Directly | `tenantAdapt` rewrites the path before the request leaves the browser |
| What is refused | Nothing, beyond ordinary authorisation | Anything the allowlist does not name, which answers 403 |
| Where the work happens | A shared module | The same shared module |

Two independent mechanisms therefore decide what a customer session may reach: the rewrite in the browser, and an allowlist in the server middleware that refuses any path a customer session is not permitted. A feature that works for one audience and 403s for the other is almost always one of those two rather than the feature itself.

## The only difference is commercial

A customer's use is gated by their plan: allowances, daily limits, what the subscription includes. The operator has no plan and no gates. The operator is also who activates and changes a customer's plan, which is why the correct question when anything is added here is never "is this an operator feature?" but "what does a customer's plan allow of it?".

Everything that follows from the plan — the daily email allowance, the budget that stops paid model work, the number of qualified prospects a month includes — is metering, not capability. The code path is identical either way; the allowance is what runs out.

## The two things that are correctly operator-only

- **Verifying customer payments.** Matching an incoming payment notification against an expected reference is JBRH administering its own business, not somebody using Connect.
- **JBRH's own pricing, and enquiries sent to JBRH through the public website.** Website enquiries sit outside every workspace by design, because they belong to the platform rather than to any customer.

Both are administration of the platform. Neither is a capability withheld from customers, and neither has a customer-facing equivalent that has been left unbuilt.

## How the rule is kept honest

Parity is enumerated rather than asserted. A test suite reads the flattened route table out of the running application and compares every operator capability against every customer one. Two tables carry the judgement: an alias table, because the customer surface renames some things — a customer's people are the operator's relationships, its knowledge sources are the knowledge bank — and a known-gaps table, which lists the capabilities a customer cannot yet reach, each with its reason. AGENTS.md records 39 of them. That list may shrink and must never grow: a new entry means somebody built a feature for one audience.

The second check is a person looking. Every change to a screen or a route is verified in a browser as the operator and as a customer before it is committed, because the three defects reported on 4 September 2026 — a toast stack covering the Assistant launcher, a remembered panel size hiding it, and that reduced Phone view — were all invisible in the source and obvious in thirty seconds of looking.

## Questions

### Does JBRH really use this to run its own business?

Yes, on the same code and the same deployment. That is why the parity rule matters commercially as well as technically: a capability the operator relies on daily is one a customer has too.

### Can the operator read a customer's data?

Not through the product. Isolation is enforced three times — the allowlist, the object layer's workspace filter, and row-level security in the database — and none of those layers has an operator exception.

### Is there an enterprise edition with more features?

No. There is one product. Plans differ in allowance rather than in what the software can do.

## Related

- [Connect by JBRH](https://connectbyjbrh.com/docs/product/)
- [The operator's workspace and a customer's](https://connectbyjbrh.com/docs/account/owner-vs-tenant/)
- [Workspace isolation](https://connectbyjbrh.com/docs/security/workspace-isolation/)
- [One implementation, two audiences](https://connectbyjbrh.com/research/two-audiences-one-implementation/)
- [Capability status](https://connectbyjbrh.com/docs/product/status/)
- [Privacy inside the product](https://connectbyjbrh.com/docs/product/privacy-in-the-product/)

## What this page is based on

- AGENTS.md §8 — the Owner and a tenant get the same product
- AGENTS.md §1 and §3 — the two routing paths and the isolation layers
- `tools/test_audience_parity_v1.py` — ALIASES and KNOWN_GAPS
- CLAUDE.md — the two-audiences gate
