Skip to content

A file is no longer trusted when a run line starts while the person is asked to trust it - #3592

Merged
bbondy merged 1 commit into
brave:mainfrom
netzenbot:fix-vouch-checks-program-count
Oct 30, 2026
Merged

bbondy merged 1 commit into
brave:mainfrom
netzenbot:fix-vouch-checks-program-count

Conversation

@netzenbot

Copy link
Copy Markdown
Collaborator

Closes #3578

User impact: a file that a run line may have rewritten while the person was asked to trust it is no longer trusted by that yes; the read says the file changed while the person was being asked, and the file stays untrusted.

Decisions to confirm

  1. TRUST-4: a vouch is checked against the file's revision alone, so a program started during the question leaves the yes spent on text the person did not see #3578: the TRUST-4 paragraph now says the program count is compared only for a vouch and for the write-back exception in WRITE-4, and that other approvals are checked against the revision alone. Instead: widen the stamp comparison to write and edit approvals in this pull request. Why: the issue is about the read_file vouch, and the write sites need their own tests. Commit: A vouch is refused when a run line started after the preview was drawn. To reverse: move the write and edit approval sites to stamp_of and reword the paragraph. The write approvals are tracked in TRUST-4: a write or edit approval is checked against the path revision alone, so a run line started during the question is not detected #3586.

The problem

#3578 A vouch is checked against the file's revision alone. A run line that starts while the person is asked whether to trust a file can rewrite it without moving the file's revision, because a program opens files its line does not name. The yes was spent on the new bytes, which the next read returned as trusted text.

Reproduce

The path needs a delegate running a run line beside the parent turn while the vouch question is open, so the test is the reproduction.

  1. In crates/core/src/policy.rs, capture stamp_of("vendor/lib.js") inside capture_files, as the preview is drawn.
  2. Call note_program_started() on the policy's file authority.
  3. Call vouch_if_unchanged("vendor/lib.js", stamp).

Before the change the call returns true and the path becomes trusted. After it, the call returns false, the path stays untrusted and the trail says the file changed while the question was being answered. cargo test -p bravebot-core a_vouch_is_not_spent_after_a_program_started covers it and fails on the parent commit.

The fix

#3578. read_file takes the path's stamp (its revision and the number of run lines started) beside the preview, and vouch_if_unchanged compares the whole stamp as numbers. Any run line that starts during the question voids the yes, and the planner gets the existing "changed while the user was being asked about it" result. TRUST-4 states this and names the new tests.

Test plan

  • BRAVEBOT_ALLOW_UNCONFIGURED_BUILD=1 make check-affected with ulimit -n 10240, on 05df365 and then d693351, before the final rebase: all recipes passed except the two below. The default limit of 256 aborts crates/cli/tests/running.rs with Too many open files.
  • The branch was then rebased onto c8164c1. Upstream changed only agents/renumbered-clauses.txt, docs/specs/README.md and docs/specs/backends.md, none of which reach the diff. On that tree cargo check --workspace --all-targets --locked, cargo fmt --all --check, both new tests and make check-spec passed.
  • bravebot_core::policy::a_vouch_is_not_spent_after_a_program_started_while_the_question_was_open: rejects a vouch compared on the revision alone; demonstrated on this tree by making Stamp equality compare only the revision, which fails it with "an answer was spent on a file a program may have rewritten since it was shown".
  • bravebot_agent::tools::a_yes_is_not_spent_when_a_program_started_while_the_person_was_asked: rejects taking the stamp after the answer, and a read that never vouches (a control case with no program started trusts the file); demonstrated by taking the stamp after the answer, which fails it with "a yes was spent on a file a program may have rewritten". It was not mutated to a revision-only comparison at this level; the core demonstration covers that.
  • a_vouch_for_the_version_shown_is_spent_on_it and a_vouch_is_not_spent_on_a_version_nobody_was_shown now pass a Stamp and pass; only_the_path_a_slot_was_read_from_is_a_write_that_changes_nothing still passes.
  • Docker gates skipped: host-only. check-msrv, check-windows and check-linux are named by the affected-checks script but docker is not installed on the machine that ran the gates.
Failures that are not from this change
- [ ] CI passes cleanly

read_file drew a preview, asked the person, and spent a yes only if the path's revision was unchanged. A program opens files its line does not name and moves no revision, so a yes given while a run line started was spent on a file the program may have rewritten after the person read it, and the next read returned those bytes as trusted text. TRUST-4 says an approval based on a preview cannot be spent after the path changed, and the same stamp already guards the write-back exception in WRITE-4.

FileCapture::stamp_of returns the path's Stamp (revision and count of run lines started). read_file takes it beside the preview, and Policy::vouch_if_unchanged compares it whole, as numbers only. A refused vouch is reported as before.

Tests: a core test starts a program while the question is open and checks the vouch is refused with revision unmoved; a read_file test does the same through dispatch, with a control that spends the yes when nothing started. TRUST-4 and its verified-by lines name them.

Closes brave#3578
@netzenbot netzenbot self-assigned this Oct 30, 2026
@bbondy
bbondy merged commit 4e93a28 into brave:main Oct 30, 2026
29 checks passed
@netzenbot-reviewer netzenbot-reviewer added the pr/risk/guarantee Can let untrusted content decide something, or changes what trust or egress allow label Oct 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr/risk/guarantee Can let untrusted content decide something, or changes what trust or egress allow

Projects

None yet

3 participants