Session tracker — decision-page-markup-review

2026-08-25 → 08-26 · Yale go-live, the Smith review, and what came out of both
Status column is derived, not typedbin/refresh-tracker reads each row’s own PR and decision links live (GitHub + blocked) and regenerates it. Last refreshed 2026-09-16 06:40Z.
TL;DR — Two Yale punch-list fixes are on main. The session's real output was not the fixes though: it was finding that Agent Smith answers every Slack message with a one-shot claude -p that SIGTERMs its own process group, and then finding that the obvious repair for that was wrong. Two independent research lanes refuted the persistent-session bridge I built — the conversation is already durable, only the process is disposable, and that is the correct Temporal shape. What survived is a smaller, sharper list: cap the workers, cap the fan-out, own the resume-miss, and build the one door that start-operator's own header claims already exists.
How to read this

Phase 1 · Yale go-live

PHASE 1

Stop Clara saying things that are not true

customer-facing

Every item here is a thing a real prospect heard or would have heard. Two are merged; the third was stranded by an auto-merge and re-landed; the P0 has not started, and its root cause on the card was wrong.

StatusItemKindEvidence
doneYale #1 — availability gate at the shared tool seamClara answered “we don’t have any one-bedrooms” off a 112-unit placeholder roll while the website listed them. Gated at buildVacantUnits, not the injection — voice’s fail-closed path bottoms out in the same tool.mergedPR #6275
merged 08-26 01:51Z
doneYale #4 — no false “confirmed”auto_confirmed was honest; the spoken sentence was not. Both twins fixed, plus the voice and SMS prompts — no prompt read the field at all.mergedPR #6276
merged 08-26 01:53Z
donesignalB — the same fabricated “no”, different doorsignalB counted a contradiction only on OCCUPIED, while the vacant list also rejects Yardi VACANT_RENTED. A Vacant-Rented roll gave an empty list AND zero contradictions → the confident negative shipped anyway. Yale is Yardi-bound.mergedPR #6312
merged 08-26 03:56Z, full CI green
doneYale #2 — one canonical caller-identity lookupThe P0. Root cause was wrong on the card — the Person spine is multi-property-safe; the bug sits in the pickers above it. resolveIdentity gated its prospect steps on propertyId but not its tenant steps, so a Yale caller who also rents at Camellia matched the Camellia tenancy and short-circuited — the Yale steps never ran. One un-gated lookup produced both field symptoms: wrong identity and “no prospect found”. Optional propertyId hard gate threaded through both trees; the discovery lane stays cross-property and is pinned green.mergedPR #6334
44 checks green, 12/12 shards
falsified twice
doneTour lookup widened to a sibling property — and then wroteFound while mapping Yale #2. findTourForProspect backs both reschedule and cancel; its property scope fell back to the unscoped pool when it came up empty, so a caller with no prospect at the property they contacted matched one at another property — and the tool then moved or cancelled that booking. A read-side widening became a cross-property destructive write. Now fails closed.mergedPR #6336
falsified; the leak between fixtures was itself the proof
doneYale #6 — a garbled name got three swingsASR heard “Fred” as “spread”. The prompt already banned re-asking; the garble defeated that rule rather than breaking it — when the word isn’t name-shaped the model concludes it never got a name, so re-asking doesn’t feel like one. Added the missing branch: confirm the noisy capture ONCE, then drop it.mergedPR #6337
eval re-landed as #6340
blockedYale #5 — bare “Hey” deflects. Not a bug.Traced the copy: “I’ll check with the team…” is uniquely the escalated handoff ack, so the “Hey” landed on an already-escalated thread, and carriesAnswerableAsk("Hey") correctly returns false. That encodes Fede’s 08-20 ruling as refined 08-23 — and the code states the rejected alternative verbatim: “reply to ‘hi’ on a thread a human owns — a reversal in the one direction nobody asked for.” Flipping it reverses a standing ruling, so it went to the Decisions tab instead.decisionb87753261
do NOT “fix” without an answer
not startedRestore Yale officePhone + the test OutlookRepointed to a test cell so escalations stop ringing the real office; one transfer already reached (303) 395-9448. Fede then attached a test Outlook. Both must be restored before real traffic.go-live gatelast checkboxes before turn-on

Phase 2 · Agent Smith — the infrastructure

PHASE 2

Stop the fleet duplicating and starving itself

two of these are outage-class

All five came out of the Temporal audit. The first is built and pushing; two of the rest are bigger than anything we were chasing when the session started.

StatusItemKindEvidence
doneslack_send idempotency keyA sync activity whose start_to_close expiry is never delivered — cancel arrives only via a failed heartbeat, and it heartbeats once at entry. The timed-out attempt keeps posting while its retry posts too: 4 identical deploy confirmations in 104s, two after the workflow gave up. Claim keyed on (workflow_id, run_id, activity_id), never a text hash.pushingPR #308
622 tests green · both halves falsified
doneCap max_concurrent_activities on both uncapped workersSDK default is 100 slots against a 20-thread executor, so 80 tasks queue with their timeout clocks already running. The generalised cause of 143 timeouts on 08-20 — and the SDK already warns at boot.not startedalready capped on main — all five workers
doneCap the alert-remediation fan-out; fix _brain_queue routingFan-out has no cap (“EVERY alert is eligible”) and its children miss the brain-queue prefix match, so they land on the uncapped interactive queue. ~20 alerts pins all 20 threads with 90-min subprocesses.not startedalready capped on main — fan-out 4, brain-queue routed
doneOwn the resume-missThe session store is claude’s local --resume DB — unreplicated, evictable, not modelled by the workflow. The code detects the miss and silently starts fresh, so a thread can lose all history with no signal.not startedPR #343
falsified; clean-resume control green
doneapproval.py’s unbounded while TrueNo deadline, no poll counter, no continue-as-new. A wedged PR polls every 15s forever: ~240 GitHub-calling activities and ~960 history events per hour.not startedalready bounded on main — three loops

Phase 3 · How work is driven

PHASE 3

Make the shape consistent, since we repeat it

process

The progress-table ask and the operator door are the same problem: a reply thread has no session to name, so the table cannot be honest and dispatched work has nothing durable to attach to.

StatusItemKindEvidence
doneFirst-turn progress table + mid-turn pulseThe pinned post-once-then-edit table already shipped 08-23 — it just never fires on a plain human turn. One patch-gated call before the ack, plus an activity-side refresh_table tick (zero new workflow commands).your askPR #345
control rewritten after it proved nothing
doneThe “substantive ask → start-operator + binding” doorstart-operator’s header claims “Agent Smith calls it from its reply workflow”. No such call exists. This is why work dispatched from a reply turn dies with no record — evidence-based arming can’t rescue work that dies before making evidence.not starteddoc rot corrected on main 2026-08-28
doneRoute decisions through blocked, everywhereBoth Smith and I had been hand-authoring docs artifacts that never reach the Decisions tab. Written as a binding wisdom rule, into global CLAUDE.md, and into memory.landedwisdom --binding · CLAUDE.md · memory
doneMake the rule self-detecting in wisdom_cli checkWisdom is not enforcement: the same store already holds a binding “never say nothing to add there” rule that fired 19×, four after the ban. A check for decision-shaped Slack posts with no blocked raise would close it.not startedPR #344
both halves falsified independently
doneRetire the two off-rails decision pagesThe undated smith-review-decisions and my dated one both sit outside the Decisions tab. Two pages, and the next reader may answer the wrong one.not startedretired in place — bindings neutralised, answers preserved

Phase 4 · Waiting on a human

PHASE 4

Nothing here is blocked on engineering

answer to unblock

Five items, none of which anyone is working on, all of which stop work downstream. The two Twilio ones have been frozen since 08-25 and were never actually put to Fede directly.

StatusItemKindEvidence
blockedTwilio: Fede’s explicit “do 1–4”SHAKEN/STIR, CNAM, Voice Integrity, Free Caller Registry. All external writes, frozen since 08-25. Never asked directly.waitingA2P already verified
blockedWhich test Outlook account Fede attachedCouldn’t verify — the local env reads the anonymized propflow-stage mirror, which strips integrations and fakes phone numbers.waiting/api/integrations/outlook/status?propertyId=1773625952029
blockedYale #3 — calendar vs auto-confirmNarrower than the card said: text-channels only — voice already auto-confirms with no calendar. Unparked by the test Outlook, still undecided.waitingConAm IT ticket filed by Fede
in flightDecision b87721567 — 15 nights of failing cronsmaintenance-eval and morpheus-nightly. The “fix” PR for the first is docs-only, so no code fix exists at all.waitinganswered: “drive all four to green now”
maintenance-eval · morpheus-nightly · conversation-review-daily dup · Actions spend $0
not started — new program, needs its own driver
blockedDecision b87721726 — where the review receipt goesNames three gate violations, a rejected customer-facing copy change, and 13+ false completions.waitingDecisions tab

What this session got wrong

Kept deliberately, because the pattern repeated and it is the most reusable thing here: every failure this session was an instrument reporting green when it had not looked.

Every one of those would have read as good news. The check that caught them was always the same: ask whether the instrument could have produced that answer without looking.

Sources: two independent research lanes (Claude Code semantics + Temporal audit) · the 08-18→08-25 Smith review (58 Slack threads, 1,993 ledger posts) · three review rounds on #6275/#6276 · prod DDB read for the Yale gate verdict. Anything unverified is labelled in place.
PropFlow Docs