mcpField
C
completion-gate

completion-gate

github.com/caanioTesting & quality042 installsUpdated today
Repository

About completion-gate

completion-gate is a skill for AI agents that defines what must be verified before work is considered complete. It separates mechanical checks from independent judgment and sets fallback rules when no reviewer is available.

Key features

  1. 01Separates mechanical checks from judgment
  2. 02Requires independent review for judgment calls
  3. 03Defines verification by artifact type
  4. 04Provides a no-reviewer downgrade path
  5. 05Specifies delivery and failure-handling rules

Use cases

  1. 01Checking code changes before a commit
  2. 02Verifying documentation and configuration edits
  3. 03Handling work when no subagent is available

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/caanio/agent-skills --skill completion-gate

After installing, type/completion-gatein Claude Code to confirm it loaded.

Details

From the project README

completion-gate

The gate between "I think it works" and "it is done".

Scope boundary — these compose in sequence, they do not compete:

  • Whether something counts as done → here.
  • How to farm a check out to a subagent (thresholds, prompt structure) → your own delegation rules, wherever they live.
  • The mechanics of committing (staging, secrets scan, message wording) → your commit-workflow skill, entirely. This skill only governs what must happen before a commit.
  • The mechanics of a thorough code review (a multi-axis check, severity labels, a real checklist) → your code-review skill, entirely — this collection doesn't ship one (e.g. a built-in /code-review that forks a fresh context, or any review agent you dispatch with only the diff). The Code row below is the one place that says what to do when none is installed.
  • Security review of code crossing a trust boundary → your security skill, entirely — this collection doesn't ship one (e.g. security-and-hardening while writing it; a built-in /security-review of the pending diff after every code change; security-audit as a focused review when the change crosses a trust boundary, and in full before a first production deploy). The security row below is the one place that says what to do when none is installed.
  • A deeper maintainer-handover pass (backfilling ADRs, checking README/CONTEXT.md against reality, recording production facts and the deploy path) → the handover skill. Run it only after this gate passes, never in place of it; wrap-up step 6 runs it.

Core Rules

  1. [NEVER VIOLATE] You may run a check; you may not be the one who decides your own work passed. Split the two:

    • Deterministic mechanical checks — a test suite's exit code, a diff, a linter, a build, a script's output. Run these yourself. The result does not depend on your opinion, and shipping them to a subagent usually just breaks them (wrong working directory, missing environment).
    • Anything requiring judgement — "is this documentation clear?", "does this design hold?", "is this test actually testing the right thing?", "is this finding real?" — goes to a fresh context that was not told your reasoning: hand it the artifact and the acceptance criteria only, never your defence of the work. A reviewer who has read your argument reviews your argument. Your own answer here is worth very little; you already believe you were right, which is why you wrote it that way.

    The trap this rule exists to close: running a green test suite and concluding the task is done. Green means the assertions you chose passed. Whether they were the right assertions is a judgement call, and therefore not yours. How much independent judgement a given change deserves is proportional to its risk — the Code row below draws that line. This rule fixes who sets the standard, not how much review every change gets: you may not quietly lower the bar for your own work. That proportionality is specific to code. The Docs row and the wrap-up read-back have no size exemption — a one-line edit to a rules file still gets read back, because the failure there is silent.

  2. [NEVER VIOLATE] A yes/no confirmation question about a destructive operation, a trust-boundary decision, or unattended automation may not recommend its own answer until the judgement-call check below has run. Check the artifact-type table before drafting the question — not after the user pushes back. If the change is a hard judgement call, get the independent second opinion first, then ask "reviewed, ready to commit?" — never "commit this? (recommended)". ⚠️ Observed twice, independently: the model proposed the risky change as done-pending-approval, and the review only happened because the user pushed back — not because the model raised it.

  3. [NEVER VIOLATE] Completion language may not precede the result it describes. Ran / PASS / verified / confirmed / passed — when used as a claim about your own deliverable — must never be written into a file or message before the corresponding check has actually returned. Draft with "pending" and fill it in once real output exists. No "it will run in a minute" exemption: writing it early plants a fact readers will believe, and it stays false even if the check later passes. (This governs claims. It does not touch ordinary content that contains those words — test fixtures, report templates, assert status == "PASS", or reporting what someone else verified.)

  4. State the verification method before you start. If you cannot write down "here is the command or observation that will prove this worked" before touching anything, you do not yet understand the task. Go gather information instead of starting.

What Counts as Verification, by Artifact Type

ArtifactLegitimate verification
CodeRun the tests or actually execute it — yourself. Compiling is not behaving. Then, when the tests are new, or the change touches anything in the judgement-call row below, hand it to a code review that runs in a fresh context (see Scope boundary) — a same-context review checklist is an authoring aid, not this check: you would be grading your own work (Core Rule 1); with none installed, at minimum have a fresh context judge whether those tests cover what the task actually asked for. A typo fix does not need a reviewer; a new module's first test suite does. ⚠️ An adversarial second opinion is the judgement-call row's check, not this one's, and it reviews only the scope you handed it. Observed: fifteen rounds of adversarial review on one class, taken as the code review of a 14-file diff; a fresh-context review of the same diff then found two real crash paths outside that class in five minutes.
Security review of code crossing a trust boundaryYour security skill (see Scope boundary). With none you can run yourself, you must at minimum hand a fresh context the diff and ask where it takes anything from outside the program's control, and what that can make the code do or expose. That is a stand-in, not the review: paste its output under part 2 of the delivery message without calling it a security review or a pass, and list the security review under part 3 as not done. No fresh context either → the downgrade below, naming the security review as the gate that did not run. The Code row governs tests and code-review triage only; it makes no security judgement of its own.
Docs, rules, configGive the file to a fresh context and have it answer questions using only that file — and the questions must target the passages your change touched, or the gate is theatre. Wrong answers are a finding about the file, not about the reader. When the change swapped a personal value (PII: a name, an address, a home or workplace coordinate) for a placeholder, one question is fixed: does anything in the file, its header or the changelog say the value was real or was replaced? A yes is a finding — a placeholder is silent about its origin. The mechanical scan for this lives in your commit-workflow skill, not here.
A hard judgement call (architecture trade-off, elusive bug, trust-boundary design, data migration, technology choice)An independent adversarial second opinion. When it disagrees, analyse the disagreement — do not pick whichever answer you preferred.
A destructive or irreversible operationOut of scope for this skill. Confirm the blast radius before, read back the effect after, and follow whatever high-risk procedure you operate under. Only add the adversarial review if the operation is also a hard judgement call, or if you cannot tell whether it is.

Where an artifact type has an authoring standard of its own — your Python standards, your skill-writing skill, your API-design skill, your TDD skill for the tests (e.g. test-driven-development), a same-context review checklist (e.g. code-review-and-quality) — that standard's rules are part of this table's verification for that type, not a separate pass beside it. Judge the diff against them one rule at a time. Rules where every reader reaches the same verdict (a missing type hint, a print where logging is required) you settle yourself; rules where competent readers could differ (does this test cover the right thing, is this the right abstraction) are the judgement-call row, whichever way you think they came out — and so is any rule you cannot confidently sort. Claiming a file has no such standard, or that its standard already ran and the work has not moved since, is a finding like any other: say where you looked. Where no such standard is installed anywhere, the type's own row already says what to do.

Choose the cheapest reviewer that is actually qualified — a cheap model doing mechanical read-back beats an expensive model doing nothing. You economise on the unit price of verification, never on its existence.

When No Subagent Is Available

Some environments cannot spawn agents at all; some runs are additionally non-interactive (CI, headless, scheduled) with nobody to authorise an exception. Neither unlocks self-certification.

Always, whatever else is or isn't available: run every deterministic mechanical check you can, yourself. That part never depends on having a reviewer.

Then find the independent judgement:

  1. A human is a fresh context. If someone is there, hand them the artifact and the acceptance criteria and ask what you would have asked a reviewer — or ask for a one-off exemption and record that you got it. "No subagents" is not the same as "no independent reader", and conflating the two is how an interactive session talks itself into self-certifying.
  2. Only when there is genuinely nobody to ask — the downgrade: mark the output "unverified draft" and name exactly which judgement-level gate did not run, and why. Where a rule elsewhere says "ask the user" and there is no user, take this same path rather than proceeding as if the question had been answered.

A downgraded delivery is honest. It is still not a pass.

The Delivery Message: Three Mandatory Parts

  1. What was done — the change, in the reader's terms.
  2. How it was verified, and the raw result — paste the actual output. A summary of a result is not a result.
  3. What was not done — skipped steps, unverified areas, known gaps, anything deferred. State it even when nobody asked.

Failure Counting (for work you performed yourself)

A failure is: verification did not pass, an acceptance criterion was violated, the same tool error recurred, or the user corrected you.

AttemptWhat you are allowed to do
1stRecord the exact error text verbatim. Identify the single difference from what you expected. Change one variable. Retry.
2ndStop trying variants. Write down what you tried and the evidence. Change approach, or escalate to a stronger model.
3rdThe same route is now forbidden. Pick one: roll back, re-plan from scratch, or take the failure record to the user (no user → downgrade as above).

⚠️ Two consecutive "I changed it but nothing changed" means you are not editing the thing that runs. Prove the code path is actually being executed before editing it a third time. Recorded repeatedly in practice, not a theoretical worry: it is the most expensive loop to stay stuck in, and from the inside it always looks like bad luck.

End-of-Session Wrap-Up (run in this order)

  1. First, confirm every artifact this round has produced — code, docs, rules, config — has actually passed its own row in the table above. For code: tests run yourself, code-review triage if the tests are new or the change is a judgement call, a security skill if it crosses a trust boundary — or, with none you can run, the security row's stand-in. For docs, rules and config: the Docs row's read-back, with no size exemption (Core Rule 1). Docs describe verified behaviour, not aspirational behaviour: writing them before this holds means step 2 documents something that may still be broken.
  2. Update the substantive docs first. Walk the diff and ask of each doc the repo tracks: "does this describe behaviour or a decision my change just invalidated?" If yes, update it. If unsure, list the candidates and ask — never skip silently. Do not re-transcribe what the code already states.
  3. Prove step 2 actually happened. If you edited any doc, hand the changed file plus a summary of the intended change to a fresh reader and ask whether the file now reflects it. It must answer yes and quote the passage back. If it cannot, return to step 2 and really make the edit — you may not proceed. Twice unable to answer → stop and ask (no user → downgrade). This is deliberately narrower than the open-ended read-back above: that one asks "does this file teach correctly?", this one only asks "did the edit land?". Telling the reader what you intended would anchor the first question, but it is the second one — which is why the answer has to be a quotation rather than a yes. A doc edited in step 2 still owes the Docs row's open read-back on top of this check; run it before step 4. ⚠️ Without this check, step 2 degrades into claiming an update that was never made — observed in practice, not hypothetical.
  4. Decide out loud whether this also needs the adversarial second opinion from the judgement-call row above, or for a rules/config file whose failure mode is silent. State a recommendation — run it or skip it — with your reasoning, every time step 3 finishes, whether it passed or had to escalate. Running it is optional and proportional to risk; skipping it is a choice you record, not a default you fall into silently. Steps 5–6 proceed either way — this step only blocks one thing: you may not write verified / PASS as a claim about the change until the second opinion you decided to run has actually come back.
  5. Then update the repo's next-steps list: the one priority list a fresh session reads to learn what's next. First list what the whole session changed, file by file, not recalled from memory: git status --short (a new tracker ticket is usually untracked), git diff --stat <last commit before this session>..HEAD, and the tickets it opened in a remote tracker, queried from the tracker. Find the list: the one the repo's CLAUDE.md / AGENTS.md routes what's-next questions to, or holds itself. No route → adopt an existing docs/TODO.md or TODO.md; two candidates → ask which one. Then: items this session closed leave the list, items it opened enter it, items it advanced get their next action rewritten. Nothing opened, closed or advanced → this step writes nothing. An item it opened or advanced is still open and no list exists anywhere → create docs/TODO.md, ending with one unranked entry that points at the repo's other open tracker tickets (their folder, label or list command). A list you adopted or created gets a route line in whichever of CLAUDE.md / AGENTS.md the repo already loads; with neither, list the missing route under part 3 of the delivery message. One entry per open item, in priority order. Each entry you write or rewrite carries what it is, why it holds that rank, its next concrete action, and the path to read first. Tickets of one feature share one entry pointing at their folder or label. Detail stays in its own doc (ADR, spec, ticket, a topic list) and the entry points at it — which is why this step comes after the real docs: written first, it points at content that no longer exists. Done when: every item this session opened, and every tracker ticket it opened or re-ranked that is still open, has an entry; every item it advanced has a current next action; every item it closed is gone; the list order is the priority order; the list, and any route line you added, passed the Docs row's read-back. ⚠️ This checks a different scope than step 2: step 2 asks "did this round's diff invalidate a doc", step 5 asks "has the whole session's accumulated work drifted from the next-steps list". A round with nothing to update in step 2 does not excuse skipping step 5 — reusing that verdict across both has produced a stale next-steps list in practice.
  6. Then run handover yourself, every time, with no question to the user. Its step 1 decides whether anything is owed: an empty candidate list ends it with one handover-skip: <reason> line in your reply. Done when: the reply shows handover's report or that skip line, before any commit is drafted. ⚠️ Observed in practice while this step was still a question to the user: finishing step 5 reflexively rolled straight into commit and the question was never asked — the reason the done-when above requires the report or skip line in the reply.

Comments

Markdown supported