Follow-through

Building, simplified · Fede's go Nov 3 night; core cut on Nov 4; Gera confirms the hook hunk Nov 4

Rewritten from scratch on Nov 3, 2026 (night), at the same address · build started the same night

What this is. How Clara keeps track of every open item in a conversation, so no ball drops and nobody gets nagged. Where it stands. The design won a tournament on 104 real moments and held up on 7,541 more. Fede decided on Nov 3: open items get their own list; the engine starts in Supervised, so every message it proposes is a held card; the digest is Gera's, read-only. Cut on Nov 4: an 8-field item with one due time, no dial, Off and Supervised only, 3 PRs. Gera confirms on Nov 4 the hook at the end of his Topic engine.

The whole picture

SIGNALS TRIGGER MIDDLE LAYER OUT, BY MODE Renter writes or calls Staff replies Clara's note to the team Meeting decisions (next) Time passes, nothing new Topic, Gera's enginelabels each saved message wake 1 Follow-through readreply, acknowledge, or quietopens, keeps, closes items Item list, its own recordheld by Clara or a staff rolecheck back, if not, expires wake 2: a timer per open item Preview: list to our side Supervised, day oneeach proposal is a held card Live, later: Clara sends Gera's digestreads the list, read-only
Two wakes, one list. A saved message reaches the read through Topic. When nothing new arrives, an open item's own timer wakes it. Items are held by Clara or a staff role, never by the renter.

Simplified, Nov 4

Fede's Nov 4 pass: the core built right and simple; complexity later.

The core in one picture

An item is something our side owes this person, or a question of ours they left unanswered that nothing on main will chase.

TRIGGER ENGINE OUT Topic finishes a runon a conversation, every runat Off, nothing starts Follow-through workflowone per conversation New messages: one readopens or closes items; never speaks An item is due: one readClara says one thing, or the item closes Item rows, keyed by company8 fields, one due time Gera's digest reads them say Main's held Clara replySupervised: a card to approve Three outcomes: say something, stay quiet, close the item. The engine never books, moves, writes or hands off.
The core, cut. One hook, one workflow per conversation, one read per run, one due time per item.
Moving parts, before and after

Every part on this page, before and after the cut.

PartBefore, on this pageAfter the cutWhy
Core
Hook (wake 1)End of Topic's workflow, only when a label was writtenEnd of Topic's workflow, every finished run; at Off it starts nothingReaches the test property with no change to Topic's skip; Off costs nothing
Second wakeA timer per item with 2 times (check back, expires)Each item's one look, at its due time1 time per item
New-message readScores reply, acknowledge and stand-down; opens itemsOpens and closes items; never speaksThe first reply already belongs to Clara's reply path
Due readActs once at check-back; closes at expiryClara says one thing, or the item closesThe item always ends
The dial10 numbers (3 levels x 3 thresholds, plus a 0.9 override)0 numbers; 1 word in the promptEagerness pick, Nov 4
Item record14 fields (17 in the draft PR)8Table below
Handling and bucket3 handlings, 4 bucketsThe holder decides: Clara's item may speak once, a teammate's is only listed3 outcomes need no buckets
Nudge token1 per item, refilled by new evidenceNoneEnding at due makes 1 nudge structural
Weak-spot rules6 new prompt rules0 new in v14 concern the first reply, 1 belongs to main's after-tour timers, 1 is the application pick
Above the core
ModesOff, Preview, Supervised, Livev1: Off and SupervisedProof runs are local replays; Supervised was already Fede's call
Preview list to our sideA new listCutProof runs are local replays
Held cardHeld-draft path, a registered sender, Approve re-reads, an expired card re-arms its itemMain's held Clara reply, unchangedMain already refuses stale drafts and withdraws them when staff answer
Gera's digest feedThe Preview list doubles as the feed1 read-only query of open itemsGera builds the digest
Ratings (Approve as the rating, turn record, Rate row)On this roadmapDeferred to their own lanev1 does not need them
Exit from Supervised90% "Right call" over 100 rated momentsDeferred; Fede and Gera gut-check the cardsIt gates Live, which is deferred
Matters fold-inRoadmap PR 4Deferredv1 skips what a matter tracks
LiveRoadmap PR 5Deferred; expected to be the same setting set to LiveNo new code expected
Roadmap9 rows3 PRsRoadmap
The item: 8 fields

Every field earns its place; property, topic, subject ids and the two times are gone.

FieldWhy
idLets the timer find this item
company_idThe wall; every query starts here
conversation_idWakes the right workflow and person
holderWho owes it: Clara, or a teammate found by role at this company; never an outside person
owedOne plain sentence the due read checks for; a teammate's promise keeps its promised time in the words
due_atOne time: look once, then end
opened_atAnything newer than this is news
statusOpen, handled or expired; nothing else
Three outcomes

One prompt, one model call per run. Nothing else comes out of it.

OutcomeWhenEffect
Stay quietEvery new-message read; a due read where speaking would not helpItems open or close; nothing is sent
Say somethingA due read on Clara's item, nothing moved it, nobody on our side is on it1 message through main's held Clara reply; the item closes as handled
CloseSomeone did it, it went moot, or it is dueHandled or expired
Does the cut still pass What we learned

Each ruling and failure below, checked against the cut.

AskFromPassed by
One nudge per itemOct 3 rulingSpeaking ends the item; a second word needs a new message and a new item
"if a human starts it we dont intervene"Oct 15 rulingClara never speaks on a teammate's item; a teammate's reply closes Clara's item, and main withdraws her pending cards
No fixed clocksOct 26 rulingThe read picks each due time from what was said and the local time; no offsets in code
"Some decisions just expire."Nov 2 rulingDue time required; at due the item always ends; a past-due row reads as ended even if a timer failed
Check rolesNov 2 rulingThe store accepts only Clara or a staff role at this company; every speaker's roles go into the read
A renter never holds; a quiet prospect is Clara'sNov 2 rulingThe store refuses an outside person; an unanswered question of ours is a Clara item
An observer that goes back and checksNov 3 rulingEach item's due look re-reads with nothing new saved
"Approve them and I'll execute them."Nov 3 rulingSupervised: every message is a card to approve; teammates' items are a read-only list, never a nag
Promises were blind to staff workFailureThe read sees teammates' turns on every channel, with roles; a human on it closes it
"Told the team" was often untrueFailureThe engine never acknowledges; the prompt forbids the claim
Nobody checked callbacksFailureA promised callback is an item, held by whoever promised it
A timer never read the threadFailureEvery due look re-reads the person first
Nothing ever closed at CamelliaLessonItems close on what people did, or end at due; no click needed

What we learned

Fede's rulings from Oct 3 to Nov 3, and four failures, set every rule below.

His rulings, the failures, the Camellia lesson
DateFedeSets
Oct 3"It should be just once for now."One nudge per item
Oct 15"if a human starts it we dont intervene"Staff work stays with staff
Oct 26"we should not be using time. we need to reason about the ask and topic."No fixed clocks
Nov 2"Some decisions just expire."Every item can expire
Nov 2"we should always check roles."Holders found by role
Nov 2The holder rule: a renter never holds an itemA quiet prospect is Clara's re-engage
Nov 3"you need an observer that goes back and checks."A timer per open item
Nov 3"Approve them and I'll execute them."Decisions, not a digest of reminders
  • Promises were too strict: blind to staff work, they tried to close everything; Fede asked for them off Sep 28 to 29.
  • "Told the team" was often untrue: 8 of 18 such replies had nothing delivered (Oct 26).
  • Nobody checked for callbacks: 0 of 24 missed-call emails were answered (Oct 12).
  • A timer never read the thread: of 9 application sends in 30 days, 3 were wrong and 1 a duplicate (counted Nov 3).
BEFORE: THE AUGUST FRAMEWORK, AUG 13 TO 26 (RAN AT CAMELLIA, THEN TURNED OFF) EvidenceClara's own calls and threads Obligationher promises and asks only Judgmentinside policy act, else ask One lane to a humanchased until it closes At Camellia, hand-checked: of 73 promises that would have sent a text or page, 46 had nothing on record, 20 could not be checked. AFTER: EVERY ITEM, FROM ANY DOOR Evidencetexts, emails, calls, PMS status Itemheld by Clara or a staff role One readreply, acknowledge, or quiet Three endsClara does it, staff does, expires Closes on what people did. Expires when moot. A person sees an item once, if at all.
Before and after. Same spine; items now come from any door, are held by Clara or a staff role, and can expire.
The Camellia lesson. The August framework could not see the team's work, so nothing closed; the team answered 5 of 144 emails in 30 days. Fede, Nov 3: "nothing was ever closed because, well, they didn't close it."

Replay case: one renewal notice, sent three times (Nov 2)

Staff got the same renewal alert three times in 3.5 hours; the engine's rule sends it once

Fede sent this case on Nov 4 via Trinity: "this needs to be folded in. We sent it 3 times." One renewal (lease_10e24acd-e996-4e66-b7b5-e8f876cfd971, Camellia) failed once at 8:34 AM Mountain on Nov 2, then never changed. Staff still got three "Action needed" emails on one thread.

SendTime (Mountain)Path that sent itRenewal changed since last send?Record id
18:34 AMWorkflow escalationNo (first send)msg_be70904c-a287-4b1e-a81f-b83cbd3a400e
29:00 AM30-minute retry cron, permanent-error branchNomsg_6ade9dd5-c042-43f4-a7ba-3b477ce6bda8
312:00 PM30-minute retry cron, signer-email branchNo stored record changedmsg_1f776d3d-f618-4587-90cb-ac7b960e4b42

Root cause. Four notice paths all feed one sender, and each keeps its own "already told" marker named after the path and the reason. Only the 24-hour safety net reads the others' markers, and only the two cron ones, not the workflow's (src/lib/domain/renewals/retry-failed-prepare.ts:1036; the workflow's marker is src/lib/temporal/activities/renewal.ts:3398). A different reason gives a different marker, so the 12:00 send looked new. The 24-hour safety net, on Nov 3 at 9:00 AM, saw the earlier markers and stayed quiet.

What the engine's rule gives. The open renewal is one item. One notice at 8:34. Nothing at 9:00, because nothing changed. At 12:00, at most a one-line update on the same thread if the new diagnosis counts as news. Staff see it once.

Quick fix outside the engine, proposed: one shared staff-told marker per open renewal, checked by every path; ships as a bug fix with no switch. Pending Fede.

Replay: should the follow-through read decide when Clara chimes in? (Nov 4)

Question. At Situs, Clara offered tour times a minute before a staff member followed up on a thread they were already running (case on the coworker page, decisions N2 and N3). Could the follow-through read replace today's wake gate, the fixed sender list in the mirror's wake-on-reply code?

Answer: not as written. Over one week of live prospect texts at Situs (42 turns, 19 threads, Oct 28 to Nov 4, read-only), the read talked over a person 7 times; today's gate did it once. The read asks "has anyone on our side answered since this item opened", not "does a person own this thread". Six of its seven talk-overs were renters writing mid-conversation with staff, who answered 1 to 21 minutes later.

Gate, 1-hour windowRightTalked over a personLeft a renter waiting
Today (sender list)34 of 4215
Follow-through read, as a gate31 of 4274

The three named cases: Nov 4, both gates wrong (the office call that proves staff had it was filed 40 minutes after Clara woke); Oct 30, both quiet, correct; Nov 2, today's gate never ran, the read stayed quiet at the staff booking notice. The simulated 15-minute pick-up (N3) fired 13 times; the read's "waiting on nobody" call was right 2 of 4 times when it said pick up and 6 of 9 when it said someone has it. Mutation control: inverting the answers drops the read to 11 of 42; shuffling gives the base rate (24.4).

Round 2 (Nov 4 evening), with the office's hand actions visible. The coworker session rebuilt 55 Situs cards with every staff action from AppFolio merged onto the timeline (showings, notes, logged calls, status changes, 181 of 228 actions found). Three arms over the same turns (36 of the 42 had a fixture), 1-hour window:

ArmRightTalked over a personLeft a renter waiting
A. Today's gate (sender list)30 of 3613
B. The read, office rows visible28 of 3671
C. The read plus "does a person at the office own this thread right now?"32 of 3604
D. Same question, but only the records production holds today (no office rows)31 of 3623

Seeing the office's actions alone (B) did not fix it; the ownership question (C) did: zero talk-overs across three runs, the Nov 4 case quiet all three times, the two mid-conversation turns where staff answered 4 and 17 minutes later quiet too. Cost: one more renter left waiting than today. Controls hold (inverted truth 4 of 36, shuffled 25.8). Favorable-case caveat: office rows were made visible at the moment the action happened; in production they arrive later, so the real number sits between B and C until the showings read lands. Files: ~/agents/006/gate-replay/chime-in/ROUND2-REPORT.md.

Round 3 (Nov 4 night), what production can see today. Arm D asked the same ownership question without the office rows (96 office actions and 23 staff showings stripped). Result: 31 of 36, 2 talk-overs, 3 left waiting; on all 42 round 1 turns 33 right with 2 talk-overs against today's 34 and 1. So the question alone does not beat today's gate; the office's actions on the timeline are what removed the talk-overs. Ship order follows: the office-activity records (coworker session) land first, then the ownership read ships as a fix. Files: ~/agents/006/gate-replay/chime-in/ROUND3-REPORT.md.

What this changes. The read gets a second question before anything goes Live: "does a person at the office own this thread right now" (any staff touch, a showing a human created, an office call, counts as yes), and that answer gates both the wake and the due speak. Per the one-pager on the coworker page, the question lives in the one existing speak decider (shouldSpeak), which the read calls; it ships as a fix with no switch once the office-action records exist in production. In Supervised nothing sends unseen, so this is not a blocker for the Supervised week; it is a blocker for Live. Limits: the read was run as a due check with one made-up Clara item per turn; office calls land 40 to 70 minutes late and staff-made showings exist only as notice text; the ground truth is partly model-labeled; one week, one customer. Numbers and runner: ~/agents/006/gate-replay/chime-in/.

Architecture: built on Topic

Gera's Topic engine is the trigger; the follow-through read is a thin layer after it.

Topic, the hook, two wakes, the item

Topic today (checked on main, Nov 3)

WritesA label per saved message: 8 topics with subtopics. No status, no roles; staff replies look like Clara
RunsHaiku 4.5 on an AWS worker, 10 s after the thread goes quiet; re-labels only the outside person's last 4 messages
Fed byEvery writer since Oct 26. Unverified: whether mirrored staff texts get labels
SkipsTest properties. Debt: a phrase list names two vendors in core code

The hook (Smith's shape, accepted Nov 3)

  • When a message gets a label, the end of Topic's workflow signals a separate follow-through workflow, keyed on the last message id; mass-text bursts skip. Timers live there, with a patched() gate, a ledger row and a replay fixture.
  • Watch: Topic writes no labels at test properties, so as shaped the hook never fires at Fairhaven.
TRIGGER (GERA'S, EXISTS) · MIDDLE LAYER, TWO WAKES · OUTPUTS BY MODE Topic, on every saved messageAWS worker, Haiku 4.5, reads the thread10 s after it goes quiet.A label per message. No status, no roles.Wake 1: the end of each run.It records; it never sends. Follow-through read (the middle layer)In: the thread, who spoke (row author + roles),open items, matters, tours, work orders.Out: an item? held by Clara or a staff role?anyone replied since? check back when? expires when?Writes one small item row per obligation. Wake 2: one timer per open item, set by the read. A check-back acts once; at its expiry the item closes. Preview, dry: item rows + a listof proposals, to our side only Supervised, day one: held cardthe team approves; Approve re-reads first Live, later: Clara's own sendown path, default off, Fede's turn-on Fede: "you need an observer that goes back and checks." Gera: "I want to make sure it's always webhooked." Both hold: Topic's end sees every saved message; the timer sees what saves none.
Two wakes. A thread that saves nothing is re-read only because its item set a timer.

The item, its own list

FieldHolds
conversation_id, org_id, property_ref?The company is the wall; property is context
topic, subject{person_id, tour_ids, work_order_id, lease_id}Topic's label; our own ids, no PMS literals
holderclara or staff:<person>, found by role; never the renter
check_back_at, expect, if_notWhen to look, what should have happened, Clara's action if not
expires_atWhen it goes moot; the timer enforces it
handling, bucket, nudge token, stateClara does it, held card, digest line or nothing; one nudge; open until closed or expired

Indexed by company and holder, by check-back time: the query Gera's digest reads.

Why not a matter (decision 1). A matter needs a property, a person and an owner's email, has no company field, runs fixed 4, 24 and 72 hour clocks, and lets the renter hold the ball. Matters fold in second.

One company setting: the engine's own path, Off when absent (under Leasing it would inherit Live at Western Slope). Preview's list goes to our side, not main's Preview digest, which reaches client staff. Outputs by mode: see Rollout. Its PRs carry:

Dark: gate.path.follow_through | feature: Clara tracks every open item and records what she would do | proof: pending | turn-on: Fede

Never: an item held by a renter, prospect, vendor or caller; a PMS write in v1; a regex deciding anything; a fixed clock; a second nudge without new evidence.

Design: the read and the item

Superseded on Nov 4 by the cut above where they differ: no dial numbers, no handling buckets, one due time, no weak-spot rules in v1 (they move to the first-reply path and main's timers).

The tournament winner, the wager book, revised three times on real moments.

The read, the item, the revisions, the weak spots

The read: reply, acknowledge, or stay quiet

One read per wake, with the thread and the sender's roles. It scores reply, acknowledge and "a human will move it", and updates the items; the dial makes the call (this page: balanced).

DialReply atAcknowledge atStand down, a human on it, at
Quiet0.700.800.55
Balanced0.550.650.70
Eager0.400.500.85

Acknowledge only when the team was told. A reply score of 0.9 or more skips the stand-down. One nudge per item; only new evidence refills it.

The item, by example

FIRST CASE: A RESCHEDULE NOBODY ANSWERED (SITUS, NOV 2) Agent offers new timesthe prospect asked to move;nobody answers Wake 1 opens an itemheld by Clara: re-engagecheck back 10:00 next dayexpires: rebooked or declined Nobody replied: Clara does itone message with the agent's times; in Supervised, a held card A teammate replied: Clara stays quietthe item closes on that reply; nobody is reminded Only staff can do it: a staff-held itemone line in Gera's digest, once; never a nag She rebooks or declines: it expiresnothing is sent, nothing stays open Wake 2, next morning: has anyone replied since? One nudge per item. A second needs new evidence, never a clock.
Holder, check-back, expect, if not, expiry.

Three revisions

VersionChangeWhy
d1, Nov 2One read per signal; items as wagers with a holder, a moot moment, one nudgeWon among 8 entries on the 104
d1b, Nov 3Fede's Nov 2 rule: the other side never holds; a quiet prospect is Clara's next-morning re-engage; an application sent is nothing owedd1 failed the golden cases on holder
d1c, Nov 3Staff work stays with the staff role; Clara's check only when a window was told to the renter; callbacks trackedd1b pulled staff work onto Clara
Expiry, Nov 3, intendedexpires_at on every item, enforced by the timerThe POC

The expiry fix. On Topic's triggers, 40% and 54% of old enough items were still open after 7 days (gate 25%); none of 951 carried an expiry. Fede: "has anyone replied since the last time I checked? That's a critical one, because otherwise everything stays open."

Weak spots, with intended fixes (not yet replayed)

SpotFound (Tier 1 unless marked)Fix
Live meetingsSilent on 10 of 100 meeting turns where staff asked Clara directlyA direct question to Clara is hers
Late word39 of 54 wrong silences held the right item but said nothing until later; 14 on weekendsThe first word goes now; only the follow-up waits
Company knowledgeSent to staff on 46 moments; staff bothered at 4 times the 104's rateIf the knowledge answers it, Clara does
Situs chime-ins9 of 14, mostly after the office system confirmedThat confirmation counts as the answer
Tours closed empty9 of 29 dropped ballsNo outcome or a quiet prospect leaves a re-engage
Rule conflict (Tier 2)An application sent closes the tour; the judge wants a re-engage. 10 of the worst 30Open decision O2

Also: 12 repeat team pings (the spent token refuses them) and one untracked callback to a named teammate (now a staff-held item).

Evidence

Five runs on Nov 2 and 3, read-only, on the subscription, each with controls.

The runs, the judge, the tour case, the ratings
RunMomentsDesign, judgePoints per moment (lower is better)No faultControls
Tournament104 (61 Western Slope, 43 Situs)d1c, v20.77 ± 0.06; August framework 4.95not computedAlways silent 11.12, always speak 10.48
Humans check46 held drafts, 59 shadow cardsd1, founders' labelsAgrees 57% and 68% (shuffled 48%, 57%)n/aShuffled labels
Tier 1, production3,968 (897 judged)d1b, v2.11.09 ± 0.10; paired 1.22 vs 4.4282.5%Silent 34.65% dropped, reply 100% needless: both red; oracle green
Tier 2, AppFolio history3,573 of 14,286 (600 judged)d1c, v2.10.77 ± 0.1085.3%Always speak 9.62, always silent 10.34
POC on Topic, Oct 20 to Nov 2625 messages, 144 staff sends, 269 wakesd1c, v2.10.69 ± 0.23 on 90 of 192 queued88.9%Always open: 100% open, red
THE 104 UNDER JUDGE V2: POINTS PER MOMENT, LOWER IS BETTER d1c, the plan0.77 d1b, holder rule1.13 d1, first winner3.82 August framework4.95 Always speak10.48 Always silent11.12
The judge was fixed first. v2 corrects v1 in 8 places to Fede's Nov 2 rule: on a planted pair, v1 scored the wrong call 0 and the right one 20; v2, 16 and 0. v2.1 stops counting Clara's check beside a staff item as a duplicate.

POC gates. Items per read 0.498 at Western Slope (gate 0.50, green), 0.57 at Situs (red); still open after 7 days, red at both. Same call as the per-moment trigger on 91% of messages; golden cases 0 in 9 of 9.

The tour case, before and after

Before: production, Nov 2After: POC replay on Topic
The prospect asked to move; nobody answered the agent's times. At 5:15 PM the timer sent the application anyway; nobody followed upThe offer opened a Clara-held item. At 10:00 local the next morning, one text offering the agent's times, no booking promised (fallback writer on d1c's plan). Judged 0

The ratings, in two lines

  • Slack ratings, Oct 26 to Nov 3: 102 of 107 presses by the two founders (76 and 26), none on a held card; the one-rater 25% cap cannot be met.
  • Of 36 "wrong" presses on the Opus comparison cards, 8 are Opus's own (4 judgment, 4 wording); 15 the prompt, 1 data, 12 aimed at Sonnet or unclear.

Rollout, not autonomous

Gera's ladder. Supervised is day one; Live is later and Fede's call.

The stages, the load, the exits
ONE PATH, OFF WHEN ABSENT. GERA'S LADDER. FEDE TURNS IT ON PER CUSTOMER. Off (default)No reads, no rows.Today's Claraunchanged. Preview, the dry modeThe read records items and its call.Nothing sent.A short list to our side only.Used for the proof runs. Supervised, day oneEvery proposed message is a held card.Approve re-reads, then sends.Silences, staff items: on the list.An expired card puts the itemback on its timer. Nobody is paged. Live, laterClara sends through theexisting prospect send door,one kind at a time.Fede's turn-on per customer. Exit from Supervised (proposed): 90% "Right call" over 100 moments the PropFlow team rated, then Fede's word. Never a number of days, never automatic. Zero wrong in 28 would still allow an 11% error rate.
The modes Gera already built. The only new switch is the engine's own path.
  • Load at Western Slope: 7.1 held messages a day already wait; 70 of 99 expired undecided. The first case adds at most one card every two days (estimate), the whole engine 3.9 a day. Every open item, uncapped, would be about 66 lines a day. Fede: "you'll drown your user."
  • Held messages and ratings as one thing: proposed, not decided. Approve or Deny would be the rating. Gera: "it's rating AND approval." 36 team decisions since Oct 20 left no usable label.
  • Silences never a live feed. Fede, Oct 30 and 31: "impossible to read", "Stop watching the email." They go on the list; the digest is Gera's call.
  • Opus per job, prompt fixed in the same move. Prospect writers moved Oct 31 to Nov 1; tenant, vendor and unknown-sender replies next, on Fede's go; voice last: simulation, then one listen-test call.
  • Exits by measured agreement, never days. Only the PropFlow team's ratings count; staff approvals mean "fine to send".

Roadmap

Fede's go on Nov 3 night: PRs 1 to 3 are built and merged dark with the setting off. Gera's Nov 4 confirm covers only the shape of the hook hunk in his Topic workflow and how Topic reaches the test property. PR 5 and any turn-on stay Fede's word.

PRs in order, proof, what goes
PRWhat mergesProofWaits on
0aNot the engine: the application timer reads the thread first, no second application (#24962)Merged Nov 4, 02:44 UTCDone
0bNot the engine: the timer asks the model whether the tour happened (#24980)Replay of fallback sends since Oct 19; Fairhaven on mergeCI; auto-merge armed
1The item store (8 fields), the engine's setting (Off when absent), the hook on every finished Topic run, a workflow that stops at OffWorkflow history replay under the patch gate, with a mutation control; Topic's own result unchanged. Merged Nov 4, 06:51 UTC (#25079), dark at every companyDone
2The read, each item's due look, item writes; "say" is logged, nothing sentRead-only replay of 30 days at Western Slope and Situs: items per read, items per teammate per day, cards a day, open items past due (must be 0); the tournament set and golden cases re-run; a Fairhaven run with record idsMerged Nov 4, 19:19 UTC (#25107), dark at every company. Replay result: 0 open items past due at both customers, at most 3 nudges to any one person in 30 days, 1.4 and 0.8 Clara messages a day per portfolio, 0 model failures; one over-messaging loop found by the replay and capped
3"Say" goes out through main's held Clara reply, on the engine's settingFairhaven end to end: a test prospect asks to move a tour, the agent offers times, the prospect goes quiet, the next-morning card appears, Approve sends it, the prospect rebooks, the item closes; plus a teammate's promise that is listed and expiresBuilding Nov 4, stacked on PR 2
ThenSupervised at a customerFede and Gera gut-check the cardsFede's word
LaterLive; matters and main's follow-ups fold in; meeting signals; one-tap decision cards; ratingsEach its own decisionFede
Watch. The hook now fires on every finished Topic run, so it reaches Fairhaven without changing Topic's skip of unlabelled messages; Gera confirms.

Also: comparison loops stopped Nov 4; the Rate row and ratings deferred to their own lane; the matters fold-in deferred.

Preview, rating and the staff-owner fix (Nov 5 overnight)

Fede, Nov 4 night: "is it using paths", "put it on preview", "how is it gonna be on slack? are we gonna rate?", "why havent we improved the engine with known defects?", "i need this all done overnight". Preview had been cut on Nov 4 as not needed; that cut is reversed.

StepWhatState
1Preview wired for the follow-through path: engine runs, Clara's check-back posts to the customer's Slack channel as "Preview, not sent", nothing is sent#25402 merged and live (Nov 5 08:40Z). Fairhaven live run: the workflow runs at Preview on the deployed worker (timer fired twice, read ran, nothing sent or held); the "Preview, not sent" copy was shown only by a direct call because the read chose to close both times; new-message start and the Paths page screenshot not proven (test texts failing, smoke login cannot load the modes page). First real lead at Situs or Western Slope is the proof
2Rate Clara buttons on every Preview copy (all paths)#25397 merged and proven in production: one press on a Preview card stored rating gv_0525694173f3dd205de9 and the card read "Rated: Fine". Copies with no conversation (renewal outreach) still have no buttons: issue #25398
3Engine fix: never speak when a person at the office owns the thread (Nov 4 replay: 7 of 42 turns)#25391 merged. Replay, 42 Situs turns, three runs: talk-overs 6 / 5 / 6 → 0 / 0 / 0; right decisions 33 / 32 / 31 → 37 / 37 / 36. Cost: one thread where a teammate had replied is now left waiting (today's standing rule). Eval dataset committed
4Situs and Western Slope set to Preview once 1 to 3 are live (Fede's "put it on preview")Done: Situs Group set to Preview Nov 5 12:25:12Z, Western Slope 12:25:33Z (the same save the Paths page makes). Copies go to #situs-group and #western-slope with Rate Clara buttons. The first real lead that goes quiet is the production proof; a watcher is counting items and copies
5Supervised at a customerFede's word, after Preview looks decent

Found on the way: the subscription pool was capped and labelling at customers had stopped (Nov 5)

While proving Preview at the test company, every test text failed. Cause: every account in our shared Claude subscription pool is capped until about Nov 10, 15:00Z. Test buildings are built to never bill the paid key, so the live test rung at Fairhaven and the Willows is blocked until then. Worse: topic labelling, the language read and grading at real customers ride the same pool, and the "fall back to the paid key" branch only fired when the pool was missing, not when it was capped. From 23:09Z on Nov 4, 98 labelling runs on 51 conversations failed for good (Situs 37, Western Slope 9, JP&Co 3), and no follow-through could start on them. Customer replies were never affected.

BeforeAfter
Labelling at real buildings while the pool is cappedfails for good, one warning per call (1,455 warnings)retries once on the paid key, one warning per lane per hour (#25480, fix, no setting, live on web and worker 12:05Z)
Conversations missing labels51 (967 messages)0, re-labelled 12:13 to 12:15Z on the paid key; follow-through was Off everywhere, so the re-run started nothing
Test buildingsfail closed on the poolunchanged (evals never bill the paid key)

Follow-ups filed: hand-off skipped when no worker slot frees in 30 s (issue #25486, 3 Situs threads); a thread with no building gets no Preview copy (issue #25475). Other background jobs (promise extraction, summaries, Ask Clara) still fail while the pool is capped.

Language from the read

Decision (Fede, Nov 4 night). Which language a person wants is learned from the model read that already classifies every inbound message, not from word lists. Fede: the categorization platform is "already reading the messages and classifying. So I feel like we could just add the metadata on the language there." On a three-field shape: "too over engineered." One field. Under the Nov 2 rule, every inbound message is read by the model; a regex in that path is a 🔴.

TodayAfter
SignalWord lists and patterns on the message text (src/lib/i18n/detect.ts, resolve-language.ts): detected language, explicit request, rejection, combined by rulesOne field the Topic read returns per inbound message, language, stored on the message row beside topic and subtopic
Where it runsInline at reply time, text and emailTopic: every saved message, every channel, every company (test properties skipped), ~10 s after the thread goes quiet
MemorylanguageToLearn → the person's language preferenceSame memory, same meaning: the newest inbound row's language, when not unknown, becomes the preference. The regex is deleted in the swap PR.

The one field. language is the language this person wants to be spoken to in, decided by the model from the message read with the thread: a base code such as es, or unknown. An explicit ask ("en español por favor", "do you speak Spanish?") or a refusal ("I don't speak Spanish") is evidence for that one value, not a field of its own. A short or neutral message (ok, yes, a phone number) is unknown, never a guess from a name.

Why Topic and not this engine's read. Language is a fact about one message; Topic reads every message everywhere. The follow-through read is one call per person per run and starts only where the company is Supervised or Live, so a memory fed from it would stop learning wherever follow-through is Off. The follow-through read sees the field for free through the person picture.

Timing. Topic lands after the reply decision, so the memory serves the next turn, which is what the preference has always meant. The current turn's reply language is the writer's own reading of the message.

Measured, Nov 5 (PR 1 as opened, #25373, separate call, 60 real cases from session 002). Asks for a language 14/14, plain Spanish 15/15. Short or neutral messages 11/15 alone and 13/15 after a Clara turn ("Yes", "No", "Old town" read as English; "Okey" as Spanish). English with Spanish words 4/6 after a Clara turn. Refusals and Spanglish as in the PR body. On 362 real rows: 295 English, 49 unknown, 18 Spanish; 251 agree with today's regex; no failed calls. Cost about 30 output tokens per message (about 260 when it rode the topic call); 95th-percentile call time 0.7 s alone, 1.2 s after a Clara turn, 3.0 s on real threads, inside the unchanged budget. Topic benchmark unchanged at 42. Call (001, under the grant; Fede can overrule): ship PR 1 as data; one-word replies can read as the thread's language, and PR 2 stores a change of preference only on an explicit ask or two consecutive reads that agree, which is the safety net. Threads that begin as a listing-site notification get no Topic read, so no language until the person writes.

Shape change, Nov 5 03:50Z. Folding the language question into the topic prompt moved topic verdicts (the 59-case topic benchmark fell from 42 to 37, repeatable) and overflowed the answer on long threads (a 185-row thread came back all blank). So the categorization run carries the language through its own small call, made alongside the topic call in the same run, writing the same row: the topic prompt stays exactly as it is, the language call is batched over the run's new inbound rows (newest 15), has its own short timeout, and a failure leaves the row unknown without touching topics. Decided by 001 under the grant; Fede can overrule.

Build. PR 1 (001): the Topic prompt, parse and row field; no behavior change, no switch; proof is a read-only replay on real inbound messages, the model's language against what today's regex path would learn, disagreements quoted. PR 2 (002): the memory writer reads the row and the regex is deleted; opens after PR 1 merges so the replay runs on real rows. Topic is Gera's engine: Smith has a heads-up on the bridge, no decision asked. PR numbers land here when open.

Decisions

Thirteen taken, three open. D1 to D17 from the first passes were paused on Nov 3 and are superseded.

Taken, dated; open, each with a pick
DateTakenFede's words
Nov 2Items can expire; the other side never holds one"Some decisions just expire."
Nov 3Hook into Topic; start small"I'll hook into that and then maybe simplify it a bit." "And start small."
Nov 3Widen the testing before deciding"expand our testing before I decide anything"
Nov 3Fix the blind application timer, no switch"yes fix the timer"
Nov 3, night1. Open items get their own list; matters fold in secondIn session
Nov 3, night2. Supervised from day oneIn session
Nov 3, night3. The digest is Gera's, fed the list read-onlyIn session
Nov 4Three outcomes only: say something, stay quiet, close the item; the engine never books, moves, writes or hands offIn session
Nov 4Core cut per the simplification pass (above)"we can always add complexity later"; "we want the core layer built right and simple to start"
Nov 4Supervised stays for this engine; his "no supervised" elsewhere was about staff chatting with Clara internally"that's a different thing"
Nov 4A teammate's promised time passes: Clara stays quiet; the item stays on Gera's list006 pick under Fede's rules, he can overrule
Nov 4Application sent, not started: nothing owed; main already chases it006 pick under Fede's rules, he can overrule
Nov 4Eagerness is one word in the prompt ("medium"), no setting006 pick under Fede's rules, he can overrule

Open

  1. O1, the hook (Gera, Nov 4). Pick (a): the end of Topic's workflow, firing on every finished run; at Off it starts nothing. (b) A new bridge consumer plus direct signals.
  2. O4, held messages and ratings (deferred to its own lane). Pick (a): Approve or Deny is the rating; needs Gera's yes. (b) Two rows.
  3. O5, chime-ins. In 10 of 39 disagreements a founder wanted Clara to speak beside a live teammate. Pick (a): keep "if a human starts it we dont intervene", the 10 as a named set. (b) Clara adds what the teammate left out.

Reference

Files, corpus, commands, earlier passes

Files under ~/agents/006/gate-replay/tournament/. Every run was read-only, on the subscription through llm.py.

  • Simplification pass (Nov 4): /Users/federicochapa/agents/006/gate-replay/tournament/rollout/SIMPLIFY-PASS.md.
  • Design: entries/d1c-wager-book/DESIGN.md. Judge: judge-v2/ (REPORT-d1c.md, rubric-v2.1.txt, CHANGELOG.md).
  • Wide pass: wide/README.md, wide/tier1/REPORT.md, wide/tier2/REPORT.md. POC: poc-on-topic/REPORT.md, item-mapping.md.
  • Rollout: rollout/PLAN.md, TOPIC-ENGINE.md, WRONG-RATINGS.md, passes/. Ratings: slack-rating/inspection.md. Golden cases: regression/scenarios.json.
  • Corpus: 21,285 moments (Western Slope 13,952, Situs 5,492, JP&Co 1,841) at s3://propflow-training-data/follow-through-corpus/2026-11-03/; inventory in corpus-inventory.md.
  • Meeting signal (next): on Nov 3, 43 decisions and action items read from the raw transcript of Western Slope's renewals meeting, every quote matched verbatim (signals/meeting-2026-11-03/).
  • Resume Tier 2 from wide/tier2/: python3 run_t2b.py C75 --workers 10, then python3 run_t2b.py retry --workers 6, then python3 analyze_t2.py score --sources CABE.
  • Earlier passes: docs history, last commit 8805a28c1 (Nov 3). Narrated tournament walkthrough (Nov 3, before the revisions). Related: coworker loop hub, testing playbook.
PropFlow Docs