Token导航 LogoToken导航

Agent Skill · 研究检索

bookforge-dependency-breaking-technique-executor(bookforge 依赖破坏技术执行器)

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

bookforge-dependency-breaking-technique-executor 是研究检索类 Agent Skill,可用宿主为 OpenClaw,通过ClawHub获取,权限为调用外部服务;许可证为 MIT-0,第三方扫描已通过,按安装量在研究检索类的 73,675 个 Skill 里排第 28,546。

总安装 3,203周安装 105GitHub Stars 公开资料未说明下载 850核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
MIT-0
版本
1.0.0

安装方式

通过对话安装

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

请帮我安装这个 Agent Skill:bookforge-dependency-breaking-technique-executor(bookforge 依赖破坏技术执行器)
来源仓库:https://github.com/quochungto/bookforge-dependency-breaking-technique-executor
安装命令:
openclaw skills install bookforge-dependency-breaking-technique-executor
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

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

ClawHubOpenClaw
openclaw skills install bookforge-dependency-breaking-technique-executor

这个 Skill 是做什么的

研究检索类 Skill 主要解决「找资料、核对事实、把来源整理清楚」的问题,通常会让助手先检索再总结。

应用 Michael Feathers 提出的依赖打破技术优化模块耦合。适用于遗留系统中难以直接重构的紧耦合组件。bookforge-dependency-breaking-technique-executor 属于研究检索类 Skill,可作为该场景下的辅助能力补充。

从 24 种命名技术中选择最适合当前场景的重构策略。执行前应充分理解各技术的适用边界,避免误用导致副作用。建议配合单元测试保障重构安全性,逐步推进解耦过程。

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 OpenClaw;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 openclaw skills install bookforge-dependency-breaking-technique-executor;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要调用外部服务,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

bookforge-dependency-breaking-technique-executor 怎么安装?

在终端执行 openclaw skills install bookforge-dependency-breaking-technique-executor。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

bookforge-dependency-breaking-technique-executor 支持哪些 AI 工具?

公开资料标注支持 OpenClaw。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

bookforge-dependency-breaking-technique-executor 需要什么权限?

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

bookforge-dependency-breaking-technique-executor 是免费的吗?

来源标注的许可证是 MIT-0。本站不代收任何费用,也不托管安装包;能否商用、要不要署名,以许可证原文为准。

bookforge-dependency-breaking-technique-executor 用的人多吗?

公开数据是累计安装 3,203 次,近一周安装 105 次,下载 850 次。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

bookforge-dependency-breaking-technique-executor 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 专注 OpenClaw 一种宿主,触发方式和使用习惯不用来回切换。
  • 许可证明确为 MIT-0,商用和分发边界好判断。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 OpenClaw,想直接扩展它能力的人。
  • 需要处理研究检索类任务、又不想每次都手写提示词的人。
  • 需要许可证清楚、并且有第三方扫描结果的团队项目。

不太适合

  • 需要厂商级技术支持和 SLA 的生产系统。

研究检索类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
find-skills

寻找技能 · Codex、Claude

31,199,81316,486操作浏览器MIT有提醒
self-improving-agent

自我改进 Agent · OpenClaw

16,464,0023,396接触敏感数据MIT-0通过
soultrace

灵魂追踪 · Codex、Claude

7,588,94412需要联网未明确有提醒
self-improving

自我完善 · OpenClaw

6,829,2841,046需要联网MIT-0通过
microsoft-foundry

微软代工厂 · Codex、Claude

6,614,144764调用外部服务未明确有提醒
bookforge-dependency-breaking-technique-executor

bookforge 依赖破坏技术执行器 · 本页

3,203—调用外部服务MIT-0通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

name
dependency-breaking-technique-executor
description
Select and execute the right dependency-breaking technique from Michael Feathers' catalog of 24 named techniques (Part III of Working Effectively with Legacy Code) for a specific testability obstacle. Use when a class or method cannot be placed under test due to a hard-coded dependency, and you need concrete step-by-step mechanics for breaking it safely — without existing tests protecting you. Activates for 'can't test this class', 'constructor dependency', 'global variable blocking tests', 'static call in method', 'inject a fake', 'break dependency for testing', 'extract interface legacy', 'subclass and override', 'parameterize constructor', 'encapsulate global', 'dependency injection without framework', 'extract and override', 'how to fake this in test', 'legacy code testability refactoring'.
version
1.0.0
homepage
https://github.com/bookforge-ai/bookforge-skills/tree/main/books/working-effectively-with-legacy-code/skills/dependency-breaking-technique-executor
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
[25]
domain
software-engineering
tags
[legacy-code, refactoring, testing, software-engineering, dependency-injection]
depends-on
execution
tier
1
mode
full
inputs
description
Class or method containing the dependency to break + language + description of the testability obstacle
tools-required
[Read, Edit, Bash]
tools-optional
[Grep]
mcps-required
[]
environment
Any codebase. Language determines which of the 24 techniques are available.
discovery
goal
Select the right technique and execute its full mechanics to break one specific dependency.
tasks

Dependency-Breaking Technique Executor

When to Use

Use this skill when you have a specific class or method that cannot be placed in a test harness because of a hard dependency — a constructor that allocates live resources, a method that calls a global or static, an interface that is sealed or final, a C++ header chain that pulls in half the system. You have already confirmed the obstacle (ideally via test-harness-entry-diagnostics) and need to choose from Feathers' 24 named techniques and execute the mechanics correctly.

Do not use this skill for design-level refactoring after tests exist — these techniques are intentionally conservative and produce imperfect intermediate states. The goal is testability, not beauty.

This skill executes Step 3 (Break Dependencies) of the Legacy Code Change Algorithm.


Context and Input Gathering

Before selecting a technique, you need four things:

ItemSourceHow to get it
Dependency typetest-harness-entry-diagnostics output or direct inspectionSee classification below
LanguageUser or codebaseDetermines which techniques apply
Constraint scopeInspectionLocalized (one method) vs pervasive (spread across methods/classes)
Can modify parameter/class?InspectionAffects Adapt Parameter vs Extract Interface choice

Dependency type classification:

  • Constructor dep — new ConcreteType() hard-coded in constructor; no way to inject alternative
  • Method param dep — method receives a hard-to-construct/fake concrete parameter
  • Global/static var — method reads or writes a global or static variable
  • Static method call — method calls SomeClass.staticMethod() with no interception point
  • Virtual/overridable call — method makes a call that could be made virtual/overridable
  • Singleton dep — class accesses a global singleton instance
  • Header dep (C++ only) — #include chain pulls in platform headers that break compilation
  • Template/generic dep — dependency baked into a type parameter

If you do not have output from test-harness-entry-diagnostics, ask:

  1. What is the exact error or obstacle when you try to instantiate the class or run the method in a test?
  2. What language and version?
  3. Is this one location or does the same dependency appear in many places across the class/codebase?

Process

Step 1: Receive the Diagnostic

If test-harness-entry-diagnostics has already run, use its output directly — it classifies the obstacle and recommends candidate techniques. If not, elicit the three context items above and classify the dependency type yourself.

Step 2: Consult the Selection Table

Use the compact table below to get to a candidate technique. Full matrix is in references/selection-table.md.

Dependency TypeLanguageConstraintRecommended Technique
Constructor creates concrete objectOOLocalizedParameterize Constructor
Constructor creates chain of objectsOOModerateExtract and Override Factory Method
Constructor creates objects (C++, no virtual in ctor)C++—Extract and Override Getter or Supersede Instance Variable
Method creates concrete object internallyOOLocalizedParameterize Method
Method parameter is hard-to-fake concreteOOLocalizedExtract Interface or Adapt Parameter
Parameter interface name taken by classOO—Extract Implementer
Parameter is sealed/final, cannot be extractedOO—Subclass and Override Method
Global/static variable — localized to one methodOOLocalizedReplace Global Reference with Getter
Global/static variable — spread across classOO/C++PervasiveEncapsulate Global References
Static method callOOLocalizedExtract and Override Call
Static method call, need instance levelOO—Introduce Instance Delegator
Singleton blocking testsOO—Introduce Static Setter
Few bad dependency methods, rest are fineOOLocalizedSubclass and Override Method or Pull Up Feature
Many bad dependency methods, few good onesOOPervasivePush Down Dependency
Method too long, uses instance dataOO—Break Out Method Object
Method pure/stateless, no instance dataOO—Expose Static Method
Global functions (C procedural)CLocalizedReplace Function with Function Pointer
Whole library/translation unitC/C++/JavaBuild-levelLink Substitution
C++ header chainC++—Definition Completion
Parameter is primitive but hides complex objectOOLast resortPrimitivize Parameter
Language has generics/templatesC++/Java—Template Redefinition
Language is interpreted (Ruby, Python, etc.)Dynamic—Text Redefinition

If two techniques appear, prefer the one higher in the list (simpler, fewer structural changes).

Step 3: Confirm the Choice

Cross-check against references/selection-table.md if in doubt, particularly for:

  • Whether the language prohibits virtual calls in constructors (C++)
  • Whether the name of the desired interface already equals the class name (Extract Interface vs Extract Implementer)
  • Whether dependencies are truly localized vs pervasive (affects Subclass and Override vs Push Down Dependency)

Step 4: Execute the Mechanics

Full mechanics for all 24 techniques are in references/all-techniques.md. The 6 most common are inlined here.


Technique A: Parameterize Constructor

Problem: Constructor hard-codes new ConcreteType() — no way to pass in a fake.

Steps:

  1. Identify the constructor and the new expression creating the problematic object. Copy the full constructor signature (Preserve Signatures).
  2. Create a new constructor with all the original parameters plus one new parameter for the object being replaced. Inside the new constructor, remove the new expression and assign the parameter to the instance variable.
  3. Give the original constructor a new body: call the new constructor, passing new ConcreteType(...) as the new argument. If your language does not support constructor delegation, extract the shared body to a private initialize() method that both constructors call.

Java example:

// BEFORE
class PaymentProcessor {
    private DatabaseConnection db;
    PaymentProcessor() {
        this.db = new DatabaseConnection("prod-host", 5432);  // untestable
    }
}

// AFTER
class PaymentProcessor {
    private DatabaseConnection db;

    // New parameterized constructor — use in tests
    PaymentProcessor(DatabaseConnection db) {
        this.db = db;
    }

    // Original constructor — production code unchanged
    PaymentProcessor() {
        this(new DatabaseConnection("prod-host", 5432));
    }
}
// Test: new PaymentProcessor(new FakeDatabase())

Lean on the Compiler: If the class is used in many places, the compiler will not complain — both constructors are valid. Rely on grep or code review to confirm production callers still use the no-arg constructor.


Technique B: Parameterize Method

Problem: A method body hard-codes new ConcreteType() — you can instantiate the class fine, but you cannot intercept the object creation inside one specific method.

Steps:

  1. Identify the method and copy its signature.
  2. Create a new version of the method with all original parameters plus one new parameter for the created object. Remove the creation expression; use the parameter.
  3. Give the original method a new body: call the new parameterized method, passing new ConcreteType(...) as the extra argument.

C++ example:

// BEFORE
void TradeRecorder::record(Trade* trade) {
    AuditLog* log = new AuditLog("/var/log/trades");  // ties to filesystem
    log->write(trade->toXml());
    delete log;
}

// AFTER
void TradeRecorder::record(Trade* trade, AuditLog* log) {
    log->write(trade->toXml());
}

void TradeRecorder::record(Trade* trade) {
    AuditLog* log = new AuditLog("/var/log/trades");
    record(trade, log);
    delete log;
}
// Test: recorder.record(trade, &fakeLog)

Technique C: Extract Interface

Problem: A parameter, instance variable, or return type is a concrete class — you cannot pass a fake without changing the production signature.

Steps:

  1. Create a new interface with the name you want. Add no methods yet. Make the existing concrete class implement it. Compile and run tests to verify nothing broke.
  2. Change the declaration of the target (parameter, field, local variable) to use the new interface type instead of the concrete class.
  3. Compile the system. Every method call on the variable that the compiler now rejects needs to become a method declaration on the interface. Add them one by one, guided by compiler errors — this is Lean on the Compiler doing method discovery.
  4. Create a fake implementation of the interface for use in tests.

Why compiler-driven discovery matters: Never extract a maximal interface (copying all public methods). Only add methods that the actual usage site needs. The compiler tells you exactly which methods those are.

Java example:

// BEFORE: UserNotifier depends on concrete UserRepository
class UserNotifier {
    private UserRepository repo;
    UserNotifier(UserRepository repo) { this.repo = repo; }
    void notify(int userId) {
        User user = repo.findById(userId);
        sendEmail(user.getEmail());
    }
}

// AFTER: Extract IUserRepository
interface IUserRepository {
    User findById(int id);  // compiler told us this is needed
}
class UserRepository implements IUserRepository { ... }
class FakeUserRepository implements IUserRepository {
    public User findById(int id) { return new User("test@test.com"); }
}
class UserNotifier {
    private IUserRepository repo;
    UserNotifier(IUserRepository repo) { this.repo = repo; }
    ...
}

C++ note: In C++, non-virtual methods are resolved at compile time. If the concrete class has non-virtual methods you rely on, Extract Interface (creating a pure-virtual abstract base) is the correct approach. Do not try to extract an interface from a class with only non-virtual methods you need — use Subclass and Override Method instead.


Technique D: Subclass and Override Method

Problem: A few methods inside a class call out to problematic dependencies (UI, network, filesystem). You cannot easily parameterize because the method uses this directly.

Steps:

  1. Identify the smallest set of methods that, if overridden, would eliminate all the problematic dependencies. Try to find one or two methods rather than a large set.
  2. Make each method overridable: in C++, add virtual; in Java, confirm it is not final (remove final if needed); in C#, add virtual or override.
  3. Adjust visibility so that a subclass can override: in Java/C#, methods must be at least protected (not private). In C++, virtual methods can have any access but protected is conventional for testing seams.
  4. Create a testing subclass in your test file. Override the methods to do nothing or return safe values. Verify that you can instantiate this subclass in your test harness and that the problematic calls are neutralized.

Language visibility quick-ref:

LanguageMake overridableVisibility minimum
C++add virtualprotected conventional
Javaremove final (default non-final)protected
C#add virtualprotected
Python/Rubynothing requirednothing required

Key risk: Test subclasses that override too many methods may stop testing the real class logic. Override only the methods that reach problematic external dependencies — not the logic you actually want to test.


Technique E: Encapsulate Global References

Problem: Free-standing global variables or functions are used throughout a class or multiple methods. The globals cannot be intercepted per-call without restructuring every call site.

Steps:

  1. Identify all the globals you want to encapsulate. Group logically-related globals together.
  2. Create a new class to hold them. Name it for its responsibility (e.g., ApplicationContext, PlatformServices).
  3. Copy the global variable declarations and function signatures into the new class as instance variables and methods.
  4. Comment out (do not delete yet) the original global declarations. Keep the definitions.
  5. Declare a global instance of the new class with the original names or a conventional name (e.g., g_context).
  6. Lean on the Compiler — attempt to compile. Every unresolved reference to an original global is now a compiler error. Navigate to each error.
  7. Prefix each formerly-global reference with the global instance name (e.g., g_context.openConnection()).
  8. Now you have an object you can replace. Use one or more follow-on techniques to enable substitution in tests: Introduce Static Setter (for singletons), Parameterize Constructor (pass the instance in), Parameterize Method, or Replace Global Reference with Getter (per-method override via subclass).

C++ example (abbreviated):

// BEFORE: globals spread everywhere
extern int g_activeConnections;
bool openConnection(const std::string& host);

// Encapsulated:
struct NetworkGlobals {
    int activeConnections;
    bool openConnection(const std::string& host);
};
extern NetworkGlobals g_network;  // replaces originals

// After Lean on the Compiler, every site becomes:
g_network.openConnection(host);
g_network.activeConnections++;

// In tests (using Parameterize Constructor afterward):
FakeNetworkGlobals fakeNet;
MyClass obj(&fakeNet);  // injected

When to use vs Replace Global Reference with Getter: Use Encapsulate Global References when the same global is accessed in multiple methods of the class. Use Replace Global Reference with Getter when only one method uses it and Subclass and Override is already in play.


Technique F: Extract and Override Factory Method

Problem: A constructor creates one or more objects internally via new, and the creation cannot simply be parameterized because it involves multiple steps or inter-object initialization.

Steps:

  1. Identify the object creation in the constructor (the new SomeType(...) expression and surrounding initialization logic).
  2. Extract all of that creation logic into a new protected method, e.g., createXxx(). The method returns the created object. The constructor calls the factory method and assigns the result.
  3. Create a testing subclass that overrides createXxx() to return a fake or null object.

Java example:

// BEFORE
class OrderProcessor {
    private ShippingService shipping;
    OrderProcessor() {
        this.shipping = new FedExShippingService(loadConfig());  // pulls config file
    }
}

// AFTER
class OrderProcessor {
    private ShippingService shipping;
    OrderProcessor() {
        this.shipping = createShippingService();
    }
    protected ShippingService createShippingService() {
        return new FedExShippingService(loadConfig());
    }
}

// In tests:
class TestOrderProcessor extends OrderProcessor {
    protected ShippingService createShippingService() {
        return new FakeShippingService();
    }
}

C++ warning: Do not call virtual methods from a C++ constructor. Virtual dispatch is not in effect during construction. If you need this pattern in C++, use Extract and Override Getter (lazy initialization via a getter that is only called after construction) or Supersede Instance Variable.


Step 5: Run Tests and Adjust

After executing the mechanics:

  1. Attempt to compile. If there are errors, use Lean on the Compiler to navigate them — do not guess at call sites; let the compiler find them.
  2. Run the tests. If a test fails because you missed an override or the fake is not wired in correctly, adjust the test subclass or fake implementation.
  3. If the change introduced a regression in existing tests, check whether you violated Preserve Signatures. The most common mistake is accidentally changing a method signature during the extraction.
  4. If compilation fails persistently, verify that you have not introduced circular dependencies (common in C++ header extraction).

Step 6: Document the Break

Create or update dependency-break-log.md in the book or module directory. Record:

## [Date] Break: [TechniqueName] on [ClassName.methodName]

**Obstacle:** [What prevented testing before]
**Technique chosen:** [Name from catalog]
**Why this technique:** [One sentence justification]
**Changes made:**
- [File and what changed]
**Remaining design debt:** [What this left imperfect — be honest]
**Next step:** [What to refactor once tests are in place]

Inputs

InputRequiredDescription
Source code fileYesThe class or method containing the dependency
LanguageYesDetermines which techniques apply
Testability obstacleYesFrom test-harness-entry-diagnostics or direct description
Constraint scopeYesLocalized vs pervasive
test-harness-entry-diagnostics outputOptional but recommendedPre-classifies obstacle; speeds selection

Outputs

OutputDescription
Refactored source codeThe class after dependency breaking — compilable and testable
chosen-technique.mdShort record of which technique was used and why
dependency-break-log.mdRunning log of all breaks for the module
Test file stubIf applicable, the testing subclass or fake used to verify the break

Key Principles

Prefer object seam techniques in OO languages. Extract Interface, Parameterize Constructor, Subclass and Override Method, and Extract and Override Factory Method all create explicit, maintainable object seams. Reserve Link Substitution, Preprocessor Seams, and procedural techniques (Replace Function with Function Pointer) for C/C++ codebases where OO techniques are unavailable or the dependencies are at the build level.

Use Preserve Signatures during step execution. When extracting a method or copying a constructor, copy the parameter list exactly as written — do not rename parameters, collapse overloads, or add convenience arguments. Introduce those improvements after tests are in place. Signature drift during dependency breaking is a leading cause of introducing bugs while trying to enable testing.

Lean on the Compiler in statically-typed languages. When you move a declaration (comment out a global, rename a class, change a field type), let compile errors guide you to every affected call site. This is more reliable than grep. Be aware of the inheritance trap: removing a method from a class will not produce a compiler error if a superclass has the same method — check the class hierarchy.

For pervasive dependencies, prefer Encapsulate Global References over per-site rewrites. If the same global or static appears in five methods of a class, encapsulating it once and replacing with a parameterized or getter-based approach costs less than applying Extract and Override Call five times separately.

Each technique is a refactoring done without tests — that is the point. The conservative step-by-step mechanics protect you in the absence of a safety net. Resist the temptation to clean up design simultaneously. "First, make it testable. Then, make it good."


Examples

Example 1: Parameterize Constructor (Java)

PaymentProcessor creates new DatabaseConnection("prod", 5432) in its constructor. Tests cannot run without a live database.

Technique: Parameterize Constructor. Add PaymentProcessor(DatabaseConnection db) constructor; original becomes this(new DatabaseConnection(...)). Tests inject new FakeDatabaseConnection(). Production callers unchanged.


Example 2: Extract Interface (Java)

UserNotifier holds a UserRepository field. Repository opens a database on construction; no way to substitute.

Technique: Extract Interface. Create empty IUserRepository; make UserRepository implements IUserRepository; change UserNotifier's field type. Compile — errors identify every method that must appear on the interface. Create FakeUserRepository for tests. Production unchanged.


Example 3: Push Down Dependency (C++)

OffMarketTradeValidator.showMessage() calls AfxMessageBox (Windows MFC) and g_dispatcher. Cannot test validation logic without the Windows GUI framework.

Technique: Push Down Dependency. Make showMessage() pure virtual in the base class. WindowsOffMarketTradeValidator holds real MFC code. TestingOffMarketTradeValidator overrides showMessage() with an empty body. Tests instantiate the testing subclass — validation logic is now testable without any UI framework. (See case study cs-012 in references/all-techniques.md.)


References

  • references/all-techniques.md — Full step-by-step mechanics for all 24 techniques, including language-specific ones (Template Redefinition, Text Redefinition, Link Substitution, Definition Completion, Replace Function with Function Pointer) and less common ones (Primitivize Parameter, Introduce Instance Delegator, Break Out Method Object, Expose Static Method, Pull Up Feature, Introduce Static Setter, Supersede Instance Variable)
  • references/selection-table.md — Comprehensive dependency-type × language × technique matrix; symptom-from-Ch9 → technique cross-reference; language applicability quick-ref

License

This skill is derived from *Working Effectively with Legacy Code* by Michael C. Feathers (Prentice Hall, 2004). Skill content is licensed under CC BY-SA 4.0.


Related BookForge Skills

Direct dependencies (invoke before this skill):

  • legacy-code-change-algorithm — outer procedure; this skill executes Step 3
  • seam-type-selector — determines seam family (object/link/preprocessor) before technique selection
  • safe-legacy-editing-discipline — Preserve Signatures, Lean on the Compiler, Single-Goal Editing disciplines used during execution
  • test-harness-entry-diagnostics — classifies the testability obstacle; feeds directly into Step 1 of this skill

Cross-references (related skills):

  • characterization-test-writing — what to do in Step 4 (write tests) after this skill completes
  • library-seam-wrapper — specialized wrapper skill for third-party library dependencies
  • legacy-code-symptom-router — routes from symptom to this skill and other Part II techniques
  • legacy-code-addition-techniques — Sprout/Wrap techniques for when you need to add code before getting under test

平台分布

OpenClaw

75.95%
按下载量换算646

安全审计

VirusTotal

通过

ClawScan

通过

Static analysis

通过

权限和风险

调用外部服务

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

安装前确认

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

继续浏览同类 Skills