Of the 202 tasks stranded in the backlog on July 9, 200 were "Reply to ..."
wake vehicles: every agent @mention creates a task plus a queued run, the
reply goes out, and nothing ever closed the task — a task with a completed
run is never enqueued again, so each one became a permanent zombie row. On
top of that, every message in an active thread minted a fresh wake even when
the target already had one queued, multiplying runs that would each read the
same conversation.
The lifecycle contract, made explicit:
- The reply run IS the wake task's deliverable. Completing a chat_mention
run now closes its task (backlog/in_progress -> done, via the audited
status path). Tasks an agent moved to review are left alone.
- One pending wake per (agent, thread): wakeFromMention returns the queued
run instead of minting a duplicate — that run reads the thread's newest
messages when it executes anyway.
- Migration 054 heals existing rows: wake tasks whose runs are all spent
close as done; in-flight wakes keep working. This also stops Fix 1's
retry-budget healing from resurrecting 31 stale replies on next launch.
The chat-governance loop test now completes each pending wake run between
posts, matching how the exchange actually interleaves in production.
A systematic review of the whole codebase (main process, renderer,
IPC/migration/packaging seams) surfaced four real defects; each is
fixed at its root:
- Legacy catalogue drift: the operator's profile still carried 89
active skills from the removed ~/.agents import era next to the 228
built-ins. Catalogue sync now mirrors the bundle - actives whose slug
the bundle does not ship retire (bindings keep resolving via their
pinned revisions; retired skills leave list_skills and cannot be
granted anew)
- Broken-bundle guard: staging now refuses a bundle without the
humanizer skill, so an empty or quarantined resources folder can
never trigger the mirror pass into retiring a healthy catalogue
- Duplicate agent names: @mentions, DM routing, and task assignment all
resolve by name, so createAgent and updateAgent renames now reject a
name already held by an active agent (case-insensitive); the mention
resolver still refuses to guess between legacy duplicates
- Stale DM titles: agent-to-agent conversation rows titled themselves
from the frozen creation-time space name, so renames never reached
the sidebar; direct titles now derive from members' current names
Verified clean in the same sweep: IPC surface (82 channels, handler +
preload + api aligned), per-migration transactions with rollback,
quota-parking month rollover, retry-budget counting, meeting spot
reuse across floor-plan rebuilds.
The legacy application - its src, tests, landing site, promo assets, docs,
release tooling, CI workflows, and root configs - leaves the tree; it stays
reachable in history. Everything under AgentCompany-New moves up unchanged:
same package name, so the production userData/database path is untouched,
and e2e/build scripts already resolved paths relative to the project. The
developer cred.txt stays gitignored at its new location. Full verify:ci
passes from the new root.