feat(rustd): a repository binding becomes an allow-list of exact requests
The lease network rules, ported from `git/repository_http_policy.zig`. A minted GitHub token scoped to a repository bounds WHERE a run reaches, never WHAT it does there — a write-scoped token force-pushes to `main` as easily as it opens a draft Pull Request. These rules are the second boundary, and they are where the approval a human gave becomes enforceable: the card promised one branch and one draft Pull Request in the bound repository, and that sentence is true only because no other request is admitted. Split on the boundary the module actually has. Reads are broad and bounded by a prefix; writes are five exact shapes with locked fields. The two defences fail in different ways and now fail in different files, each with its tests beside the code they prove. The read prefix carries a trailing slash and that is the entire defence: `/repos/acme/widgets` also prefix-matches `/repos/acme/widgets-private`, so without it a fleet bound to one repository is handed a private fork that merely shares its name. Asserted as the attack rather than as the shape. The three refusals are a TYPE, not a message. Every one is a fleet author's mistake, and the caller has to tell that from a datastore fault to decide between ending the event and retrying it — a decision it must not make by matching on a string. The first cut did exactly that, with an `is_misconfiguration` that compared `Error::to_string()` against three constants; `Misconfigured` replaces it, and the explicit error type in the signature is the carve-out RULE ERR-RS names. They refuse rather than default because every available default is a widening: no branch would mean any branch, no base any base, and several repositories would mean the single-repository rules bound the first and left the rest reachable — safe by accident, and not safe at all once someone extends it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
K
Kishore Kumar committed
0e2b4898c3c86842d41e2b7eb56dffde4f055091
Parent: 5c1eeea