Runs record a context manifest once a model turn succeeds; the chat
marks each human message with the agents that read its current version.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Write-granted runs whose directories overlap (same folder, symlink or
junction, or nested) wait for each other, at claim time and for manual
runs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claims skip agents that already have a running run, manual runs refuse a
busy agent, a run whose task was reassigned fails before executing, and
tasks with a run in progress cannot be deleted.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
create_task now pins upstream files by content hash and carries the
source task, source thread, verified facts, open questions and
acceptance criteria into the assignee's prompt.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every mention already wakes the agent through its own chat-wake task, so
ordinary tasks no longer inject the org-wide mention inbox.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A wake run whose model answered in plain final text (the coding-tuned
Kimi family does this instead of calling send_message) completed
'successfully', closed its vehicle task, and left the founder staring
at a silent conversation — the reply lived only in provider_requests.
deliverChatReplyIfMissing now runs before a chat-wake run may complete:
when the run never posted into the source thread (run-start watermark,
so a send_message it did make suppresses the fallback), its final text
is delivered as the agent's reply. A delivery failure fails the run
loudly instead of closing it on silence.
A single transient failure from a background run used to silence the whole
company — founder included — for the full ten-minute cooldown. The
interactive lane now claims one probe per park window: the founder's
message tries the provider immediately, a success lifts the cooldown for
everyone (a served request is proof of health), and a failed probe re-arms
the park with the probe spent, so a real outage is never hammered.
Autonomous work still waits cooldowns out unconditionally.
Claim priority alone still left the founder waiting behind whatever long
autonomous run held the single execution slot. The worker now runs two
slots: autonomous grinds the queue one run at a time as before, while
the interactive slot claims only human-triggered wakes and executes them
concurrently — a founder message answers in seconds regardless of what
the company is building in the background. Housekeeping (wake expiry,
goal reviews, heartbeat enqueue) now runs every tick instead of pausing
during long runs. Integration test pins the concurrency: the CEO's reply
lands while a gated autonomous run is still in flight.
loadChatContext labels human senders "[Name (founder)]" so a woken agent
knows it answers its boss, not a teammate. New integration test drives
the whole loop — founder DM wakes the CEO, the prompt names the founder,
the reply lands in the same pinned conversation and thread, the wake
task closes — and a Playwright spec pins the UI contract: badged CEO row
first, selected by default, message queues the wake run, channel recency
never displaces the pin. AGENTS.md documents the feature contracts.
The two real goal tasks from July 9 each got exactly one session: the run
completed, the agent never moved the task off backlog, and the heartbeat's
"has a completed run" exclusion locked them out forever. The agents could
not have closed them anyway — update_task_status requires a task_id the
prompt never carried.
The progress contract, made explicit end to end:
- The task prompt now carries "Task id: ..." and tells the agent exactly how
to end a session: done via update_task_status when the work is complete,
in_progress with a note on what remains when it is not.
- The heartbeat re-enqueues any open task with no run in flight — a
completed run that left its task open earns a follow-up session, with the
prompt stating how many prior sessions were spent so the agent continues
instead of redoing work. The retry budget (3 non-transient runs) still
bounds every task; a task that spends it parks with one log line naming it.
- Scripted agents in the integration suites now close their tasks the way
the contract expects real ones to.
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.
The whole app turned to molasses because snapshot.load() shipped the
entire skill_runtime_snapshots table - unbounded, compiled_prompt
included - over IPC on every refresh. A real profile carried 142 rows
totaling 144MB (1.1MB each from the pre-cap CEO compile-all era), so
every coalesced refresh serialized ~144MB of JSON. The forced-humanizer
rework made it worse by adding a row per run for every agent.
- Drop skillRuntimeSnapshots, skillRevisions, skillTests, and
skillBindings from the renderer snapshot: no renderer surface reads
them; skill internals are main-process state. Only the lightweight
skillDefinitions catalogue still ships.
- Project provider_requests without raw_response_json (4.1MB across the
newest 100 rows; RunsPage only reads responseText)
- Migration 051 purges the bug-era compiled prompts from existing DBs
- resolveRuntimeSnapshot is now idempotent per run: a run re-queued by
startup recovery reuses its frozen snapshot instead of dying on the
uniqueness guard and burning real retry budget
- Regression test pins the contract: a 2MB database row must not add
bytes to the snapshot (payload asserted under 400KB)
A human message in a channel woke agents only through @mentions, DM
counterparts, or prior thread participants - and the flat composer
always sends threadId=null, so typing in #general summoned nobody and
the room stayed silent.
- Track which agents each wake path summoned in one woken set (also
prevents latent double-wakes between the paths)
- When a non-slash human message in a channel wakes nobody, wake the
channel's most senior active agent member with an enabled provider
(c_suite > director > lead > staff, then hire date); they can pull
teammates in with @mentions
- Log when a channel has no runnable agent so silence is diagnosable
- Integration test: plain #general message wakes the CEO who replies;
an explicit mention still wakes exactly one agent