Create and move tags

tovio tag, why a tag is set once, and what --force actually costs.

Written By Dustin

Last updated 25 minutes ago

tovio tag                          # list every tagtovio tag v1.0.0                   # tag the current lane tiptovio tag v1.0.0 blake3:a3f7b2...  # tag a specific commit

A tag is a fixed, named pointer to a commit. The optional second argument is a commit address — blake3:<hex> or the bare hex — and it defaults to the current lane's tip. It is not a lane name: passing one is TVO-TAG-002.

Tags are set once

Re-pointing an existing tag at a different commit is refused with TVO-TAG-001. This is not a safety prompt you can dismiss — it is the behaviour of the object, and the receiving side of a sync enforces it too, so a moved tag cannot be smuggled in over the wire.

Re-tagging the same commit is not an error. It is idempotent and reports the tag unchanged, so a repeatable release script can run twice safely.

tovio tag v1.0.0 blake3:9c14ef... --force

The override. Locally you are the tag authority, so it succeeds and is written to the op-log. Over the wire the relay demands a verified tag:force authorization proof and writes an audit entry before it will accept the move. --force requires a tag name; it is not a bulk operation.

Why the asymmetry

A tag that moves silently is a supply-chain problem: anyone who verified v1.0.0 yesterday verified something else. Making the re-point explicit, authorized and audited is the entire point.

What can go wrong

  • TVO-TAG-001 — the tag exists and points somewhere else. Pick a new name, or force it.
  • TVO-TAG-002 — the target is not a valid commit address. tovio log prints them.

Undo does not move a tag back

This is the one place tovio undo will not save you. The op-log snapshot records lanes, the current change and the working copy — it does not record tag state. Undoing a tag --force reports success and leaves the tag where the force put it.

So re-point a tag deliberately, and if you get it wrong, fix it forward with another explicit --force at the right commit rather than reaching for undo. Check where a tag actually points with tovio tag before you rely on it.

Tags are not lanes

Lanes are mutable CRDT references that converge under concurrent writes. Tags are immutable and refuse to converge. They are different objects with different rules, and the difference is deliberate.