Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

Back to skills

Incremental Safety

ASecurity

Decompose a large or risky change into a sequence of independently safe intermediate states, so the system stays green at every step and any step can be reverted alone.

31 stars
0 votes
0 copies
0 views
Added 9/19/2026
ai-agentsgoexpressrefactoringgitapi

Works with

api

Security Analysis

A100/100

Scanned 9/19/2026

Install to Claude Code

$npx -y skills add rlaope/ultraprompt --skill incremental-safety --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Incremental Safety?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Incremental Safety
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/rlaope-incremental-safety/badge)](https://www.skillsdirectory.com/skills/rlaope-incremental-safety)

More formats (shields.io, HTML) on the badges page.

Download Zip
Files
SKILL.md
---
name: incremental-safety
description: Decompose a large or risky change into a sequence of independently safe intermediate states, so the system stays green at every step and any step can be reverted alone.
---
# Incremental Safety

> Status: v0.1 baseline draft — derived from the case catalog and axis definitions; awaiting trace evidence from Fable 5.1 case runs.

## When to apply

- The change touches 3+ files, crosses a module boundary, or alters a public interface, schema, or wire format.
- You are migrating between technologies (framework swap, storage engine, protocol version) while the system must keep running.
- The change cannot be verified in one shot — the test suite, a benchmark, or production traffic is the only real oracle.
- Rollback matters: the target runs in production, other agents or humans work on the same tree, or the deploy is not atomic.
- A refactor started as "small" but the diff keeps growing and you have not committed anything runnable yet.
- You are about to do a big-bang rewrite and cannot state what proves the rewrite behaves identically to the original.

## Core loop

1. **Name the end state and the invariant.** Write one sentence for the target and one for what must stay true throughout,
   e.g. "all existing tests pass", "API responses byte-identical", "p99 within 5% of baseline".
   The invariant is the operational definition of "safe" for every intermediate state; if you cannot state it, you cannot know a step succeeded.
2. **Find the seam.** Identify the narrowest interface where old and new can coexist:
   a function boundary, an adapter or facade, a routing layer, a config flag, a duplicated column.
   If no seam exists, your first change is to *create* one — extract an interface, funnel scattered call sites through a single wrapper — with zero behavior change.
   Seam-creation commits are mechanical and easy to verify; they buy safety for everything after.
3. **Plan backward from the end state as a step ladder.** List steps such that:
   - each step leaves the system fully working (the invariant holds),
   - each step is independently revertable without conflicting with later steps,
   - each step is verifiable by an existing check or by a check the step itself adds.
   If a candidate step fails the first condition, split it. Order steps so the riskiest one lands when the blast radius is smallest — after reversible steps have proven the design, before irreversible cleanup.
4. **Add the new alongside the old — never replace in the same step.** Strangler-fig: introduce the new path dark
   (unreferenced, or behind a flag defaulting to the old path). Commit it.
   The old path is your rollback mechanism; deleting it now would destroy the very thing that makes the migration safe.
5. **Parallel-run before cutover whenever outputs are comparable.** Route real inputs through both paths and compare:
   shadow traffic, dual-write with reconciliation, golden-file diffing, or characterization tests executed against both implementations.
   Cut over only when the diff count over a meaningful sample is zero, or every remaining diff is individually explained and explicitly accepted.
6. **Cut over reversibly.** Flip the flag, switch the route, or swap the import as its own minimal commit.
   The cutover commit contains *only* the switch — no cleanup, no drive-by fixes — so reverting it restores the old path instantly without touching the new code.
7. **Verify at the invariant after every step, not just at the end.** Run the invariant's check (tests, diff harness, benchmark) after each commit.
   A red intermediate state means the step was too big — revert or split it.
   Do not "push through and fix at the end"; that converts a step ladder back into a big bang.
8. **Delete the old path as a separate final step.** Only after the new path has survived verification — and, in production settings, a soak period.
   Removal is its own commit: pure deletion, trivially reviewable, and it marks the migration's true completion. Until it lands, the migration is open.
9. **Watch for scope creep and re-plan when detected.** If mid-step you discover the change fans out —
   new callers, hidden coupling, schema implications, an undocumented feature the new path can't express — stop.
   Commit or stash the green portion, restate the end state, and re-run steps 2–3 with the new information instead of absorbing the growth silently.

## Choosing seam points

The seam determines the size of the risk window; choose it deliberately, not by convenience.

- **Prefer data boundaries over call boundaries** when the two sides deploy independently — serialized formats, DB rows, and message payloads outlive processes, so a seam there survives partial deploys.
- **Prefer one choke point over many.** A seam through which all traffic already flows (single entry function, one router, one loader) needs one cutover commit; a seam scattered across N call sites needs N flips and gives you N chances to miss one. Funnel first.
- **Prefer seams with an existing oracle.** If the boundary already has tests, logs, or metrics on it, you get parallel-run comparison nearly for free.
- **Minimize the interface you freeze.** Everything crossing the seam is frozen until cutover completes; a fat seam blocks unrelated work for the whole migration. Narrow it before starting.
- **Check both directions.** A good seam lets the old call the new (strangler) *and*, if needed, the new fall back to the old (safety net). If only one direction works, know which one you have.

## Heuristics

- If you cannot describe an intermediate state in which both old and new code exist and everything works, you have not found the seam yet — keep looking before writing any new-path code.
- A step is right-sized when its diff is reviewable in one sitting and its revert is a single `git revert` with no conflicts against later steps.
- Expand-migrate-contract for any schema or interface change: add the new field/method (expand), move all readers then all writers (migrate), remove the old one (contract). Never combine expand and contract in one commit.
- Flags are for cutover, not for living architecture: every flag you add gets a removal step written into the plan at creation time. A flag that outlives its migration is debt that doubles a test matrix.
- Parallel-run cost check: if comparing old vs new outputs costs less than one production incident, run both. It almost always does.
- Diff-size tripwire: if the working diff exceeds roughly 2x your estimate, or you touch a file you did not plan to touch, treat it as a hard signal to stop and re-plan — the "small change" has silently become a big one.
- Riskiest-step placement: do irreversible or hard-to-verify steps (data backfills, destructive renames, dropped columns) as late as possible, after everything reversible has already proven the design.
- When the test suite is weak, write characterization tests against the *old* behavior first; they double as the parallel-run harness and the invariant check.
- Commit cadence is a safety mechanism: commit every time you return to green, even if the message is boring. Uncommitted green states cannot be reverted to.
- Refactoring commits and behavior-changing commits never mix: a pure-move commit is provably behavior-preserving and lets `git bisect` do its job; a mixed commit blinds both reviewers and bisect.
- During parallel-run, treat every old-vs-new mismatch as "old is the spec" by default. Improving semantics is a separate change after cutover; conflating fidelity with cleanup is how migrations grow unbounded.
- Count the states you must keep working, not the lines you change: a 10-line edit that leaves the system broken for an hour is bigger than a 500-line mechanical rename that is green throughout.

## Cutover readiness checklist

Answer all five before flipping the switch; a "no" on any of them means the cutover step is premature.

1. Has the new path processed representative real inputs (not just unit-test fixtures), and were its outputs compared against the old path's?
2. Is the rollback a single revert or flag flip that one person can execute in under a minute, and has it actually been exercised once?
3. Is the cutover commit free of any other change — no cleanup, no renames, no opportunistic fixes riding along?
4. Is there a signal that would tell you within one verification cycle that the cutover regressed the invariant (failing test, diverging metric, error-rate alert)?
5. Does the plan already contain the follow-up steps — soak, old-path deletion, flag removal — with the migration held open until they land?

## Anti-patterns

- **Big-bang replacement** — deleting the old implementation in the same change that introduces the new one.
  → Corrective: re-introduce the old path from history, put both behind a seam, and cut over as a separate flagged step.
- **Long-lived red branch** — a feature branch that stays broken for days and merges as one giant diff nobody can review or bisect.
  → Corrective: slice it into green steps landed sequentially into the mainline; if a slice cannot be green on its own, hide it behind a flag or land it as a dark, unreferenced module.
- **Refactor + behavior change in one commit** — reviewers and `git bisect` cannot separate the mechanical move from the semantic change, so a regression hides inside noise.
  → Corrective: pure-refactor commit first, then the behavior change as a small readable diff on top.
- **Cutover commit that also cleans up** — flipping the switch and deleting the old path together, so rollback requires resurrecting code instead of reverting one commit.
  → Corrective: split into a flip commit and a delete commit; delete only after the flip has soaked.
- **Silent scope absorption** — noticing mid-task that the change is bigger than planned and quietly continuing because "I'm already halfway".
  → Corrective: the moment an unplanned file or subsystem enters the diff, stop, commit the green portion, and re-plan explicitly with the new scope stated out loud.
- **Flag graveyard** — cutover flags left in the code after migration, so every future test run pays for both branches forever.
  → Corrective: schedule flag removal as the migration's final step and treat the migration as open until that deletion commit lands.

## Worked example

*Illustrative construction, not a recorded run.*

Task: replace a hand-rolled JSON config parser with a schema-validated loader across a service with 14 call sites.

- Agent estimates "small change, just swap the parser" — then applies the tripwire check: 14 call sites is a fan-out risk, so it plans incrementally anyway.
- Agent names the invariant first: *every call site receives an identical config object for all existing config files in the repo.*
- Agent looks for a seam → finds call sites import `parse_config()` directly from 6 different modules. No choke point exists, so step 0 is to create one.
- Step 0: add `config/loader.py` exposing `load()` that wraps the old parser; repoint all 14 imports. Purely mechanical, zero behavior change. Tests green → commit ("route all config loading through loader facade").
- Step 1: write the new schema-validated loader as `load_v2()` in the same module — dark, nothing calls it — plus unit tests for it. Commit. Old path untouched; this commit is trivially revertable and blocks nobody.
- Step 2: build the parallel-run harness — iterate every `*.json` config in the repo, run both `load()` and `load_v2()`, deep-diff the results.
- First harness run → 3 mismatches. Agent observes the old parser silently coerced `"8080"` to int while v2 rejects it → classifies this as a real behavioral difference, not a v2 bug.
- Agent adds explicit string-to-int coercion to the schema *because the invariant is "identical output", not "cleaner semantics"* — tightening semantics is queued as a follow-up change after cutover, not folded in.
- Second harness run → diff count 0 across all configs. Commit harness + coercion fix.
- Mid-task the scope tripwire fires: while fixing coercion, agent notices two config files use an undocumented `include` directive the schema cannot express. The diff is about to grow into "redesign config includes."
- Agent stops, keeps `include` handling in an unchanged pre-validation pass, and files the redesign as a follow-up instead of absorbing it — the migration ships on schedule with scope intact.
- Step 3 (cutover): `load()` body becomes `return load_v2(...)`. One-line commit, nothing else in it. Tests green. Rollback path: revert this single commit.
- Step 4 (contract): after one green CI cycle, delete the old parser and the harness's old-path arm. Pure deletion commit; migration closed.

Six commits, every one green, every one revertable alone. The riskiest discovery — the coercion mismatch — was caught by the parallel-run harness in seconds, not by production.

## Trace evidence

| Case | Session | What it showed |
|------|---------|----------------|
| _awaiting case runs_ | — | — |

Attribution

rlaoperlaope
View sourceMore from rlaope →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Caveman

Ultra-compressed communication mode. Cuts token usage ~75% by speaking like caveman while keeping full technical accuracy. Supports intensity levels: lite, full (default), ultra, wenyan-lite, wenyan-full, wenyan-ultra. Use when user says "caveman mode", "talk like caveman", "use caveman", "less tokens", "be brief", or invokes /caveman. Also auto-triggers when token efficiency is requested.

1023331 votes

Hyperplan

Adversarial multi-agent planning skill. Self-orchestrates 5 hostile category members (unspecified-low, unspecified-high, deep, ultrabrain, artistry) via team-mode for ruthless cross-critique debate, distills only the defensible insights, then MANDATORILY hands the distilled insight bundle to the `plan` agent for executable plan formalization. Use when planning needs maximum rigor and surfacing of weak assumptions, blind spots, and over-engineering. Triggers: 'hyperplan', 'hpp', '/hyperplan', ...

686011 votes

Mcp Code Execution

Routes multi-tool workflows through MCP servers for large datasets and pipelines. Use when Bash tool overhead is limiting throughput on data-heavy tasks.

3331 votes

catchup

Recovers prior coding-agent session context by running `catchup <agent> --since-compact`, which extracts a clean summary of a previous Codex, Claude Code, Antigravity, OpenCode, or Pi Agent session. Use when the user says "catch up", "what did the last session do", "get me up to speed", "I switched agents", or asks to recover/summarize a previous session before continuing. Do NOT use for the current conversation, git history, or any non-agent log.

611 votes

math-skill

A comprehensive mathematical reasoning skill for AI assistants — handles arithmetic to research-level problems with rigorous step-by-step reasoning, systematic verification, and transparent uncertainty handling

381 votes
View all in ai-agents →