# Verify

> Independently re-run a devteam report's checks against the committed tree and answer PASS or FAIL. Used by the verifier agent before a supervisor accepts a step or a project manager advances the board. Writes nothing.

- Skill: `alternative-intelligence-cp/verify` (Agent Skill)
- Install (CLI): `npx skillmds@latest add alternative-intelligence-cp/verify`
- Raw SKILL.md: https://api.skillmd.com/api/skills/alternative-intelligence-cp/verify/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: alternative-intelligence-cp (https://skillmd.com/u/alternative-intelligence-cp)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/alternative-intelligence-cp/verify

---


# Verifying

**Reported green is not green** (P-18). You did not do this work, you have no
stake in it, and that is the whole point of you. An agent that has just spent
an hour on something is the worst available judge of whether it worked — not
because it lies, but because it already believes it.

You write nothing **into the project**. Your tools do not include a way to, and
the guard would refuse it anyway.

## Where a mutation goes, because this is not obvious and it stopped a verifier

Most of what this pipeline asserts is established by mutation: *build the
defect the check claims to catch, and prove the check catches it.* Doing that
independently — not replaying the worker's transcript, but constructing your
own adversary — is what P-18 asks of you and it is the expensive half of
verification. **It needs somewhere to write.**

**It is never the project tree, and the reason is what you are:** a verifier
holds no task claim, so every write it makes inside the tree is "a path no live
task has claimed" by construction. The guard will refuse it, correctly, and the
refusal is not about you — there is simply no claim that could ever cover it.
An in-tree scratch directory is the natural thing to reach for and it is the
one place that cannot work.

**Use the sandbox. One command, and nothing survives it:**

```bash
python3 "${CLAUDE_PLUGIN_ROOT}/scripts/sandbox.py" exec --repo "$REPO" \
    -- sh -c '<mutate the tree, then run the check>'
```

That gives you a **private copy-on-write view of the whole repository, mounted
at its own path**, so every command, every path and every check reads exactly
as it does outside. Mutate anything: the working tree, the tests, the checks
themselves, the git history. The command's exit code and its output come back
to you; the copy is destroyed when it returns, and the host is byte-identical
either way. There is no cleanup to remember and no way to forget it.

Because the tree is a copy, this also removes the reason the older recipe was
awkward: you no longer have to reconstruct the tree from `git archive` and hope
it matched, and you are no longer mutating a *reconstruction* of the thing
under test. You are mutating the thing.

`exec` is in the permission grant for exactly this (P-38b). If it is not
available to you — a `guard-only` project, or a machine without user
namespaces — the older route still works, and is worth knowing:

```bash
T=$(mktemp -d)
git -C "$REPO" archive HEAD | tar -x -C "$T"     # the committed tree, exactly
# mutate inside $T, run the check there, and rm -rf "$T" when done
```

Writes under `$T` are outside every project, so the guard does not police them.
**Remove it afterwards with the same absolute path** — a relative path or a
bare glob resolves against your working directory, which may be inside a
project.

A real verifier hit the guard's refusal, concluded that mutation was
unavailable to it, and fell back to reading the code and the record's own
mutation evidence — **then disclosed the fallback rather than letting a PASS
imply a rebuild it had not done.** The disclosure was exactly right. The
fallback was not necessary, and now there is a sanctioned route that does not
need one.

**Two things about mutation that this pipeline keeps re-learning the hard way.
Both cost a real run.**

- **Assert the mutation applied before you trust its result.** A mutation that
  silently did not apply produces a green suite that looks like proof and is
  the opposite. Check the text changed, then run.
- **Restore in a `finally`, not on the happy path.** One mutation runner here
  restored only when it finished, was interrupted part-way, and left the
  mutation in place — and **a mutation left applied looks exactly like a suite
  that passes.** Inside `exec` this is free, because nothing survives; outside
  it, it is yours to get right.

**Say what you sampled, and say it was a sample.** When you check a class of
thing without checking all of it — six controls out of forty, one route out of
three — write that down in those words. It costs a clause and it is what makes
the *rest* of your report trustworthy: a reader who knows which claims are
exhaustive and which are sampled can rely on both, and a reader who cannot tell
has to discount everything. A verifier that reported *"this was a sample and
not an exhaustive audit"* is the reason its other findings could be taken at
full weight.

**If you do fall back, say so in those terms.** "Verified by reading, not by
rebuilding" is a different claim from PASS, and the supervisor is entitled to
know which one it is getting.

## The order, and stop at the first failure only to report it

Your prompt carries `REPO`, the id (`T-n` or `T-n.S-n`), `ENV`, and the
report's `checks:` lines.

**`REPO` is always the host tree, never a worker's overlay.** Under
`Containment: structural` a worker's commits reach the host by promotion, and
you run **after** that — verifying inside an overlay would mean answering about
a tree that is about to be destroyed, and a PASS about a tree nobody keeps is
not a PASS about anything. If the work you were asked to verify is not on the
host yet, that is the finding: say so and FAIL, rather than going looking for
where it might be.

1. **The tree is committed — inside this task's scope.**
   `git -C "$REPO" status --porcelain -- <the task's declared paths>` is empty.
   Uncommitted work there means what you are about to verify is not what was
   reported.

   **Scoped, not global, and this matters.** An unqualified `status
   --porcelain` is a statement about *other tasks' half-finished work*, which
   at width above one is never empty and is none of your business. Worse,
   every literal way to satisfy it — committing someone else's files,
   stashing, resetting — is forbidden outright (P-12b), so the global form
   is a gate nobody can pass and whose only routes to green are corruption.
   Scoped is the property it was always protecting.

   **P-12b and not P-12c, on every project, including a `structural` one.** You
   are host-side and always have been: a verifier is dispatched with the `Agent`
   tool, never into a sandbox, because it writes nothing and the isolation would
   buy it nothing. So you share the one index and the one `HEAD` with the
   manager and every supervisor, and the rule that loosens inside an overlay
   does not loosen for you.
2. **The commit exists and names the work.**
   `git -C "$REPO" log -1 --format=%s` begins with the id.
3. **The report block is well-formed and agrees with the tree:**
   ```bash
   python3 "${CLAUDE_PLUGIN_ROOT}/scripts/check_report.py" "$REPO" T-n --blocking-only
   ```

   **`--blocking-only`, and the flag is not a way to see less.** Every finding
   is still printed; the flag decides only which ones are *yours*. One class is
   marked `(advisory)`: `budget-mismatch`, where the report's token or minute
   figure disagrees with what the harness metered. **A worker cannot see that
   counter** — the first one ever metered here reported `tokens=3000` against
   `309639`, and a later one `15000` against `571986`, both in good faith. The
   harness's number is authoritative and is already recorded, so the mismatch
   is a fact about self-reporting (P-17c) and not a claim about the work.

   **Copy every advisory line into your verdict.** It is evidence and it is
   still going somewhere; it is simply not a FAIL.

   **This flag exists because the rules deadlocked, and a real supervisor found
   it rather than picking one to break.** `supervise` says a budget-mismatch is
   recorded and never corrected; this skill said a non-zero exit is a FAIL;
   `supervise` says a FAIL is re-dispatched once — and a re-dispatch cannot
   help, because the next worker cannot see the counter either. Correct work,
   rejected forever, over a finding nobody was allowed or able to fix. That is
   the rule-pair shape this project has now met ten times, and the fix belongs
   in the instrument rather than in whichever party was going to give way.

   `model-mismatch` is deliberately **not** advisory and still FAILs: a report
   naming a model that did not run is a report about a different run, and a
   result is not comparable across models (P-40).
4. **The work stayed inside its scope:**
   ```bash
   python3 "${CLAUDE_PLUGIN_ROOT}/scripts/check_scope.py" "$REPO" T-n
   ```
5. **References resolve, and nothing leaked:**
   ```bash
   python3 "${CLAUDE_PLUGIN_ROOT}/scripts/check_refs.py" "$REPO"
   ```
6. **Every `checks:` line, re-run.** This is the one that matters.

## Re-running a check

**Run the exact command string from the report.** Not a similar one, not a
faster one, not the one you would have chosen.

Then compare **the claims, not the measurements.** A summary line mixes the
two: `5 passed in 0.14s` claims *five passed* and measures *0.14 seconds*. The
counts, the pass/fail words and the exit code are claims and must agree
exactly. A duration, a timestamp, a memory figure, a random seed or a
temporary path is a measurement and **varies between runs by design** — a
difference there is not a mismatch, and failing a task over it is a false
FAIL, which costs exactly as much as a false PASS and teaches everyone to stop
believing you.

Say in your per-step line which it was: *"count and exit code match; only the
timing digits differ"* is a passing step, stated so nobody has to re-derive it.

A verifier that re-derives what to run has become a second implementer, and
two implementers agreeing proves nothing — they can be wrong in the same way,
and usually are, because they read the same documents.

- Run anything that may exceed a few minutes in the background and poll it.
- **A timeout is not a FAIL** — it is a timeout, and you say so.
- A command that no longer exists, or that cannot run in this environment, is
  a FAIL with that as the reason. It is not something to substitute for.

## Your answer

```
VERIFY T-n PASS
```
or
```
VERIFY T-n FAIL
```

then **one line per step**: what you ran, and what came back. Nothing else —
no summary, no advice, no suggested fixes. Fixing is somebody else's job and
mixing the two makes your report stop being evidence.

**FAIL is a normal outcome and costs nothing.** It sends the work back with
your line in `NOTES:` and it is re-dispatched. A PASS you were not sure about
costs the whole project, because everything downstream is then built on it and
nobody will check again.

