Files
zeekayandHanzo Dev b497511c04 no hogs: stamphog and review_hog are stamp and review
Both are Django apps, and both pin `label` in apps.py — "stamp" and "review".
django_migrations keys a row on (app_label, name), and app_label comes from that
pin and not from the import path, so moving the directory does not orphan a
single migration. All six stay where they are, untouched.

  products/stamphog -> products/stamp     name = products.stamp.backend
  products/review_hog -> products/review  name = products.review.backend
  StamphogScene/ -> StampScene/, and stamphogSceneLogic.ts with it

189 files follow. An earlier attempt at this move failed twice for reasons worth
recording: `git mv A B` where B exists puts A INSIDE B, and a stray
products/stamp/node_modules from an abandoned run was enough to make B exist —
the app ended up nested two deep. And `git ls-files` does not list a file moved
with plain mv and not yet staged, so a pass over "every tracked file" silently
skips it; that is how StampScene.tsx kept importing ./stampSceneLogic after the
file beside it had been renamed back.

bin/check-imports-are-committed: all first-party imports across 15,843 files
resolve.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-09 10:18:18 -07:00

3.1 KiB

Stamp

Approve-first PR review: an LLM reviewer that runs deterministic gates plus a scoped review over a pull request and, when the policy allows it, posts an actual GitHub approval — not just comments. Repos opt in per-repo; everything else stays untouched.

Two runtimes, one engine

The review engine lives in tools/pr-approval-agent/ and runs in two places:

  • GitHub Action — runs in the repo's own CI with the repo's own secrets (review_pr.py).
  • Hosted (this product) — a GitHub App delivers webhooks here; reviews run in an isolated Modal sandbox with per-run minted credentials (review_local.py consumes a pre-fetched context, no GitHub token inside the sandbox).

Hosted flow: webhook → Celery (backend/tasks/tasks.py) → Temporal (backend/temporal/workflow.py) → sandboxed engine → verdict posted back (post_verdict). The workflow dismisses stale approvals first, waits out other in-flight reviewer bots, then reviews.

There is one non-webhook entry: self-driving inbox PRs. When a self-driving Inbox implementation run opens its (bot-authored, draft) PR, review's inbox receiver calls the queue_inbox_pr_review facade — gated by the assigned reviewers' per-user stamp_review_inbox_prs toggles on Review's settings (any opted-in reviewer is enough) — and the initial review runs while the PR is still a draft so the verdict is ready at Inbox triage time. Later pushes re-review through the normal webhook path via a positively identified carve-out (task linkage through the tasks facade, toggle re-checked through facade/inbox_hooks.py); every other bot author stays refused at every layer. See AGENTS.md § the self-driving carve-out.

The digest

Independently of reviews, a repo can enable a daily Slack digest of its merged PRs (backend/tasks/digest.py): merges are stamped with an audience (author's GitHub team, or a channel the repo declares under digest: in .stamp/policy.yml), summarized with a small model, and posted per channel. Review-enabled repos digest only stamp-approved merges; digest-only repos (review off) digest every merge.

Configuration

Per-repo settings live on StampRepoConfig (synced via the GitHub App install flow, managed in the Stamp scene): review on/off, review mode (auto vs trigger label), digest on/off. Review policy (gates, deny-lists, tiers, ownership) is read from .stamp/policy.yml on the repo's default branch — never from the PR head — layered over hosted defaults in backend/logic/policy_defaults/.

Security model, in one paragraph

The sandbox runs an LLM over untrusted PR content, so it holds no long-lived secrets: it gets a per-run OAuth token (scoped to llm_gateway:read + the server-mint marker) that only works against the gateway's stamp route, egress is fenced to an explicit domain allowlist, posted bodies are scrubbed and markdown-image-neutralized, and approvals are governed by a strict supersession protocol so no approval survives events it shouldn't (pushes, re-reviews, repo disable). Details and invariants: AGENTS.md.