Docs

Reference

Events

Every event the Vinaya process writes to the Log: the header on every line, the ten families and all their fields, how each maps to a generic event, and the rules for reading them back.

Partial
10 families
Header schema 3
Generic mapping
Reference

Header fields

These fields are on every line. The harness fills them; a caller cannot set them.

FieldTypeSince schemaMeaning
kindfamily nameallOne of dispatch, dev_review_loop, forge_write, gate, operation, usage, role_attempt, handoff, effect, custom. Closed list. command and tokens are refused by name (they became operation and usage).
eventstringallThe event within the family.
duration_msnumber ≥ 0, optionalallHow long the act took. On gate · summary, the run's total time.
payload{}allAlways an empty strict object. Families carry their content in named fields.
meta.schema1 | 2 | 3allHeader version. New lines are always 3; 1 and 2 exist so old lines keep parsing.
meta.tsstringallISO 8601, UTC, millisecond precision.
meta.run_idstring, ^[A-Za-z0-9_.-]{1,128}$allVINAYA_RUN_ID, else a random id generated once per process. A dispatched child inherits its parent's run_id.
meta.seqinteger ≥ 0allPer-process counter from 0. Readers sort by it, never by file position.
meta.repostring | nullallowner/name from the origin remote; null when it cannot be resolved.
meta.vinayastringallThe CLI version that wrote the line.
meta.doctrinestringallaeg-root@<sha> for a source checkout, the package version for a bundle, unknown when git cannot be reached.
meta.hosthook | ci | cli | loopallci when GITHUB_ACTIONS is set; else hook or loop from VINAYA_HOST; else cli.
meta.machinestringallsha256 of the hostname, never the name.
meta.event_idstring, not empty2Stable identity of this event, generated once per write. The key for removing duplicates.
meta.process_idstring, not empty2Opaque per-process id, distinct from run_id.
meta.actor_idstring | null2Opaque, unchecked actor claim from VINAYA_ROLE. Not checked against the role list. Empty or absent reads null.
meta.lineage.runstring | null2VINAYA_RUN; the loop driver sets it to its loop_id. Defaults to the process's own run_id.
meta.lineage.attemptinteger | null2VINAYA_ATTEMPT; role dispatch sets it to the dispatch attempt. Else null.
meta.lineage.parentstring | null2VINAYA_PARENT_EVENT: the event_id this event continues. Planned; written as null.
meta.input_versions.manifest_version2 | null, optional2Generation of the review-input manifest. New lines write 2; older lines may leave it out. Any other number is rejected.
meta.input_versions.objectives_versionstring | null2Objectives version, from the review-input manifest.
meta.input_versions.brief_hashstring | null2Digest of the brief.
meta.input_versions.ruling_ordinalinteger | null2Ruling ordinal.
meta.input_versions.pause_bound_ruling{ rulingId, pauseId, contentDigest } | null, optional2The ruling bound to a pause; each part a non-empty string. Older lines may leave it out.
meta.input_versions.policy_digeststring | null2Digest of the review policy.
meta.provenanceparent_attributed | env_correlated | self_reported | unavailable2How far the attribution can be trusted. env_correlated when VINAYA_ROLE or VINAYA_TASK is set, else unavailable, and always unavailable when subject.issue came from the branch. Only a caller that asserts it can set a stronger value. See Redaction and trust.
meta.work.refstring | null3The unit of work, opaque and never parsed. VINAYA_WORK_REF, else subject.issue as text, else null.
meta.work.repostring | null3Same value as meta.repo.
meta.work.changestring | null3The pull request, as text, when VINAYA_PR is set; else null.
meta.work.revisionstring | null3The commit checked (git rev-parse HEAD), on gate events; else null.
meta.flow.idstring | null3The way of working. VINAYA_FLOW; unset reads vinaya.
meta.flow.versionstring | null3VINAYA_FLOW_VERSION, else null.
meta.runtimestring | null3VINAYA_RUNTIME, else null.
meta.sourcestring | null3VINAYA_SOURCE, else null.
subject.issueinteger | nullallVINAYA_TASK; else the Issue the checked-out branch names (task/issue-<n> or task/<tranche>/<n>, confirmed with the forge; in CI, GITHUB_HEAD_REF); else null.
subject.printeger, optionalallVINAYA_PR, a positive integer. The loop driver sets it once a pull request exists.
subject.shastring, optionalallGate events only: the 40-hex HEAD of the working directory. Absent when it cannot be resolved. In pull-request CI this is the merge commit, not the pull request's head.
subject.roleplanner | developer | code-reviewer | security | principal | archivist | architect | unattributedallVINAYA_ROLE when it is one of the roles, else unattributed. A caller never declares its own.
subject.roundinteger, optionalallVINAYA_ROUND.
subject.objectives_versionstring, optionalallsha256 hex of the objectives block.

input_versions is filled only when a caller passes it: the loop's reviewer dispatch passes it from its review-input manifest. Otherwise every part is null.

Schema 3 is a new version, not extra fields on 2, so a server that knows only 1 and 2 keeps a schema 3 line as an unknown-version record instead of rejecting it.

Families at a glance

FamilyEventsProcess part
dispatchdispatched, outcome_received, dispatch_failedExecuting (any dispatched role)
dev_review_loop15 eventsExecuting
forge_writevalidated, refused, writtenNone; nothing writes it
gatesummary, checkedGates
operationcompletedHarness (an operation, not a process part)
usageobservedExecuting
role_attemptattemptedExecuting
handoffraised, resolvedExecuting
effectverified (plus attempted, observed, which nothing writes)Executing
customrecordedDeclared by your team

Which code may write each family is enforced by tests; see Redaction and trust.

dispatch

A role dispatch, seen from the parent. In the loop, Developer, Code Reviewer and Security turns are dispatched this way; vinaya dispatch <role> reaches it for any role.

EventWhen it firesMain fieldsGeneric family
dispatchedA role is about to be launchedprompt_hashexecution.started; for reviewer roles also review.requested
outcome_receivedThe child exited cleanlyoutcome, usageexecution.completed
dispatch_failedA refusal before launch, a crash at launch, a timeout, or a non-zero exitreason, usage_limit, usageexecution.failed

dev_review_loop

The Developer and reviewer loop of one task. Every event carries loop_id (string). Process part: Executing. See The loop.

EventWhen it firesMain fieldsGeneric family
loop_startedA loop beginstask, policyrun.started
round_startedA round beginsround, base_headdecision.recorded (round outcome, paired with round_ended)
gate_result_readThe loop reads the gate result, on every read, including the second read after a re-askround, head, green, confidence fieldsevidence.completed
verdicts_readThe round's reviewer verdicts are readround, head, all_approve, blockers, findings, reviewersreview.completed
findings_comparedThis round's findings are compared with the last round'sround, open, resolved, new, recurringreview.finding_recorded
stop_condition_metThe loop decides to stopround, conditionrun.completed / failed / exhausted
pausedThe loop pausesround, reason, reason_coderun.paused
resumedA paused loop resumes, once, right after the ruling is consumedround, byrun.resumed
cancelledA paused loop is cancelled, onceround, byrun.cancelled
unpushed_work_resumeThe driver resumes, in the same round, a Developer that stopped without pushinground, branch, detailNot mapped
round_endedA round endsround, heads, change size, wall_ms, outcomedecision.recorded (round outcome)
journal_finalizedThe loop's journal closesrounds, times, final_head, resultrun.completed / failed / exhausted
infrastructure_retryOnce per retry episode, after its last attemptround, failure_kind, attempts, outcomerun detail
driver_heartbeatAt most every five minutes while a driver process is alive; only the driver writes ittask, pr, round, phaseLiveness, for Mission Control
driver_exitedExactly once per driver exit, on every path; the heartbeat stops firsttask, reason, last_decision, exit_code, error_classrun.completed / failed / exhausted

Round assessment builds loop_started, round_started, gate_result_read, verdicts_read, findings_compared, stop_condition_met, paused, round_ended and journal_finalized. The loop driver writes them, and writes resumed, cancelled, unpushed_work_resume, infrastructure_retry, driver_heartbeat and driver_exited itself. The driver's own round assessment and live check also build stop_condition_met, paused, round_ended and journal_finalized.

forge_write

Kept only so lines posted long ago still parse. Nothing writes this family, and all three events are exempt from the producer test. The Log is never written to the forge. Process part: none. Generic family: none.

EventWhen it firesMain fieldsGeneric family
validatedA payload passed its schema checknone beyond the shared fieldsNone
refusedThe write failed or was refusedreason (string)None
writtenThe forge accepted the writecomment_ids (string[]): comment ids the forge returnedNone
Shared fieldTypeMeaning
oppr.create | pr.comment | pr.body.replace | pr.refreeze | issue.create | issue.edit | issue.comment | milestone.create | milestone.edit | milestone.close | label.add | label.removeThe forge operation.
target.issueinteger, optionalTarget Issue.
target.printeger, optionalTarget pull request.

gate

One run of the checks. Process part: Gates. Every gate event carries subject.sha when it can be resolved. A run writes one summary plus one checked for each check that did not pass. See Gates.

EventWhen it firesMain fieldsGeneric family
summaryOnce per run, after all checksran, passed, failed, skipped, failed_checks, duration_msgate.evaluated
checkedA check ends with an outcome other than pass or skip, including a check stopped by SIGINT or SIGTERM (cancelled)check, outcome, reason, input_fingerprintgate.evaluated

operation

A normalized operation or tool call: from the CLI, the broker, the Operator's tools, vinaya log emit, or sandbox setup. One event. Process part: Harness.

EventWhen it firesMain fieldsGeneric family
completedAn operation ends (see the table below)operation, target, result, error_class, field_nameshuman.intervened (Operator acts)
FieldTypeMeaning
operationstringOperation name, below.
targetstring | nullWhat it acted on.
resultok | error | refused | timeout | cancelled | unavailableOutcome.
error_classstring | nullError class or code.
field_namesstring[] (at most 20, each at most 64), optionalThe fields a refused custom event concerned. Never values.

Operations written:

operationWhentarget, result, error_class
cli_commandEvery vinaya <command> exittarget: the command name from a fixed list (help, unknown, log selftest, task run, …). result: ok (exit 0), refused (exit 2), error (other). error_class: the exit code as text.
authenticate-invocationA Worker or Operator invocation is authenticatedtarget: task:<n>. ok, or refused with the error class.
The request's own operation nameThe broker checks an effect request's grant, target or replayFrom the request; ok or refused.
task_cancelThe Operator's cancel handler runs—
task_resumeThe Operator's resume handler runs—
log.emitA custom event was refusedtarget: the name if it is name-shaped, else null. refused. error_class: the refusal reason. field_names set.
claude-sandbox-confinementClaude's sandbox could not be set uptarget: the missing tools. unavailable.
linux-sandbox-probeThe Linux sandbox probe failedtarget: the agent. unavailable.
log.selftestvinaya log selftest sends its test event straight to the server, not through the normal pathA marker so readers leave self-test traffic out.

cli_command does not record vinaya log send, a process ended by a signal, or a parent that hands off to the author repository's own source.

usage

Token use of one dispatched turn, written once per attempt on every exit path. Process part: Executing.

EventWhen it firesMain fieldsGeneric family
observedA dispatched turn ends, however it endsmodel, source, semantics, units, unknown_reasonexecution.usage
FieldTypeMeaning
modelstring | nullModel.
sourcestringThe vendor (claude, codex, gemini), or claude-transcript when read from Claude's session transcript.
semanticscumulative | deltaA dispatch always writes cumulative.
units.inputnumber ≥ 0 | nullInput tokens; null when unknown, never 0.
units.outputnumber ≥ 0 | nullOutput tokens.
units.cachenumber ≥ 0 | nullCache tokens (Claude: creation plus read; Codex: cached input).
unknown_reasonstring | nullWhy the units are unknown. Gemini always reports null units with a reason.

role_attempt

The normalized outcome of one role attempt. Process part: Executing.

EventWhen it firesMain fieldsGeneric family
attemptedOnce per dispatch attempt; once more when a reviewer or security report fails to validate (incomplete or infrastructure_failed, with usage: null)actor, attempt, effect_id, model, outcome, usageexecution.completed / failed / cancelled
FieldTypeMeaning
actorstring | nullOpaque actor; a dispatch writes the vendor.
attemptinteger | nullAttempt counter within its scope.
effect_idstringSame as on the matching dispatch line.
modelstring | nullThe runtime's receipt, else the requested label.
outcomecompleted | incomplete | infrastructure_failed | cancelled | timed_out | capability_refusedThe classified outcome.
usage{ input, output } | nullSame shape as dispatch_failed.usage.

handoff

A hand-off to a human, when the loop pauses. Process part: Executing. See Pauses and rulings.

EventWhen it firesMain fieldsGeneric family
raisedThe escalation record and the paused state are durably written; not again for an idempotent rerun of the same pauseclass, reason, requested_decisionhandoff.raised, human.intervened
resolvedA resume decision is durably consumed; never for cancel, never twice for one escalationclass, reason, resolution, resolved_byhandoff.resolved, human.intervened
FieldTypeOnMeaning
classauthority | strategy | productbothKind of hand-off, derived from the pause reason.
reasonstringbothThe pause reason.
requested_decisionstring | nullraisedThe decision asked for, cleaned the same way as the public pause comment.
resolutionstring | nullresolvedThe recorded decision.
resolved_bystring | nullresolvedWho authenticated it.

effect

The final outcome of a governed external write. Pause and escalation comment posts go through it. Process part: Executing.

EventWhen it firesMain fieldsGeneric family
verifiedOnce per write call, including an idempotent replayeffect_id, target, outcomeeffect.committed / reconciled
attemptedNothing writes it; kept in the schemaeffect_id, targetNot mapped
observedNothing writes it; kept in the schemaeffect_id, target, outcomeNot mapped
FieldTypeMeaning
effect_idstringThe key of the write in the control store; the same across crash, retry and replay.
target.kindstringThe operation of the effect.
target.refstringThe target of the effect.
outcomesuccess | failure | uncertainfailure when the post threw; uncertain when reconciliation was ambiguous or the record was corrupt.

custom

An event your team declared in logs.events in vinaya.config.json, emitted by Vinaya code or by vinaya log emit <event>. Valid only under a schema 3 header. It sits outside the Vinaya process parts. See Custom events for the declaration rules and refusals.

EventWhen it firesMain fieldsGeneric family
recordedA declared event is emitted with valid fieldsname, fieldsNamespaced process event
FieldTypeMeaning
namestring ≤ 64, ^[a-z][a-z0-9_]*\.[a-z][a-z0-9_.]*$The declared name.
fieldsrecord of field name (^[a-z][a-z0-9_]*$, ≤ 64) → string ≤ 500 | finite number | boolean; at most 20The values, flat.

Generic mapping

Vinaya's families are named for the process's own acts. Each maps to the generic families every process must report; see Process contract.

Family · eventGeneric family
dev_review_loop · loop_started, resumed, paused, cancelledrun.started / resumed / paused / cancelled
dev_review_loop · stop_condition_met, journal_finalized, driver_exitedrun.completed / failed / exhausted
dev_review_loop · driver_heartbeatLiveness, for Mission Control
dev_review_loop · round_started, round_endeddecision.recorded (round outcome)
dispatch · dispatched, outcome_received, dispatch_failedexecution.started / completed / failed
role_attempt · attemptedexecution.completed / failed / cancelled
usage · observedexecution.usage
gate · summary, checkedgate.evaluated
dev_review_loop · gate_result_readevidence.completed
dev_review_loop · verdicts_read, findings_comparedreview.completed, review.finding_recorded
handoff · raised, resolvedhandoff.raised / resolved, human.intervened
effect · verifiedeffect.committed / reconciled
operation · completedhuman.intervened (Operator acts)
dev_review_loop · infrastructure_retryrun detail
custom · recordedNamespaced process event

Not in the mapping: dev_review_loop · unpushed_work_resume, all of forge_write, and effect · attempted and observed.

Generic families without an event of their own

Reading rules

RuleWhat it says
OrderSort a process's lines by meta.seq, never by file position.
IdentityAn event is its meta.event_id; a schema 1 line is <run_id>:<seq>. The same event seen in two places is one event.
Liveness (ten-minute rule)For one Issue's dev_review_loop lines in time order: running when the newest line is under ten minutes old and no driver_exited is newer; finished, paused or exited when the newest line is a driver_exited (its reason says which); stale, presumed dead when the newest line is over ten minutes old with no driver_exited. Ten minutes is twice the heartbeat interval. meta.machine says where it runs.
Unknown, never zeroA field a line's schema never had reads unknown with a reason, never a default. null usage units are unknown, never 0.
Low trustA line from a CLI older than 0.33.0, or with an unreadable meta.vinaya, is low trust whatever its header says.
Passing checksA passing or skipped check has no checked line; it is only counted in summary.
UsagePer run and model, only the last cumulative observation counts; delta observations add up; never add one kind to the other. A dispatch line and a role_attempt line with the same effect_id are one attempt.
Finding idsA finding id is stable only within one round's comment. Read recurrence from findings_compared.recurring, never from an id appearing again.
EffectsExpect one effect · verified per forge write.
Self-testLeave operation · log.selftest out of real telemetry.
Unknown versionsA meta.schema other than 1, 2 or 3 is kept word for word as an unknown-version record, not a row.
Not control stateThe Log never authorizes, resumes or recovers a run.

What's next