Propose a change and review one¶
This guide covers the proposal lifecycle — TOVIO's equivalent of a pull request — from opening a change for review through approval and landing. It also covers the case that has no Git analogue: reviewing a change that touches files you aren't cleared to read.
Built and tested; release evidence remains open
The Forge collaboration server (proposals, review, lane protection, connection ACL, authenticated
REST, locking, webhooks) is built and passes its hermetic --features tls test suite. Production
binaries passed the distinct-Docker-host exercise under a real operator CA; public-release,
broader HA/load, hosted-parity, and external evidence remain Phase 5 gates.
flowchart LR
D["draft"] --> O["open"] --> AP["approved"] --> LD([landed])
O -. "request-changes" .-> O
AP -. "amend" .-> O
More diagrams for the full team collaboration flow: Team workflows.
Open a change for review¶
When a change is ready for other eyes, propose it. A proposal (prop:…) is a
first-class Forge object: it pins the exact commit under review and its base, and accumulates the
reviewers' decisions against that pin. A draft or abandoned change isn't proposable — promote or
restore it first.
Push the change first so its commits are on the Forge, then propose it. --target defaults to main,
and omitting the change id proposes the current one:
$ tovio change propose chg:a3f7b2 --remote forge.example.dev:7743 --target main
✓ Proposed chg:a3f7b2 to main on the Forge (proposal prop:003 is now open).
You don't name the reviewers
There is no --reviewers flag. Who may approve is repository policy, not a per-proposal
choice — tovio policy protect for a lane, tovio policy change-control for a path. The Forge
reads the requirement from the served manifest at land time, so a proposer can't widen their own
reviewer set. See lane protection.
Your change keeps its Change ID the whole way through. Amend it, rebase it, land it — the identity is stable, so the proposal never loses track of the work.
The proposal lifecycle¶
A proposal is a small state machine. Knowing the states tells you exactly where a change stands.
| State | What it means |
|---|---|
draft |
A draft change, not yet proposable. |
open |
Proposed and awaiting review. |
approved |
All required reviewers approved; ready to land. |
landed |
Landed onto the target lane. |
closed |
Withdrawn by the author or a maintainer (from any non-landed state). |
propose approve (all required) land
(draft) ─────────────▶ open ──────────────────────────▶ approved ────────▶ landed
│ ▲ │
request-changes / │ │ amend (author re-pushes) │ close
new amendment ─────┘ └──── re-open ◀── (changes) ▼
closed
Amending re-opens review¶
When you amend a proposed change — a new commit under the same Change ID — every prior approval is
invalidated and the proposal returns to open with its revision bumped. The old approvals stay in the
proposal's history, marked superseded, so the audit trail is intact. Reviewers re-approve the new
version. There is no trivial-amendment exemption: a message-only fix drops the sign-offs just as a code
change does.
request-changes blocks landing¶
A reviewer who requests changes keeps the proposal open and sets a hard gate: it also drops that
reviewer's own live approval, and the proposal cannot be marked approved while the flag stands. The
flag is cleared by an amendment — the author pushes a new revision, which resets it (and, as above,
invalidates the other approvals too). It's a block you clear by doing the work, not a rejection you have
to argue with.
If the target lane moves, the review is re-pinned — not rebased for you¶
A proposal pins the exact (reviewed_base, reviewed_commit) pair the reviewers saw, and reviewed_base
is Forge-computed — the served tip of the target lane at pin time, never something the proposer sets. If
another proposal lands first, that pin is stale: the land is refused (TVO-FORGE-013), because the
coverage the approvals were computed against no longer describes what would land. The proposal is not
closed — it needs a re-pin onto the new tip and a fresh review. Your Change ID survives it.
The same defense runs on the clearance side: coverage is re-computed at land time against the current
roster, so a clearance revoked between approve and land blocks the land even though the proposal already
reads approved.
Review a change¶
tovio review takes the change id, not the proposal id — it renders the change's diff against its
base locally. With no decision flag it is a pure local render and touches no network:
To record a decision, add --approve (or --request-changes) together with the proposal it transitions
and the Forge to submit to. The reviewer is your signing identity — never a field you can set:
$ tovio review chg:a3f7b2 --approve --proposal prop:003 --remote forge.example.dev:7743
$ tovio review chg:a3f7b2 --request-changes --proposal prop:003 --remote forge.example.dev:7743
--approve and --request-changes are mutually exclusive, and both require --proposal and
--remote.
Reviewing files you can't read¶
The Forge stores policy-protected payloads as ciphertext. Its authorized projection and the enrolled client/local bridge render review according to your own keys. If a change touches a file your clearance doesn't cover, the projection does not return its content.
Instead you see a redacted entry: the path and a coarse marker for what happened to it — added,
modified, or removed. Never the plaintext, never a content diff, never a byte count. A protected
path you can decrypt diffs normally and is flagged as such, so you can tell the two apart at a glance.
The render ends with a coverage summary:
$ tovio review chg:00d4e1
Review of chg:00d4e1 (vs its base):
~ src/integrations/cgm/dexcom.ts
- const retry = 3;
+ const retry = 5;
+ tests/integrations/cgm.test.ts
+ it("reconnects after a dropped session", …)
~ config/production/api-keys.env 🔒 protected — not accessible to you (modified)
Reviewed 2 file(s) (2 clear, 0 protected-readable); 1 protected file(s) not accessible to you.
note: coverage is advisory — 1 file(s) you cannot decrypt were NOT reviewed for content.
A redacted file does not block your review
You approve the portion you can see. The protected file is reviewed by someone who holds the clearance — see cleared-reviewer coverage — but the presence of a file you can't read never stops you from signing off on the rest.
Your coverage report is display only
The covered / not-accessible lists your client computes ride along with the decision and are
recorded on the proposal, but they are never a gate — a client could forge them. The enforceable
clearance check is re-derived server-side from the Forge's own objects, the served manifest, and the
signed roster.
Approval is a landing gate¶
A lane whose policy requires review is Forge-advanced only: the ref moves when the Forge lands the
proposal, and not before. Marking a proposal approved needs every demanded reviewer's live approval,
no outstanding request-changes, every required check passing, and cleared-reviewer coverage for the
protected paths the land introduces. Landing then re-checks coverage and the base pin. Each of those
gates is described in lane protection.
Recap¶
tovio change propose <chg> --remote <forge>— open a proposal (prop:…); the Change ID is stable through the whole lifecycle. Reviewers come from policy, not from a flag.- States:
draft → open → approved → landed, plusclosed. Amending re-opens and invalidates every approval;request-changesblocks approval until an amendment clears it. tovio review <chg>renders locally; add--approve/--request-changeswith--proposaland--remoteto record a decision.- Files you can't read render redacted (path + a coarse added/modified/removed marker, never contents) and don't block your review.
- A target lane that advanced under the review makes the pin stale and the land is refused
(
TVO-FORGE-013) — re-pin and re-review.
Where to next¶
- See how the landing gate is configured in lane protection.
- Reviewing a feature that spans repos? See cross-repo changes.
- Curious how agents and CI runners review and check? See the agents guides.
Last reviewed September 9, 2026
Suggest an improvement to this page Not for security reports — see disclosure