Token导航 LogoToken导航TokenDH.com
研究检索external-serviceclawhub未标认证来源可访问clear审计通过

bookforge-safe-legacy-editing-disciplineBookforge 安全遗产编辑规则

Agent Skill

bookforge-safe-legacy-editing-discipline 用于查找、检索和筛选相关信息,适合在 OpenClaw 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

1,298

周安装

52

GitHub Stars

公开资料未说明

下载量

420
OpenClaw

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

MIT-0

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:bookforge-safe-legacy-editing-discipline(Bookforge 安全遗产编辑规则)
来源仓库:https://github.com/quochungto/bookforge-safe-legacy-editing-discipline
安装命令:
openclaw skills install bookforge-safe-legacy-editing-discipline
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 OpenClaw 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

ClawHubOpenClaw
openclaw skills install bookforge-safe-legacy-editing-discipline

简介

用于查找、检索和筛选相关信息,适合在 OpenClaw 中快速定位候选结果。

  • 适用于修改遗留代码时应用四项编辑规则:Hyperaware 编辑、单目标编辑、保留签名、依赖编译器。
  • 可结合来源仓库和原始 README 核验具体用法,确保代码变更安全可控。
  • 安装前需确认权限范围、维护状态,注意是否会触发联网、命令执行或文件读写。
  • 建议在使用前评估技能的实际输出边界,避免依赖其直接决策。

SKILL.md

name
safe-legacy-editing-discipline
description
Apply 4 editing disciplines when modifying legacy code: Hyperaware Editing, Single-Goal Editing, Preserve Signatures, Lean on the Compiler. Use whenever a developer is about to edit untested code, refactor without a safety net, or is caught in avoidance anti-patterns (Edit-and-Pray, Minimization Freeze, Legacy Code Dilemma paralysis). Activates for 'how do I refactor safely', 'edit legacy code without breaking it', 'preserve behavior during refactor', 'lean on the compiler', 'preserve signatures', 'single-goal editing', 'make safe changes', 'edit and pray', 'cover and modify', 'careful editing', 'refactor without tests', 'break dependencies safely', 'avoid regressions in legacy code'.
version
1.0.0
homepage
https://github.com/bookforge-ai/bookforge-skills/tree/main/books/working-effectively-with-legacy-code/skills/safe-legacy-editing-discipline
metadata
{"openclaw":{"emoji":"📚","homepage":"https://github.com/bookforge-ai/bookforge-skills"}}
status
draft
source-books
title
Working Effectively with Legacy Code
authors
["Michael C. Feathers"]
chapters
[1, 23]
domain
software-engineering
tags
[legacy-code, refactoring, software-engineering, code-quality, editing-discipline]
depends-on
execution
tier
1
mode
hybrid
inputs
description
Pending change specification + current test coverage status for the target code
tools-required
[Read, Grep, Edit]
tools-optional
[Bash]
mcps-required
[]
environment
Codebase in any language; Lean on the Compiler discipline applies only to statically-typed languages.
discovery
goal
Produce a safe-editing plan applying the 4 disciplines to a specific legacy code change.
tasks
audience
roles
[software-engineer, backend-developer, tech-lead]
experience
intermediate
when_to_use
triggers
prerequisites
why
The disciplines apply during Steps 3 and 5 of the algorithm
not_for
environment
codebase_required
true
codebase_helpful
true
works_offline
true
quality
scores
{with_skill: null, baseline: null, delta: null}
tested_at
null
eval_count
null
assertion_count
13
iterations_needed
null

Safe Legacy Editing Discipline

When to Use

You are about to edit code that has no tests, or you are doing the initial dependency-breaking refactoring that must happen *before* tests can be written. These disciplines exist precisely for this window — the gap between "no tests" and "some tests."

Apply this skill when any of the following are true:

  • You are about to make an edit and there are no automated tests covering the code
  • You are mid-dependency-breaking and tempted to also "clean up" something you notice
  • You catch yourself reasoning: "I'll just tweak it here — it's a small change"
  • Your team has stopped touching code because "if it's not broke, don't fix it"
  • You recognize the Edit-and-Pray pattern in your own recent work

Relationship to the Legacy Code Change Algorithm: These disciplines activate at Step 3 (break dependencies) and continue through Step 5 (make the change). They are the behavioral layer underneath the algorithm — the how of editing when the safety net is thin.

Context & Input Gathering

Before producing the editing plan, gather:

InputHow to Obtain
Target codeRead the file(s) being changed — understand current signatures, method bodies, and call sites
Planned change descriptionOne sentence: what will change and why
Test coverage statusAre there any tests covering this code right now? (zero / partial / good)
LanguageDetermines whether Lean on the Compiler is applicable (statically-typed: yes; dynamically-typed: no)
Phase of workInitial dependency-breaking (before tests) or post-test refactoring?

The editing plan format differs depending on phase:

  • Before first test: All four disciplines are in play; Preserve Signatures is mandatory.
  • After tests are in place: Hyperaware Editing and Single-Goal Editing remain; Preserve Signatures is no longer required; Lean on the Compiler is optional.

Process

Step 1: Classify the Editing Context

ACTION: Determine which phase of the Legacy Code Change Algorithm you are in.

Three contexts:

  1. Tested: Tests exist and cover the code being changed. The tests ARE your safety net. These disciplines are supplementary, not critical.
  2. Untested — initial dependency-breaking: You are breaking dependencies as a bootstrap to writing tests. No tests exist yet. This is the highest-risk editing context. ALL four disciplines apply.
  3. Untested — direct edit: You are making a behavioral change directly to untested code (a bug fix, a feature). Tests do not exist. This is Edit-and-Pray territory — name the anti-pattern and recommend writing characterization tests first (invoke legacy-code-change-algorithm Step 4 before proceeding).

ARTIFACT: Record the context:

Editing context: [Tested / Untested-bootstrap / Untested-direct]

Step 2: Name the Anti-Pattern to Avoid

ACTION: Identify which avoidance pattern is most present. This is not optional — naming the pattern makes it visible and prevents relapse.

Ask these diagnostic questions:

Is this Edit-and-Pray?

  • "Will I verify this change by manually running the application and poking around?"
  • "Am I about to trust my own memory of which paths I need to test?"
  • If yes: the change needs characterization tests before it proceeds. The target mental model is Cover-and-Modify — wrap the change in tests so that any behavior change is detected automatically, not discovered by memory-guided poking.

Is this the Legacy Code Dilemma?

  • "Do we refuse to add tests because refactoring is needed, but refuse to refactor because tests are needed?"
  • "Has the team been stuck in this circularity for weeks or months?"
  • If yes: conservative dependency-breaking techniques (Ch 25 catalog) break the cycle. These are safe enough to apply without tests and unlock the first test.

Is this Minimization Freeze?

  • "Does the team decline to extract methods or create seams with 'if it's not broke, don't fix it' reasoning?"
  • "Is the implicit rule 'make as few edits as possible'?"
  • If yes: the reasoning is inverted. True safety requires *more* edits (to create seams and tests), not fewer. Minimizing edits without a safety net accumulates risk on every future change — methods grow, dependencies harden, and every future edit becomes more dangerous.

ARTIFACT: Record the anti-pattern:

Anti-pattern in play: [Edit-and-Pray / Legacy Code Dilemma / Minimization Freeze / None]
Diagnostic evidence: [what the developer said or planned that signals this]

Step 3: Apply Hyperaware Editing

ACTION: Before making any edit, classify each planned change as behavior-changing or not.

Walk through your intended edit and label each action:

ActionBehavior-changing?
Add/change a string literal in live codeYes
Rename a local variableNo (if renamed consistently)
Change a numeric literalYes
Add whitespace / reformatNo
Add a new method callYes
Copy-paste a method signatureNo (same type, same name)
Change a parameter typeYes
Add a commentNo

WHY: Every behavior-changing keystroke is a risk when tests are absent. Knowing exactly which actions change behavior lets you treat those actions with more care — run a build after them, pause and re-read, consider whether a test should exist before you make the change.

Closing the feedback loop: The ideal is test-driven development where you can run tests in under a second after every change. When that is not possible, use pair programming (second person watches for accidental edits) as the nearest substitute.

ARTIFACT: For each planned edit, annotate your change-plan.md:

- [action]: behavior-changing: yes/no — risk level if no tests: [low/medium/high]

Step 4: Apply Single-Goal Editing

ACTION: Write down the one thing you intend to accomplish in this editing session. Then, as you work, capture every "also" item on paper instead of acting on it.

The single goal (write this before touching the keyboard):

Goal: [one sentence — e.g., "Extract the body of processOrders() into a private static method"]

The "also" list (capture mid-edit, do NOT act on these):

Also noticed:
- [thing 1 you want to clean up]
- [thing 2 that looks wrong but is out of scope]

Enforcement pattern (when pairing): The partner's job is to ask "What are you doing?" If the answer includes more than one thing, stop. Pick one. Return to the goal.

Why the paper list matters: The list prevents two failure modes:

  1. Forgetting the secondary item entirely (and leaving it broken)
  2. Acting on it now and losing track of the primary goal

The items on the paper list become future tasks — possibly new tickets. They are not lost; they are deferred with intention.

ARTIFACT: Append to change-plan.md:

## Single-Goal Edit
Goal: [one sentence]
Deferred items:
- [ ] [item 1]
- [ ] [item 2]

Step 5: Apply Preserve Signatures

ACTION: During initial dependency-breaking (before any tests exist), never retype a method signature — always copy-paste it.

Scope constraint — critical: Preserve Signatures applies ONLY when you are doing initial dependency-breaking refactoring with no tests in place. It is NOT a rule for general refactoring once tests exist. When tests are in place, the tests tell you when you've mistyped a signature.

The mechanical procedure:

  1. Copy the entire argument list from the source method into the clipboard
  2. Type the new method declaration with empty parentheses
  3. Paste the clipboard into the new method declaration
  4. Type the call site for the new method with empty parentheses
  5. Paste the clipboard into the call
  6. Delete the types, leaving only argument names in the call

What this eliminates:

  • Wrong parameter type (e.g., int vs long)
  • Wrong parameter order (e.g., rate, target vs target, rate)
  • Wrong variable name (e.g., interestRate vs interest_rate)
  • Accidental signature "improvements" (e.g., changing a parameter to take an object when the original took a primitive)

What Preserve Signatures does NOT mean: You may add new methods, move code, and create new classes. You just may not change the signatures of the methods you are copying or calling while doing so.

ARTIFACT: Add to dependency-break-log.md:

- [technique name]: signatures preserved: yes — method: [ClassName.methodName(args)]

Step 6: Apply Lean on the Compiler

PRECONDITION: Language must be statically typed (Java, C++, C#, Go, TypeScript, Kotlin, Rust, Swift). If the codebase uses Python, Ruby, or JavaScript: skip this step and rely on text-based search (Grep) instead.

ACTION: To find all locations that need updating after a declaration change, deliberately introduce a compile error by altering or removing the declaration, then let the compiler guide you to every affected location.

Two steps:

  1. Alter the declaration to cause compile errors (e.g., comment out a global variable, change a class type to an interface, remove a method)
  2. Compile; navigate to each error; make the required change

Example (C++ global encapsulation): Comment out double domestic_exchange_rate;. The compiler reports every file and line that references it. Update each reference to exchange.domestic_exchange_rate. Re-compile. Repeat until clean.

The inheritance trap — do not skip this caveat: If you comment out a method in a class and get zero compile errors, do NOT conclude the method is unused. If the method's parent class (or any ancestor) has a method with the same name and signature, the compiler will silently resolve all call sites to the parent's version. The method may have many callers — you just can't see them. This applies equally to variables and multiple inheritance hierarchies.

Safe procedure: Before concluding "no callers," verify whether any superclass in the hierarchy has a method with the same signature. If yes, use text search (Grep) to find callers instead.

ARTIFACT: Add to change-plan.md:

## Lean on the Compiler Plan
Declaration altered: [e.g., removed / commented out / type-changed]
Inheritance check: [verified no superclass has same signature: yes/no/N/A]
Errors found at: [list of files/lines]

Step 7: Produce the Editing Plan Artifact

Consolidate the outputs from Steps 1–6 into a single editing-plan.md for the change. This is the artifact that lets you (or a reviewer) verify the disciplines were applied.

See the Outputs section for the template.

Inputs

InputRequiredDescription
Target source file(s)YesThe code being modified
Change descriptionYesOne sentence — what changes and why
Test coverage statusYesZero tests / some tests / well-tested
LanguageYesDetermines Lean on the Compiler applicability
Phase of workYesBootstrap dependency-breaking vs. post-test change

Outputs

OutputDescription
editing-plan.mdDisciplines applied, anti-pattern identified, step-by-step edit sequence with rollback points
Annotations in change-plan.mdBehavior-change classification per edit, single-goal declaration, deferred items
Annotations in dependency-break-log.mdSignatures-preserved confirmation per technique applied

editing-plan.md Template

# Editing Plan

## Context
Editing context: [Tested / Untested-bootstrap / Untested-direct]
Language: [e.g., Java / C++ / Python]
Lean on the Compiler: [applicable / not applicable — reason]

## Anti-Pattern Identified
Anti-pattern: [Edit-and-Pray / Legacy Code Dilemma / Minimization Freeze / None]
Evidence: [what signaled this]
Mitigation: [what discipline or action addresses it]

## Single-Goal Edit
Goal: [one sentence]
Deferred items:
- [ ] [item 1]
- [ ] [item 2]

## Edit Sequence
For each step in the planned edit:
1. [action] — behavior-changing: yes/no — rollback point: yes/no
2. [action] — behavior-changing: yes/no — rollback point: yes/no

## Preserve Signatures
Applies: [yes / no — reason]
Methods copied (not retyped): [list]

## Lean on the Compiler
Declaration altered: [or N/A]
Inheritance check completed: [yes / no / N/A]
Errors found at: [list or N/A]

## Rollback Points
- After step [N]: compile clean, behavior unchanged
- After step [M]: compile clean, behavior unchanged

Key Principles

  • Safety comes from disciplines before it comes from tests. When tests do not yet exist, the four disciplines are the only systematic protection between you and an invisible regression. They are not a substitute for tests — they are the bridge to getting tests in place.
  • Do one thing at a time — "also" items go on paper. The paper list is not a concession. It is a precision tool. It captures what you noticed without letting it derail what you intended, and it ensures deferred items become tracked work rather than forgotten debt.
  • Preserve Signatures during initial dependency-breaking — the machine-perfect copy is a safety net. Retyping a parameter list introduces a class of error that tests would catch if tests existed. They do not exist yet. Copy-paste eliminates that error class entirely. Preserve Signatures is not a permanent style rule — it applies only in the pre-test window.
  • In typed languages, lean on the compiler — but beware inheritance masking. The compiler is a trustworthy guide for finding all callers of a declaration you change. The one place it fails silently is inheritance: a superclass method with the same signature will silently absorb all call sites when the subclass method is removed. Always verify the inheritance hierarchy before concluding the compiler found all callers.
  • Name the anti-pattern you're avoiding — awareness prevents relapse. Edit-and-Pray, Legacy Code Dilemma, and Minimization Freeze are named patterns for a reason: naming them makes them visible. A team that can say "we're in Minimization Freeze" can reason about how to exit it. A team that just has a vague feeling of avoidance cannot.

Examples

(a) Java developer about to add a parameter to a legacy method with no tests

Situation: A Java developer needs to add a locale parameter to a 200-line method InvoiceFormatter.format(Invoice invoice) that has no tests.

Step 1 (context): Untested-bootstrap. There are no tests. This is initial dependency-breaking work.

Step 2 (anti-pattern): Edit-and-Pray risk — the developer plans to add the parameter and then "test it manually by running the UI." Name the pattern and flag it.

Step 3 (Hyperaware): Adding a new parameter is behavior-changing. Every call site that currently compiles with one argument will break. Every place that constructs the string output may now differ. High-risk edits — note them explicitly.

Step 4 (Single-Goal): Write: "Goal: add Locale locale parameter to format() and thread it to the one callsite that needs it." While reading the method, the developer notices three other parameters that "should really be an object." Write them on the deferred list. Do not act on them now.

Step 5 (Preserve Signatures): Copy Invoice invoice from the current signature. Type public String format( then paste, add , Locale locale). Do not retype. Do not reorder. Do not rename invoice to inv.

Step 6 (Lean on the Compiler): The compiler error list after adding the parameter reveals 7 call sites, not the 2 the developer thought existed. Update all 7 before checking inheritance (no superclass has a format() method — confirmed via Grep).

Result: The parameter is threaded through all 7 call sites. No signature mutations were introduced. 5 deferred cleanup items are on paper. The code compiles. The developer can now write a characterization test.


(b) Team stuck in Minimization Freeze rationalization

Situation: A tech lead says: "Our core billing class has 800 lines. We can't add tests without refactoring, but we don't want to refactor because something might break. The policy is: if it's not broke, don't fix it."

Step 2 (anti-pattern): This is Minimization Freeze combined with Legacy Code Dilemma. Name both.

The inversion to surface: "It involves less editing, and it's safer" is backwards. Every future change to the 800-line class is made without any safety net. The cumulative risk grows with every undisciplined edit. True safety requires more edits (to create seams), not fewer.

The path out of Legacy Code Dilemma: Conservative dependency-breaking techniques (from Chapter 25) are designed specifically to be safe enough to apply without tests. They are not general refactoring — they are a bootstrap protocol. Apply one conservative technique (e.g., Parameterize Constructor), confirm it compiles, write the first test against the newly isolated code. The circularity is broken at the first test.

Single-Goal application: The first goal is not "clean up the billing class." It is: "break one dependency so we can write one test." Write that as the goal. Everything else is deferred.


(c) C++ developer encapsulating globals via Lean on the Compiler

Situation: A C++ developer wants to encapsulate two global variables (domestic_exchange_rate, foreign_exchange_rate) into a class so they can be substituted in tests.

Step 1 (context): Untested-bootstrap. Encapsulating globals IS a dependency-breaking technique. No tests yet.

Step 5 (Preserve Signatures): The globals are variables, not methods. The principle still applies: the new class fields should have identical names (domestic_exchange_rate, foreign_exchange_rate), not renamed versions.

Step 6 (Lean on the Compiler):

  1. Comment out both global variable declarations
  2. Compile — 34 errors across 9 files
  3. Navigate to each error; prefix the reference with exchange.
  4. Re-compile — 0 errors

Inheritance check: These are global variables, not class methods. Inheritance masking does not apply. The compiler's 34 errors are the complete set of usages.

Result: All 34 usages updated mechanically. No manual search required. The change is ready for a characterization test of the exchange rate behavior.

References

No supplementary reference files for this skill. The disciplines are self-contained.

Source material: Chapter 23 of Working Effectively with Legacy Code (the full chapter is dedicated to these four disciplines). Chapter 1 provides the Minimization Freeze and Edit-and-Pray context.

License

This skill is licensed under CC-BY-SA-4.0. Source: BookForge — Working Effectively with Legacy Code by Michael C. Feathers (2004, Prentice Hall).

Related BookForge Skills

  • legacy-code-change-algorithm — The parent algorithm. These disciplines apply at Steps 3 and 5. IF not installed → apply the inline discipline guidance above.
  • dependency-breaking-technique-executor — The full Chapter 25 catalog of 24 techniques. Lean on the Compiler is a sub-step within many of them. IF not installed → use the abbreviated technique descriptions in legacy-code-change-algorithm Step 3.
  • characterization-test-writing — Step 4 of the algorithm: how to write tests that document current behavior. Applies after these disciplines have made the code testable. IF not installed → use the inline Step 4 guidance in legacy-code-change-algorithm.

适合场景

01

OpenClaw 用户查找和安装 Skill 时

02

用户想查找某类 Agent Skill 时

03

需要根据任务场景推荐可安装能力包时

04

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

补充不同宿主或平台的使用分布数据

能力 5

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

OpenClaw

74.92%
按下载量换算315

安全审计

VirusTotal

通过

ClawScan

通过

Static analysis

通过

权限和风险

external-service

该 Skill 可能调用第三方服务、云服务或外部模型 API,使用前需要确认账号、额度、数据发送范围和服务条款。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills