agentleFS
sponge-b0bsponge-b0b/Polaris/.agents/skills/coding-standards/SKILL.md

coding-standards

Skill4 starsChanged 3 months agoApache-2.0View on GitHub

Apply the repository's Python coding standards whenever creating, modifying, refactoring, fixing, or reviewing Python source code. Enforce repository configuration, project-specific data-contract, scoring, precision, async and observability requirements, modern typing, simple Pythonic design, authoritative contract migrations, minimum total complexity, and root-cause fixes. Use for any task that writes or changes Python files.

120 other projects use a version of this.

Adopted by

Most recently taken up by

Used with

Projects with it also use everything-claude-code, everything-claude-code-conventions and 10 more.

Other files people use alongside this one.

Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
  • InfopibeSkill

    everything-claude-code

    Also in 9 projects that use this

  • mryeastcodeSkill

    everything-claude-code-conventions

    Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

    Also in 8 projects that use this

  • niloykumarbarmanSkill

    agent-sort

    Build an evidence-backed ECC install plan for a specific repo by sorting skills, commands, rules, hooks, and extras into DAILY vs LIBRARY buckets using parallel repo-aware review passes. Use when ECC should be trimmed to what a project actually needs instead of loading the full bundle.

    Also in 8 projects that use this

  • tpavanipradeepSkill

    nextjs-turbopack

    Next.js 16+ and Turbopack — incremental bundling, FS caching, dev speed, and when to use Turbopack vs webpack.

    Also in 15 projects that use this

  • CodeWithBehnamSkill

    dmux-workflows

    Multi-agent orchestration using dmux (tmux pane manager for AI agents). Patterns for parallel agent workflows across Claude Code, Codex, OpenCode, and other harnesses. Use when running multiple agent sessions in parallel or coordinating multi-agent development workflows.

    Also in 17 projects that use this

  • InfopibeSkill

    investor-outreach

    Draft cold emails, warm intro blurbs, follow-ups, update emails, and investor communications for fundraising. Use when the user wants outreach to angels, VCs, strategic investors, or accelerators and needs concise, personalized, investor-facing messaging.

    Also in 22 projects that use this

  • +1 more from Infopibe

The file

Show its rules and text

We split this skill into the rules it gives an agent

76 rules. 0 are common, 70 are distinctive, and 6 are very specific to this project.

  • 0

    Common

    Most of the 104 edited versions we read keep these.

  • 70

    Distinctive

    This author's own choices. Worth a look.

  • 6

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Read applicable repository instructions such as AGENTS.md.

    line 18
  2. Distinctive:

    Follow repository-configured Python, Ruff, Mypy, formatting, and testing rules over generic defaults in this skill.

    line 21
  3. Very specific:

    Follow authoritative ADRs and docs/current/ sources when a coding rule depends on project architecture or semantics.

    line 22
  4. Distinctive:

    Do not modify lint, formatting, typing, or test configuration merely to make code pass unless changing that policy is itself part of the …

    line 24
  5. Distinctive:

    When changing domain, application, infrastructure, interface, persistence, runtime, or other contract boundaries, read:

    line 34
  6. Distinctive:

    Follow current greenfield authority:

    line 42
  7. Very specific:

    Do not treat legacy/v0_1/, quarantined historical documents, or a removed pre-greenfield contract inventory as current semantic authority.

    line 49
  8. Distinctive:

    If a concrete representation, range, polarity, fallback meaning, authority meaning, or other material contract is not established by …

    line 51
  9. Distinctive:

    When creating, modifying, or reviewing scoring code:

    line 57
  10. Distinctive:

    If the exact semantics required by new scoring code are absent from current authority, treat that as a design gap rather than choosing a …

    line 68
  11. Distinctive:

    Use modern built-in typing syntax supported by the configured Python version.

    line 80
  12. Very specific:

    Treat # type: ignore as a last resort and specify the exact error code when required.

    line 86
  13. Very specific:

    Do not use cast() merely to hide a legitimate type error.

    line 88
  14. Distinctive:

    Do not introduce another model merely to satisfy this preference when an existing type already owns the concept.

    line 98
  15. Very specific:

    Do not make pure deterministic domain calculations async when they perform no concurrent I/O or waiting.

    line 106
  16. Distinctive:

    When creating or modifying an operational boundary, consult the applicable current observability and platform architecture documents.

    line 118
  17. Distinctive:

    create parallel telemetry systems.

    line 130
  18. Distinctive:

    create competing instrumentation ownership.

    line 132
  19. Distinctive:

    consider operational behavior complete when required observability has been lost.

    line 134
  20. Distinctive:

    Use repository-configured Ruff, formatting, and Mypy rules as the source of truth.

    line 144
  21. Distinctive:

    Prefer clear, idiomatic Python over cleverness.

    line 146
  22. Distinctive:

    Use names that communicate domain meaning:

    line 150
  23. Distinctive:

    Do not encode incidental implementation details into names.

    line 156
  24. Distinctive:

    Use context managers where appropriate.

    line 178
  25. Distinctive:

    Do not impose per-call lifecycle management on long-lived resources intentionally owned elsewhere.

    line 180
  26. Distinctive:

    Every abstraction, type, option, representation, execution path, dependency, indirection layer, and file carries maintenance cost.

    line 190
  27. Distinctive:

    After understanding the real execution and data flow, evaluate these in order.

    line 194
  28. Distinctive:

    Stop at the first rung that cleanly satisfies the requirement.

    line 196
  29. Distinctive:

    If it serves only a speculative future requirement, do not implement it.

    line 200
  30. Distinctive:

    Search for existing helpers, types, services, models, and patterns before creating another implementation.

    line 206
  31. Distinctive:

    Do not duplicate behavior the repository already owns.

    line 208
  32. Distinctive:

    Prefer clear built-ins and standard-library primitives.

    line 212
  33. Distinctive:

    Do not replace obvious control flow with clever expressions merely to save lines.

    line 214
  34. Distinctive:

    Do not add a dependency merely to avoid a few clear native lines.

    line 220
  35. Distinctive:

    Prefer existing domain objects and straightforward control flow over new wrappers, helpers, configuration, or layers.

    line 224
  36. Distinctive:

    Write only what the current requirement actually needs.

    line 228
  37. Distinctive:

    If multiple solutions are equally correct, choose the one with fewer concepts and less machinery.

    line 230
  38. Distinctive:

    Before finalizing, remove anything newly introduced that is not required.

    line 234
  39. Distinctive:

    Do not use subtraction as justification for unrelated cleanup.

    line 248
  40. Distinctive:

    Do not introduce an interface, factory, base class, strategy, adapter, registry, plugin point, hook, configuration option, or extension …

    line 256
  41. Distinctive:

    Do not create wrappers, services, managers, adapters, or helpers that merely rename or forward an existing operation.

    line 262
  42. Distinctive:

    If it only delegates, remove it.

    line 272
  43. Distinctive:

    Do not introduce another DTO, model, wrapper, context object, enum, state container, or intermediate representation when an existing type …

    line 276
  44. Distinctive:

    Treat file length as an attention signal, not a defect.

    line 282
  45. Distinctive:

    Do not impose or satisfy arbitrary line-count limits unless repository configuration or an explicit requirement establishes one.

    line 284
  46. Distinctive:

    When splitting, split along real domain, ownership, dependency, or behavioral boundaries.

    line 297
  47. Distinctive:

    Do not split code merely to reduce line count when doing so would:

    line 299
  48. Distinctive:

    create circular imports or unnecessary indirection.

    line 302
  49. Distinctive:

    Prefer the smallest number of cohesive modules that make ownership and navigation clear.

    line 306
  50. Distinctive:

    When ownership, an internal contract, an API, or an invariant changes:

    line 314
  51. Distinctive:

    update every affected caller, implementation, protocol, adapter, fake, fixture, test, configuration surface, registry/bootstrap path, and …

    line 317
  52. Distinctive:

    remove the superseded internal contract and representation in the same change.

    line 318
  53. Distinctive:

    Do not preserve obsolete internal behavior by:

    line 320
  54. Distinctive:

    If genuine compatibility is explicitly required, isolate it at the compatibility boundary, identify the authority requiring it, and keep …

    line 328
  55. Distinctive:

    If the correct implementation is blocked by unresolved architecture or an external requirement, surface the blocker.

    line 330
  56. Distinctive:

    Before fixing shared behavior:

    line 336
  57. Distinctive:

    Prefer one root-cause correction over repeated downstream guards.

    line 343
  58. Distinctive:

    Do not scatter defensive checks for impossible internal states.

    line 351
  59. Distinctive:

    Do not narrate mechanics already clear from the code.

    line 363
  60. Distinctive:

    Use docstrings to preserve non-obvious semantic information, not to satisfy a documentation quota.

    line 367
  61. Distinctive:

    Do not add docstrings that merely:

    line 380
  62. Distinctive:

    Keep docstrings behavior- and contract-oriented so they remain valid when implementation details change.

    line 388
  63. Distinctive:

    Do not add machinery merely to demonstrate SOLID, DRY, dependency injection, or another design pattern.

    line 396
  64. Distinctive:

    Do not interpret this as one tiny operation per function.

    line 408
  65. Distinctive:

    Do not pre-build extension mechanisms.

    line 412
  66. Distinctive:

    Use polymorphism, protocols, strategies, or registries only when there are real implementations, an established extension boundary, …

    line 414
  67. Very specific:

    Prefer composition over inheritance unless a genuine substitutable is-a relationship exists.

    line 428
  68. Distinctive:

    Test behavior and contracts, not implementation details.

    line 434
  69. Distinctive:

    Prefer existing test modules and infrastructure.

    line 443
  70. Distinctive:

    Use integration tests when the real contract depends on wiring, persistence, component interaction, framework behavior, or an external …

    line 453
  71. Distinctive:

    Do not distort production architecture merely to make everything unit-testable.

    line 455
  72. Distinctive:

    When scoring behavior changes, verification must cover canonical score semantics and precision.

    line 459
  73. Distinctive:

    When an operational boundary changes, verification must cover required observability through the established telemetry path.

    line 461
  74. Distinctive:

    Do not duplicate issues that Ruff, Mypy, formatting, or tests already reliably detect.

    line 473
  75. Distinctive:

    Never apply a textbook refactoring mechanically.

    line 490
  76. Distinctive:

    Never simplify away required:

    line 498

“Common” is measured: kept by at least 6 in 10 of the 104 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Coding Standards

Apply these standards whenever creating, modifying, refactoring, fixing, or reviewing Python source code.

Optimize for correct, readable, maintainable Python with the minimum total complexity necessary.

Scope and Precedence

These rules apply to Python source and tests.

Before changing code:

  1. Read applicable repository instructions such as AGENTS.md.
  2. Inspect relevant code, callers, tests, and established patterns.
  3. Inspect repository configuration such as pyproject.toml, ruff.toml, and mypy.ini.
  4. Follow repository-configured Python, Ruff, Mypy, formatting, and testing rules over generic defaults in this skill.
  5. Follow authoritative ADRs and docs/current/ sources when a coding rule depends on project architecture or semantics.

Do not modify lint, formatting, typing, or test configuration merely to make code pass unless changing that policy is itself part of the task.

A direct user requirement or documented repository rule overrides a design preference here. Required correctness, security, data integrity, domain contracts, scoring semantics, and observability are not optional simplifications.


Polaris Non-Negotiables

Contract Boundaries

When changing domain, application, infrastructure, interface, persistence, runtime, or other contract boundaries, read:

docs/current/platform-architecture-0.2.0.md

and the current Spec, accepted ADR/design source, or domain contract that owns the concrete semantics being changed.

Follow current greenfield authority:

  • inward-owned ports express the semantics Polaris requires rather than mirroring vendor APIs;
  • vendor, ORM, driver, transport, and other replaceable implementation types stay behind their owning adapter boundary unless current authority explicitly makes the representation semantic;
  • externally sourced facts are normalized into Polaris-owned contracts with their required identity, time, provenance, and authority meaning;
  • application/domain contracts remain independent of incidental runtime or infrastructure mechanics.

Do not treat legacy/v0_1/, quarantined historical documents, or a removed pre-greenfield contract inventory as current semantic authority.

If a concrete representation, range, polarity, fallback meaning, authority meaning, or other material contract is not established by current authority and reasonable implementations could differ materially, surface a design/authority gap instead of reviving a legacy rule or inventing one locally.

Score Semantics and Precision

The current greenfield architecture does not define one repository-wide canonical score-family table. Do not resurrect the retired pre-greenfield score inventory or infer score direction, range, sign, normalization, or meaning from a field name.

When creating, modifying, or reviewing scoring code:

  1. identify the current Spec/domain/ADR authority that owns the score or quantitative contract;
  2. preserve and validate that field's exact range, polarity, units, neutral/default meaning, and unresolved/fallback semantics;
  3. convert between materially different quantitative meanings only through an explicit formula whose intent is evident at the boundary.

Current product authority also requires:

  • Portfolio Risk to remain multidimensional; a single generic Risk Score is not the universal Portfolio Risk representation (PRT-006);
  • materially unknown Portfolio consequence or risk to remain unresolved rather than manufacturing precision (PRT-012).

If the exact semantics required by new scoring code are absent from current authority, treat that as a design gap rather than choosing a legacy or conventional score family during implementation.

As a coding-policy precision rule, preserve full numerical precision internally. Use rounding only in human-facing presentation or where an explicit external contract requires fixed precision.

Changing established score semantics is a contract/design change, not a local implementation decision.

Typing and Internal Models

Type public functions and methods explicitly, including return types.

Type private interfaces when repository Mypy policy requires it or when doing so materially improves correctness.

Use modern built-in typing syntax supported by the configured Python version.

Represent nullable values honestly.

Contain Any at genuinely dynamic or untyped boundaries and narrow it before typed domain logic.

Treat # type: ignore as a last resort and specify the exact error code when required.

Do not use cast() merely to hide a legitimate type error.

Prefer:

@dataclass(frozen=True, slots=True)

for immutable internal models when a dataclass is the appropriate representation.

Do not introduce another model merely to satisfy this preference when an existing type already owns the concept.

Async and Parallel Execution Boundaries

Polaris treats asynchronous I/O and multi-core execution as first-class runtime capabilities. Follow docs/current/platform-architecture-0.2.0.md and the accepted runtime-concurrency ADR for the governing execution model.

Use established asynchronous provider and client interfaces consistently. Do not introduce synchronous alternatives to canonical async boundaries, sync/async compatibility branches, or duplicate execution paths unless a real boundary requirement exists and is supported by the applicable architecture source. Do not preserve an incorrect synchronous path merely for compatibility.

Do not make pure deterministic domain calculations async when they perform no concurrent I/O or waiting. Keep async at boundaries that own waiting, orchestration, or concurrent I/O.

For CPU-bound work, choose the smallest execution mechanism that satisfies the real isolation and sharing requirements: free-threaded threads for safe shared-memory parallelism, subinterpreters for isolated in-process parallelism, and processes only when hard isolation or dependency constraints require them. Do not leak that mechanism into domain/application contracts.

No correctness guarantee may depend on the CPython GIL serializing access. Shared mutable state must have explicit ownership, synchronization, immutability, isolation, or another race-safe invariant that remains correct under genuinely parallel execution. Treat code that is only safe because ordinary CPython happens to serialize bytecode as defective.

When adding or changing runtime dependencies, concurrency-sensitive code, worker execution, or application bootstrap/import surfaces, preserve free-threaded compatibility and run the repository's free-threaded qualification gate. A dependency that re-enables the GIL makes the free-threaded target fail until the dependency or design is corrected or explicitly re-architected.

Observability

Observability is required operational behavior, not an optional enhancement.

When creating or modifying an operational boundary, consult the applicable current observability and platform architecture documents.

Preserve established conventions for applicable:

  • structured logs;
  • trace spans;
  • trace-context propagation;
  • metrics;
  • failure visibility.

Do not:

  • create parallel telemetry systems;
  • duplicate lifecycle emission paths;
  • create competing instrumentation ownership;
  • bypass canonical telemetry boundaries;
  • consider operational behavior complete when required observability has been lost.

Extend the canonical observability path instead of creating local alternatives.

Pure helpers and internal calculations do not need ceremonial telemetry. Instrument the operational boundary that owns the behavior.


Core Python Standards

Use repository-configured Ruff, formatting, and Mypy rules as the source of truth.

Prefer clear, idiomatic Python over cleverness.

Naming

Use names that communicate domain meaning:

  • snake_case for functions, variables, methods, modules, and packages;
  • PascalCase for classes;
  • UPPER_SNAKE_CASE for module constants.

Do not encode incidental implementation details into names.

Exception Handling

Catch the narrowest exception the current layer can meaningfully handle.

Do not:

  • use bare except:;
  • silently swallow failures;
  • catch broad exceptions merely to continue;
  • turn failures into misleading success values;
  • log an exception and then pretend the operation succeeded.

A deliberate except Exception is appropriate only at a genuine boundary that owns failure reporting, translation, cleanup, or isolation.

Preserve the original cause when translating exceptions where useful.

Resources

Give files, connections, transactions, locks, streams, and similar resources deterministic ownership and lifecycle.

Use context managers where appropriate.

Do not impose per-call lifecycle management on long-lived resources intentionally owned elsewhere.


Efficient Coding

The best code is the code never written.

Optimize for minimum total complexity, not minimum line count.

Every abstraction, type, option, representation, execution path, dependency, indirection layer, and file carries maintenance cost.

The Coding Ladder

After understanding the real execution and data flow, evaluate these in order.

Stop at the first rung that cleanly satisfies the requirement.

  1. Does this need to exist at all?

    If it serves only a speculative future requirement, do not implement it.

    Apply YAGNI. Do not leave speculative hooks, TODOs, extension points, or scaffolding behind.

  2. Does the codebase already solve it?

    Search for existing helpers, types, services, models, and patterns before creating another implementation.

    Do not duplicate behavior the repository already owns.

  3. Does Python already express it directly?

    Prefer clear built-ins and standard-library primitives.

    Do not replace obvious control flow with clever expressions merely to save lines.

  4. Does an installed dependency naturally own it?

    Reuse an existing dependency when it eliminates meaningful custom logic without disproportionate coupling.

    Do not add a dependency merely to avoid a few clear native lines.

  5. Can the requirement be solved directly?

    Prefer existing domain objects and straightforward control flow over new wrappers, helpers, configuration, or layers.

  6. Only then write custom machinery.

    Write only what the current requirement actually needs.

If multiple solutions are equally correct, choose the one with fewer concepts and less machinery.

Subtract Before Finishing

Before finalizing, remove anything newly introduced that is not required.

Ask:

  • Did this duplicate something the codebase already owns?
  • Did it create another representation of an existing concept?
  • Is every new abstraction or layer performing meaningful work?
  • Did obsolete behavior remain after being superseded?
  • Does every input accepted by a changed internal contract still have real semantic effect?
  • Did defensive validation spread beyond the boundary that owns it?
  • Can the same behavior remain clear and correct with fewer concepts?

Simplify when the answer is yes.

Do not use subtraction as justification for unrelated cleanup.


Structural Design Rules

No Speculative Abstractions

Do not introduce an interface, factory, base class, strategy, adapter, registry, plugin point, hook, configuration option, or extension mechanism for hypothetical future consumers.

An abstraction must solve a current structural problem.

No Pass-Through Layers

Do not create wrappers, services, managers, adapters, or helpers that merely rename or forward an existing operation.

A layer should perform meaningful work such as:

  • owning a domain responsibility;
  • enforcing a real boundary;
  • translating representations;
  • applying policy or invariants;
  • coordinating behavior that belongs together.

If it only delegates, remove it.

One Concept, One Representation

Do not introduce another DTO, model, wrapper, context object, enum, state container, or intermediate representation when an existing type already represents the concept adequately.

Convert representations at genuine boundaries.

File Size and Module Cohesion

Treat file length as an attention signal, not a defect.

Do not impose or satisfy arbitrary line-count limits unless repository configuration or an explicit requirement establishes one. A large cohesive module is preferable to several artificial micro-modules that scatter one responsibility.

Review a growing module for separation when size reveals structural evidence such as:

  • multiple independently meaningful domain concepts;
  • different sections changing for different reasons;
  • clearly separate dependency or import clusters;
  • tests naturally dividing into independent behavioral surfaces;
  • substantial navigation burden when understanding one operation;
  • a section that has earned a clear, purpose-specific module name of its own.

A module in the high hundreds of lines merits a cohesion review; crossing roughly 1,000 lines is a stronger review signal, not an automatic split requirement. Generated, declarative, table-driven, or tightly coupled state-machine modules may legitimately be larger.

When splitting, split along real domain, ownership, dependency, or behavioral boundaries.

Do not split code merely to reduce line count when doing so would:

  • scatter one invariant or state transition across modules;
  • create circular imports or unnecessary indirection;
  • introduce vague utils, helpers, common, or misc modules;
  • separate value objects or operations that are easier to understand together.

Prefer the smallest number of cohesive modules that make ownership and navigation clear.

Authoritative Contract Changes and Compatibility

Internal source compatibility is not a default Polaris requirement.

Compatibility exists only when an explicit user requirement, accepted architecture, versioned migration contract, or genuine external/public compatibility obligation requires it. Existing internal callers, tests, or implementation history do not by themselves establish a compatibility requirement.

When ownership, an internal contract, an API, or an invariant changes:

  1. make the authoritative layer correct first, even when downstream callers break;
  2. update every affected caller, implementation, protocol, adapter, fake, fixture, test, configuration surface, registry/bootstrap path, and other consumer;
  3. remove the superseded internal contract and representation in the same change.

Do not preserve obsolete internal behavior by:

  • accepting and ignoring, discarding, overwriting, or neutralizing obsolete inputs;
  • absorbing stale calls through *args or **kwargs;
  • retaining stale aliases, compatibility shims, wrappers, flags, or no-op parameters;
  • maintaining parallel old/new execution paths;
  • falling back to behavior that the authoritative contract replaced.

If genuine compatibility is explicitly required, isolate it at the compatibility boundary, identify the authority requiring it, and keep the canonical internal contract free of compatibility residue.

If the correct implementation is blocked by unresolved architecture or an external requirement, surface the blocker. Do not substitute a hack, workaround, bypass, compromise design, or silent behavioral degradation.

Root-Cause Fixes

A reported symptom is not necessarily the defect location.

Before fixing shared behavior:

  1. identify the violated invariant;
  2. inspect relevant callers;
  3. identify the layer that owns the invariant;
  4. fix the narrowest authoritative point.

Prefer one root-cause correction over repeated downstream guards.

Validate at Boundaries

Validate untrusted, serialized, external, or loosely typed data where it enters the trusted system.

Once an invariant is established, trust it internally unless the domain permits it to become invalid again.

Do not scatter defensive checks for impossible internal states.

Comments

Comments should explain non-obvious:

  • constraints;
  • invariants;
  • tradeoffs;
  • compatibility requirements;
  • reasons.

Do not narrate mechanics already clear from the code.

Docstrings

Use docstrings to preserve non-obvious semantic information, not to satisfy a documentation quota.

A useful docstring may explain:

  • domain meaning or business semantics;
  • invariants, preconditions, or postconditions not evident from the signature;
  • side effects or ownership boundaries;
  • failure semantics that callers must understand;
  • temporal, authority, trust, or concurrency behavior;
  • a public API contract whose meaning is not obvious from names and types.

For public or domain-facing APIs, add a docstring when there is meaningful contract information that the signature, type hints, and name do not already communicate. For private helpers, add one only when the helper has a non-obvious invariant, algorithm, or behavioral contract worth preserving.

Do not add docstrings that merely:

  • restate the function, class, or field name;
  • paraphrase parameters already clear from names and type hints;
  • narrate straightforward implementation mechanics;
  • duplicate nearby comments or authoritative documentation;
  • exist only to satisfy a docstring coverage metric.

Keep docstrings behavior- and contract-oriented so they remain valid when implementation details change.


Architecture Heuristics

Named design principles are heuristics, not abstraction quotas.

Do not add machinery merely to demonstrate SOLID, DRY, dependency injection, or another design pattern.

DRY

Centralize duplicated knowledge, policy, invariants, and business rules, not merely similar syntax.

A small amount of obvious syntactic duplication is cheaper than the wrong abstraction.

Responsibility

A function, class, or module should own one coherent responsibility.

Do not interpret this as one tiny operation per function. Keep sequential steps together when they form one domain operation.

Extensibility

Do not pre-build extension mechanisms.

Use polymorphism, protocols, strategies, or registries only when there are real implementations, an established extension boundary, repeated variation, or an explicit requirement.

Interfaces and Dependency Injection

Introduce abstract boundaries when they provide real value, such as:

  • isolating infrastructure from domain logic;
  • supporting multiple actual implementations;
  • establishing a stable external boundary;
  • replacing an unstable dependency;
  • creating a necessary test seam.

Depending directly on a stable concrete implementation is acceptable when no meaningful abstraction boundary exists.

Prefer composition over inheritance unless a genuine substitutable is-a relationship exists.


Testing Expectations

Test behavior and contracts, not implementation details.

For non-trivial changed behavior, add the smallest number of tests necessary to prove:

  • the required behavior; and
  • its important failure boundary.

A defect fix should ordinarily include a focused regression test that would have failed before the fix.

Prefer existing test modules and infrastructure.

Avoid:

  • elaborate fixture hierarchies;
  • unnecessary mocks;
  • redundant permutations;
  • ceremonial tests;
  • production abstractions created solely for unit-test convenience.

Use integration tests when the real contract depends on wiring, persistence, component interaction, framework behavior, or an external boundary.

Do not distort production architecture merely to make everything unit-testable.

For procedural testing workflow, use the applicable $tdd, $verify-code, or $verify-spec skill rather than duplicating those workflows here.

When scoring behavior changes, verification must cover canonical score semantics and precision.

When an operational boundary changes, verification must cover required observability through the established telemetry path.


Code-Smell Review

Smells are diagnostic signals, not automatic violations.

Repository architecture and explicit standards take precedence.

Smells are Advisory by default unless a documented rule makes the condition a violation.

Do not duplicate issues that Ruff, Mypy, formatting, or tests already reliably detect.

Watch for:

  • Mysterious Name — names conceal domain intent.
  • Duplicated Code — the same knowledge or business rule has multiple owners.
  • Feature Envy — behavior appears to belong with another component's state.
  • Data Clumps — a repeated value group may represent a real domain concept.
  • Primitive Obsession — primitives repeatedly reconstruct meaningful domain invariants.
  • Repeated Switches — repeated dispatch may indicate fragmented ownership.
  • Shotgun Surgery — one concept requires changes across many unrelated locations.
  • Divergent Change — one module owns unrelated reasons to change.
  • Speculative Generality — abstractions exist for requirements that do not.
  • Message Chains — callers navigate another component's internal structure.
  • Middle Man — a layer delegates without adding meaningful responsibility.
  • Refused Bequest — inheritance does not satisfy true substitutability.

Never apply a textbook refactoring mechanically.

Refactor only when the result is simpler and more correct for the actual system.


Required Correctness

Never simplify away required:

  • trust-boundary validation;
  • authentication or authorization;
  • security and accessibility controls;
  • transaction, rollback, concurrency, or idempotency behavior;
  • domain invariants;
  • external contracts;
  • canonical data-contract semantics;
  • canonical score semantics;
  • numerical precision;
  • observability;
  • explicitly required architecture.

The goal is not the smallest diff or fewest lines.

The goal is the smallest correct resulting system.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.