HomeZero · Design spec

Tend the board

The kanban built the surface. This builds the gardener — the advisor cell that places zeroed homes, writes the take when a Brief lands, digests every tap, re-ranks, and asks the next question.

Date 2026-06-18 Powers the board-kanban MVP Status design · pending plan

The one rule

The wake is gated. The judgment is not.

The advisor runs at most once every ~30 minutes — cost is bounded by how often it wakes, never by throttling its thinking. Within a wake, every call is the agent's own reasoning: which column a home belongs in, what the take says, what to re-rank, which question to ask. The single thing that happens with no agent in the loop is the instant inbox receipt the moment a home is zeroed.

01

The relay

A zeroed home travels three hops to become a tended card. The first two already exist — the star path and the market cell's per-home Brief. This spec adds the inbox card in hop 1 and all of hop 3.

1
Zero → Inbox agentless · instant
The buyer zeros a home and a stage:inbox card appears at once — titled from the Zillow capture, reading “Analyzing…”. No agent fires. Zero ten homes, the advisor never wakes.
2
Market cell → Brief existing pipeline
The zero rings the market cell awake (zero-created doorbell); it drains its queue and writes a covered listing + verdict. The Brief is its deep read of the county data — parcels, deeds, permits, water rights, distress — not Zillow. Zillow is only the capture that triggers it.
3
Advisor → tend heartbeat · agentic
Every ~30 min (or on a staff trigger) the advisor places the home, writes the take, sorts the board, and asks what it needs to know.

Live by default

Every hop is a real Convex write to boardCards, and the board subscribes with a reactive query — so a buyer sitting on /board watches it happen: the card appears in Inbox the instant they zero, the take writes itself in and the card slides to Worth-seeing when the advisor tends, re-ranks and the new question land — no refresh. The design rule that buys this: nothing lives only on the cell; state is always a write Convex can push.

02

The inbox receipt agentless

The buyer should see a zeroed home immediately — not up to 30 minutes later, when the advisor next wakes. So the zero path (hop 1) writes the inbox card directly, with no agent involved.

Where: starHome in convex/stars.ts already creates the saved row. Extend it to also upsert a type:"home" card at stage:"inbox" — title, price and thumbnail pulled from the capture (or the listing, for an already-covered save), body empty until there's a take. A plain write inside an existing mutation: no scheduler, no doorbell.

Home cards are keyed by zpid

The inbox card is born before a listing exists, so it can't key on a slug. Every home card keys on home:zpid:<zpid> instead — stable from the moment of zero through coverage. When the advisor later authors the same home, it reuses that key, so the “Analyzing…” card is patched in place into a placed, commented card. One card, never two. The backfill adopts the same key (covered listings always carry a zpid).

03

The tend pass agentic · hop 3

One heartbeat is one pass. The agent reads what changed since its cursor and works the batch in order. Every step is judgment expressed through the Convex surface — there is no scoring formula in code.

  1. Place + comment the ready inbox cards
    For each inbox home whose Brief has landed: write the take, and judge it into worth-seeing or passed — weighing the market verdict and the buyer's taste. It can forgive a “caution” verdict that nonetheless nails a stated yearning. No Brief yet → left in inbox for a later pass.
  2. Digest the new signals
    Read the taps since the cursor — concerns, this-or-that picks, pass reasons, manual drags, thumbs-up/down, and visit reads (how long the buyer lingered on a Brief). Update the agent's model of the buyer, then re-rank or move cards: surface a cheaper cousin of a shortlisted home, demote a category the buyer keeps passing. A drag the buyer already made is a signal to learn from, not undo.
  3. Ask the one question
    Author a single question card with a widget — or stay silent if nothing clears the bar. Never more than one open ask at a time.
  4. Refresh the voice
    Re-author the morning note and the one-line “this week” agenda so the board's header reflects the pass.

Idempotent, ≤1 in flight. The pass only touches what changed since the cursor, so a re-run with no new signals and no newly-landed Briefs is a no-op. The heartbeat is serial; a manual trigger fired mid-pass just folds into the running one — no second pass.

The board it places onto

inbox → worth-seeing → scheduled → seen → shortlist passed

This engine authors only the entry — inbox → worth-seeing / passed. The faded columns (scheduled, seen, shortlist) are buyer- and staff-driven states the kanban already tracks; the tend pass doesn't move cards there.

04

State — the cursor

A lastTendedAt field on the buyers table — one advisor serves one buyer, so one cursor each. A pass reads since = lastTendedAt and stamps its start time. On completion it sets lastTendedAt to that start time — not the end — so any signal that arrived mid-pass is re-read next time instead of being skipped. Stored in Convex so it survives a cell restart or rebuild.

05

The Convex surface

One new read, one cursor write, and the receipt. Everything else reuses what the kanban MVP already shipped.

New

  • tendDigest — internal readthe board + signals since the cursor + the inbox homes now ready to place
  • markTended — internal writestamps lastTendedAt at pass end
  • inbox receipt in starHomeextends an existing mutation

Reused

  • addCardplace a home, refresh the note, author the ask
  • setStageInternalthe agent's own sort (no buyer signal)
  • highlightCardelevate the one to look at first
  • dismissCardretire a stale card — never one the buyer pinned

The agent writes with the advisor cell's Convex deploy key, as agent actions following the playbook — no sync script on the Mac.

06

Where it lives

The tend logic is prose the pi agent follows, not a script — the same shape as the market cell's daily loop. It ships in the advisor cell seed, delivered through cellTemplateFiles:

Picking the one ask

The agent picks from its own uncertainty — the widest gap between what it knows and what it needs to serve this buyer (a yearning it can't yet weigh, a budget ceiling it's guessing at, a trade-off the signals left ambiguous). Bounded by two rules: at most one open question, and silence beats a low-value tap.

The buyer model

The buyer model is the advisor's on-cell memory (BUYER.md / yearnings) — the store it reasons from, updated each pass. The Convex buyers.profile stays the public-safe mirror for the app to read; this engine doesn't change that contract.

07

Testing

08

Rollout

  1. App / Convex first. The receipt, tendDigest, markTended, the cursor, the zpid rekey, and tests. Ships on its own — zeros land in the inbox column live, before the cell adopts the playbook.
  2. One-time cleanup. After the rekey, dismiss any already-backfilled home:<slug> cards (pre-launch, ~one live buyer) so they don't double with the new zpid cards.
  3. Cell side. Add the HEARTBEAT.md entry + TEND playbook to the advisor template, bump the version, refresh the live advisor. Validate with a staff-triggered dry-run before relying on the cadence.

Out of scope (later)

The buyer-facing refresh button; a per-Brief doorbell (commentary waits for the heartbeat by design); tour booking and outbound to listing agents; multi-buyer advisors; any scoring formula in code.