maintenance-routine

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Running a Maintenance Routine

运行维护例程

Overview

概述

A routine is one mechanical maintenance pass, run on a schedule, that either opens a small reviewable PR or reports that it found nothing. Seven archetypes ship with this skill. Each has its own qualification test; all of them share one contract.
Routines exist because the maintenance nobody has time for — dead code, tests that cannot fail, layering drift, duplicates that drift apart — is exactly the work that survives being done mechanically, provided the qualification bar is high enough that a "no findings" result is normal and acceptable.
This skill supplies the method. The repo supplies the parameters. Scan scope, forbidden paths, verification commands and the framework traps that defeat static search are all repo-specific and live in
.claude/routines.md
in the target repo. That split is deliberate: the routine's own tuning loop is "a PR gets rejected → adjust the routine" and the adjustable half has to be inside the repo the routine can open PRs against.
Scope: one archetype per invocation. Running several is the scheduler's job — stagger them so they do not compete for the same runner.
例程(routine) 指按计划执行的一次机械维护巡检,要么创建一个可评审的小型 PR,要么报告未发现可维护项。本技能内置 7 种维护原型(archetype),每种都有独立的准入测试,且全部遵循同一套契约。
维护例程的存在意义在于:那些没人有空做的维护工作——死代码、永远不会失败的测试、分层偏移、逐渐差异的重复代码——恰恰适合用机械化方式完成,前提是准入门槛足够高,使得“未发现问题”是正常且可接受的结果。
本技能提供方法,代码仓库提供参数。 扫描范围、禁止路径、验证命令,以及会导致静态搜索失效的框架陷阱,都是仓库特有的,存放在目标仓库的
.claude/routines.md
文件中。这种拆分是刻意设计的:例程的调优逻辑是“PR 被驳回 → 调整例程”,而可调整的部分必须位于例程能够提交 PR 的仓库内部。
范围:每次调用仅执行一种原型。执行多种原型是调度器的职责——请错开执行时间,避免它们争抢同一运行器资源。

Invocation

调用方式

/cadence:maintenance-routine <archetype>
<archetype>
is one of the seven below. From a scheduler, the whole prompt can be that one line.
ArchetypeWhat it doesObjectivity
dead-code-removal
Deletes code provably unreachable by static searchhighest
useless-test-pruner
Finds tests that cannot fail; fixes them, deletes only as a last resorthigh
abstraction-police
Fixes violations of layering rules the repo has written downhigh
dup-unifier
Converges duplicate implementations that provably change togethermedium
logic-bugfixer
Models one module against its spec and fixes real bugs, test-firstmedium
logic-simplifier
Untangles logic inside a single functionlow
abstraction-improver
Flattens indirection layers that carry no meaninglowest
Objectivity predicts first-round merge rate. When adopting routines in a new repo, enable the top of this table first and only add the lower rows once the earlier ones are landing.
Scheduler hygiene, whatever fires the run — the specifics belong in the target repo's own operator docs, but three things hold everywhere:
  • Pin the model explicitly if the scheduler exposes one. Left blank it inherits a default, and the default is usually the expensive one — a poor trade for work this mechanical.
  • Do not carry state between runs. Each run starts cold and reads the repo. Scheduler-side session memory gets reclaimed on its own schedule, so a routine that depends on remembering last time will silently start over.
  • Stagger the schedules against whatever concurrency limit the runner enforces. Same-minute triggers queue up and hold their workspaces while they wait.
/cadence:maintenance-routine <archetype>
<archetype>
为下方 7 种原型之一。从调度器调用时,整个提示词只需这一行。
原型功能客观性
dead-code-removal
删除经静态搜索证明确实无法访问的代码最高
useless-test-pruner
找出永远不会失败的测试;优先修复,仅在万不得已时删除
abstraction-police
修复违反仓库已书面规定的分层规则的问题
dup-unifier
合并且经证明会同步变更的重复实现
logic-bugfixer
对照模块规格建模,采用测试先行的方式修复真实缺陷
logic-simplifier
梳理单个函数内部的混乱逻辑
abstraction-improver
扁平化无实际意义的间接层最低
客观性可预测首轮合并率。在新仓库启用维护例程时,请先开启表格顶部的原型,待前面的原型稳定落地后再逐步添加下方的类型。
调度器规范:无论由什么触发执行,具体细节属于目标仓库自身的运维文档范畴,但以下三点通用:
  • 显式指定模型(如果调度器支持选择模型)。留空会继承默认模型,而默认模型通常成本更高——对于这种机械化工作来说性价比很低。
  • 不要在运行之间保留状态。 每次运行都是冷启动,直接读取仓库。调度器侧的会话内存会按自身计划回收,因此依赖上次运行记忆的例程会悄无声息地从头开始。
  • 错开调度时间,避免超出运行器的并发限制。同一分钟触发的任务会排队等待,并在等待期间占用工作区。

Preflight — all four gates must pass before any scanning

前置检查——扫描前必须通过全部四道关卡

1. Load the repo config. Read
.claude/routines.md
in the target repo.
If it does not exist, stop. Do not infer scope, forbidden paths or verification commands from the codebase — guessing them is how a routine ends up editing migrations. Print the template from Repo Config Schema, say it needs to be filled in and committed first, and end the run.
2. Load the archetype. Read
routines/<archetype>.md
next to this file. It defines the qualification test, the workflow, the PR body sections and the per-run PR cap. Its rules are additive to this file, never a relaxation of it — where the two differ, the stricter one wins.
3. Detect the forge.
gh
for GitHub,
glab
for GitLab. Check which is installed and authenticated:
bash
gh auth status 2>/dev/null || glab auth status 2>/dev/null
Neither → stop, report it. This skill's examples use
gh
; the
glab
equivalents are in Forge Commands. "PR" below means MR on GitLab.
4. Establish a green baseline. Run the config's verification commands at HEAD before changing anything.
If the baseline is red, stop and report which command failed. Do not attempt to fix it — a routine that arrives to delete dead code and leaves having repaired an unrelated broken test is out of scope, and worse, a red baseline makes every later "my change is safe" claim unfalsifiable. A broken HEAD is a human's problem.
Record the baseline output. You will diff against it later.
1. 加载仓库配置。 读取目标仓库中的
.claude/routines.md
如果该文件不存在,立即停止。不要从代码库中推断扫描范围、禁止路径或验证命令——猜测会导致例程错误修改数据库迁移文件等问题。输出仓库配置模式中的模板,说明需要先填写并提交该文件,然后结束运行。
2. 加载对应原型。 读取本文件同级目录下的
routines/<archetype>.md
。该文件定义了准入测试、工作流程、PR 正文结构以及单次运行的 PR 数量上限。其规则是对本文件的补充,绝不会放宽本文件的要求——两者存在冲突时,以更严格的规则为准。
3. 检测代码托管平台。 GitHub 用
gh
,GitLab 用
glab
。检查哪个工具已安装并完成认证:
bash
gh auth status 2>/dev/null || glab auth status 2>/dev/null
两者都没有 → 停止并报告问题。本技能的示例使用
gh
;对应的
glab
命令见代码托管平台命令。下文的“PR”在 GitLab 中对应 MR。
4. 建立绿色基线。 在做任何修改之前,在 HEAD 版本运行配置中的验证命令。
如果基线不通过,停止并报告失败的命令。不要尝试修复——一个本来要删除死代码的例程,最后却修复了一个不相关的失败测试,这属于超出范围的行为。更糟的是,红色基线会导致后续所有“我的修改是安全的”声明都无法验证。HEAD 版本有问题是需要人工处理的事。
记录基线输出,后续会用它来做对比。

The Routine Contract

例程契约

Every archetype obeys all of this. Archetype files restate the parts they most often get wrong; that repetition is intentional.
Open PRs. Never merge. Not with
--auto
, not when CI is green, not when the change is trivial. Merge is a human decision. This is the single invariant that makes the whole mechanism safe to run unattended.
No findings → no PR. An empty or padded PR is worse than silence: it costs review attention and it corrupts the merge-rate signal that tells you whether the routine is worth running. Ending with "scanned X, considered Y and Z, neither cleared condition 3, opened nothing" is a successful run. Say so plainly rather than reaching for something marginal.
Respect the per-run PR cap. Each archetype file states its own (1–3). The cap is about reviewer throughput, not about how much you found. Surplus candidates go in
## Observations
.
Name branches for accounting.
claude/<archetype>/<YYYY-MM-DD>-<n>
<n>
starts at 1 within a run. This is what makes merge rate computable without instrumenting anything — see Merge-Rate Accounting. Do not improvise a different scheme.
Stay out of the forbidden paths. The config's list, plus these, which hold in every repo:
  • Spec and decision records — architecture docs, ADRs, domain glossaries, feature specs, archived change records. For several archetypes these files are the oracle the work is judged against. Editing your own oracle is not maintenance. If you believe a rule is wrong, that goes in
    ## Observations
    for a human to turn into a decision.
  • CI workflow definitions — a routine must not be able to weaken the checks that gate its own PRs.
Nothing enforces this at the platform level. Branch protection and human review are the real defense; the list lowers the odds of getting there.
Do not fix what you notice in passing. A routine that wandered off its archetype produces a diff nobody can review against a stated intent. Real bugs spotted while pruning tests, schema problems found while chasing a logic bug, "while I was here" cleanups — all of it goes in
## Observations
.
Every PR body carries
## Verification
and
## Observations
.
Archetype files add their own required sections.
## Verification
pastes the actual command output, not a claim that it passed.
## Observations
is never omitted — write
none
when there is nothing.
Keep PRs single-topic and small. Archetype files set line ceilings. Over the ceiling means split, not "just this once".
所有原型都必须遵守以下全部规则。各原型文件会重申最容易出错的部分;这种重复是刻意设计的。
仅创建 PR,绝不合并。 即使用
--auto
也不行,CI 全绿也不行,修改再小也不行。合并是人类的决策。这是让整套机制可以无人值守安全运行的核心不变量。
无发现 → 不创建 PR。 一个空的或凑数的 PR 比什么都不做更糟:它会消耗评审精力,还会破坏用于判断例程是否值得运行的合并率信号。以“扫描了 X,考虑了 Y 和 Z,均未通过条件 3,未创建任何 PR”结束,是一次成功的运行。请直白地说明这一点,不要硬找一些边缘修改来凑数。
遵守单次运行的 PR 数量上限。 每个原型文件都规定了自己的上限(1-3 个)。上限是根据评审吞吐量设置的,和你发现了多少问题无关。多余的候选修改放入
## Observations
(观察项)部分。
按规范命名分支以便统计。
claude/<archetype>/<YYYY-MM-DD>-<n>
<n>
在单次运行中从 1 开始计数。这种命名方式使得无需额外埋点就能计算合并率——参见合并率统计。不要自行发明其他命名方案。
避开禁止路径。 除了配置文件中的列表,以下路径在所有仓库中都属于禁止范围:
  • 规格与决策记录 —— 架构文档、ADR(架构决策记录)、领域术语表、功能规格、归档的变更记录。对于多种原型来说,这些文件是评判工作的基准。修改自己的评判基准不属于维护工作。如果你认为某个规则有误,将其写入
    ## Observations
    ,由人工来决策是否修改。
  • CI 工作流定义 —— 例程绝不能削弱用于把关自身 PR 的检查规则。
平台层面没有强制机制来执行这些规则。分支保护和人工评审才是真正的防线;这个列表只是降低了违规的概率。
不要顺手修复偶然发现的问题。 偏离自身原型的例程产生的 diff,没有人能对照既定意图进行评审。修剪测试时发现的真实缺陷、追查逻辑缺陷时发现的 schema 问题、“顺手做的”清理——所有这些都要放入
## Observations
每个 PR 的正文都必须包含
## Verification
## Observations
部分。
各原型文件会添加自己要求的其他部分。
## Verification
要粘贴实际的命令输出,而不是只声明测试通过。
## Observations
绝不能省略——没有内容就写
none
保持 PR 单主题且小体量。 各原型文件会设置行数上限。超出上限就要拆分,不能“就这一次例外”。

Workflow

工作流程

  1. Preflight (all four gates).
  2. Pick this run's target — subdirectory, module, or whatever unit the archetype rotates over. Prefer areas untouched recently;
    git log --since='60 days ago' --name-only
    shows which parts of the tree are cold. State the choice and the reason in the PR body.
  3. Enumerate candidates.
  4. Apply the archetype's qualification test to each. This is where most candidates die, and that is the design working.
  5. Make the change for the survivors, up to the PR cap.
  6. Run the full verification suite. Compare against the baseline.
  7. Open the PR(s), or report that nothing qualified.
  1. 前置检查(通过全部四道关卡)。
  2. 选择本次运行的目标——子目录、模块,或原型轮询的其他单位。优先选择近期未改动的区域;
    git log --since='60 days ago' --name-only
    可以显示代码树中哪些部分是冷的。在 PR 正文中说明选择的目标和原因。
  3. 枚举候选修改项。
  4. 对每个候选项应用原型的准入测试。大多数候选项会在这一步被淘汰,这正是设计预期的效果。
  5. 对通过测试的候选项执行修改,数量不超过 PR 上限。
  6. 运行完整的验证套件,与基线做对比。
  7. 创建 PR,或报告没有符合条件的修改。

Verification

验证

Run the config's commands verbatim. A candidate whose change does not come back green is abandoned, not debugged into submission — write it up in
## Observations
and move on.
Paste real output in
## Verification
. When an archetype requires a red-then-green demonstration (
logic-bugfixer
's failing test,
abstraction-police
's new lint rule), both halves are required.
Leave the tree clean. Archetypes that temporarily mutate source to test something (
useless-test-pruner
,
logic-simplifier
) must restore it and confirm with
git status
before continuing. A mutation that leaks into a PR discredits every routine PR that follows it.
原封不动地运行配置中的命令。如果某个候选项的修改无法通过验证,直接放弃,不要反复调试让它通过——将情况写入
## Observations
然后继续。
## Verification
中粘贴真实输出。如果原型要求先红后绿的演示(比如
logic-bugfixer
的失败测试、
abstraction-police
的新 lint 规则),两部分的输出都必须提供。
保持代码树干净。 那些会临时修改源码来测试的原型(
useless-test-pruner
logic-simplifier
)必须恢复修改,并在继续之前用
git status
确认。泄漏到 PR 中的临时修改会让后续所有例程 PR 都失去可信度。

Merge-Rate Accounting

合并率统计

The branch naming convention is the entire instrumentation. After a couple of weeks:
bash
undefined
分支命名约定就是全部的统计埋点。运行几周后,可以用以下命令统计:
bash
undefined

GitHub

GitHub

gh pr list --search "head:claude/<archetype>" --state all
--json number,state,mergedAt,title
gh pr list --search "head:claude/<archetype>" --state all
--json number,state,mergedAt,title

GitLab

GitLab

glab mr list --source-branch "claude/<archetype>" --all

A routine landing well below the others is a routine whose qualification test is too loose or whose repo config is missing a trap. Tighten the archetype's conditions or add to `.claude/routines.md` — then let the next tick pick up the change.
glab mr list --source-branch "claude/<archetype>" --all

如果某个原型的合并率远低于其他原型,说明它的准入测试太松,或者仓库配置缺少对应的陷阱规则。请收紧该原型的条件,或补充到 `.claude/routines.md` 中——然后等待下一次调度执行时生效。

When Nothing Qualifies

无符合条件的修改时

Report, in the run output rather than a PR:
  • Which target was scanned and why it was chosen
  • Which candidates were considered
  • Which condition each one failed
This is the most common outcome for the lower-objectivity archetypes and it is not a failure. Padding it into a PR is.
请在运行输出中(而不是 PR 中)报告以下内容:
  • 扫描了哪个目标,以及选择该目标的原因
  • 考虑了哪些候选项
  • 每个候选项未通过的条件
对于客观性较低的原型来说,这是最常见的结果,并不算失败。硬凑出一个 PR 才是失败。

Forge Commands

代码托管平台命令

PurposeGitHubGitLab
Create PR
gh pr create --head <branch> --title T --body-file -
glab mr create --source-branch <branch> --title T --description "$(cat -)"
Auth check
gh auth status
glab auth status
List by branch
gh pr list --search "head:<prefix>"
glab mr list --source-branch <prefix>
Pass PR bodies via
--body-file -
/ stdin. Multi-line bodies through shell arguments get mangled.
On GitLab, never pass
--merge-when-pipeline-succeeds
(or
--auto-merge
). It violates the never-merge invariant.
用途GitHubGitLab
创建 PR
gh pr create --head <branch> --title T --body-file -
glab mr create --source-branch <branch> --title T --description "$(cat -)"
认证检查
gh auth status
glab auth status
按分支列出
gh pr list --search "head:<prefix>"
glab mr list --source-branch <prefix>
请通过
--body-file -
或标准输入传递 PR 正文。通过 shell 参数传递多行正文会被破坏格式。
在 GitLab 上,绝不要传递
--merge-when-pipeline-succeeds
(或
--auto-merge
)参数。这违反了绝不合并的不变量。

Repo Config Schema

仓库配置模式

.claude/routines.md
in the target repo. Everything here is repo-specific by definition — this skill has no defaults for any of it.
markdown
undefined
目标仓库中的
.claude/routines.md
文件。按定义,这里的所有内容都是仓库特有的——本技能没有任何默认值。
markdown
undefined

Maintenance routine config

Maintenance routine config

Verification

Verification

Commands every routine runs, in order, before opening a PR. Include whatever build step the tests depend on — a missing one produces failures that look like the routine's fault.
bash
<install command>
<build command, if the test run needs built artifacts>
<lint command>
<test command>
Commands every routine runs, in order, before opening a PR. Include whatever build step the tests depend on — a missing one produces failures that look like the routine's fault.
bash
<install command>
<build command, if the test run needs built artifacts>
<lint command>
<test command>

Forbidden paths

Forbidden paths

PathWhy
<glob>
<reason a human can check>
PathWhy
<glob>
<reason a human can check>

Spec sources

Spec sources

Where the written rules live.
abstraction-police
and
logic-bugfixer
use these as their oracle; every archetype treats them as read-only.
WhatWhere
Architecture constraints
<path>
Decision records
<path>
Domain glossary / state-machine invariants
<path>
Where the written rules live.
abstraction-police
and
logic-bugfixer
use these as their oracle; every archetype treats them as read-only.
WhatWhere
Architecture constraints
<path>
Decision records
<path>
Domain glossary / state-machine invariants
<path>

Commit conventions

Commit conventions

Anything a commit lint will reject: title format, body line length, allowed scopes.
Anything a commit lint will reject: title format, body line length, allowed scopes.

Dynamic-reference traps

Dynamic-reference traps

Constructs that look unreferenced to static search but are live: framework convention files, glob-loaded test files, string-keyed dispatch tables, cross-package boundaries, config that names symbols as strings, and any deliberately-retained transitional code. Each entry: what it is, how to recognise it, and that the routine must skip it.
Constructs that look unreferenced to static search but are live: framework convention files, glob-loaded test files, string-keyed dispatch tables, cross-package boundaries, config that names symbols as strings, and any deliberately-retained transitional code. Each entry: what it is, how to recognise it, and that the routine must skip it.

Per-routine

Per-routine

<archetype>

<archetype>

Scan scope, rotation order, or archetype-specific exclusions. Omit an archetype to accept the defaults in its file.

Sections may be empty but should not be absent — an empty **Dynamic-reference traps** is a claim that the repo has none, and it should be a deliberate claim.
Scan scope, rotation order, or archetype-specific exclusions. Omit an archetype to accept the defaults in its file.

各个部分可以为空,但不能缺失——空的 **Dynamic-reference traps**(动态引用陷阱)意味着声明该仓库没有这类陷阱,这必须是一个刻意的声明。

Design Notes

设计说明

  • The qualification test is the product. Each archetype's value comes from what it refuses to do. A routine that opens a PR on every run has a broken test, not a productive one.
  • Method here, parameters in the repo. Rules that generalise live in this skill; anything naming a path, a package manager or an internal symbol belongs in
    .claude/routines.md
    . A generalisable rule that has drifted into a repo config is a bug in this skill — pull it back.
  • Routines feed the rest of cadence. A routine's output is a PR, which is
    pr-review
    's input, which is
    pr-babysit
    's input. Routines are the leftmost stage of the lifecycle, and the only one with no human at the start.
  • 准入测试才是核心产品。 每个原型的价值来自于它拒绝做的事。如果一个例程每次运行都创建 PR,说明它的测试有问题,而不是它很高效。
  • 方法存于技能,参数存于仓库。 通用的规则放在本技能中;任何涉及具体路径、包管理器或内部符号的内容都属于
    .claude/routines.md
    。如果一个可通用的规则被放到了仓库配置中,那是本技能的 bug——应该把它收回来。
  • 例程为 cadence 的其他环节提供输入。 例程的输出是 PR,PR 是
    pr-review
    的输入,而
    pr-review
    的输出又是
    pr-babysit
    的输入。例程是整个生命周期的最左侧阶段,也是唯一一开始没有人工参与的阶段。