Every lifecycle event, and which ones fire

All twenty-four event names, what each means, and whether it has a firing site today.

Written By Dustin

Last updated About 3 hours ago

Event names are a closed set pinned in TOVIO's core. An unknown name on a manifest or a binding is refused with a typed error rather than quietly accepted, so a typo is caught at bind time instead of showing up as a plugin that silently never runs.

Being bindable and being fired are separate things. An event is dispatched only where the subsystem that owns the operation has a wired firing site. Binding an event that does not fire yet is legal and deliberate — it lets a manifest be authored, reviewed, and pinned ahead of the subsystem, so nothing needs editing when dispatch lands.

Snapshot and change lifecycle

EventMeaningFires today
pre-snapshotBefore the working copy is snapshotted into the active change. TOVIO's pre-commit, over an auto-snapshot rather than an index.Yes.
post-snapshotAfter a snapshot has been persisted. Observational.Yes.

Land

EventMeaningFires today
pre-landBefore a change lands onto a target lane or ref. The usual home for required checks.Yes.
post-landAfter a change has landed and refs advanced.Yes.

Sync

EventMeaningFires today
pre-syncBefore an outgoing sync opens its transport. An enforcing block aborts it before any network activity.Yes. A whole-repo sync has no changed paths, so a pre-sync binding must not set path filters — an empty path set never matches one.
post-syncAfter a sync completes, on success or failure. The transfer result rides the event subject.Yes. A failed transfer still fires, then the original error propagates; a post-sync block never masks it.

Conflicts

EventMeaningFires today
conflict-createdA typed conflict object was stored on a change. Observational — it does not gate.Yes, post-durability, for land, checkout, rewrite, descendant, split, absorb, agent-promote checkout, and isolation reconciliation. Not for previews, refused operations, carried conflicts, or orphans of a failed mutation.
resolve-requestedPlugin-assisted conflict resolution was explicitly asked for.Yes, but only on the fallback path. tovio resolve --ai first checks .tovio/config ai.provider: with a provider configured it uses the built-in LLM resolver and a bound resolver plugin never fires. Only with ai.provider unset does it reach the plugin seam. With neither, the conflict is left unchanged and the no-resolver error is returned.

Review and proposals

EventMeaningFires today
proposal-createdA Forge proposal was created. Metadata-safe input by default.Yes, Forge-side.
review-submittedA review was submitted — approve, request changes, or comment.Yes, Forge-side on approve and request-changes. Advisory only.

Permissions and policy

EventMeaningFires today
policy-changedA policy declaration was added, modified, or removed.Yes, once per policy set, remove, or web-auth. Mid-commit secret-scan remediation does not fire it.
access-grantedAn identity was granted read access to a protected path.Yes, when the grant is recorded. The re-wrap itself is prospective, applied on the next commit of a matching path.
access-revokedAn identity was revoked from a protected path.Yes, after the rotate and re-seal.

Locks

EventMeaningFires today
lock-acquiredA file or asset lock was acquired.Yes.
lock-releasedA lock was released.Yes, only when a lock was actually held.

Agents

EventMeaningFires today
agent-session-startedA scoped capability token was issued and bound to an agent session.Yes.
agent-scope-exceededAn agent attempted an operation outside its token's scope. A security event.Yes, and it is observational — it observes an already-denied operation and cannot un-deny or mask it.

Git bridge

EventMeaningFires today
git-importedA Git repository was imported.Yes, after the refs advance.
git-exportedTOVIO history was exported to a Git remote.Yes, after the push succeeds. A purely local export stays silent.

Release and distribution

EventMeaningFires today
release-createdA signed release marker was created.No.
archive-createdA repository archive object was created.No.
bundle-createdA portable transport bundle was created.No.
bundle-appliedA bundle was applied to a repository.No.

Those four have no backing subsystem yet — no command, object kind, or transport format — so nothing dispatches them. They remain bindable placeholders.

The one request-and-response event

transcript-parse is unlike everything above. Every other event is observe-or-block: TOVIO announces something 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.

It exists so per-runtime transcript adapters can be written by anyone. Three things make it safe:

  • Its grant is empty and none is grantable. A manifest declaring transcript-parse must request no capability at all; one that asks for even a single capability is refused at validation, naming the offender. The guest runs with an empty grant no matter what a binding approves. TOVIO reads the file itself, first-party and in-process, because transcript files live outside the repository next to ~/.aws and ~/.ssh. Only parsing is sandboxed.
  • It receives nothing that locates the bytes — no path, no handle, no repository root.
  • It cannot fail a commit. Mode and required are inert here. A refusal, timeout, or undecodable answer makes TOVIO fall through to its built-in adapters silently. Built-ins are consulted first; yours is reached only for bytes none of them claims.

It fires today during tovio commit for a transcript no built-in adapter recognises — in practice an explicit --session-from, or a file in the open-transcript drop directory.

Post-event semantics

Post-events fire after their operation is already durable. An enforcing binding on a post-event cannot undo it — the commit is committed, the ref has advanced. TOVIO still runs the binding and audits the result, but the failure is diagnostic. If you need to gate, bind the matching pre-event.