0143 — Turnover and new-lease automation follow the gatekeeper; Supervised holds their property-software writes
- Status: Accepted
- Date: 2026-10-15
- Deciders: Gera (ruling, 2026-10-15); Trinity (sign-off on the rule, #engineering-bridge thread 1792085968.591899)
- Related: ADR-0139 (one switch per module; Supervised is its middle mode), ADR-0141 (held messages, per-module reviewers), ADR-0034 and ADR-0044 (turnover)
Context
Turnover automation and the new-lease pipeline were each turned on by their own switches, and the company's gatekeeper module status was not asked:
- turnover: a platform-wide arm (
turnoverSendingon the arm row) AND a per-building flag (Property.autonomousTurnoverEnabled); - new lease: a platform-wide arm (
newLeasePipelineSending) AND three per-building flags ("prepare next steps", "draft the lease", "send for signature").
So the one switch staff and customers look at (ADR-0139) did not say whether these ran. Gera, 2026-10-15: stop relying on the old switches; the gatekeeper status governs.
Decision
1. One gate per feature, the module status. Turnover follows the building's Maintenance
status; the new-lease pipeline follows the building's Leasing (leasing.prospects) status, the
module the staff registry already files every new-lease switch under. The status is the existing
per-building answer (resolveModuleStateForOrg: the building's own row, else its company's, under
the company plan ceiling). For turnover the one reader is src/lib/temporal/turnover-gate.ts
(turnoverModeAt).
2. What each status means for these features.
| Status | Behavior |
|---|---|
| Off | None of it runs. |
| Supervised | It runs. Every outbound message to a resident, prospect or vendor is held by the existing Supervised doors (ADR-0139 §9). Every write it would make to the property software (tenant charges, work-order create/sync, the move-out draft, unit availability, the lease send) is held for a person to approve through the held-write flow (HeldPmsWrite, shown on /review beside the held messages, with exactly what would be written). A write that flow cannot carry yet is skipped, never made, and named in the PR that gates it. Notes to the customer's own staff go, as everywhere (hot rule 10). |
| Live | It runs and acts. |
A held write is a person's decision. If the building later moves to Live, the Live path does not write the same change itself, and it does not close the hold: a waiting hold still waits for a person, an approved one is written once, and a rejected one stays unwritten.
An unreadable status is unresolved: a Temporal activity throws so it retries; a hook that is not
retried reads it as off.
3. This extends Supervised for these features only. The rule elsewhere stays "Supervised holds outbound messages only; property-software writes go". Turnover and new-lease writes are the exception because they change a tenant's ledger, a work order of record or a lease, which a manager must see before it happens (Gera: "on supervised, we should see like pms writes to change charges").
4. The lease send. Approving a new-lease item always drafts the lease. It is SENT for signature
only when Leasing is Live AND the company setting "Send leases for signature" is on (off by default;
Fede turns it on per company, like turnover.auto_release). Otherwise the send is held in the plain
sense: not sent, and staff send it from the property software. There is no second approval item.
5. The old switches are retired. The per-building flags, the platform arm fields, their staff rows and their registry entries are removed once both features read the module status. Their stored values are left in place (orphaned rows are fine); nothing reads them.
Consequences
- Turning a module to Supervised now starts turnover (Maintenance) or new-lease (Leasing) automation at that building, with every property-software write held. The 2026-10-15 census (in the PR bodies) lists which buildings start, and at merge no customer-facing send turns on: the new-lease send stays held everywhere until the company setting is turned on.
- A held write is performed later by a durable Temporal workflow (
heldPmsWriteWorkflow) from the exact params stored on the hold; nothing is recomputed at decision time. - The Willows (Sandbox) keeps acting only because Sandbox's Maintenance is set Live (a staff write before the turnover part merges); a Supervised test building now holds its turnover writes, which changes what a live Willows run can show.
Alternatives considered
- Keep the per-building switches beside the module status. Two answers to "is this on here?" is the problem ADR-0139 removed for every other feature.
- Supervised holds messages only, writes go (the general rule). Rejected for these two features: a turnover charge or a sent lease is the thing a manager supervising them most needs to see first.
- A per-company new-lease level (supervised / live / follow-module). Replaced by one company setting for the send (decision 4): fewer states, and drafting is safe at every status that runs.