Pandora's Router
One close, measured. DONE needs all seven; one failure names itself and the grade drops. The three squares below stop the close outright.
The seven gates a close measures, and what each one refuses Merged refuses content that is not on main. Green refuses a build nobody observed. Live refuses a deployment that is not serving this build. Renamed refuses a brief still wearing a live filename. In-scope refuses a branch that wrote outside its declaration. Findings refuses a problem raised with no fix attached. No-side-files refuses a new tracker-shaped file. All seven passing is DONE; any one failing is PARTIAL with that gate named. Below them, three conditions stop a close entirely: no status word, DONE with no evidence line, and DONE beside a body that names a skipped step. merged content not on main green no build observed live not serving this build renamed brief still reads live in-scope wrote outside scope findings no fix attached no-side-files a new tracker file DONE Stops the close entirely no-status-word done-without-evidence done-honest-unaddressed The seven gates a close measures, and what each one refuses Merged refuses content that is not on main. Green refuses a build nobody observed. Live refuses a deployment that is not serving this build. Renamed refuses a brief still wearing a live filename. In-scope refuses a branch that wrote outside its declaration. Findings refuses a problem raised with no fix attached. No-side-files refuses a new tracker-shaped file. All seven passing is DONE; any one failing is PARTIAL with that gate named. Below them, three conditions stop a close entirely: no status word, DONE with no evidence line, and DONE beside a body that names a skipped step. merged content not on main green no build observed live not serving this build renamed brief still reads live in-scope wrote outside scope findings no fix attached no-side-files a new tracker file DONE Stops the close entirely no-status-word done-without-evidence done-honest-unaddressed

The gates

Everything this tool refuses, and why it refuses it rather than warning. A warning that fires on ordinary work gets muted within a week; a refusal that fires on ordinary work gets fixed.

Back to the overview Source on GitHub

The five verdict values

Every gate records one of five words, and three of them are passes. The distinction between the two failing words is the important one.

ValueMeaningGrade
yesMeasured, and it passed.pass
n/aStructurally nothing to measure: no branch, no deployed surface, no declared scope.pass
exemptMeasured, and a refusal was the correct answer. A gated product refusing an unauthenticated probe is working.pass
noMeasured, and it failed. A real red.fail
skipNothing was measured, for a named reason.fail

A skip is not a pass. Neither n/a nor exempt claims the build was verified, and every close that records one says so in words.

The seven gates a close measures

DONE requires all seven. Anything else is PARTIAL, with the failing gates named in the reason line, so a lane can't report DONE and then list a barred step underneath it.

merged

Refuses a branch whose content isn't on main. It compares the blob of every path the branch touched in three trees: the merge base, the branch, and origin/main. Not git ancestry, because a squash merge copies a branch's changes onto main and throws the commit fingerprints away, so git branch --merged says "not merged" about work that's fully shipped. A lane with no branch, running in place on a target that isn't a git repository, records n/a.

green

Refuses a build that wasn't observed green: npm run build in the lane's own checkout, exit 0. Running the close with --no-build records skip, not a pass, so choosing not to build can't produce a DONE.

live

Refuses a deployment that wasn't proved to be serving this build. The close issues a GET at the URL the repo's policy row names and reads the body. Two proof forms:

  • A commit echo: the deployment reports its own release, and the gate requires it to equal or contain the branch head. This is the only form that can't pass on stale bytes.
  • A proof string that must appear in the response. The gate refuses a proof string that isn't new in this branch's own diff. A string already on main proves nothing about whether this deploy landed, and an assertion every build passes is not an assertion.

Credentials are named, never stored. A policy row carries the name of an environment variable; the value is read at probe time and never printed, not in a verdict and not in an error. If the variable is unset the probe isn't sent bare, because grading the resulting 401 would measure the credential rather than the deployment. That case is a skip naming the variable.

renamed

Refuses a brief that still carries no closed prefix, because the next dispatch will read it as live and fire it a second time. The lane id has to appear in the brief's filename as a whole hyphen-delimited token, never as a substring, so lane ops-l1 doesn't match a file belonging to ops-l14.

in-scope

Refuses a branch that touched files outside the scope its lane declared at open. This is the other end of the allocator's promise: proving two scopes disjoint before dispatch is worth nothing if a lane can then edit outside its declaration. Every path from the merge gate's own diff is tested for containment in the declared scope, with a small allowlist for files a required procedure regenerates. A lane that declared nothing records n/a, having already paid for it by serializing against the whole repo.

findings

Refuses a problem raised with no solution attached. A report line in this shape:

FINDING: <what> | fix: <the fix> | size: small|medium|large | owner: <seat or owner>

A line missing the fix, a valid size, or an owner fails the gate and is quoted back verbatim. A report with zero findings passes: the gate polices completeness, never quantity. A small finding assigned to the human owner is refused outright, because a small thing the lane could have done itself isn't a decision to hand upward.

no-side-files

Refuses a new tracker-shaped file on the bridge: REFERENCE-*.md, SWEEP-*.md, TRIAGE-*.md. The project already has a tracker, and a second static surface beside it is a place for facts to go stale.

A window is not an attribution: many lanes run at once, so a matching file counts against a lane only if its body names the lane or the brief's title, or it sits in the lane's own branch diff, or the lane's own report names it. The opt-out is printed, never inferred: a Side-file: allowed line in the brief's header makes the gate n/a.

Three gates the grader supports and this driver does not measure

Named here so their absence is visible rather than mistaken for a pass. The grader accepts a verdict for each; the shipped close driver records them as not measured, and they don't affect the grade.

GateWhat it would refuse
owner-way-in A live deployment the owner's stored credential no longer opens. When it fails it leads the reason line, ahead of every other failure: a product the owner can't open is the first sentence, not a line item.
report-free A report filename already taken, where writing would land on top of another lane's report. The derived filename carries the lane, so two sessions of one brief produce two different names, and a taken name gets a numbered variant.
roadmap A brief that cites no board row, so finishing it moves nothing anybody can see.

Three refusals that stop a close entirely

These aren't gates. A failing gate makes the close PARTIAL and the close still happens. These three abort it: nothing is recorded, nothing is renamed, no worktree is removed, no claim is released, and the same is true on a dry run. The disagreement is between the report and itself, and no grade can be recorded honestly until a person resolves it.

ConditionWhat triggers it
no-status-word The report carries no DONE, PARTIAL or BLOCKED. A report with no status word is unreadable as a scope claim, whatever the gates measured.
done-without-evidence STATUS DONE with no Evidence: line naming the verification run, its result and the date. Without one, the done- prefix means consumed and nothing more.
done-honest-unaddressed STATUS DONE beside a body that names a skipped, barred or deferred step. A reviewer's objection has two valid answers, fix it or overrule it in writing, and silence is not a third. An overruled: line naming the check lets the close through; nothing else does.

A report that says PARTIAL or BLOCKED in its own words is a separate rule and a softer one: it lowers a grade of DONE to match, and it never raises one. The status word inside the report is the only scope claim the lane gets to make, and it outranks a passing gate grade.

What the allocator refuses before a lane opens

Half the value is here, before any agent runs. None of these produce a warning; each one keeps the lane out of the FIRE NOW list and prints the reason.

RefusalWhy
Scope overlap The lane is queued behind the one it collides with, and the card names the paths where the two scopes intersect. Opening it anyway needs an explicit override, which is written into the ledger, because deciding to run it regardless is a decision somebody should be able to find later.
Repo at its writer cap A repo declares how many sessions may hold it at once. A cap above 1 is only safe because every concurrent pair was proved disjoint by path comparison.
No policy row A repo that isn't in the policy table routes nothing. Guessing its deploy style or verification method is how a change ships that nobody proved.
No readable target A brief whose routing block names no repo isn't carded, and the router won't infer the target from the prose.
Unrecognized filename word An unknown word routes nothing and is printed with the word it should have been, so a near-miss is caught rather than resurrecting a closed brief.
Already closed A brief whose lane already filed a CLOSE record is finished work wearing a live filename. It's refused unless its header declares that it's meant to refire, and the card says so in both directions.
Held elsewhere A repo belonging to another dispatcher is skipped by name rather than silently omitted.
Held until a date A brief with a not-before date stays visible and carded the whole time it's held, rather than disappearing from the board on the day somebody needs to see it.
Existing branch or checkout Opening a lane refuses to reuse a branch name or a checkout directory that already exists. Reusing a merged branch name is the consumed-name problem in git form.

Two quieter refusals matter as much. A card whose scope is truncated by the display limit is counted and named, because a work queue that truncates without saying so reads as "there is nothing for you to do". And a lane left open with no close is flagged as orphaned and stops holding its slot, but is never auto-closed: writing a close record here would manufacture measurements nobody took.