Skip to content

When each check runs

A reference. Every check Procoder runs, placed at the lifecycle event that fires it. The ten domains lists the checks by subject; this page is the other cut — by moment. For why the chain refuses at all, see the quality chain.

Nothing here waits to be asked. Each check fires on an event, whether or not anyone remembered it existed — which is the whole point, because a check you have to know about protects only the people who already know about it.

Two tiers run the same rules at different scopes: the gate answers about the change, CI answers about the tree. A commit is judged on what it carries; the repository is judged on all of it.

  • Blocks stops the commit, or fails the job
  • Reports printed; blocks only where the repository asked
  • Info context for a judgement you make
1

Session starts

SessionStart · 15s

The agent is handed the rules and the state of the repository before it writes anything — computed fresh, never carried over from a previous session.

  • Infoengineering principlesThe ladder, the delegation rules, the formatting contract.
  • Infostate of playBranch against the default, dirty count, active sprint, open stories, unlearned lessons, index freshness — inside a hard three-second budget.
  • Infodeferred suitesNames the test suites the gate will not run here, so a green gate is never mistaken for a suite that passed.
  • Infoversion checkAsks GitHub off the critical path — a slow network cannot hold a session open.
  • Inforeceipt checkThe payload opens with an instruction and closes with an end marker. A host that inlines only the first 2KB and writes the rest to a file leaves a reader holding a preview — the marker is how it can tell, and the instruction says to go and read the remainder.
2

Every file written

PostToolUse · Write|Edit · 60s

The fastest feedback in the chain, on the one file that just changed. Everything here is milliseconds, because it runs on every edit.

  • Reportsformat verdictClean, unformatted, UNCHECKED, or out of scope — for that file.
  • Reportssecret scanA flagged value is never echoed — not to the terminal, not into a question.
  • ReportslinterThe language's canonical linter, over just this file.
  • Infocode indexKept current, but only where an index already exists.
3

Before the commit — the gate

PreToolUse · Bash · 120s

The big one. Eighteen legs over the changed set, intercepting git commit before it runs — and installable as a real pre-commit hook, so it holds outside the agent too. A file the gate could not look at is not a passing file: UNCHECKED fails it exactly like unformatted does.

  • BlockssecretsIn a changed file. Always blocking, never configurable.
  • BlocksSASTsemgrep over the files carried, at the severity [security] sast_blocks_at sets.
  • Blocksknown vulnerabilitiesOnly when the commit touches a dependency manifest.
  • Blocksagents driftA host rule file out of step with AGENTS.md is another agent reading rules this repository dropped.
  • Blocksdocumentation obligationA new exported symbol changes a doc, or the message carries docs: none — reason.
  • Blockstest suiteNarrowed to the changed packages. A failure blocks under [test] policy; a suite that could not run blocks either way.
  • Blocksemptied documentationA Markdown file reduced to nothing, with the command to restore it.
  • Blocksconfig that could not applyAn unreadable config.toml never silently falls back to defaults.
  • Blocksconflict markers, junk, oversized filesAnd commits landing straight on the default branch.
  • BlocksAI attribution in the messageCommits are the author's alone.
  • Reportsformat verdictsOver every changed file. Unformatted fails the gate.
  • ReportslintersBlocking where the repository sets [lint] policy = "block".
  • ReportscomplexityNamed as the function is written. Blocks under [maintain] policy.
  • Reportsdebt with no revisit conditionAsked while the reason for the shortcut is still in your head.
  • Reportsworkflow and infra hygienePinned actions, timeouts, concurrency — across all workflows, not only changed ones.
  • Reportsloosened defaultsEvery setting weakened from its default prints on every run. Strengthening one is silent.
  • Infoblast radiusWhat else the changed symbols reach, from the code index.
  • Infoopen questions and captured leaksReview findings recorded and never closed; questions waiting on a person.
4

Session ends or compacts

Stop · PreCompact · 10s

The handoff. What the next session inherits is written down rather than reconstructed from scrollback.

  • Infohandoff noteWritten to state. A note that cannot be written is a lost note, never a broken session.
  • Blocksan unasked decisionA turn ending with a decision put to the user in prose, and none recorded in .procoder/ask/decisions.md, does not end. The hook reads last_assistant_message from the host and exits 2, which continues the conversation.

The detector is deliberately conservative: an explicit ask, never a bare question mark, and an interrogative phrase only counts with a question mark in the same sentence — otherwise narration about a decision already taken reads as a new one. The same message never blocks twice, and the handoff note is written first, on every path including the blocking one.

5

Push and pull request

CI · test + gate jobs

Where the tree gets answered for. The gate saw only what the commit carried; these run over everything, on three operating systems.

  • Blocksthe suite — ubuntu, macOS, windowsThe full run on all three, every push.
  • Blockscommitted binaries rebuildRebuilt reproducibly and compared by hash. A shipped binary nobody can reproduce is one nobody can check.
  • Blocksgofmt, build, launcherIncluding that the launcher resolves a binary in the shell each OS really uses.
  • Blocksthe gate over the whole tracked treegit ls-files | xargs procoder check — every file, not just the diff.
  • Blockssecurity, the deep passFull SAST and dependency scan across the repository.
  • Blocksdocumentation, external links includedThe check that needs the network, kept off the commit path.
  • Blocksmaintain, debt, depsThe whole-tree pass: complexity everywhere, the full debt ledger, dependency freshness.
  • BlocksdoctorEvery tool present and answering, so no check above can pass by being absent.
6

Merged to main

CI · docs job

Publication. Branch protection requires linear history and every check green on the tip, so nothing arrives here unverified.

  • Blocksmkdocs --strictA broken reference fails the build rather than shipping a dead page.
  • Infothe changelog, served twiceOne file copied into the site, so the repository and the docs cannot disagree.
7

Tagged v*

CI · release job

A tag is the release. The job runs only after the suite and the gate pass on the tagged tree — what people download is published on the same evidence as everything else.

  • Blockssuite and gate on the tagged treeRe-verified at the tag, not inherited from the branch.
  • Infothe changelog entry becomes the notesExtracted verbatim — what is written there is what a person downloading reads.
  • Infofive platform binaries and SHA256SUMSThe manifest procoder self-upgrade verifies a download against.

Off the arrow: the controllers that refuse

These are not on the timeline, because they do not fire at a fixed moment. They fire whenever you try to call something finished — and each one refuses, naming what is missing.

Controller What it refuses
procoder spec, procoder plan Hollow documents. A section left as its template comment is not a filled section.
procoder backlog close story A story with no real description, unchecked criteria, or no recorded evidence — then it runs the gate and the suite before agreeing.
procoder backlog close epic, close milestone Closing while any child is still open.
procoder sprint close Closing unless every story is done or explicitly carried, with a reason.
procoder sprint start Starting until the last sprint's retro is written. The learning loop is enforced, not encouraged.
procoder adr check Hollow records, unknown statuses, and supersede references pointing at nothing.
procoder release <version> Tagging until the version matches across every file, the changelog entry exists, the tree is clean, the gate is clean and the suite is green. It then prints the git tag command — it tags nothing itself.
procoder audit Nothing — it is the onboarding sweep, every domain's checks over a tree Procoder has not governed before.

The three rules underneath

No silent green. A check that could not run never reads as one that passed. A missing tool, an unparseable config, a suite that never started — each says so, and blocks. The failure this exists to prevent is the comfortable default: nothing found, therefore nothing wrong.

No budget on the heavy checks. A slow scan finishes and reports what it found, rather than being cut off and reported anyway. A verdict that depends on how fast your laptop is, is not a verdict about your code. The ceiling that remains is a hung-process net: when it fires, it says the check was NOT run.

The binary prints, the agent writes. Nothing here edits your files. Every check computes and reports; acting on the result is the author's move. That is what makes the whole chain safe to run on every event.