bin/refresh-tracker reads each row’s own PR and decision links live (GitHub + blocked) and regenerates it. Last refreshed 2026-09-16 06:40Z.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.
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.
| Status | Item | Kind | Evidence |
|---|---|---|---|
| done | Yale #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. | merged | PR #6275 merged 08-26 01:51Z |
| done | Yale #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. | merged | PR #6276 merged 08-26 01:53Z |
| done | signalB — 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. | merged | PR #6312 merged 08-26 03:56Z, full CI green |
| done | Yale #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. | merged | PR #6334 44 checks green, 12/12 shards falsified twice |
| done | Tour 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. | merged | PR #6336 falsified; the leak between fixtures was itself the proof |
| done | Yale #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. | merged | PR #6337 eval re-landed as #6340 |
| blocked | Yale #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. | decision | b87753261 do NOT “fix” without an answer |
| not started | Restore 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 gate | last checkboxes before turn-on |
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.
| Status | Item | Kind | Evidence |
|---|---|---|---|
| done | slack_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. | pushing | PR #308 622 tests green · both halves falsified |
| done | Cap 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 started | already capped on main — all five workers |
| done | Cap 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 started | already capped on main — fan-out 4, brain-queue routed |
| done | Own 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 started | PR #343 falsified; clean-resume control green |
| done | approval.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 started | already bounded on main — three loops |
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.
| Status | Item | Kind | Evidence |
|---|---|---|---|
| done | First-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 ask | PR #345 control rewritten after it proved nothing |
| done | The “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 started | doc rot corrected on main 2026-08-28 |
| done | Route 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. | landed | wisdom --binding · CLAUDE.md · memory |
| done | Make 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 started | PR #344 both halves falsified independently |
| done | Retire 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 started | retired in place — bindings neutralised, answers preserved |
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.
| Status | Item | Kind | Evidence |
|---|---|---|---|
| blocked | Twilio: Fede’s explicit “do 1–4”SHAKEN/STIR, CNAM, Voice Integrity, Free Caller Registry. All external writes, frozen since 08-25. Never asked directly. | waiting | A2P already verified |
| blocked | Which 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 |
| blocked | Yale #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. | waiting | ConAm IT ticket filed by Fede |
| in flight | Decision 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. | waiting | answered: “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 |
| blocked | Decision b87721726 — where the review receipt goesNames three gate violations, a rejected customer-facing copy change, and 13+ false completions. | waiting | Decisions tab |
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.
tail in a pipe reported exit 0 for a pytest run that never finished.ps under fork pressure reported 8,898 zombie processes; a clean snapshot showed 111.npm run typecheck passed on an import that dies at esbuild — @/lib/data resolves to a different module per tree.pgrep found the live process that owned it.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.