Lifecycle events¶
Plugins run at named lifecycle events. The set below is the full list of events TOVIO defines;
all names are pinned in tovio-core's closed LifecycleEvent enum, so an unknown event on a
manifest or binding is rejected with a typed error rather than silently accepted.
An event is only fired by the subsystem that owns the corresponding operation. Event names may be legal to declare and bind before their firing site is wired. Sync, Forge review, locks, and agent sessions now exist, but that does not imply every corresponding lifecycle event is dispatched; the status table below records firing-site availability explicitly.
Snapshot & change lifecycle¶
pre-snapshot¶
Fires before TOVIO snapshots the working copy into the active change.
- Replaces
pre-commit. TOVIO has no staging area; the working copy auto-snapshots into the active change, so the architectural event ispre-snapshot. - Typical uses: formatters (as
transform), lint rules (ascheck), secret scanners (metadata-only), local-only advisory checks. - Common capabilities:
read_metadata,read_clear_paths(narrow globs),propose_transformfor formatters. - What blocks: a
failfrom an enforcing binding prevents the snapshot from being taken.
post-snapshot¶
Fires after a snapshot has been persisted into the active change. Observational — cannot undo the snapshot.
- Typical uses: telemetry, indexers, background analyzers, notifier delivery.
- Common capabilities:
read_metadata,emit_audit. Enforcing bindings are unusual here since the snapshot has already happened.
Sync¶
pre-sync¶
Fires before an outgoing sync (fetch/push/mirror) opens its transport.
- Typical uses: connectivity gates, org network policy, off-hours enforcement.
- Common capabilities:
read_metadata,block_operation,emit_audit. - What blocks: an enforcing
failaborts the sync before any network activity.
post-sync¶
Fires after a sync completes (successful or failed). The result status is part of the payload.
- Typical uses: notifiers, dashboards, follow-up automation.
- Common capabilities:
read_metadata,emit_audit.
Land¶
pre-land¶
Fires before a change is landed onto a target branch/ref.
- Typical uses: required checks (license, dependency, policy), build-check bridges, org-wide compliance.
- Payload includes: target branch/ref, change id, changed paths (with redacted metadata for protected paths).
- Common capabilities:
read_metadata,read_clear_paths,block_operation,emit_audit. - What blocks: any enforcing
fail; onrequiredbindings, alsoerror/skipped/unsupportedand malformed output.
post-land¶
Fires after a change has been landed and refs advanced.
- Typical uses: deploy triggers, changelog updates, downstream notifiers, index refresh.
- Common capabilities:
read_metadata,emit_audit.
Conflicts¶
conflict-created¶
Fires when a typed conflict object is stored on a change (a merge or land computed a stored conflict, per TOVIO's "conflicts as data" model).
- Typical uses: trackers, notifiers, first-pass triage helpers.
- Common capabilities:
read_metadata,emit_audit. - Note: this event is observational; it does not gate the operation.
resolve-requestedis the seam for plugin-driven resolution.
resolve-requested¶
Fires only when a user, agent, or configured operation asks for plugin-assisted conflict
resolution. This is the seam behind tovio resolve --ai.
- Typical uses: AI or heuristic conflict resolvers.
- Common capabilities:
read_metadata,read_clear_paths(for the conflicted paths),propose_resolution. - Behavior: if no resolver plugin is configured,
tovio resolve --aileaves the conflict unchanged and returns a no-resolver typed error. Accepted resolutions are applied through the normal conflict-resolution path.
Review & proposals¶
proposal-created¶
Fires when a Forge proposal is created.
- Typical uses: first-pass gates that inform reviewers, changelog validators, ticket-linkage checks.
- Payload: metadata-safe by default. Protected paths are redacted; cleartext requires
explicit
read_clear_pathsand policy approval. - Where it runs: typically Forge-side, subject to server-side execution or policy-approved attestation.
review-submitted¶
Fires when a review (approve / request-changes / comment) is submitted on a proposal.
- Typical uses: required-reviewer checks, sign-off validators, review-completeness gates.
- Common capabilities:
read_metadata,emit_audit.
Permissions & policy¶
policy-changed¶
Fires when a policy manifest is updated — a declaration added, modified, or removed.
- Typical uses: compliance audits, policy-diff notifiers, escalation triggers.
- Common capabilities:
read_metadata,emit_audit.block_operationis used sparingly (the KA already enforces the write) — most consumers observe.
access-granted¶
Fires when an identity is granted read access to a policy-protected path (a re-wrap is issued).
- Typical uses: access reviews, notifiers, downstream provisioning.
- Common capabilities:
read_metadata,emit_audit.
access-revoked¶
Fires when an identity is revoked from a policy-protected path (a rotate + re-wrap is performed).
- Typical uses: offboarding automation, revocation notifiers, evidence collection.
- Common capabilities:
read_metadata,emit_audit.
Locks¶
lock-acquired¶
Fires when a file or asset lock is acquired.
- Typical uses: collaboration notifiers, asset-editing coordination for binary workflows.
- Common capabilities:
read_metadata,emit_audit.
lock-released¶
Fires when a lock is released.
- Typical uses: notifier delivery, downstream queue triggers.
- Common capabilities:
read_metadata,emit_audit.
Agents¶
agent-session-started¶
Fires when an agent session is started — a scoped capability token has been issued and bound to a session.
- Typical uses: session logging, session-level rate limits, downstream provisioning.
- Common capabilities:
read_metadata,emit_audit.
agent-scope-exceeded¶
Fires when an agent attempts an operation outside its capability token's scope. Security event.
- Typical uses: SIEM forwarding, incident triggers, token revocation automation.
- Common capabilities:
read_metadata,emit_audit,block_operation. - What blocks: the attempted operation is already blocked by the token check itself; an enforcing binding here can additionally block a follow-up recovery action if policy requires it.
Release & distribution¶
release-created¶
Fires when a signed release marker is created for a set of changes.
- Typical uses: deploy pipelines, external release-notes generators, evidence generators.
- Common capabilities:
read_metadata,emit_audit.
archive-created¶
Fires when a repository archive object is created.
- Typical uses: retention automation, off-site copy triggers, compliance evidence.
- Common capabilities:
read_metadata,emit_audit.
bundle-created¶
Fires when a portable .vbundle transport bundle is created.
- Typical uses: air-gap transfer workflows, external-audit hand-offs.
- Common capabilities:
read_metadata,emit_audit.
bundle-applied¶
Fires when a .vbundle is applied to a repository.
- Typical uses: provenance checks on the applying side, downstream trigger.
- Common capabilities:
read_metadata,emit_audit,block_operation(rarely).
Git bridge¶
git-imported¶
Fires when a Git repository is imported via the Git bridge.
- Typical uses: import validators, provenance recording, changelog seeding.
- Common capabilities:
read_metadata,emit_audit.
git-exported¶
Fires when TOVIO history is exported to a Git remote via the Git bridge.
- Typical uses: downstream Git-side automation triggers, mirror validators.
- Common capabilities:
read_metadata,emit_audit.
Transcript adapters¶
transcript-parse¶
The one request/response event. Every other event on this page is observe-or-block: TOVIO tells your plugin something happened and reads a verdict. This one asks a question — here are an AI agent transcript's raw bytes, what turns are in them? — and uses the answer to build the commit's observed session record.
It exists so per-runtime transcript adapters can be written by anyone. TOVIO ships adapters for
claude-code, codex, and the open transcript format; the long tail is meant to be your work, not ours.
- Typical uses: parsing a runtime TOVIO does not ship an adapter for.
- Capabilities: none, and none is grantable. A manifest declaring
transcript-parsemust request an empty capability set — a package asking for even one is refused at install, naming it — and the guest is run with a completely empty grant no matter what a binding approves. That is the whole point: reading the transcript is done by TOVIO itself, first-party and in-process, because transcript files live outside the repository next to~/.awsand~/.ssh, and a plugin capability that could reach them would break the repo-bounded model every other capability on this page respects. Only parsing — a pure bytes-to-turns function — is sandboxed.
The payload is {"abi": "v1", "runtime": "…", "source_name": "…", "text": "<the transcript>"} — bytes
and a display name, no path and no handle. Return your turns as a proposed_action of kind
transcript-turns whose payload is the JSON adapter output (prompt_index, turns[], model, usage,
meta, diagnostics). Status pass (or warning) means "I parsed this"; skipped / unsupported means
"not my format", which is a perfectly ordinary answer.
Three things you cannot do, by construction rather than by check: name a content address, stamp a redaction result, or set the source digest. TOVIO computes all three, and the adapter id and version recorded in the session come from your validated manifest, not from your output.
TOVIO's built-in adapters always go first. Yours is consulted only for bytes none of them claims. And
the fall-through is total: if your adapter errors, times out, refuses, or returns something undecodable,
TOVIO silently carries on as though it were not installed. mode and required are inert here — an
adapter cannot fail someone's commit.
Payload envelope¶
All events share the same envelope shape (see Write a plugin for the full example):
{
"api_version": "v1",
"schema_version": "v1",
"execution_id": "plgexec_…",
"event": "pre-land",
"mode": "enforcing",
"plugin_id": "com.example.…",
"actor": { "kind": "human", "id": "did:tovio:…" },
"repo": { "id": "…", "name": "…" },
"target": { "change_id": "chg:…", "branch": "…" },
"capabilities": { /* effective set — every field present */ },
"redaction": "metadata_only",
"payload": [ /* opaque, event-specific bytes */ ]
}
The payload bytes are event-specific and marshalled across the sandbox boundary; tovio-core
does not interpret them. Redaction is metadata-only by default across every event — cleartext
of a protected path is only ever included when a plugin has been granted read_clear_paths for
that path and the operation's policy approves it.
For a change-shaped event the payload is {"changed_paths":[{"path":…,"protected":…}]}. Each record
carries two more optional keys on the content-scan path: content, the path's clear text, present only
for an unprotected path the effective read_clear_paths grant admits; and skipped, a marker
(too-large, binary, payload-cap, non-utf8) saying the host held that path's clear bytes and
deliberately withheld them. A path with neither key was never marshalled with content at all, so a plugin
that reads only content cannot tell a file it never saw from a file with nothing to read — check
skipped too. Events whose
subject is not a changed-path set (e.g. access-revoked's revoked identity, policy-changed's
changed patterns, agent-session-started's token scope, post-sync's result) additionally carry a
top-level subject object — a plain, non-secret JSON value naming just that subject
({"changed_paths":[…], "subject": {…}}). It is deliberately kept out of changed_paths (a DID or a
policy glob is not a repo path, and abusing that field would corrupt binding path-filter matching and
per-path redaction). The key is optional and additive — a plugin that does not need it can ignore it,
and the input schema version is unchanged.
Which events fire today¶
| Event | Fired by | Availability |
|---|---|---|
pre-snapshot, pre-land |
tovio-core + tovio-cli |
Fires today. |
post-snapshot, post-land |
tovio-core + tovio-cli |
Fires today (post-event semantics — see below). |
resolve-requested |
tovio-cli (behind tovio resolve --ai) |
Fires today when a resolver plugin is bound. |
proposal-created |
tovio-forge |
Fires today Forge-side — a metadata-safe input hook on the native forge; the hosted adapter runs registered proposal-created plugins. |
review-submitted |
tovio-forge |
Fires today Forge-side on a review approve / request-changes — a metadata-safe input hook (carrying the decision in subject) on the native forge; the hosted adapter runs registered review-submitted plugins. Advisory only. |
conflict-created |
tovio-core + tovio-cli |
Fires post-durability for implemented land, checkout, rewrite/descendant/split/absorb, agent-promote checkout, and isolation-reconciliation conflict edges. It does not fire for previews, refused operations, carried conflicts, or orphan objects from a failed mutation. |
pre-sync |
tovio-cli sync |
Fires today before an outgoing tovio sync opens its transport — a required enforcing block aborts the sync before any network activity. A whole-repo sync has no changed paths and no single target, so a pre-sync binding must not set path filters (an empty changed-path set never matches one). |
post-sync |
tovio-cli sync |
Fires today after an outgoing sync completes — on success or failure (a failed transfer still fires, then the original sync error propagates; a post-sync block never masks it). The transfer result / counts ride the event subject. |
policy-changed |
tovio-cli policy commands |
Fires today, once per tovio policy set / remove / web-auth. The changed patterns ride the subject (the mid-commit secret-scan remediation does not fire it). |
access-granted |
tovio-cli access grant |
Fires today when a grant is recorded. The re-wrap is prospective (applied on the next commit of a matching protected path), not at grant time. The grantee DID + attributes ride the subject. |
access-revoked |
tovio-cli access revoke / device revoke |
Fires today after the rotate + re-seal (a new commit exists). The revoked identity + reseal result ride the subject. |
lock-acquired, lock-released |
tovio-cli lock commands |
Fires today on tovio lock / tovio lock release (a release fires only when a lock was actually held). The lock path is the changed path; kind / holder / ttl ride the subject. |
agent-session-started |
tovio-cli agent new |
Fires today when a scoped capability token is issued and bound to an agent. The agent DID + token scope ride the subject. |
agent-scope-exceeded |
tovio-cli token gates |
Fires today (security) when a --token commit or read is denied for an out-of-scope path / branch / op. Observational — it observes an already-denied operation and never gates (its verdict cannot un-deny or mask the token denial). |
release-created, archive-created, bundle-created, bundle-applied |
(no subsystem yet) | No backing subsystem exists — no command, object kind, or transport format — so nothing fires. (The audit archive and CI binary archives are unrelated and do not satisfy these.) They stay bindable placeholders until those subsystems are built. |
git-imported, git-exported |
tovio-cli git bridge |
Fires today via tovio git bridge — git-imported after the live-repo refs advance, git-exported after the remote push succeeds. A direct tovio git import also fires git-imported; a plain local tovio git export <dir> stays silent (the event means "exported to a Git remote"). |
transcript-parse |
tovio-cli observed capture |
Fires today during tovio commit, for a transcript whose format no built-in adapter recognizes — in practice an explicit tovio commit --session-from <path>, or a file in the open-transcript drop directory. Request/response, not a gate: the answer is used or ignored, never obeyed, and any failure falls through to the built-ins silently. Transcript discovery stays first-party, so an adapter for a runtime TOVIO does not know the directories of is reached by naming the file, not by auto-discovery. |
Declaring one of the not-yet-fired events in a manifest today is legal — it just means the plugin won't be called until its subsystem ships. This is deliberate: it lets manifests and bindings be authored, reviewed, and pinned ahead of the subsystem, so nothing has to be edited when the event starts dispatching.
Post-event semantics: no rollback¶
Post-events (post-snapshot, post-land, and the other post-* names) fire after their
underlying operation is already durable. That means an enforcing binding on a post-event cannot
undo the operation — the commit is committed, the ref has advanced. TOVIO still runs the
binding, and if it fails:
- The signed audit chain records the block exactly as it does for a pre-event.
- Advisory bindings surface findings and never gate.
- A required, enforcing binding that fails returns a typed
TVO-PLUGIN-013error with exit class12(POST_EVENT_FAIL), so CI or orchestration observes the failure. The operation itself stays in place; any remediation is a follow-up change.
In practice, most post-event bindings should be advisory — they exist to observe, notify, or kick off downstream work. Reserve enforcing/required on a post-event for the cases where you genuinely need CI-visible signal that "the op happened, but something the org cares about is broken."
Last reviewed September 9, 2026
Suggest an improvement to this page Not for security reports — see disclosure