Communitygithub.com

lguidolin/變更衛生與程式碼工藝

在編寫或重構程式碼、建構提交或 PR、或決定是否抽象化重複程式時使用。徵兆包括:在重組中混入邏輯變更、一個 PR 同時做多件事、檔案變得龐大、出現第二份相似程式碼、或不確定是否該進行 DRY。

變更衛生與程式碼工藝 是什麼?

此技能專注於如何塑造變更與撰寫程式碼,主要圍繞兩個核心主題:**區分結構性與行為性變更**,以及**用最簡潔明確的方式表達意圖**。在變更衛生方面,它強調結構性變更(如重新命名、拆分檔案)應與行為性變更(如新增邏輯)分開驗證與提交,確保每次變更只有單一且可說明的目的。此外,它鼓勵在任務範圍內改善現有程式碼,但避免進行無關的重構。在程式碼工藝方面,技能提倡明確優於隱含、使用描述性命名、註解專注於原因而非機制,以及保持單元小型且單一職責。它也深入探討 DRY(不重複自己)與 DAMP(描述性且有意義的短語)之間的平衡,以及何時應避免過早抽象化。此技能支援各種開發平台與工具,包括 Claude Code、Cursor 等 AI 代理,並以 Markdown 文件(SKILL.md)形式提供完整說明,幫助開發者在提交、PR 審查及重構決策中遵循最佳實踐。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/lguidolin/agent-skills/tree/main/skills/change-hygiene-and-code-craft

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

變更衛生與程式碼工藝 是做什麼的?

概述

如何塑造變更以及如何撰寫程式碼。兩個主題:將結構性變更與行為性變更分開,以及用最不耍聰明的方式說出你的意圖。

變更衛生

  • 結構性變更先於行為性變更,且獨立驗證。 重組(拆分檔案、重新命名、新增註解)是與改變行為(新增限制、修改邏輯)獨立且可分別檢查的步驟。絕不要將它們混在一個不可分割的變更中——審查者無法分辨安全的重新排列與真正的邏輯變更。
  • 每次變更改變一件事。 一個變更只有單一且可說明的目的。
  • 改善你正在處理的程式碼,當其問題影響你的任務時(讓露營地比來時更乾淨)——但不要開始無關的重構。專注於目標。

程式碼工藝

  • 明確優於隱含。 不該用通配符的地方就不要用,不該有隱式轉換,不使用空字串或魔術哨兵。說出你的意圖。
  • 描述性命名。 函式/變數名稱說明它們的功能;遵循語言與生態系統的慣例。
  • 註解意圖,而非機制。 在非顯而易見時解釋為什麼;對不言自明的程式碼省略註解。
  • 小型且單一職責的單元。 對於任何單元,你應該能夠說明它做什麼、如何使用、依賴什麼——而不需閱讀其內部實作。一個大型檔案通常做了太多事。
  • 生產程式碼中的 DRY 需謹慎判斷。 重複是信號,而非自動錯誤。第二次出現極相似的程式碼時,需要做出審慎決定:抽象化,或記錄為什麼不抽象。抽象化共享的意義,絕非偶然的形狀——看起來相似但因為不同原因而變化的東西應保持分離。
  • 遵循生態系統標準。 使用熟練從業者預期的慣用法與良好支援的函式庫。不要重新發明平台已經解決的問題。

命名的張力

  • DRY 與過早抽象化: 生產程式碼僅在已證實的意圖重複上進行抽象,而非預期的形狀重複。不確定時,等待第三次出現(YAGNI 規則主導最終決定)。
  • DRY 與 DAMP: 生產程式碼應 DRY;測試程式碼應 DAMP(清晰優於去重,參見 tests-as-a-control)。將 DRY 應用於測試是一種違反。

常見合理化藉口

藉口現實
「我會在同一個提交中重新命名並新增功能」結構與行為混在同一個 diff 中是無法審查的。分開它們。
「兩份拷貝,我必須立刻 DRY 化」第二次出現 = 做決定。相同形狀 ≠ 相同意義。偶然的重複應保持分離。
「既然來了,讓我把這個其他模組也重構一下」無關的重構會擴大範圍與風險。記下來;現在不要做。
「巧妙的單行更優雅」明確勝過聰明。為下一位閱讀者最佳化。

紅旗 — 停下來

  • 一個 diff 既移動程式碼又改變其行為
  • 一個 PR 的目的需要用「與」來描述
  • 在第一次看到相似性時就抽象化,或基於預期(而非實際)的重複
  • 一個你再也無法記在腦中的檔案

完整理由:憲法的第 V 條與第 VI 條,收錄在 engineering-constitution/references/engineering-constitution.md。

Individual skills in this repo

This repo contains 18 individual skills — each has its own dedicated page.

lguidolin/cloud-delivery-aks

Use when deploying to Kubernetes or Azure Kubernetes Service (AKS), configuring cloud secrets, setting up progressive rollout/canary, per-PR ephemeral environments, or k8s health probes. Keywords — Kubernetes, AKS, Key Vault, Argo Rollouts, Flagger, canary, blue-green, liveness, readiness, PodDisruptionBudget, HPA, rollback, GHCR.

lguidolin/commit-history-rewrite

Use when an existing repository has messy commit history that needs to conform to conventional commits before adopting release-please, or when intermediate WIP/fixup/merge commits need to be cleaned up.

lguidolin/conventional-commits-and-releases

Use when committing, writing a commit message, opening a PR that will be squash-merged, or configuring automated versioning/changelogs. Keywords — conventional commits, release-please, semver, feat/fix/chore, breaking change, changelog.

lguidolin/defense-in-depth-security

Use when handling untrusted input, secrets, authentication/authorization, or dependencies — or threat-modeling a new surface. Keywords — STRIDE, threat model, least privilege, secrets management, supply chain, dependency scanning, input validation, audit log, defense in depth.

lguidolin/designing-before-building

Use when starting a feature, fixing a non-trivial bug, or about to write implementation code — before any code exists. Symptoms you need this: "this is simple, I'll just code it", reaching for the editor before a design is approved, or an idea that hasn't been turned into a spec and plan.

lguidolin/engineering-constitution

Use when starting work in a project that follows the engineering constitution, orienting to its rules, or deciding which engineering practice applies to a task — spec writing, commits, testing, security, deploys, database, or UI work.

lguidolin/graphql-contract-testing

Use when writing a GraphQL query/mutation that the UI and a test will share, or building route/schema contract or smoke tests. Symptoms — copying a query into a test, a test asserting on query text, schema change that didn't break the UI build, or RLS/permission drift. Keywords — graphql-codegen, typed document, contract test, route smoke test.

lguidolin/init-repo-CI

Use when setting up a new repository with conventional commits, release-please, and CI automation, or when retrofitting an existing repository that lacks automated versioning and PR validation workflows.

lguidolin/interface-craft-and-accessibility

Use when building or styling UI — components, layouts, forms, design tokens — or making accessibility decisions. Keywords — a11y, WCAG, keyboard navigation, focus state, contrast, design system, minimalist UI, component reuse, ARIA, semantic HTML.

lguidolin/merge-gates-and-automation

Use when setting up or changing CI, pre-push hooks, or a task runner, or deciding what must pass before merge. Symptoms — tempted to put authoritative checks only in a local hook, skip CI, bypass with --no-verify, or unsure what gates a merge vs. runs locally.

lguidolin/observability-and-slos

Use when adding logging, metrics, tracing, health checks, SLOs, or alerting — or when building a service surface that needs to be operable and debuggable. Keywords — structured logs, OpenTelemetry, correlation id, RED metrics, liveness, readiness, SLI, SLO, error budget, alerting.

lguidolin/performance-and-scale

Use when working on hot paths, list endpoints, pagination, data-access in loops, or public interfaces/schemas. Symptoms — unbounded queries, N+1 access, no latency budget, optimizing without measuring, or changing an interface many consumers depend on. Keywords — pagination, N+1, Hyrum's Law, performance budget, bundle size.

lguidolin/postgres-postgraphile-rls-and-sql

Use when writing PostgreSQL, PostGraphile config, Row-Level Security policies, SQL schema files, or working on the Browser→App→PostGraphile→Postgres data path. Keywords — RLS, SECURITY DEFINER, search_path, pgSettings, grants, roles, GraphQL depth limit, query cost, statement_timeout, SQL file organization.

lguidolin/recording-decisions

Use when a design or architecture decision has been made and needs to be captured — writing a decision record or ADR, updating a decision index, noting a deferred idea, or superseding a past decision. Keywords — ADR, decision record, rationale, rejected alternatives, dependency index.

lguidolin/resilience-and-deploy-safety

Use when planning a deploy, designing a rollback, or responding to an incident or writing a postmortem. Keywords — deploy safety, rollback, immutable artifact, progressive delivery, canary, blast radius, incident response, blameless postmortem, error budget.

lguidolin/ship-it

Use when the user wants to ship work — push, PR, archive decision records, merge, and clean up. Handles the full lifecycle from committing final changes through post-merge cleanup including converting specs/plans to compact decision records.

lguidolin/tests-as-a-control

Use when writing or modifying tests, when a test breaks during a refactor, or when testing permission/role rules. Symptoms — tempted to edit a test to make it pass, testing only the happy path, a deny-test that started passing, flaky tests, or unsure what to assert.

lguidolin/zero-downtime-migrations

Use when changing a database schema where data must survive the change — adding/removing/renaming columns, constraints, indexes, or backfilling. Symptoms — a destructive migration bundled with a code deploy, a NOT NULL column with a backfill, a table-locking UPDATE, or a rename. Keywords — expand/contract, parallel change, backfill, NOT VALID, CREATE INDEX CONCURRENTLY, graphile-migrate.

相關技能