Skip to content
Docs/Guides

How your engineers verify work

Your engineering seats do not open a pull request on their own say-so. Every change is proven by running your repository’s own checks — build, lint, type-check, tests — and the result is written on the pull request for you and the code reviewer to see. This page explains what those checks are, how to declare them for your repository, what the engineer does when they fail, and the limits that stop a runaway job.

Every pull request an engineer opens carries two sections under the ticket text:

  • Self-verification — a one-line matrix of the four check categories (Build · Lint · Types · Tests) with ✓, ✗ or — (not run), and how many attempts it took to get there. If nothing could be run, the line is followed by a warning: NO CHECKS RAN. A pull request never opens on that warning unless your repository has declared that it has nothing to verify (see below); the story stops first and tells you why.
  • Self-audit — before opening the pull request the engineer re-reads its own diff against every acceptance criterion of the story and writes down what it checked, the problems it found in its own work, and, per criterion, the evidence it has for it (the command it ran and the result, the test that passed, the file and line it inspected). Anything it could not verify in the session is listed as an issue rather than claimed. If the audit changed the code, the checks were re-run afterward and the section says so. If the model did not produce an audit, the section says Not produced rather than inventing one.

The code reviewer reads both sections. The review gate is separate and still applies — see GitHub and Sapient Forge.

The engineer decides which commands to run in this order:

  1. Your repository’s conventions. If the repository’s conventions document (the notes your Tech Lead keeps per repository) contains a fenced verify block, that block is the whole contract:

    ```verify
    build: cd web && npm ci && npm run build
    typecheck: cd web && npx tsc --noEmit
    test: cd web && npm test
    ```

    Each of build, lint, typecheck and test is optional; an optional dir: line runs every command from that subdirectory. A repository with nothing to verify — documentation, static content — declares it explicitly:

    ```verify
    none: true
    ```

    A malformed block is ignored (the engineer logs why) and the next rule applies.

  2. Your deploy configuration. If the product has a managed deploy target with a build command, the engineer runs that build exactly as the deploy would — from the repository root — and, when a backend directory is configured, builds, vets and tests that Go module too. Any tests the repository declares in its own manifests are run as well.

  3. What the repository declares itself. Otherwise the engineer looks for go.mod and package.json files up to two directories deep (so web/ and server/ layouts work) and runs go build, go vet and go test for each Go module, and the build, lint, typecheck and test scripts a package.json actually declares, installing dependencies first when needed.

If none of these finds anything to run and the repository has not declared none: true, the story stops before a pull request with the reason “self-verification ran no checks” and what to do about it. That is deliberate: a green result that ran nothing is not evidence, and it is exactly how a build break once reached production. Add a verify block or a manifest and re-run the story.

Verification commands run in a clean sandbox without your production secrets; keep them free of credentials.

A failing check is not the end of the story. The engineer receives the failing output verbatim, fixes the root cause, re-runs the check, and tries again — up to a bounded number of attempts (six by default). It is told never to disable, skip or delete a failing check to make it pass, and after two failures to stop and list the likely causes before editing again. If the checks are still red when the attempts run out, the story stops with the last failing output attached instead of opening a broken pull request.

Two safety limits end a job early, each with a clear reason on the story:

  • Stuck loop. If the engineer repeats the same action with the same result several times in a row (or alternates between two such actions), it is nudged once to change approach; if it keeps repeating, the job stops rather than spending your credits on a loop.
  • Token ceiling. Every job has a ceiling on the total tokens its model calls may use — including its research sub-agents and any context compaction. A job that crosses it stops rather than running unbounded.

Both show up as a failed job with the reason attached; re-running the story starts a fresh attempt.