跳到正文
cccskills
免费在 GitHub 公开

boring-engineering

Prevents overengineering when designing, implementing, refactoring, or reviewing software. Use when the user asks to implement a feature, add an abstraction, refactor code, review a design, simplify existing code, or make an architectural decision. Also triggers when the user asks if code is too complex, whether to abstract something, or how to structure something. Do not use for deployment, infrastructure configuration, or debugging runtime errors unrelated to code structure.

中文简介正在准备中。当前显示原文说明。

查看安装方法

包含的文件(37)

  • SKILL.md5.1 KB
  • assets/decision-tree.md3.0 KB
  • benchmarks/.gitignore249 B
  • benchmarks/agentic/fixtures/mini-ecommerce/opencode.json169 B
  • benchmarks/agentic/fixtures/mini-ecommerce/package.json81 B
  • benchmarks/agentic/fixtures/mini-ecommerce/README.md109 B
  • benchmarks/agentic/fixtures/mini-ecommerce/src/api/items.js98 B
  • benchmarks/agentic/fixtures/mini-ecommerce/src/utils/formatMoney.js117 B
  • benchmarks/agentic/README.md3.8 KB
  • benchmarks/agentic/run.ps13.9 KB
  • benchmarks/agentic/runner-agentic.cmd271 B
  • benchmarks/agentic/tickets.json1.3 KB
  • benchmarks/aggregate.js3.5 KB
  • benchmarks/arms/caveman.md611 B
  • benchmarks/arms/ponytail.md6.5 KB
  • benchmarks/arms/v11.md5.1 KB
  • benchmarks/arms/v12.md5.1 KB
  • benchmarks/arms/yagni-oneliner.md203 B
  • benchmarks/lib/loc.js522 B
  • benchmarks/opencode.json157 B
  • benchmarks/package-lock.json6.3 KB
  • benchmarks/package.json301 B
  • benchmarks/results/2026-08-28-boring-v1.1.md11.0 KB
  • benchmarks/results/report.md2.4 KB
  • benchmarks/run.js7.9 KB
  • benchmarks/run.ps16.3 KB
  • benchmarks/runner.cmd300 B
  • benchmarks/tasks/tasks.json17.5 KB
  • examples/bad-abstractions.md2.6 KB
  • examples/before-after.md3.3 KB
  • examples/good-abstractions.md2.4 KB
  • LICENSE1.0 KB
  • README.md10.5 KB
  • references/decision-framework.md7.3 KB
  • references/dry.md2.3 KB
  • references/kiss.md1.8 KB
  • references/yagni.md2.0 KB

SKILL.md(原文)

安装前可以查看交给 AI 代理的指令内容。

Boring Engineering

Build exactly what the current problem requires. No less, no more.

Step 1 — Requirement Filter (YAGNI)

Before writing any code, ask: is this explicitly required by the current task or an explicit stakeholder requirement?

  • NO → Do not build it. Stop.
  • YES → Continue to Step 2.

If uncertain, default to not building it. A missing feature is easier to add than a wrong abstraction is to remove.

Step 2 — Reuse Check

Ask: does something already exist in the codebase that solves this?

  • YES → Reuse it. Stop.
  • NO → Continue to Step 3.

Search the codebase before implementing. Prefer extending an existing solution over creating a parallel one.

Step 3 — Simplicity Check (KISS)

Ask: what is the simplest correct implementation?

First, name the built-in. Before writing any parsing, formatting, validation, retry, or data-shaping logic, name the standard library or platform feature that already does it. If you can name it, use it — even if you have to look up its exact API. Hand-rolling a built-in is a defect, not a style choice.

Use current idiomatic language features — modern syntax is typically shorter and clearer. But existing project conventions win: a codebase on old style stays old style.

Choose the implementation that a reasonably experienced developer can understand without explanation.

Prefer:

  • Direct over indirect
  • Flat over nested
  • Explicit over generic
  • Inline over extracted (when logic is used only once)
  • Compact over sprawling: single-line statements where still readable (short object literals, simple returns); blank lines only between functions

Two correct solutions? Take the one with fewer moving parts.

Implement that. Continue to Step 4.

Step 4 — Abstraction Check (Practical DRY)

Only run this step if the implementation introduces a shared utility, base class, or abstraction.

Ask all three:

  1. Does this logic already appear in multiple real places in the codebase (not hypothetically)?
  2. Would all those places need the same change if the logic changed?
  3. Can this abstraction be named clearly without using "and" or "or"?
  • All YES → Abstract only the genuinely shared behavior.
  • Any NO → Keep the implementation direct. Duplication is acceptable.

For detailed decision trees and worked examples, read references/decision-framework.md.

Step 5 — Final Review

Before completing any task, run this checklist:

  • Could any block here be replaced by a standard library or platform built-in?
  • Does the exported name and signature match exactly what was asked?
  • Did I add anything the current requirement did not ask for?
  • Did I create an abstraction without enough proven evidence?

If any box is checked — revise before finishing.

Use assets/decision-tree.md as a quick reference for the full decision flow in one view.

Output

Solution code first. Then at most three short lines: what you skipped, when it becomes worth adding. Do not narrate which check fired or walk through the examples unless asked. If the explanation is longer than the code, cut the explanation.

Avoid

  • Unnecessary design patterns (factory, registry, strategy) for single use cases
  • Generic abstractions before there are multiple real consumers
  • Future-proofing without an explicit requirement
  • Extra configuration options with only one known value
  • Unused utilities, helpers, or dependencies
  • Hand-rolled versions of standard library or platform features (parsing, formatting, cloning, debouncing, retries)
  • Premature optimization without measured evidence
  • Excessive file splitting for small, cohesive modules
  • Large architectural layers (service/repository/domain) for features that need three lines

When Complexity Is Allowed

Do not simplify by removing legitimate requirements. Complexity is always acceptable for:

  • Security and authentication
  • Input validation and error handling
  • Accessibility compliance
  • Measured performance requirements
  • Reliability and fault tolerance
  • Existing project architecture and conventions
  • Explicit requirements from stakeholders

Examples

Bad — premature abstraction: User needs one API client. Building: BaseApiClient, AbstractApiProvider, ApiClientFactory, ApiClientRegistry.

Good:

export async function fetchUser(id) {
  const res = await fetch(`/api/users/${id}`);
  return res.json();
}

For more patterns, read examples/bad-abstractions.md and examples/before-after.md.

评价

还没有评价。欢迎分享你的使用感受。

评论

无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。

还没有评论。来写第一条吧。

提交后会立即公开。请勿填写邮箱、电话等个人信息。URL 最多 2 个。

0 / 1000 字

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

报告此技能的问题