How we prove a change before a customer sees it, for the two customer shapes: centralized leasing over distributed properties (one office runs many scattered buildings, like Western Slope) and a single community with its own onsite team (like Camellia). For engineers and the agent fleet.
2026-10-09 · standing playbook · applies to every lane · written from the renewals work at Camellia (single community, live) and Western Slope (centralized leasing, going live)
Willows testing is OFF (Gera 2026-11-02). Clara stays configured; reopen only on Gera's word. Rung 5 (the Willows live run) and every robot call, robot text, harness or E2E at the Willows (appfolio-45) is closed: the robot-call chokepoint and the robot text sender refuse it unless WILLOWS_TESTING_ALLOWED=1 is set, and only Gera sets that. Use the Fairhaven test company.
1. The ladder 2. Fix vs new feature 3. The two team shapes 4. Test companies 5. Pass bar and report 6. Rules 7. What "tested" means 8. Live test at the Willows
Every change climbs the same ladder; what differs is how far it must go. A fix stops at rung 5 and ships with no switch. A new feature climbs to rung 7, in the sandbox company shaped like the customer who gets it, and only Fede turns it on.
| Rung | What it is | Pass | Where it lives today |
|---|---|---|---|
| 1 | Unit tests for the exact path changed, plus one planted defect that must go red | Green, and the planted defect fails | Vitest, review:self |
| 2 (new) | Adversarial fleet on the bench: simulated staff, prospects and tenants attack the changed lane with production's breaking data shape, outbound suppressed | Every failure two independent skeptics confirm is fixed or catalogued with a severity; incident fixtures red then green | Staff-desk fleet exists; prospect and tenant fleets to build (section 7) |
| 3 | Every live customer's real book run through the engine before and after, no writes | Decisions, terms and text identical; strict-inputs diff green | Renewal replay harness, diff script |
| 4 | Live workflow histories replayed on the new code | Every history replays clean | Temporal history replay |
| 5 | A seeded run on Willows: real engine, real texts to our registered phones only | Scorecard green: no unsafe send, no PMS write, expected holds | Willows seed, dry run, live run |
| 6 | Anonymized copy of the target customer's whole portfolio in the test company of its shape, PMS in sandbox mode | Same scorecard, across every building and setting level | To be standardized (section 4) |
| 7 | Supervised at the customer: every message held for a person | One clean week, before/after on the page | Gera's Supervised mode, review page |
The Willows bench is shared. Two other rigs wipe every open work order on the Willows (appfolio-45) nightly: Agent Smith’s maintenance eval about 07:00–07:45 UTC and the CI “Clara Behavior Evals” run about 03:40–04:30 UTC; Gera’s fast-lane scripts also dial the same line. A live run there never crosses those windows, claims the bench on #engineering-bridge before each cycle (a BRIDGE CLAIM with the window), and grades a work order that vanished between a read and a re-read as interference, never as a product defect.
Dark: line; the dark-features register tracks it.Why the split: three improvements to live behavior once shipped behind settings that nobody pressed, and a sync guard sat off at three customers. A fix that waits for a switch is a fix nobody gets.
Centralized leasing, distributed properties (Western Slope): one office runs ~90 scattered buildings. Company-level policy with building overrides, one approval desk, one contact, the team sends paperwork where no template exists. Test company: Fairhaven.
Single community, onsite team (Camellia, JP&Co): one property with its own staff. Property-level policy, its own contacts and channel, Clara sends the paperwork in AppFolio, fully autonomous. Test company: Willows.
| Must be exercised | Centralized leasing (Fairhaven) | Single community (Willows) |
|---|---|---|
| Settings inheritance: company value, building override, default | All three levels, including a building that overrides the company | Property level, plus a property with nothing set |
| Who sends the paperwork | Team path: no PMS offer, no letter, team copy, term change goes to a person | Clara path: PMS offer created, letter attached, portal signing |
| Where approvals and alerts land | One desk: the review page and one contact for the whole company | Per-property channel and contact; the wrong property's channel is a failure |
| Volume | Dozens of holds in one run; the board and the queue must stay readable | A handful per property |
| Transfers and escalations | To the central team's line and inbox | To the onsite manager |
| Eligibility data | Account balance from the daily rent-roll pull, no live PMS reads | Same, plus the PMS open-offer check before starting |
| Rung 3 book | Their anonymized copy, replayed read-only | Their live book, replayed read-only, byte-identical |
Fede, 10/9: standardize and clean up, do not add more. Read-only inventory of production, 10/9 02:40Z: 6 test companies, 234 buildings between them. None is usable as the portfolio practice today.
| Test company | What it is | State | Proposal |
|---|---|---|---|
| Western Slope Mirror (TEST) | 70 buildings, 185 leases, ~15.5k conversations | Deleted 10/9 | gone (193,355 rows, 0 left; harness re-pointed at Fairhaven first, #18109) |
| Willows (in the sandbox company) | Our one-building engine bench, JP&Co's AppFolio with writes allowed | Supervised, team sends; the rung-5 bench | keep: the single-community shape and the engine bench; in sandbox PMS mode since 10/9 |
| Fairhaven Residential (TEST) | 11 buildings, the voice bench | Cleaned 10/9 03:30Z: 4,737 copied JP&Co rows removed, 0 left; 11 buildings, voice intact; its three jpco-bound buildings moved to sandbox PMS mode | clean (E11, Fede: clean), then the practice company for centralized leasing over distributed properties, loaded from Western Slope's anonymized book |
| Second Mirror (TEST) | 2 buildings, JP&Co replay pair | Deleted 10/9 | gone (23,972 rows, 0 left) |
| Test Client Co | 3 demo buildings from the "Test company" box | Deleted 10/9 | gone (150 rows, 4 test logins, 0 phone lines) |
| Module Gate Probe (TEST) | 1 building, a probe | Deleted 10/9 | gone (1,850 rows, mostly sync logs) |
Why no company is ready: the daily renewal check scans the whole platform, so turning a building on also scans every old lease already on it; the recipient guard lets staff email through and fails open; held messages fall back to #alerts when a company has no channel; and nothing copies settings between companies or cleans a multi-building seed. Those four gaps are the loader.
The standard (Fede, 10/9: "fairhaven and willows thats it"): Fairhaven for centralized leasing over distributed properties, Willows for a single community. Two test companies, never a third. Fairhaven can carry Western Slope's and Situs's anonymized books side by side, each under its own prefix, when a run needs more realism. Each is in sandbox PMS mode, Supervised, with a test Slack channel, contacts pointed only at registered team phones and inboxes, and is rebuilt by one command from an anonymized copy of a customer's book with a building map. "Clean up" becomes "delete and rebuild", which is also the proof that the loader works.
Overnight: the loader (prepare, seed, cleanup, dry run) merges as scripts; its first real target is Fairhaven once E11 finishes.
| Check | Fix | New feature |
|---|---|---|
| Planted defect goes red | required | required |
| Fleet attack (rung 2) | required | required |
| Every live customer byte-identical (rung 3 + 4) | required | required |
| Willows scorecard green (rung 5) | required when the path touches sends, PMS writes or workflows | required |
| Sandbox company in the customer's shape (rung 6) | no | required before turn-on |
| Supervised week (rung 7) | no | required at the first customer |
| Before → after on the page, with the proof artifact | required | required |
The report is always before → after: what the tenant or the team experienced, what they experience now, and the thing that proves it (a delivered text, a scorecard, a diff). "Much better, and here is how you can tell."
Per-release model and refactor decisions (new model out, big layer rebuilt) use a separate procedure with its own frozen set, budget and verdict: Clara Bench (proposed 2026-10-23). The ladder on this page stays the per-change proof; Clara Bench is the per-release decision. Its standing rule for every run: agree the bar and the budget before the run starts.
Proposed — pending Fede's review (2026-10-17)
A change to what a customer sees is "tested" only when four proofs hold: incident fixtures, a fleet attack on the bench, the real-book replay, and the live run. Unit tests and type checks are the floor. They are reported as "unit-covered", never as "tested".
Why now. The staff leasing desk (the text line a leasing agent uses to tell Clara about no-shows, notes and tours) failed a trivial ask at a customer after 59 commits in three weeks, unit tests on every one, and a 22% replay on Sept 30 that nobody acted on. One bench run of simulated agents then failed 21 of 45 scenarios on main in two hours, including the customer's exact case.
| Proof | Passes when | Evidence |
|---|---|---|
| floor Unit tests, types | Green. Necessary, never sufficient: "unit-covered" | Test output |
| A. Incident fixtures | Every past incident in the area replays as a fixture: red at its pre-fix commit, green now | Red and green runs |
| B. Fleet attack | Simulated staff, prospects and tenants (persona plus seeded production data shape) attacked it on the bench. Two independent skeptics confirmed each failure; each is fixed or catalogued with a severity | Results file, catalogue |
| C. Real book | Every live customer's book, read-only. Fix: byte-identical. Redesign: at or above baseline on every grader | Diff, scorecard |
| D. Live run | On bench numbers. Fix: stops at Willows, no switch. New feature: sandbox company, then a supervised week | Record ids |
The replay said 22% pass. No owner, no row, no work.
Below the bar is work the same day: an owner lane and a row on the initiative's page.
Not a kill switch (fixes still ship with no switch), not a human approval queue, not a reason to hold a PR (a missing proof is work for the lane). It is how we prove a change before merge and find the next incident before a customer does.
added 2026-10-22, from the first document-engine run (renewal packet parked in 7 s, then cancelled) · Fede: "the Willows should never ask for permission to change things"
The Willows (test property 45 in JP&Co's AppFolio, PropFlow property appfolio-45, company org_sandbox) is the only place a session may change things. Writes scoped to it are pre-approved; a write that touches a shared JP&Co object (a template or setting other properties use) still asks. Western Slope, Situs and Camellia are read-only, always.
| Need | Use | Never |
|---|---|---|
| Look at the Willows in AppFolio | The deployed robot: screenshot route, print-order read, vendor reads. Look at the PNG before trusting "captured". | A fresh browser, the saved Browserbase profile, the heartbeat route, any login |
| Write in the Willows' AppFolio | The robot's write verbs (park, cancel, send-parked) with an expect clause; the robot answers done / blocked / refused and never writes on a mismatch | A hand script against AppFolio |
| Read PropFlow rows | The data facade from a worktree with DATA_BACKEND=dynamodb DYNAMODB_TABLE_NAME=propflow-prod AWS_REGION=us-east-1 | Local JSON |
| Start or reset a flow at the Willows (a renewal, a new-lease packet) | No login. Go straight to production the way every Willows write already does: a tsx script with DATA_BACKEND=dynamodb DYNAMODB_TABLE_NAME=propflow-prod that calls the same domain function the route calls after its auth check, or temporal workflow start with the input the route would build (Temporal address and API key from the Keychain). Scope every write to org_sandbox / the Willows lease or application; one ledger line per write. Fede, 2026-10-23: "we have full admin access for the Willows, we do it every day." | Any staff login: the regular smoke login is view-only by ruling (2026-10-16) and answers 403 on writes; the MFA e2e test account stays waitlisted; the nightly smoke login stays in GitHub secrets. A customer's staff user. Enrolling a factor on anything. |
| Point the flow at the Willows only | The building-level setting on appfolio-45 (it wins over the company row). Set it in the same shell command that starts the flow, and set it back right after the start answers; the running flow keeps the value it was started with. | Leaving a Willows rung on: the daily scanner would act on every other Willows lease |
read); the dry run of every write prints exactly what it would change.expect on the ids it created → stop the workflow → reset the one tenant's PropFlow state (always with the tenant id; the bare route resets every open saga) → release the claim rows the start created → take the test recipe or setting out of use → confirm the rung is back. The lease keeps its outcome record by design.Closed 2026-10-23: no prod staff login is needed for Willows runs. The first two runs on Oct 22 improvised one (the MFA e2e account, un-waitlisted per run); that was the mistake. Start and reset flows directly, as above.