gap-trap
Sets up a quality framework for repositories where agents write most of
the code. Every rule the agents follow has a gate that fails a commit, a
push, or a CI run when the rule breaks. A rule a script could check but
that names no gate is a defect. The framework is the one described in
reference/framework.md; read it before either mode.
Two modes: setup builds the framework in a repo that has none.
refine audits a repo that has it and proposes the next rules and gates
from what broke. Bare gap-trap with no keyword means setup when the
repo has no AGENTS.project.md, otherwise refine. A hand-written
AGENTS.md or CLAUDE.md on its own is input to setup, not a sign the
framework exists.
Model gate
This skill runs on the top coding model of your harness: in Claude Code,
Opus or a more capable model (Opus 4.8 or newer, Opus 5, Fable, Mythos);
in Codex, the frontier coding model at high or xhigh reasoning effort.
Discovery decides which parts of a codebase get a contract, and a wrong
contract costs every later session. Your system prompt names your model.
If it is a cheaper or faster tier (Sonnet, Haiku, a mini model, or low
reasoning effort), stop. Read nothing, write nothing. Say exactly this
and end the turn:
gap-trap runs on the top coding model of this harness. You are on
. Switch with /model, then run gap-trap again.
Do not dispatch stronger subagents from a weaker orchestrator, start
"the easy parts", or offer a lighter version.
setup
- Discover. Follow
reference/discovery.md. It produces a plan
file in your scratch directory: stack, commands, CI provider,
contract candidates with real symbol names, the first domain facts
from history (the revert probe runs at any commit count), and one
row per rule found in an existing instruction file with where it
goes and what gates it.
- Confirm once. Show the plan as a short list: the contracts you
will write (at most six), the gates you will add, the test and lint
commands you found, the migrated-rules table, and where slop-mop
goes. A build, type check, or
lint that is already red is the first item: setup fixes only what
its own gate files need (a missing type package, a lockfile) and
records the rest as a ratchet count or an out-of-scope entry. Name
the cause of each red before recording it: reproduce it, read the
failure, and say what is broken. A failure that names an environment
variable can still be a code defect. In one trial, seven tests
failing with
Environment variable not found: DATABASE_URL were a
Prisma mock loaded after the module under test, not a missing .env;
recording that as an environment gap would have buried the bug and
the contract that prevents it. Ask one round of questions, only about
what discovery could not settle. Then proceed.
- Install slop-mop.
git clone https://github.com/pliablepixels/slop-mop.git
into your scratch directory and copy slop-mop/slop-mop to the skills
directory of the harness you are running in (Claude Code:
~/.claude/skills/; Codex: ~/.agents/skills/), skipping it if
present. It is not vendored into
the repo; the project rule in AGENTS.project.md requires it.
A harness loads its skill list when the session starts, so a skill
installed here is not available to the run that installed it: write
this run's prose from P10 in AGENTS.md, and tell the user in the
report that slop-mop applies from their next session.
- Write the instruction files from
templates/. AGENTS.md and
agents/generic/agent-workflows.md are copied unchanged, with one
exception: a rule whose gate cannot exist in this repo (I3's
accessibility lint and C3's locales in a repo with no UI) gets its
Gate: clause replaced by Gate: n/a, no <thing> in this repo.
Nothing else in AGENTS.md changes. AGENTS.project.md,
CLAUDE.md, and agents/project/ are filled from the plan; drop the
UI and end-to-end lines and {{E2E_CMD}} when the repo has no UI, and
delete every placeholder you cannot fill with a verified value.
Contracts name real symbols only. Existing instruction files
(AGENTS.md, CLAUDE.md, .cursorrules,
.github/copilot-instructions.md, CONTRIBUTING.md) are migrated
from the plan's migrated-rules table, one row at a time: a contract
row becomes a contract block, a rule row becomes a project rule with
its gate name or Gate: review, a playbook row goes verbatim into
the named agents/project/ file, a command row fills the
verification block, and a duplicate or dropped row is left out. No
rule is dropped silently; the confirm step showed the table. A file
whose name a template owns (AGENTS.md, CLAUDE.md) is replaced by
that template. Any other instruction file (.cursorrules,
.github/copilot-instructions.md) becomes a one-line pointer to
AGENTS.md, so the agent that reads it lands on the rules instead of
a stale copy. CONTRIBUTING.md stays where it is. The user sees the
diff.
- Write the gates from
reference/gates.md, in the repo's own test
runner and CI provider: the instruction gate, proven red, the PR body
check, the ratchet (always, seeded with the counters the repo
supports: files over the C2 length, lint problems per rule when a
linter runs, each contract Never clause that has violations today),
and the mutation smoke when discovery named a risky module (auth, a
parser, the API client); otherwise refine adds it after the first
fix chain. The stack table there picks the reference: native ports
for Node and Python, shell references that need only git, grep, and
awk for every other language. Set the instruction gate's word budget
at the current count plus half, rounded up to the next 500.
- Prove each gate red with a scratch violation, remove the
violation, run the repo's full test command, and commit one logical
change per commit, in this order: the instruction files with the gate
that checks them; one commit per gate after that (ratchet, proven
red, mutation smoke, PR body check); the combined gate command and
the pre-commit hook; CI last. One commit holding the whole framework
hides which gate was proven red against what, and leaves nothing to
revert on its own. Do not push unless asked.
- Report what was written, the instruction word count against the
budget, which contracts say
Gate: review and why, whether this run
installed slop-mop and so it applies from the next session, any
always-loaded file outside the repo whose prose style conflicts with
the repo's (~/.codex/AGENTS.md, ~/.claude/CLAUDE.md, a terse or
compressed house style): name the file, and say that the repo's rule
governs repo prose. End with the one next step: run gap-trap refine
after the first incident or in a month.
- Offer a check. End the report with one question: check the repo
against the new framework now? On no, stop. On yes, change no files
and list, grouped by contract or rule ID:
- each ratchet counter, its count, and the file and line behind each
unit of it;
- each
Gate: review contract: read the code its Path: and
Never: lines cover and list suspected violations with file and
line, marked unverified because no gate checks them;
- the red build, type check, or lint items recorded in step 2.
Fix nothing in this pass. A fix the user picks is its own commit,
and a fix that lowers a count reruns the ratchet with
--update.
Instruction files are read by agents. Write them as terse statements
with IDs and gate names. Human-voice prose belongs in the repo's docs,
not in AGENTS*.md or agents/.
refine
Follow reference/refine.md. It audits rules without gates, contract
names that no longer exist, and the commit history since the last
refine, and it proposes edits through the self-improvement protocol as
one PR. It removes rules with no incident behind them as readily as it
adds gates.
Common mistakes
| Mistake |
Fix |
| A contract with a guessed symbol name |
Every name in a Path: line is greppable in the tree; the instruction gate fails otherwise |
| Writing ten contracts on day one |
Start with the places that have one sanctioned path and a violation today; add the rest through refine |
| A gate that passed on first run |
Prove it red with a scratch violation first; a gate that never failed proves nothing |
| Vendoring slop-mop into the repo |
It installs per agent from its repo; the project rule requires it |
| Instruction prose polished for people |
Agents read it. Statement, one-clause why, gate name |
| Skipping the model gate because the repo is small |
Discovery quality is the deliverable; the gate is first for a reason |
1---2name: gap-trap3description: Use when asked to set up, install, or refine an agent quality framework in a repository (rules with gates, architecture contracts, proven-red tests, ratchets, playbooks), or when the user says "gap-trap", "gap-trap setup", "gap-trap refine", "gate the rules", or "make the agents' code match the rules".4---56# gap-trap78Sets up a quality framework for repositories where agents write most of9the code. Every rule the agents follow has a gate that fails a commit, a10push, or a CI run when the rule breaks. A rule a script could check but11that names no gate is a defect. The framework is the one described in12`reference/framework.md`; read it before either mode.1314Two modes: `setup` builds the framework in a repo that has none.15`refine` audits a repo that has it and proposes the next rules and gates16from what broke. Bare `gap-trap` with no keyword means `setup` when the17repo has no `AGENTS.project.md`, otherwise `refine`. A hand-written18`AGENTS.md` or `CLAUDE.md` on its own is input to setup, not a sign the19framework exists.2021## Model gate2223This skill runs on the top coding model of your harness: in Claude Code,24Opus or a more capable model (Opus 4.8 or newer, Opus 5, Fable, Mythos);25in Codex, the frontier coding model at high or xhigh reasoning effort.26Discovery decides which parts of a codebase get a contract, and a wrong27contract costs every later session. Your system prompt names your model.2829If it is a cheaper or faster tier (Sonnet, Haiku, a mini model, or low30reasoning effort), stop. Read nothing, write nothing. Say exactly this31and end the turn:3233> gap-trap runs on the top coding model of this harness. You are on34> <model name>. Switch with `/model`, then run gap-trap again.3536Do not dispatch stronger subagents from a weaker orchestrator, start37"the easy parts", or offer a lighter version.3839## setup40411. **Discover.** Follow `reference/discovery.md`. It produces a plan42 file in your scratch directory: stack, commands, CI provider,43 contract candidates with real symbol names, the first domain facts44 from history (the revert probe runs at any commit count), and one45 row per rule found in an existing instruction file with where it46 goes and what gates it.472. **Confirm once.** Show the plan as a short list: the contracts you48 will write (at most six), the gates you will add, the test and lint49 commands you found, the migrated-rules table, and where slop-mop50 goes. A build, type check, or51 lint that is already red is the first item: setup fixes only what52 its own gate files need (a missing type package, a lockfile) and53 records the rest as a ratchet count or an out-of-scope entry. Name54 the cause of each red before recording it: reproduce it, read the55 failure, and say what is broken. A failure that names an environment56 variable can still be a code defect. In one trial, seven tests57 failing with `Environment variable not found: DATABASE_URL` were a58 Prisma mock loaded after the module under test, not a missing `.env`;59 recording that as an environment gap would have buried the bug and60 the contract that prevents it. Ask one round of questions, only about61 what discovery could not settle. Then proceed.623. **Install slop-mop.** `git clone https://github.com/pliablepixels/slop-mop.git`63 into your scratch directory and copy `slop-mop/slop-mop` to the skills64 directory of the harness you are running in (Claude Code:65 `~/.claude/skills/`; Codex: `~/.agents/skills/`), skipping it if66 present. It is not vendored into67 the repo; the project rule in `AGENTS.project.md` requires it.68 A harness loads its skill list when the session starts, so a skill69 installed here is not available to the run that installed it: write70 this run's prose from P10 in `AGENTS.md`, and tell the user in the71 report that slop-mop applies from their next session.724. **Write the instruction files** from `templates/`. `AGENTS.md` and73 `agents/generic/agent-workflows.md` are copied unchanged, with one74 exception: a rule whose gate cannot exist in this repo (I3's75 accessibility lint and C3's locales in a repo with no UI) gets its76 `Gate:` clause replaced by `Gate: n/a, no <thing> in this repo`.77 Nothing else in `AGENTS.md` changes. `AGENTS.project.md`,78 `CLAUDE.md`, and `agents/project/` are filled from the plan; drop the79 UI and end-to-end lines and `{{E2E_CMD}}` when the repo has no UI, and80 delete every placeholder you cannot fill with a verified value.81 Contracts name real symbols only. Existing instruction files82 (`AGENTS.md`, `CLAUDE.md`, `.cursorrules`,83 `.github/copilot-instructions.md`, `CONTRIBUTING.md`) are migrated84 from the plan's migrated-rules table, one row at a time: a contract85 row becomes a contract block, a rule row becomes a project rule with86 its gate name or `Gate: review`, a playbook row goes verbatim into87 the named `agents/project/` file, a command row fills the88 verification block, and a duplicate or dropped row is left out. No89 rule is dropped silently; the confirm step showed the table. A file90 whose name a template owns (`AGENTS.md`, `CLAUDE.md`) is replaced by91 that template. Any other instruction file (`.cursorrules`,92 `.github/copilot-instructions.md`) becomes a one-line pointer to93 `AGENTS.md`, so the agent that reads it lands on the rules instead of94 a stale copy. `CONTRIBUTING.md` stays where it is. The user sees the95 diff.965. **Write the gates** from `reference/gates.md`, in the repo's own test97 runner and CI provider: the instruction gate, proven red, the PR body98 check, the ratchet (always, seeded with the counters the repo99 supports: files over the C2 length, lint problems per rule when a100 linter runs, each contract Never clause that has violations today),101 and the mutation smoke when discovery named a risky module (auth, a102 parser, the API client); otherwise refine adds it after the first103 fix chain. The stack table there picks the reference: native ports104 for Node and Python, shell references that need only git, grep, and105 awk for every other language. Set the instruction gate's word budget106 at the current count plus half, rounded up to the next 500.1076. **Prove each gate red** with a scratch violation, remove the108 violation, run the repo's full test command, and commit one logical109 change per commit, in this order: the instruction files with the gate110 that checks them; one commit per gate after that (ratchet, proven111 red, mutation smoke, PR body check); the combined gate command and112 the pre-commit hook; CI last. One commit holding the whole framework113 hides which gate was proven red against what, and leaves nothing to114 revert on its own. Do not push unless asked.1157. **Report** what was written, the instruction word count against the116 budget, which contracts say `Gate: review` and why, whether this run117 installed slop-mop and so it applies from the next session, any118 always-loaded file outside the repo whose prose style conflicts with119 the repo's (`~/.codex/AGENTS.md`, `~/.claude/CLAUDE.md`, a terse or120 compressed house style): name the file, and say that the repo's rule121 governs repo prose. End with the one next step: run `gap-trap refine`122 after the first incident or in a month.1238. **Offer a check.** End the report with one question: check the repo124 against the new framework now? On no, stop. On yes, change no files125 and list, grouped by contract or rule ID:126 - each ratchet counter, its count, and the file and line behind each127 unit of it;128 - each `Gate: review` contract: read the code its `Path:` and129 `Never:` lines cover and list suspected violations with file and130 line, marked unverified because no gate checks them;131 - the red build, type check, or lint items recorded in step 2.132 Fix nothing in this pass. A fix the user picks is its own commit,133 and a fix that lowers a count reruns the ratchet with `--update`.134135Instruction files are read by agents. Write them as terse statements136with IDs and gate names. Human-voice prose belongs in the repo's docs,137not in `AGENTS*.md` or `agents/`.138139## refine140141Follow `reference/refine.md`. It audits rules without gates, contract142names that no longer exist, and the commit history since the last143refine, and it proposes edits through the self-improvement protocol as144one PR. It removes rules with no incident behind them as readily as it145adds gates.146147## Common mistakes148149| Mistake | Fix |150|---|---|151| A contract with a guessed symbol name | Every name in a `Path:` line is greppable in the tree; the instruction gate fails otherwise |152| Writing ten contracts on day one | Start with the places that have one sanctioned path and a violation today; add the rest through refine |153| A gate that passed on first run | Prove it red with a scratch violation first; a gate that never failed proves nothing |154| Vendoring slop-mop into the repo | It installs per agent from its repo; the project rule requires it |155| Instruction prose polished for people | Agents read it. Statement, one-clause why, gate name |156| Skipping the model gate because the repo is small | Discovery quality is the deliverable; the gate is first for a reason |