# Follow-ups for the Owner and for a customer

The Owner and a customer reach the same follow-up code through their own thin router, and the rows behave identically — same six channels, same gates, same duplicate and lateness rules. What differs is the vocabulary on the screen and the allowance behind the gates. Website enquiries are the one queue that belongs to JBRH rather than to any workspace.

- **Status:** Available
- **Audience:** both
- **In the app:** #/follow-ups
- **Last verified:** 2026-09-10
- **Canonical:** https://connectbyjbrh.com/docs/follow-ups/followups-owner-tenant/

## What is identical

- **The record.** Person, when, channel, reason. There is no extra field on one side and no missing one on the other.
- **The drain.** `runner.chase_phone` takes two rows per tick through the same call path, whichever workspace the row is in.
- **The gates.** Autonomy, suppression, line readiness and lateness apply the same way. An Owner row is not privileged.
- **The rules.** Same person plus same *when* is a duplicate on both sides; twenty-four hours late closes a phone row as `missed:` on both sides.
- **The `task` channel.** Nothing drains it for anybody.

This is the same pattern the relationship console uses: one body, two thin routers. New behaviour lives in the shared module and each side adds only the route, which is why a follow-up capability cannot quietly exist for one audience and not the other.

## What differs

|  | Owner | Customer |
|---|---|---|
| Workspace | JBRH's own workspace | The customer's own workspace |
| Plan and allowance | No plan, no allowances | The plan decides the allowance, and an exhausted one refuses an attempt |
| Vocabulary | `relationships` | `people` — the same records, renamed on the way out |
| Route | The operator API | `/api/customer/ui/…`, after the path is rewritten |
| Visibility | JBRH's own rows only | That workspace's rows only |

The allowance line is the one that produces a real behavioural difference. A customer workspace can have a follow-up attempt refused because the plan's allowance is spent; the Owner workspace has no plan, so that particular refusal cannot occur there. A capability that behaves differently for that reason is behaving correctly — it is metering, not a feature gap.

## The queue that belongs to neither

Website enquiries are not a workspace's follow-ups. An enquiry submitted on the public site belongs to **JBRH**, and it lives in a control-plane table that sits deliberately outside every workspace. It is handled by the operator, and it is not visible in a customer workspace at all.

> **Careful** A customer asking "why is this enquiry not in my workspace" is seeing isolation working, not a fault. The answer is that the enquiry was made to JBRH rather than to them; anything that ought to reach their workspace reaches it through a channel they own — their mailbox, their number, their WhatsApp handle.

The same principle explains why an Owner session cannot casually work a customer's follow-up queue. Rows belong to exactly one workspace, and the boundary is enforced beneath the application by row-level security rather than by the screen choosing what to show.

## Checking both doors

1. When a follow-up behaviour looks wrong on one audience, check the other before assuming the feature is broken.
   - Result: An asymmetry is nearly always the routing or the allowance, not the follow-up code — which is one module for both.
2. Read the refusal's reason rather than the audience.
   - Result: `refused: <reason>` names a gate. An allowance refusal on a customer workspace and a suppression refusal anywhere are different problems with different fixes.
3. When reporting a difference, say what each audience sees.
   - Result: "The Owner shows the row and the customer does not" is actionable; "follow-ups are broken" is not.

## Questions

### Can the operator create a follow-up in a customer's workspace?

Rows belong to one workspace and the isolation boundary is enforced below the application, so this is not a matter of a screen hiding a button. Work that needs doing in a customer workspace is done by that workspace.

### Why does my workspace refuse an attempt that the operator's does not?

Most likely the allowance. A customer workspace's plan decides what it may spend, and an exhausted allowance refuses the attempt with that reason; the operator workspace has no plan and therefore no such refusal.

### Do the two audiences share a follow-up queue for a shared customer?

No. There is no shared queue. If a person exists as a relationship in two workspaces, those are two records with two sets of commitments, which is isolation working as intended.

## Related

- [Follow-ups in Connect](https://connectbyjbrh.com/docs/follow-ups/)
- [Executing a follow-up](https://connectbyjbrh.com/docs/follow-ups/execution/)
- [Website enquiries](https://connectbyjbrh.com/docs/support/website-enquiries/)
- [Relationships for the Owner and for a customer](https://connectbyjbrh.com/docs/relationships/relationship-owner-tenant/)
- [Workspace isolation](https://connectbyjbrh.com/docs/security/workspace-isolation/)
- [Approval on a follow-up](https://connectbyjbrh.com/docs/follow-ups/approval/)

## What this page is based on

- `docs-source/sources/CHANNELS.md` §7 — enquiries as a control-plane table
- `docs-source/sources/CHANNELS.md` §5 — one body, two thin routers
- `docs-source/sources/GENERAL.md` §7 — the shared drain
- Connect capability registry (docs-source/facts.py)
