Agents add abstractions nobody asked for and dependencies for three lines of logic. Told to keep it simple, they cite stdlib APIs that don't exist. omit asks them to write less and cite every shortcut, then checks, from hooks, a pre-commit gate and CI that run outside the model.
$ omit gate
omit verdict
────────────
net: +0−168 lines across 1 file
new deps: 0 ✅
hazards: 0 ✅
footnotes: 0 recorded · load-bearing: 0 marked
receipts: none recorded
lint: no linter configured
@@ 01 · what it refuses @@
Four refusals, copied from real runs.
Nothing below is a mock-up. Each block is output from omit 0.9.0: three from a scratch repository with the staged change described beside it, one from the session that built this page.
Every repo, every mode
A secret, and TLS switched off.
Staged: an AWS-shaped access key, an HTTPS agent with certificate verification disabled, and a new left-pad dependency, in a repo that never adopted omit.
The key and the TLS bypass block the commit. The uncited dependency is counted and let through, because this repo didn't agree to editorial rules. Secrets have no override.
pre-commit · repo without .omit/
$ omit gate
omit verdict
────────────
net: +3 −0 lines across 2 files
new deps: 1: left-pad (1 without receipts ⚠)
hazards: secret:aws-access-key, tls:reject-unauthorized-false ⛔
footnotes: 0 recorded · load-bearing: 0 marked
receipts: none recorded
lint: skipped
⛔ omit gate: 1 secret(s) staged. Move to env/secrets manager, rotate if real, restage.
⛔ omit gate: TLS-verification bypass staged. Point TLS at the CA bundle instead of switching verification off, or mark a reviewed line with omit-allow: <reason>.
Repos that adopted omit
A dependency nobody justified.
Staged: the same left-pad line in package.json, this time in a repo that tracks .omit/.
A new dependency needs a receipt naming the omissions that were tried first. The refusal prints the exact line to write.
pre-commit · adopted repo
$ omit gate
omit verdict
────────────
net: +1 −1 lines across 1 file
new deps: 1: left-pad (1 without receipts ⚠)
hazards: 0 ✅
footnotes: 0 recorded · load-bearing: 0 marked
receipts: none recorded
lint: no linter configured
⛔ omit gate: new dep(s) without a verified receipt: left-pad.
Add one line to .omit/receipts.jsonl naming the dep and the omission you tried (each entry is re-checked, and must NOT hold):
{"claim":"new-dep","rung":7,"dep":"left-pad","tried":[{"rung":2,"absent":"<symbol you searched for>"}]}
Run `omit verify` to check it before committing.
Repos that adopted omit
A shortcut that was never checked.
The agent writes the receipt: "I looked for padTo, it isn't here, so I need left-pad." omit searches the tree itself. padTo is at src/util.ts, so the agent's own citation refutes the dependency.
A receipt is one JSON line with evidence the tool can re-run: a file:line:symbol, an argv that exercises the API it names, or a symbol to search for. Evidence only its author can read is a self-report.
$ omit verify
✅ line 1 verified reuse
✅ line 2 verified stdlib
⛔ line 3 failed new-dep
[new-dep] tried[0] (rung 2) actually HOLDS: padTo is present at src/util.ts — so the omission applies and this dep is not needed
2/3 claims survived re-checking · 1 refuted · 0 unverifiable
Every repo, every mode
A command that could hit your home directory.
This one happened while this page was being built. The agent writing it tried to clear a scratch directory with rm -rf $R. The command sentinel stopped it before the shell ran.
Sentinels run inside the agent session, on the command or edit itself: destructive commands, secrets about to be printed into the transcript, hardcoded keys, and attempts to disarm omit's own hooks.
command sentinel · before the shell runs
omit blocks this command: the machine is load-bearing.
[unset-variable-delete] recursive delete through a variable ($R); if it is empty or unset this can hit / or the home directory. Use ${VAR:?} or check it first
Use a narrower target inside the workspace, or guard variables with ${VAR:?}.
Only after genuine review with the user, append: # omit-allow: <reason>
@@ 02 · where it applies @@
Safety is everywhere. Editing is opt-in.
Objecting to an uncited dependency is an imposition on a codebase that never agreed to it. Objecting to a leaked key is not.
Every repo, every mode
Safety
Destructive shell commands
Hardcoded secrets, and commands that would print one
Certificate-verification bypass
Tampering with omit's own hooks, mode or trust keys
The commit gate always blocks secrets and TLS bypass, even with the mode set to off.
Repos that adopted omit
Editorial
Injection-prone patterns on added lines
New dependencies without a verified receipt
Receipts the tree refutes
The repo's own linter, run on the staged content
The Final Draft gate at the end of a session
Adopted means .omit/ is tracked, or git config omit.enforce true is set.
margin
Editorial objections are reported, not enforced.
redline default
Full enforcement.
rewrite
Redline, and question the assignment before building.
off
Editorial gates are quiet. Safety stays on.
The mode lives in .omit/mode. The hooks enforce it, and the tamper sentinel stops the agent from writing it, or from running git config omit.enforce false.
@@ 03 · the discipline @@
Draft less. Cite everything. Cut last.
The rule file turns the agent from author into editor. It is plain markdown, and it works in any agent that reads one.
Before codeThe Seven Omissions
Try not to write it, in order. Stop at the first omission that holds.
The feature. Speculative need is needless until proven.
The new code. The codebase already does this.
The custom. The standard library covers it.
The script. The platform does it natively.
The dependency. An installed one covers it.
The ceremony. One plain line beats a pattern.
What survives editing, ships. Fewest files, shortest diff.
While writingThe Fact-Check
No omission counts without a receipt that something other than the agent can check. "The codebase has this" cites a file, line and symbol. "Stdlib covers it" carries a snippet that runs.
A new dependency is the strongest claim. Its receipt says the earlier omissions were tried and did not hold, so every one is re-checked and must fail.
Never cutLoad-bearing lines
Input validation at trust boundaries
Error handling that prevents data loss
Security, accessibility, concurrency
Anything explicitly requested
After it worksThe Final Draft
Working code is a first draft. One ruthless edit of the agent's own diff, then a net report in .omit/final-draft.md:
files touched: <n>
lines +<added> −<removed>
new dependencies: <n>
The session can't end with an edited tree and no current report, and its counts are checked against the actual diff, so a stub fails. Done means final draft, not green tests.
On the recordFootnotes
// omitted: retries; single caller tolerates failure; add backoff if this goes multi-tenant
@@ 04 · ci · new in 0.9 @@
The hook runs as the agent it checks. So CI checks again.
omit gate --range judges every commit in a pull request against its first parent. A secret added in one commit and removed in the next still fails.
The base decides the rules. Adoption and mode are read from the base revision's tree. A PR that deletes .omit/ or sets the mode to off is still gated by the base's rules.
The verdict is deterministic.--json prints sorted keys, no timestamps and no paths: byte-identical for the same inputs, with the omit version and a hash of the rule files.
A PR can't rewrite the job. This repo runs the range as a job named omit-gate on pull_request_target, which uses the base branch's workflow definition. It has contents: read only, checks the PR out as inert files, and runs with execution off.
Make it a required check so the job can't be deleted either.
The published Action also comments the verdict on each pull request and edits that comment in place. Its gate input runs inside your own pull_request job, which a PR can edit. For a gate a PR cannot rewrite, use a separate pull_request_target workflow. See this repo's.
A list of mechanisms invites you to read it as a guarantee. It isn't one. Each of these is a known, reproduced limit.
The gate runs a repo's own code by default. Receipts' run snippets and the repo's linter execute as you. In a repo you haven't read, set OMIT_NO_EXEC=1. Range mode in CI already runs with execution off.
Some writes reach no file sentinel. When the path can't be read out of the command (python -c, curl -o, node -e), a literal secret in the command text is still caught. Its injection patterns are not.
It is a git hook.git commit --no-verify skips it. The command sentinel stops an agent from running that, not a person. Nothing can stop you bypassing your own pre-commit hook, which is why CI recomputes the verdict.
The dependency parser list is short.setup.py, build.gradle, Package.swift and *.csproj are reported as unparsed, and the gate does not fail on them.
Receipt evidence is bound textually. A snippet that names a symbol without calling it passes.
The leak sentinel misses one shape. A redirect trailing a for … done loop isn't attributed back to the loop body.
Needs Node 20 or newer. Or brew install sriinnu/tap/omit.
npm install -g @sriinnu/omit
Gate every commit in a repo
Writes omit gate into .git/hooks/pre-commit. It checks every commit, whatever wrote it.
omit hook install
Give your agent the rules and live hooks
Claude Code
Skill, /omit, /omit-edit and every hook.
/plugin marketplace add sriinnu/omit
/plugin install omit@omit
Codex
Rule file, then sentinels merged into .codex/hooks.json.
omit init codex
omit hook install codex
Cursor, Cline, Windsurf, Copilot
A rule file in the place each one reads. Swap the name.
omit init cursor
Anything else
Any SKILL.md-aware agent, or plain AGENTS.md.
npx skills add sriinnu/omit
omit init agents
Agents without a hook system still meet the pre-commit gate and the CI check. To opt a repo into the editorial half, commit .omit/ or run git config omit.enforce true.