Two decisions you made today are sitting unexecuted. You answered the Camellia Saturday rule at
12:01 and the #5236 reshape at 13:11. Both blocks still read state: open in the ledger,
and the Camellia one has not been touched since 02:46 — nine hours before you answered it. Details in
the first two cards.
Blocks are per-session: only the owning session can run
blocked resolve, because cmd_resolve scans only its own sid. So these cannot be closed by
anyone else, including this page.
How each verdict was reached, since the agent view's own text cannot be
trusted for this. A row's summary is a claim — “confirm whether X” may have been
answered two days ago. status: busy means only that the process said it was in a turn; two sessions
below have said busy for 11 days and 21 hours with zero turns behind it. And silence is not a signal
— a session that stopped without reporting has usually finished and lost the report, which happened
repeatedly today.
So every verdict here rests on an instrument other than the row: the
transcript on disk, the block ledger under ~/.claude/jobs/blocked/, the central answer store via
bin/docs answers decisions, live PR state via gh, and ps for whether the
process exists at all. Where a count appears, the matches were printed — a grep returning zero is evidence
about the grep.
Sorted by how directly a human unblocks it. The first three are the expensive ones: two are decisions you already made today that are sitting unexecuted, and one is a session that has been waiting two days for a keystroke.
Waiting on you to type /compact — since Aug 1. Nothing else is wrong with it.
/compact is a built-in CLI command — I can't invoke it myself, only you can. Please run /compact and I'll pick up exactly where this left off."gera/sms-review-gate-harness, file src/__tests__/sms-review-gate-e2e.test.ts, 6 tests / 3 failing, uncommitted and untracked so nothing disturbs it. Nothing pushed.get_tour_slots for a tenant sender, so tests 4–6 were passing without ever dispatching).Run /compact in that session. That is the entire ask; it resumes itself.
One production write away from done. It has the write ready, refuses to route around the gate that stops it, and is right to refuse.
tourDayPolicy is null in prod — a same-day Saturday booking is still accepted today.b85743159::gera@propflowai.co → “Turn the rule on for Camellia — Saturday tours need to be booked at least a day ahead”, written 12:01:39, confirmed in both answer stores with identical text.choice_matched_option: true). It resolved itself while this page was being written — which is the whole reason a row's summary text cannot be trusted as a verdict.1773625953462 (Camellia Apartments), tourDayPolicy = {"saturday": {"allowSameDay": false}}. Read-modify-write, script staged at /tmp/apply.ts — not a replace: the row already carries tourDurationMinutes 15, tourMinLeadMinutes 60, renewalAutoStart 90, applicationLink, postTourFollowUp{Delay,Channel}.minLeadMinutes is offer-only — zero references in either write path, so setting it would stop Clara suggesting a same-day Saturday while still accepting one. allowSameDay is the write-enforced field, via sameDayBanRefusal. Read from the code, not taken on trust.c431cb6972.Run the one prod write, or grant the permission. This is no longer a decision — you have made it, the session has verified it in both stores and resolved its block correctly. It is a single gated write that needs a human's hands. Until then Camellia keeps accepting same-day Saturday tours.
You answered this at 13:11 today. Two of its three blocks got executed; this one did not.
b85734077::gera@propflowai.co → “Reshape #5236: keep the manifest entry as RETIRING (the listings-sync house pattern), leave the Vercel cron at 30 13”, written 13:11:08, matching offered option B verbatim.state: open, resolution: None; the file is untouched since 00:14. Its two sibling blocks (b85730961, b85732722) were both resolved at 13:11 — so this is a specific miss, not a dead session.Nothing new is needed from you — this is an execution gap. fa126b98 must resolve its own block and reshape #5236. Worth a nudge, not a decision.
It found production data loss and stopped there. Nobody owns the finding.
posts_on() returns 0 rows for today, yesterday and 07-30 — and on 07-30 the same session had counted 2,143 rows in that table earlier the same morning. One ledger file, so there is nowhere else it could be reading from._connect() runs CREATE TABLE IF NOT EXISTS posts, so a vanished table is silently re-created empty and reads as “no posts.” The failure is indistinguishable from a quiet day.Does anyone own “the agent-smith posts ledger lost 2,143 rows and re-creates itself empty”? No PR, no issue, no session is carrying it.
Shipped, then proved itself PARTIAL against prod: $70,100.77 is invisible on the page it built.
propflow-prod, live snapshots, running the shipped predicate: Camellia has 84 tenants with a balance, 25 shown on /collections, 59 hidden holding $70,100.77. Snapshot recordedAt 2026-08-01T12:27:40Z.isDelinquentSnapshot (aging.ts, DELINQUENCY_MIN_DOLLARS=50 at :59) includes only 31+ days aged over $50.Should /collections show 0–30 day arrears, or say out loud that it is hiding them? A product decision, not a bug fix.
Proved its own invariant cannot hold where it was placed. Issue #4911 is open on origin/main.
origin/main, not in a PR: src/lib/domain/tenants/handle-tenant-confirmation.ts — notifyVendorOfConfirmedTime (:383) and notifyVendorOfReschedule (:398) both call sendTelegramMessage(chatId, message) and write no row.sendSms / sendMms / sendTelegramMessage).Nobody owns moving the ADR-0119 fence from entry points down to the carriers. Until that happens #4911 reopens by construction.
#4846 met at the layer it was written for, PARTIAL at the layer it was written for the sake of.
origin/main 941860dab — not its own branch, not PR state.conversation-manager.ts:5221 → 3 failed / 4 passed; restore → 7/7.Same root as ad8b46c6 above — the orphan-send class does not close until the fence moves to the carrier layer. These two are one problem with two sessions parked on it.
The fleet ledger it was built to keep. It reconciled, produced three questions for you, and stopped.
~/code/PropFlow/primary/LEDGER.md. Last turn 2026-08-01 06:11.Three questions were raised for you and never made it onto a decision page — #5130 (PII in logs) is the one it flagged as not-a-residual. They are in LEDGER.md, not in the block ledger, so nothing will re-surface them.
Not fleet work — your Austin tree-permit consultation. Three items need you.
Three photo/paperwork items only you can supply. Listed here because it sits in the same agent view and looks identical to a stalled engineering session — it isn't one.
A zombie holding a row for 11 days. It has never run a single turn.
claude --dangerously-skip-permissions --model claude-opus-4-8).~/.claude/projects/-Users-miniclaw-code-PropFlow/ holds 2,894 files and not one of them matches 8f1d6d4d — so this is a populated directory returning a real zero, not a broken search.~/.claude/global-progress/8f1d6d4d….json is frozen at updatedAt 2026-07-23T16:34:36Z with tasks: [].~/.claude/session-env/8f1d6d4d…/ is empty.Nothing to recover — there is no work to lose. kill 47234. It is one of the “3d”-style rows that made the agent view unreadable.
Zero-turn zombie showing busy for 21 hours. Its task was finished by someone else.
status: busy. This is exactly the case the roster warns about: busy means “the process said it was in a turn”, not “alive.”b6c9b983 docs-tagging was re-dispatched on the same task and completed it — TAGS.md exists, 15 tags, zero unused, 91 artifacts carrying pf-tags, and the build guard is live.kill 14970. Nothing is lost. Worth knowing the failure mode: a session can register as busy with no process behind the claim and never start — and this is the second recorded instance on this exact task.
All 16 are DONE, and they are the same event. A fan-out delivery test on 2026-08-03 woke every awake session with a decision-page notice that was not theirs. Not one of them belonged to the session that received it.
Every single one checked the block ledger and declined to act. Sixteen sessions, independently, given a
plausible instruction attached to a real block id and a real quote from you — and sixteen ran
blocked check, found no open blocks, established the block belonged to someone else, and
did nothing. Several went further unprompted: they distinguished a probe from an answer
(by: probe, not gera@propflowai.co), and one noted that a resolved block with no chosen
option is not a decision.
That is the healthy outcome, and it is worth saying out loud rather than burying: the fleet's default on an unverified claim is to verify and stand down, not to act. The wall of identical rows in the agent view is evidence the protocol worked, not evidence of sixteen stalled sessions.
6a7af8d4 decision-page-verification · 700a173a decision-page-verification · 2c1fd367 ledger-verify-block · b7dd0698 decision-page-ledger-verify · 923b728e broadcast ignore protocol · 68d1ffaa blocked-page verify · 5d26a281 block verification fanout · 98096c6c block verification routing · c83c964e block ownership verification · d43a62f1 ledger verification broadcast · 8cfe182b verify decision page change · d165b9f9 verify fan-out decision change · 6ad7c089 block coordination routing · 37f56e19 fan-out decision verification · 28f8dce0 ledger verification fan-out · c337df29 propflow-ee
Not a terminal state. Listed so nothing in the roster is unaccounted for.
The coordinator. Mid-turn right now, not terminal.
DRIVE-GATE (~/.claude/jobs/DRIVE-GATE reads cc4ad587…).b85719449, b85728416, b85728943, b85728957) are resolved with no reason recorded — those are not decisions and must not be read as answers.This session. It wrote the page you are reading.
claude agents --json --all (52 records), not hand-copied.Sibling child, started 14:17 today. Deciding what docs.propflowai.co should be made of, as an ADR.
god-today.html returned zero — I need to confirm that's a real zero, not a broken probe.”Each of these was checked against something other than its own summary: a merge timestamp, a CI lane, a query against prod, a commit in the log.
Built the tour calendar the team asked for twice. PR #5308 MERGED.
propflow-prod read-only, real document.body.innerText: “Monday, August 3, 2026 · 1 tour booked — 4:30 PM · Confirmed · Camellia Apartments.”getTours, healTourProspectNames and the property-scope gate rather than building a second data layer.Stopped paying for the same test run 3–4× per PR. PR #5309 MERGED.
ci.yml lanes split by cost: every push pays type-check + lint + the drift/replay guards; the affected suite starts on the reviewer's verdict or a run-tests label.in_progress/null ext=ci-yml-unit-tests — pending, not failure, which was the exact risk.success would be a green tick on a lane that never ran.Drove PR #5013 to a clean verdict. MERGED 05:46:07Z.
1ca8676f5: 🟢 “round 2's blocker is properly fixed. Ship it.” No 🔴, no 🟡.2 failed / 70 passed on ca321c23c → 70 passed (70). 72 − 2 deleted cases = 70, so it checked that nothing else went quiet.Unit Tests (affected) — passed empirically rather than by inference.Its block was answered, it executed within the minute, and #4851 is MERGED.
hold-for-review label cleared — one minute later on the local clock.state: resolved, reason: answered, choice_matched_option: true. This is the reference case for what the whole block mechanism is supposed to do.Fixed the bug that stranded your answers — the reason two decisions sat unread all afternoon.
blocked check, all firing against fa126b98 at once: it read only blocked-<sid> so answers written to the shared decisions page were unreachable; the regex made -note:: keys invisible by construction; and ::<email> bled into the printed value.bin/docs answers <slug> --json so callers read the record rather than scraping the human table. Confirmed in this repo's log: 9fb600f docs: add `answers <slug> --json` for structured callers.Seven ownerless PRs, all seven driven to a terminal state. Nothing merged without a human.
7f2c6e008 · #4851 🟢 at exact head a589ef79c · #4705 parked by Fede · #4264, #4826, #4969 CLOSED as superseded or stale · #4970 CLOSED on your own decision.blocked resolve TEST-no-gate, it reported “TEST-no-gate does not exist” — every grep hit was message text, zero hits in any session's blocked store.PR #5317 fixed and 🟢 after 8 review rounds. Still OPEN — deliberately.
unit-tests-check had no actions/checkout, so moving the decision into scripts/ci/decide-unit-tests-conclusion.sh put it where the job could not see it. Exit 127 lands before the check is written — the required Unit Tests context was absent, not red.origin/main's ci.yml contains the script path zero times, and the failing run echoed a comment existing only in 7c94890d.run-tests label: “an unrequested state change on a PR held for a human.” That is why #5317 is still open, and it is correct.Tagged the docs corpus — then found the tagging was already built, and found two real bugs verifying it.
609d9bb, 7038fe6), so the job became verification.agent-ops 19 · infra 18 · decisions 16 · evals 14 · maintenance 14 · architecture 13 · conversations 13 · money 12 · leasing 9 · turnovers 9 · voice 8 · incidents 7 · collections 4 · design 4 · renewals 3.data-tags. The chips hide on that tab, so nothing on screen explained it.d1c99950's job after that one never started.Built loop-kickoff standalone, and fixed the race that dropped live #5232 from the registry.
DRAFT_GRACE observation cache closing the draft-toggle race that had silently dropped a live PR from the work registry.a99f5076's work rather than over it, keeping that session's REST migration and its “do not simplify this back” warning.Moved register-work off GraphQL onto REST. One item, announced, finished, independently re-measured.
4592 → 4592, zero GraphQL.7 in the output and proved it a dry-run artifact rather than a defect: --dry returns before save_draftseen().Executed /tmp/pr55-findings.md, then spent the day correctly declining other sessions' blocks.
b85734077 is fa126b98's block — not mine, not the coordinator → no action, per protocol.”Started as a WhatsApp lookup; ended up producing the diagnosis that 97078deb then shipped a fix for.
fa126b98's blocks, what the session could read vs what you actually decided — “the session is alive … awake, polling, and being fed stale data on all three.”Traced the stranded-answer failure to its end and confirmed the one clean counter-example.
cb989158 healthy: answer at 10:11:05, merge at 15:12:05Z, session clock UTC−5 → one minute apart.decisions page was doing into two distinct behaviours — harmless mirroring of answers already consumed, versus carrying answers that never reached the owner — which is what made the problem tractable.blocked check was still lying about b85734077 while the real answer sat elsewhere.Corrected itself twice in public and landed on the right diagnosis: two answer stores.
decisions notices as claims the ledger didn't back, implying they were noise. They are real. Gera wrote every one of them, and they're newer than the answers on the per-session pages.”blocked check reads answers(slug_for(sid)) — one store, the session's own page — so a session polling correctly still reads the stale value.Called four sessions dead, then published the correction when two of them came back and did the work.
choice is your note prose, not an option.Ran a hypothesis, then killed it on the grounds that its own test could not discriminate.
decisions equals its block's rec — 4 for 4. That looks like confirmation, but it isn't, because accepting the recommendation is also the most common thing a human does. My 'test' couldn't discriminate.”b85730961 got a hedged note in unmistakably human register that declines the recommendation. A mechanical mirror would have written the rec.Supplied the control case that narrowed the stranded-decision problem to one session.
b85743815 — decisions at 13:11:41 is a faithful copy of blocked-cb989158 at 10:11:05.decisions is not systematically diverging — it is correct wherever you had not changed your mind. The only genuinely stranded decisions were fa126b98's.gera, all clean (unset) → transitions. “Probing the notifier can't corrupt a decision.”A duplicate coordinator spawned before the fork guard existed. Both its blocks folded, nothing lost.
The other duplicate fork. Killed 5 seconds into its first turn.
Bash calls at 05:22:01–03, terminated. No output, no writes, no blocks raised.5cff2f82, which ran the same kickoff to a conclusion.Launcher control test. Asked for the word OK, used no tools, replied OK.
Spawn probe. Asked for four characters, produced four characters.
PROBE, no tools. Confirms the spawn path works headless.The delivery test itself — and it passed. Both “failing” commands were behaving correctly.
delivered.broadcast … reason:"no DRIVE-GATE — nobody is armed", tried:28, delivered:14 at 14:54:35Z. Delivery works with no gate armed — which is what the test asked.~/.claude/jobs/blocked/ all created 09:54–09:55, i.e. each recipient running blocked check on wake.TEST-no-gate is not a block anywhere, so there was nothing to resolve.There were two answer stores, and parked sessions read the stale one. Answers written to the shared
decisions page were invisible to blocked check, which read only
blocked-<sid>. A session could poll correctly, forever, and never see your answer. Three defects
lived in that one line — wrong page, -note:: keys unreadable by construction, and
::<email> bleeding into the value. 97078deb fixed all three and shipped
bin/docs answers <slug> --json so callers stop scraping a human-facing table.
Reports were lost in one direction only. god→child delivery worked; child→god was silently
dropped with exit 0. That is why several sessions look abandoned and are not — they finished and
the report evaporated. Its mirror also bit: fa126b98 proved that no trace of a message is not
evidence of non-delivery either.
A decision page that states a count goes stale as fast as the work moves. god's push question was withdrawn and re-asked twice — four commits, then six, then ten — before it was reshaped to ask by category. The categories held.
A resolved block with no reason recorded is not a decision. Four of god's blocks
are in exactly that state. The tooling prints RESOLVED WITH NO REASON RECORDED for this case, and it
must not be read as an answer.
Every decision page on the live site is currently stale, and the cause is one line of
git. propflow-docs' local main is 3 commits behind origin/main and 2
ahead, so git push is rejected as non-fast-forward. Both bin/docs and
blocked resolve push to publish — so every page they have tried to update since the divergence
has failed to reach the site. That is why blocked-616c7e1f still renders its question as
open on docs.propflowai.co when the ledger has it resolved. Fix is git pull --rebase in that
checkout before the next publish; it was left undone here deliberately, since another session may hold the tree.
Two honest notes on the shape you asked for, rather than silently bending the labels to fit.
Zombies do not fit any of the five. propflow-b9 and propflow-docs-25 are live
processes that never ran a turn. They are not stuck in the sense the taxonomy means (a session that tried
and hit a wall) — they never started. They are filed as STUCK because that is the state that gets a
human to act, and the action is one kill each. But the real category is zombie, and it is
worth a sixth label if this keeps happening — it has now happened twice on the same task.
Three sessions are genuinely running, which is not a terminal state at all. They are listed under Running right now rather than forced into one, so that every one of the 52 roster records is accounted for exactly once.
Generated from the roster, not hand-copied: the generator asserts that every
sessionId returned by claude agents --json --all appears in this page exactly once, and it
fails rather than publishing if one is missing, duplicated, or invented. The verdict counts in the pills at the top
are computed from the cards below them.