factory-judge · git:20260908.fe9b83c · 2026-09-08 · sha256 f0f2da81e9a7ba93
factory-judge git:20260908.fe9b83cA
Immutable. This exact content is served forever at /api/v1/blob/f0f2da81e9a7ba93.
--- name: factory-judge description: Judge a pull request as an independent reader who did not write it. argument-hint: the pull request, e.g. `gh:pr:14` --- # factory-judge **The judgement is `archon-accept`'s, not ours.** It fetches the exact head and base into a temporary repository of its own, runs the commands a trusted profile pins, hands a fresh judge the real streams and the original request, and writes an `acceptance.json` receipt. It never merges, comments, or touches the pull request. ```bash archon workflow run archon-accept --no-worktree \ --input target=OWNER/REPO#N \ --input work_order=file:/absolute/path/outside/the/checkout/work-order.txt \ --input policy=/absolute/path/outside/the/checkout/gate-profile.json ``` Both paths must resolve OUTSIDE the application checkout. That is not tidiness: a policy the candidate can write is not a policy, and a work order the candidate can edit is not the thing it was asked to do. ## What the factory supplies `factory/sdlc.py` builds both inputs for every automatic validation, and it is worth knowing what they are before you hand-roll them: - **the work order** is the ORIGINAL issue text, captured the first time the factory needed it and kept outside every checkout. Re-reading the issue now reads whatever it says today. - **the policy** pins one command: `factory/fixed_gate.py`, reconstructed out of the BASE tree along with `config.py`, `guard.py`, `gate.py` and `tripwire.py`. The gate a pull request is held to is the gate a human last agreed to, and the candidate cannot supply it. - **what the judge is allowed to know about that gate.** Its argv and its streams stay private, so the policy also declares that this one command is the whole applicable gate, describes in public terms what it covers, and hands over `MISSION.md` and `FACTORY_RULES.md` read from the base commit -- the judge has no tools and cannot follow a pointer from one document into another. - **one piece of required evidence.** A report at the repository-relative path `FACTORY_ACCEPT_REPORT` names, which the gate writes into the candidate checkout bound to that evaluation's id and identity: the gate's status, which required markers reported, and the counts. Never a raw failure, a holdout scenario, an evaluator path or the command itself. Acceptance refuses the file if the path was tracked or already there, so it is only ever this run's output. To reproduce one by hand, read the `gate.json` and `policy.json` of a real run under the operator runtime root (`factory doctor` prints where that is). ## What the receipt does and does not prove `verdict == "approve"` is approval. Workflow success is not: a run that finishes and returns `inconclusive` finished. Read `checks` before you read `summary` -- deterministic failed checks outrank a model's approval, and incomplete evidence outranks findings. **These worktrees are not sandboxes.** Candidate code runs as you, with your credentials. The receipt says `isolation: fresh_context_only` and means exactly that. ## What the factory adds around it - **the identity check, twice.** The receipt certifies one repository, one PR and one pair of commits. The factory re-resolves the live head and base before it applies anything, and a pull request that moved during validation goes to a person. - **the digests.** The stream and evidence hashes in the receipt are re-computed against the run's own artifacts. A digest nobody checks is decoration. - **the hold.** Green with ratchet slack, uncalibrated margins or recorded assumptions becomes `factory:held`, not `factory:approved`. Nothing is wrong; a person has to agree, with `factory accept gh:pr:N`, which is the command that keeps the record.