Every event the loop writes to its log and emits on its bus, with the fields it carries.
View raw Markdown · llms.txt · For agents
Every loop event is appended to <stateDir>/events.ndjson and emitted on the plugin bus, with at (ISO
timestamp) and type on top of the fields below. A plugin subscribes with
bus.on('<type>' | '*', listener); a notification channel subscribes by listing types in
notifications.events.
The vocabulary is enforced by the compiler: appendLoopEvent accepts only these names, so an event that is not
here cannot be emitted — and a name here that nothing emits fails the test suite.
63 loop events.
contract.*
| Event | Carries | What it means |
|---|---|---|
contract.escalated | issue, reasons, digest | A contract was frozen but is not dispatchable; a human was asked to settle it. |
contract.failed | issue, error | Contract generation failed on every candidate provider. |
plan.*
| Event | Carries | What it means |
|---|---|---|
plan.voted | issue, cycle, approvals, votes | One planning cycle finished: how many agents approved the plan, out of how many voted. |
plan.failed | issue, error | Planning failed on every candidate provider. |
plan.escalated | issue, cycles, unresolved | The cycles ran out without consensus; the unresolved objections are a human's to settle. |
worker.*
| Event | Carries | What it means |
|---|---|---|
worker.dispatched | issue, worktree, worktreeId, branch, terminal, provider, model, contractDigest, briefDigest, command, briefAccepted, tuiIdle | A worker was launched in its own worktree. Carries the whole dispatch record plus the command that ran. |
worker.dispatch-failed | issue, error | The dispatch itself failed — worktree, terminal or brief — before any work started. |
worker.setup | issue, worktreeId, ok | project.setup.command ran in the fresh worktree. |
worker.nudged | issue, kind, reason, worktreeId | An idle worker was nudged in its own terminal — and also the terminal outcome nudged, which ends a delivery pass on the same issue. Two emissions, one name: kind is present on the first, reason on the second. |
worker.reactivated | issue, terminal, previousTerminal | A stale terminal was relaunched for a worker that was still supposed to be working. |
worker.reopened | issue, pr, previousHead, head, previousOutcome | A finished issue came back: a new head on a PR the loop had already closed out. |
worker.handed-off | issue, from, to, worktreeId, branch, reason, briefAccepted | The task was handed to another provider in the same worktree, on the same branch — and also the terminal outcome handed-off that ends the delivery pass which did it. |
worker.ci-round | issue, pr, head, round | CI is red; the failing checks went back to the worker as a fix round. |
worker.review-round | issue, pr, head, round | The review found blocking issues; the findings went back to the worker as a fix round. |
worker.conflict-round | issue, pr, head, round | The PR conflicts with the base branch; the rebase instruction went back to the worker. It costs no fix round. |
worker.merged | issue, reason, worktreeId | Delivery finished for this issue: the pull request was merged and the issue closed out. |
worker.held | issue, reason, worktreeId | Held for a human: protected paths, a secret-shaped file, a crossed layer boundary, or a gate the config demands. |
worker.blocked | issue, reason, worktreeId | Blocked: the fix rounds ran out, or a circuit breaker stopped the dispatch. |
worker.stuck | issue, reason, worktreeId | The worker stopped producing output for longer than the idle timeout and could not be revived. |
worker.abandoned | issue, reason, worktreeId | The pull request was closed without merging, or the branch disappeared. |
worker.failed | issue, reason, worktreeId | The delivery pass itself failed - a tool, a credential, an unexpected state. |
worker.waiting | issue, reason, worktreeId | Nothing to do at this head: the pass ended waiting for CI, a push, or a human. |
worker.reviewed | issue, reason, worktreeId | The review ran and the pass ended there, without merging. |
worker.fix-round | issue, reason, worktreeId | The pass ended by sending the worker back to work. |
pr.*
| Event | Carries | What it means |
|---|---|---|
pr.reviewed | issue, pr, head, status, blocking, provider, model, source | A review ran against a PR, with the verdict and who gave it. source marks a PR that came from GitHub intake. |
pr.merged | issue, pr, head, sha | The PR was squash-merged by the loop. |
pr.merge-refused | issue, pr, head, message | GitHub refused the merge — branch protection, a required check, a race with another merge. |
pr.smoke-failed | issue, pr, head, detail | The optional post-merge smoke failed. |
github-intake.*
| Event | Carries | What it means |
|---|---|---|
github-intake.merged | pr, reason | Merged by the loop. |
github-intake.held | pr, reason | Held for a human. |
github-intake.blocked | pr, reason | Out of fix rounds. |
github-intake.failed | pr, reason | The pass over it failed. |
github-intake.stuck | pr, reason | It stopped moving. |
github-intake.abandoned | pr, reason | Closed without merging. |
github-intake.waiting | pr, reason | Nothing to do at this head. |
github-intake.reviewed | pr, reason | Reviewed without merging. |
github-intake.fix-round | pr, reason | Sent back to its author. |
github-intake.nudged | pr, reason | Its author was nudged. |
github-intake.handed-off | pr, reason | It changed hands. |
release.*
| Event | Carries | What it means |
|---|---|---|
release.waiting | head, branch, commits, issues, detail | A batch is on the integration branch with nobody's approval behind it. Emitted once per head. |
release.promoted | head, branch, commits, issues, approvedBy | The approved batch reached the release branch. |
release.deployed | head, branch | The deploy command succeeded. |
release.failed | head, phase, detail | Promotion or deploy failed; phase says which. |
release.smoke-failed | head, detail | The post-deploy smoke failed. |
release.rolled-back | head, ok, detail | The rollback ran after a failed smoke; ok says whether it worked. |
intake.*
| Event | Carries | What it means |
|---|---|---|
intake.filed | issue, source, fingerprint, severity | An external alert became a tracked issue. |
maintain.*
| Event | Carries | What it means |
|---|---|---|
maintain.filed | issue, check, fingerprint | A maintenance check became a tracked issue. |
memory.*
| Event | Carries | What it means |
|---|---|---|
memory.recalled | issue, hits, docBridgeBefore, docBridgeAfter, approxCharsSaved, memoryDigest | Approved memory was recalled into a prompt, with what it cost and what it saved. |
memory.auto-promoted | ids, remembered, digest | Learnings the retro promoted into memory without a human in the middle (memory.autoPromote). |
memory.auto-promote-failed | error | The automatic promotion itself failed; the learnings stay in the ledger. |
provider.*
| Event | Carries | What it means |
|---|---|---|
provider.cooldown | provider, kind, until, source | A provider was put on cooldown after a quota/auth/timeout failure. source names the caller when not a dispatch. |
queue.*
| Event | Carries | What it means |
|---|---|---|
queue.claim-failed | issue, assignee, error | The tracker refused the claim that reserves an issue for this loop. |
security.*
| Event | Carries | What it means |
|---|---|---|
security.pii-detected | issue, source, kinds, count | Text that looks like PII was found before it reached a model. |
issue.*
| Event | Carries | What it means |
|---|---|---|
issue.paused | issue, kind, consecutive, reason | An issue was paused after consecutive failures; it needs a human before it is tried again. |
stage.*
| Event | Carries | What it means |
|---|---|---|
stage.paused | stage, reason, consecutiveFailures | A whole stage was paused after consecutive failures. |
agent.*
| Event | Carries | What it means |
|---|---|---|
agent.adopted | role, agent, detail | The retro's agent-improvement pass adopted a dated note into the agent's instructions; the eval passed. |
agent.rejected | role, agent, detail | Nothing was adopted: no installed agent for the role, or nothing to measure the change with. |
agent.needs-human | role, agent, detail | A proposal was recorded for a human: a critical role, too many lines, or an agent that is code. |
agent.reverted | role, agent, detail | The change was applied, the eval did not pass, and the file was put back exactly as it was. |
tuning.*
| Event | Carries | What it means |
|---|---|---|
tuning.applied | path, from, to, metric, reason | A tuning knob moved by itself after a retro, inside its declared range and justified by its declared metric. |
tuning.reverted | path, from, to, metric, reason | The same knob moved back, because the metric that justified the change got worse. |
cost-guard.*
| Event | Carries | What it means |
|---|---|---|
cost-guard.tripped | issue, reason | The cost circuit breaker stopped a dispatch that burned more usage than resilience.maxUsageDeltaPercent allows. |
max-duration.*
| Event | Carries | What it means |
|---|---|---|
max-duration.tripped | issue, reason | The time circuit breaker stopped a dispatch older than delivery.maxDispatchMinutes. |
Harness run events
A separate, older vocabulary: the run-level event log the harness keeps for a single verification run
(HARNESS_EVENT_TYPES), independent of the loop.
run.createdstate.transitionedcontext.attachedverification.completedartifact.recordedapproval.recordedauthorization.recordedsession.startedsession.resumedagent.turn.startedpolicy.evaluatedtool.approval.requestedtool.approval.recordedtool.requestedtool.execution.startedtool.recovery.recordedtool.blockedtool.completedtool.failedsession.ended