agentsclimarketplace

Tacape code

Skill mateussatoh/tacape/skills/tacape-code

Language-agnostic engineering principles: boring and searchable code, one-way module boundaries, errors that stay visible, data at the edges, honest tests, and a discovery order that finds the right file fast. No stack, no framework, no project assumptions. Use when writing, refactoring, or reviewing code in any language, when starting a new repo, or when the user asks for "the principles", "house style", "how we write code". Defer to the repo's own CLAUDE.md or AGENTS.md when one exists: that file always wins.From its SKILL.md

Install
npx -y skills add mateussatoh/tacape --skill tacape-code

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

14.4 KB, as published. Nobody here has run it

Principles, not rules for a stack. They hold in any language and any framework.

Most were extracted from production incidents. The ideas underneath belong to the people who named them first: Sandi Metz on the wrong abstraction, Carson Gross on complexity, tef on writing code that is easy to delete, Alexis King on parsing at the edge, Gary Bernhardt on separating decisions from effects, Ousterhout on interface depth, Fowler on the rule of three. See the README for the full attribution table.

Precedence: the repo's own CLAUDE.md / AGENTS.md > the conventions already visible in the surrounding code > this skill. Never impose these over a codebase that consistently does otherwise.

1. Boring, searchable, safe to edit

  • Boring wins. Obvious, explicit and local beats clever. If it looks smart, simplify it. Code is read far more often than written, and it is read under pressure.
  • Name for the domain, not the mechanism. activateSubscriptionAfterPayment, not process, handle, execute, doWork, manager, helper. A good name is the one a stranger greps for.
  • One unit, one responsibility. No utils / helpers / misc grab-bags. A module that collects unrelated functions has no reason to change together, so it changes constantly.
  • Boring control flow. Early returns, guard clauses, named booleans, flat if/else. No nested ternaries, no five-level indentation, no clever short-circuit chains.
  • Smallest correct diff. No drive-by refactors, no formatting churn, no renaming on the way past. A reviewable diff gets reviewed. A large one gets approved unread.
  • Comments explain WHY. The code already says what. Comment the constraint, the tradeoff, the bug this guards against, the thing that looks wrong but is not.

2. Abstract late

  • Duplication is cheaper than the wrong abstraction. Two similar things are not one thing. Wait for the third occurrence, and wait for it to actually be the same shape.
  • No architecture cosplay. No factory, registry, manager, adapter, wrapper, plugin system, or framework without a concrete repeated need you can point at. Patterns are a response to pressure, not a starting position.
  • Do not extract a shared library until a second real consumer duplicates the code. Premature extraction turns a local edit into a cross-repo negotiation.
  • New dependencies are guilty until proven. For anything small, check the standard library and the deps you already have. Every dependency is a supply chain, a version bump, and a license. The exception that is not optional: cryptography, authentication, date and timezone arithmetic, and anything parsing a hostile format. Hand-rolling those is not independence, it is a CVE with your name on it. "No new dependency for something small" means small, not merely short.
  • You get about three innovation tokens. Choosing the unfamiliar database, the unfamiliar language and the unfamiliar deployment model at once spends them all before you have shipped anything, and every unknown then compounds with every other. Spend the tokens where the novelty is the actual product, and take the boring, widely deployed, well documented option everywhere else. Boring here means well understood failure modes, not old.

3. Modules are deep, not wide

  • A good module hides more than it exposes. Measure an interface by what a caller must understand to use it, and the implementation by how much work it does on their behalf. The best ratio is a small interface over substantial functionality. A class with fifteen setters and no behavior is the worst ratio: pure cost, zero leverage.
  • Shallow layers that only pass calls through are negative value. They add a name to learn, a file to open and a place to be out of date, while hiding nothing. If a layer's methods map one to one onto the layer below, delete it.
  • Define errors out of existence where you honestly can. The best handling of an error case is a design where it cannot arise: an operation that is idempotent needs no "already applied" branch, a delete that tolerates a missing key needs no existence check. Every error you eliminate is a branch nobody has to test, read, or get wrong. This is not the same as swallowing errors, which is rule 6. Eliminate the case, or surface it. Never hide it.
  • Push complexity down, into the module, not out onto every caller. One hard implementation read by its author beats twenty callers each solving the same problem slightly differently.
  • Tactical work accumulates interest. Shipping the quick version is a real and often correct choice, but it is a loan. Say out loud that you are taking it, and against what. The failure mode is not one tactical fix, it is a hundred of them with nobody ever having decided.

4. Write code that is easy to delete

  • Optimize for removal, not for extension. You will be wrong about the future. Code you can delete in an afternoon costs nothing when you are wrong. Code that everything extends costs a quarter.
  • Layer by expected lifetime. Put the parts most likely to change, the vendor integration, the experiment, the campaign logic, in their own layer at the edge, so they can be cut out whole. Keep the stable core free of references to them.
  • Repeat yourself to avoid a dependency, but never to manage one. Copying a helper into two packages so neither depends on the other is often correct. Copying the same business rule into two places so it must be changed twice is never correct. The test: would a change to this need to happen in both copies at the same time? If yes, it is one thing.
  • A dependency you can delete is worth more than an abstraction you cannot.

5. Boundaries are one-way and enforced

  • Dependencies point one direction. Low-level and general at the bottom, specific and deployable at the top. Policy does not import mechanism's caller. Cycles are a design smell, not a build problem to work around.
  • Cross a boundary through its public interface, never by reaching into another module's internals. Internals are internal so they can change.
  • The owner of a resource is the layer that can see all of it. A generic mechanism should not own domain state it cannot fully observe. Let the owner declare it and pass it in.
  • Enforce boundaries with a tool, and verify with a negative probe. Write the forbidden import, confirm the check actually fails, then delete it. A rule that silently never fires is indistinguishable from a rule that passes. Config that looks right is not evidence.

6. Failures stay visible

  • Structured logging, never bare stdout printing. Distinguish the levels and mean them: error is an operational alert someone is paged for, warn is an expected anomaly that resolves itself, info is flow.
  • A caught error on a retried path must reach the alerting system, not just the log. Swallowing an exception into a log line that nobody watches is how a system stays broken in production for days while every dashboard reads green.
  • Never pattern-match on a wrapped error's surface. Libraries wrap driver and transport errors and move the original to a cause chain. Match by walking the chain behind a named helper. A direct field check silently stops matching on a version bump and converts a handled case into a crash.
  • Fail closed on ambiguity for anything touching money, permissions, or deletion. When the code cannot tell, it refuses. It does not guess.

7. Make invalid states unrepresentable

  • Push correctness into types, schemas and validators at the boundary. A comment saying "must be positive" is a wish. A type that cannot hold a negative is a guarantee.
  • Validate at the edge, trust inside. Parse untrusted input once, at the entry point, into a known-good shape. Do not re-check the same thing in nine places.
  • Never return an internal record straight to a caller you do not control. Whitelist the fields you mean to expose. Spreading an internal object is how a password hash, an internal flag, or a soft-deleted row ships to a client.
  • Separate decision from effect. Pure logic first, then the writes, calls and logs. The pure part is the part you can test without a world.

8. Data and time

  • Store instants in UTC, render in the viewer's timezone. Every timestamp is an absolute instant. Never persist local wall-clock time, never do arithmetic on a formatted string.
  • Never format a date without an explicit timezone. Defaulting to the machine's zone means the output changes depending on which server ran it.
  • A store holds what its name says. Do not smuggle UI state, flow progress or preferences into a domain record because it was the convenient table. It is convenient once and wrong forever.
  • Identifiers are opaque and stable. Never key on a mutable human-readable string.

9. Tests that would have caught it

  • A feature ships with tests. Integration across the real critical path, unit on new pure logic. No test, not done.
  • Read the existing tests before editing the implementation. They are the contract, and they document intent better than the code does.
  • Mocking the layer under test hides the bug you are shipping. If a path writes to a store or speaks a protocol, pin its real shape in at least one test that does not mock the boundary. A suite that is green because everything is faked proves only that the fakes agree.
  • Test the failure, not just the happy path. The race, the duplicate, the timeout, the retry, the empty list, the permission denial.
  • A bug fix ships with the test that reproduces it. Otherwise it comes back.
  • Deterministic. Same input, same result, every run. A test that depends on the clock, on random, on map ordering, or on the network is not a test, it is a coin flip that occasionally blames the wrong commit. Inject the clock and the seed.
  • Isolated. Tests do not share mutable state and do not care what order they run in. Order dependence hides as a pass until someone parallelizes the suite.
  • Fast. A suite nobody waits for is a suite nobody runs. Speed is not a nicety here, it decides whether the tests participate in the edit loop or become a thing CI complains about later.
  • Test behavior, not implementation. A test that breaks on every refactor while the behavior is unchanged is a tax on improvement, and teaches people to delete tests.

10. Localization and copy

  • User-facing text in the product's language, identifiers in English. No mixed-language identifiers, keys, columns, or route segments. Code is read by people who did not ship it.
  • Never render an internal enum, code or id raw to a user. Map stored values through an explicit label layer. A new enum value ships its label in the same change.
  • Reader-facing copy fits its objective. For sales, lead with value and a credible action. For product copy, prioritize comprehension and task completion. For technical content, prioritize accuracy, prerequisites, examples, and limits. For editorial prose, prioritize voice and flow.
  • Avoid em dashes in reader-facing prose. This is a writing preference, never a tool, CI, or write constraint. Code, comments, commits, and technical artifacts are not subject to it.

11. Interface states are not optional

  • Every asynchronous view handles all four states: loading, empty, error, loaded. A blank screen during load is a bug, not a default.
  • Extend a component through its parameters, never by forking a variant. Two nearly identical components drift, and the fix lands in one of them.
  • Keep presentation, data access and business rules in different places. A view that queries is a view you cannot reuse or test.

12. Secrets and destructive actions

  • Secrets live in a secret store, never in the repo and never in a local file the agent reads.
  • Never run or suggest a command that prints secret values. If something fails on a missing secret, report only its NAME and let a human set it.
  • Confirm before anything irreversible or outward-facing: deletion, migration, force push, deploy, or sending to a real recipient. Approval for one such action does not carry to the next.

13. Find the file, do not grep the repo

Map, then scope, then read. Blind repo-wide content search is the last resort, not the first move.

  1. Map the task to likely modules using the repo's own index, package map, or directory layout.
  2. Filename search before content search. Names are cheap to scan and usually right.
  3. Scoped content search before repo-wide. Widen only after the narrow search fails.
  4. Read the nearby tests before editing the implementation.
  5. Structural search when the shape matters more than the text ("find every call to X with two arguments"). Fall back to text search when no structural tool is available.

14. Ask versus decide

Ask only when the answer changes the outcome AND the call belongs to the owner: conflicting requirements, an architectural fork with real tradeoffs, a product, pricing, legal or safety judgment, anything irreversible or outward-facing, or scope materially larger than requested. Batch the questions into one round.

Do not ask about cosmetics, conventional defaults, reversible low-stakes choices, or anything derivable from the code and docs. Make the call, state it in one line, keep moving.

15. Documentation is part of the change

  • Docs live next to what they describe. Do not dump new files at the repo root.
  • Changed a decision, contract, or rule? Update its doc in the same change. A stale doc is worse than no doc: it is believed.
  • Each rule lives in exactly one place. The index links, the owning document details. Duplicated rules drift and then disagree.
  • Decisions are append-only. Supersede a decision with a new dated one, never rewrite the record. The reasoning that was wrong is the most useful part of the history.
  • Maintenance is incremental and on contact. No full rewrites in the middle of a feature.

Keep looking

Skills are one crate of 627,801. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.