Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Share reviews across a team

A review is a line in a file in your repository. So the question “how does my teammate see my review?” has the same answer as “how does my teammate see my code?” You commit it and they pull.

There is a second, optional path through the hosted portal. It is worth understanding what it does and does not do, because the names mislead.

The default: commit .vidi/

vidi init creates the ledger files and tells you to commit them:

$ vidi init
initialized: this repo can now track reviews in .vidi/
  created  .vidi/: commit these files so reviews travel with the repo
  updated  .gitattributes + .gitignore: combine review records across branches; keep the scan cache out of git
  stage    git add .vidi/ .gitattributes .gitignore

That is the entire sharing mechanism. Vouch, commit, push:

$ vidi vouch "crates/vidi-core/src/crypto/keyid.rs::impl:KeyId::fn:of_public_key"
vouched crates/vidi-core/src/crypto/keyid.rs::impl:KeyId::fn:of_public_key as you@example.com (maintainer)
  content_id 8384bb1382675eb3dd0b7d3e9d858c5f · appended to .vidi/ (bare line, diff-visible)

$ git add .vidi/reviews.jsonl && git commit -m "review: vouch KeyId::of_public_key"

Your teammate pulls the branch and runs vidi status. Your review is theirs now, and it counts toward coverage on their machine exactly as it did on yours.

No account, no server, no token. This is the free tier, and it is the recommended path.

Why two people’s reviews never collide

Review files are append-only JSONL — one claim per line, and nothing is ever rewritten in place. vidi init adds one line to .gitattributes:

.vidi/*.jsonl merge=union

That tells git to resolve these files by keeping every line from both sides rather than asking you to pick. Two people reviewing different units on different branches produce two sets of lines, and the merge is their union.

Order does not matter either, because the merge algebra is monotone: union, dedupe by content_id, and revoke-wins. Everyone who merges the same set of records computes the same coverage, whatever sequence the merges happened in.

Commit that .gitattributes line along with .vidi/, the guarantee only holds if everyone has the rule. See Why review files never conflict.

Reviews travel with the branch

Because they are ordinary tracked files, review records follow the same rules as code:

  • they arrive with git pull and move with git push
  • they are visible in a pull request diff, one added line per review
  • a branch that is behind on reviews is behind in the ordinary git sense
  • rebasing replays review commits like any other commit

If your team rebases rather than merges, set it once per repo:

$ git config pull.rebase true

Nothing about the ledger objects to being rebased. The merge=union rule exists for the case where two histories genuinely diverge, which rebasing avoids by construction.

What the hosted lane actually is

The paid portal adds two commands. They sound like a matched pair and are not:

vidi pullvidi push
Directionportal → your machineyour machine → portal
What movesreview and revocation recordsa coverage snapshot
Effectunion-merges into your local .vidi/stored server-side for re-rendering
Gates anything?the records it adds donever

vidi push does not share your reviews. It uploads an already-computed coverage snapshot, the numbers behind vidi json, so the portal can render a dashboard. The server stores it verbatim and it never gates anything. The half of push that would upload an authoritative review store is not built.

Pushing reviews outward stays git’s job. The portal is a read-and-display surface over a git-native ledger, plus the hydrate path below.

Logging in

Two logins, and they are for different things:

$ vidi login --local          # offline identity, no account, free tier
$ vidi login                  # vidivouch.com device flow, the paid lane

--local records a self-asserted identity enough to authorize writes, which is all the free tier needs. The hosted form runs a device flow and stores a revocable bearer token, never a signing key, at ~/.vidi/token.

The two record different identity strings, which is the one thing here that will silently cost a team coverage:

LoginattesterIdentity.id recorded
vidi login --localyour git email, e.g. you@example.com
vidi logina person GUID, vidi:p:<uuid>

Your policy’s [reviewers] keys are matched literally against that string. If your team switches from local to hosted logins, list both forms for each person, or the reviews made under the other one stop counting silently. See policy.toml.

What vidi pull fetches

vidi pull fetches the tenant’s stored review and revocation lines and splits them by kind. Revocations into .vidi/revocations.jsonl, everything else into .vidi/reviews.jsonl, then union-merges each into the local file.

$ vidi pull
pulled github.com/graze-ai/vidi → 0 review + 0 revocation line(s) fetched · 0 new review + 0 new revocation merged · 0 already present

The three counts are worth reading separately: what the server served, what was new to you, and what you already had. A healthy repeat pull shows lines fetched and nothing new, which means you are in sync rather than that nothing happened.

The pull above returned nothing on a repository whose local ledger holds several reviews, which is the push/pull asymmetry made concrete. Those reviews live in git and have never been in the portal’s review store, because no command uploads them there. vidi push uploads coverage, not reviews.

What comes back depends on which bearer you hold:

TokenRepo selectorScope of the result
person (vida_ / vidc_, from vidi login)required — sent as ?repo=host/owner/namethat repository
tenant API tokennone; the bearer is already tenant-scopedthe whole tenant

A person token can belong to several tenants, which is why it must name the repo; a tenant token already implies one, so a tenant-wide pull works even where no git remote resolves.

The merge is the same algebra as the git path, plus two rules: a review that arrives notary-signed where you held only a self-asserted copy is reported as an upgrade, and an undecodable remote line is refused rather than appended. A refusal means something is wrong in transport, so pull exits non-zero if any line was refused, even though the lines that did decode merged normally.

Configuring the remote

Both commands resolve a URL and a bearer, each by its own ladder:

Order
URL--url > $VIDI_REMOTE_URL > $VIDI_NOTARY_URL > the production host
Token--token > $VIDI_REMOTE_TOKEN > the stored vidi login token

URL resolution never fails, a missing URL falls back to production rather than erroring. The repo slug resolves as --repo > $GITHUB_REPOSITORY > the origin remote, taking the host from $GITHUB_SERVER_URL so GitHub Enterprise works without assuming github.com.

$VIDI_REMOTE_TOKEN is the CI path: it passes through untouched with no refresh half, so a build authenticates without an interactive login. Keep it in your CI secret store, not in the repository.

Pointing at a self-hosted portal, vidi will not send a bearer over plain HTTP to a non-loopback host: use https://, or loopback for local testing.

Which path to use

Commit .vidi/ regardless, it is the source of truth and it costs nothing.

Add the portal when you want coverage dashboards across repos, or when you want fresh clones and CI to hydrate reviews without a full checkout of every branch that produced them.

Next

Editor extensions