Lint-Enforced Agent Guardrails

Custom linting rules are the strongest anti-slop mechanism for AI-assisted codebases. They make bad patterns impossible to commit, forcing agents to solve problems correctly instead of cheating.

The Insight

Agent rules, system prompts, and code review catch slop after the fact. Custom lint rules catch it at write time. When an agent generates code that violates a lint rule, the agent's own feedback loop rejects it before the code can land. The agent is forced to try again with a valid approach.

This is especially capable for test quality. Agents commonly generate tests that look correct but prove nothing. A custom lint rule that detects these patterns turns a review burden into an automated gate.

Codex agents are particularly effective at creating custom ESLint rules. Point an agent at a pattern you want banned, and it will produce an AST visitor that detects it. The agent that creates the rule is preventing its future self from cutting corners.

Test-Quality Rules (Dedalus)

Three custom ESLint rules built by a Codex agent to enforce test rigor on Supabase service tests:

Rule Severity What it catches
no-unscoped-service-test error Test files that create a mock Supabase client but never assert org/user scoping. The mock exists, but the test never verifies that queries are scoped to the right tenant.
require-error-code-assertion warn Tests that check ok === false without asserting the specific error code. Proves the call failed, but not how it failed.
no-mock-echo warn Tests that compare result.data to the exact value the mock was told to return. The test is just echoing the mock setup back - it proves the mock works, not the code.

The no-mock-echo pattern is the most common agent failure mode. An agent sets up mockReturnValue({ id: 1, name: "test" }), calls the function, then asserts expect(result.data).toEqual({ id: 1, name: "test" }). This test will always pass and tests nothing. The lint rule makes this pattern impossible to commit, forcing the agent to write a test that actually exercises logic.

The reviewed KingBootoshi artifact is useful because it shows the rules as delivered agent output, not only as advice: one blocking rule for missing tenant scoping and two warning rules for weak error-code and mock-echo assertions. The follow-up generalizes the pattern beyond TypeScript: pylint, clippy, and clang-tidy are equivalent structural enforcement surfaces when the codebase is Python, Rust, or C++. Source: X/@KingBootoshi thread and local image artifact, 2026-07-03

Architecture-Policy Rules (Dedalus React)

Custom mft-react plugin rules that encode repo-specific architectural decisions:

Rule What it catches
no-derived-state-in-effect useEffect that only computes derived state from props/state and calls setState - should be useMemo or inline render logic
no-fetch-in-effect fetch() or axios.*() inside useEffect - should use TanStack Query, SWR, or server-side fetching
no-query-client-in-component new QueryClient() inside a component body - creates a new client per render
no-void-query-fn TanStack Query queryFn that returns void (calling setState instead of returning data)
no-unstable-query-result-deps Destructured TanStack Query results (data, error, isLoading) in dependency arrays - these are new object references every render
query-key-deps queryKey missing variables that queryFn uses - causes stale cache hits

These rules are invisible to engineers who already know the patterns. They exist to catch agents and newer contributors who default to anti-patterns that look correct but cause subtle bugs.

The reviewed @ismailhoush image shows this table as a concrete React policy bundle rather than a generic linting slogan: three upstream React rules catch unstable render identity, while the custom mft-react rules block architectural drift around derived state, data fetching, QueryClient lifetime, void query functions, unstable query-result dependencies, and incomplete query keys. Source: X/@ismailhoush and local image artifact, 2026-07-04

Upstream Rules (ESLint 10)

Upstream React rules shimmed via @eslint/compat for ESLint 10:

Rule What it catches
react/jsx-no-constructed-context-values New objects/arrays inline in context providers - re-renders all consumers
react/no-array-index-key Array index as React key - causes subtle bugs on reorder/delete
react/no-unstable-nested-components Components defined inside other components - remounts on every render

The Principle

Rules, prompts, and code review are advisory. Lint rules are structural. An agent can ignore a comment in AGENTS.md. It cannot ignore a lint error that blocks the commit hook.

The hierarchy of enforcement:

  1. Brin allowlist - blocks dangerous dependencies at install time (see Brin - Agent Context Security)
  2. Lint rules - impossible to violate (blocks commit)
  3. Type system - impossible to violate (blocks compile)
  4. Codebase doctors - catches systemic drift at session end (see Doctor Pattern)
  5. Pre-commit hooks - impossible to skip (blocks push)
  6. CI checks - caught before merge
  7. Code review - caught before merge, but requires human attention
  8. System prompts / rules files - advisory, agent may ignore or misinterpret

Invest in the top of this hierarchy. Every pattern you can move from level 5-6 to level 1-2 is a pattern you never review again.


Timeline

  • 2026-07-04 | Added the @ismailhoush React architecture-policy table as corroborating artifact for the Dedalus mft-react rule set and upstream React identity rules. Source: local artifact wiki/assets/x-bookmarks/2041263014200975585/image-01.png
  • 2026-07-03 | Deep-reviewed the local screenshot for the KingBootoshi bookmark. It shows three agent-authored ESLint rules wired up (no-unscoped-service-test, require-error-code-assertion, no-mock-echo), matching this page's Dedalus rule set and reinforcing that lint rules should encode concrete failure modes discovered in agent-written tests. Source: local artifact wiki/assets/x-bookmarks/2041215775034487267/image-01.jpg
  • 2026-04-06 | @KingBootoshi's viral restatement of the thesis: "PUT YOUR AGENTS ON CUSTOM ESLINT RULES ASAP… the best way to GUARANTEE ANTI-SLOP… by making it impossible to do slop patterns. Codex agents are REALLY good at creating custom ESLint patterns." 730 likes, 1,109 bookmarks. His follow-up generalizes across languages — pylint (Python), clippy (Rust), clang-tidy (C++) all support custom lints, and agents implement them well when pointed at the right docs. Source: X/@KingBootoshi, 2026-04-06
  • 2026-04-07 | Page created from Kevin's X post + Codex agent output (Dedalus test-quality + React architecture-policy rules). Source: Kevin Liu, 2026-04-07