Repository navigation
Vetted removes secrets and Singapore personal data from a pull request's diff before an AI model sees it, reports prompt-injection attempts instead of obeying them, and posts comments that are clearly labelled as AI advice. It never approves, requests changes or merges. Milestone 1 of the AI Governance Toolkit, reviewed and approved by Michael Mendoza on 2026-10-01.
Use it
permissions:
contents: read # read the diff and config
pull-requests: write # post comments (never approve)
actions: read # count today's runs for the budget guard
steps:
- uses: makoydev/vetted@2ae958e0fbf14fb9c74c2423059a49762927a192 # v0.1.0
with:
mode: shadow # then opt-in, with the ai-review label
openai-api-key: ${{ secrets.OPENAI_API_KEY }} # optional; without it, the free mock is usedThe full quickstart is in the README.
What it does
- Scrubs before sending: a path deny list, byte caps, gitleaks' 221 secret rules (with five deliberately stricter differences), an entropy check, and Singapore NRIC/FIN, phone and email detection from sg-pii-rules v0.1.0.
- Resists prompt injection: the diff is labelled untrusted inside a random-nonce delimiter, the model has no tools, its output must match a strict schema, and rule-based detection reports attempts as findings.
- Caps spending by construction: at most US$0.0104 per review and US$0.20 a day per repository by default.
- Leaves evidence: an audit record for every run (hashes and counts, never code), and a disclosure footer on every review.
Evidence
- 0 leaks in the canary suite: 144 fake secrets and identity numbers, 34 runs, 4 output channels, including against a hostile model that echoes its input. It fails when any protection is removed.
- 0 misses compared with the real gitleaks 8.30.1 on its own 3,658 test cases, and identical results on 2,028 real source files.
- 408 unit tests; 12 decision records; CONTROLS.md maps each feature to IMDA, PDPA/PDPC, OWASP, CSA, NIST and ISO controls; THREAT_MODEL.md; EVALS.md.
Known limitations
- No real-model results yet: every review so far used the mock model.
- The phone detector fires on bare eight-digit numeric constants in code.
- Base64-encoded secrets aren't decoded; names and addresses aren't detected.
- Not yet on the Marketplace (Milestone 3).
How this release was made
Drafted with Claude Code under a written brief. Every change went through a pull request with required CI (tests, the canary suite, CodeQL). Michael merged the early pull requests himself, then chose an integration branch (ADR 0009): Claude Code merged checked changes into next, and Michael reviewed the batch with a decision report and approved it. At his instruction, Claude Code rebase-merged it into main and published this release. Every AI mistake and how it was caught: docs/HOW-THIS-WAS-BUILT.md.