agentsclimarketplace

Tsve refactoring

Skill pipi-1997/agent-skills/skills/tsve-refactoring

AI-assisted code refactoring using the T-S-V-E (Types, Specs, Verification, Evolution) workflow with Code Hollowing. Use when refactoring complex logic, rewriting legacy code, restructuring modules, or when AI-generated refactors produce patch-on-patch results instead of clean redesigns. Activates for requests like "refactor this class", "rewrite this module", "clean up this spaghetti code", or "redesign this API".From its SKILL.md

Install
npx -y skills add pipi-1997/agent-skills --skill tsve-refactoring

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its file declares

Copied from the file, not written here

The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

6.9 KB, ~1.5k tokens by cl100k_base, as published. Nobody here has run it

T-S-V-E Refactoring

Break the "local optimum trap" in AI refactoring. Instead of patching legacy code, hollow it out and rebuild from type contracts.

Why This Exists

When refactoring complex code, AI tends to patch the existing mess — adding more if-else branches, wrapping with adapters — because old tokens dominate the context window. The result: code worse than before. T-S-V-E fixes this by removing old implementations entirely and letting AI derive fresh solutions from constraints alone.

When to Use

ScenarioApproach
Simple rename / moveSkip T-S-V-E, use standard tools
Logic change in clean codeStart at Phase S
Legacy spaghetti rewriteFull T-S-V-E
Cross-module restructureT-S-V-E per module, integrate after E

Workflow

Execute phases strictly in order: T → S → V → E

T — Types: Define the Algebra

Preserve all type signatures and interfaces. Delete every implementation body.

TypeScript:

// KEEP: the full type surface
interface PaymentGateway {
  charge(amount: Money, method: PaymentMethod): Promise<Result<Receipt, PaymentError>>;
  refund(receiptId: string, reason: RefundReason): Promise<Result<Refund, RefundError>>;
}

// DELETE: the entire class body
class StripeGateway implements PaymentGateway {
  async charge(amount: Money, method: PaymentMethod): Promise<Result<Receipt, PaymentError>> {
    // ← delete everything here
  }
  async refund(receiptId: string, reason: RefundReason): Promise<Result<Refund, RefundError>> {
    // ← delete everything here
  }
}

Python:

# KEEP: signatures + type hints
class OrderProcessor:
    def process(self, order: Order) -> Result[Receipt, OrderError]: ...
    def validate(self, order: Order) -> list[ValidationError]: ...

# DELETE: all implementation bodies

Go:

// KEEP: interface definition
type Repository interface {
    FindByID(ctx context.Context, id string) (*Entity, error)
    Save(ctx context.Context, entity *Entity) error
}

// DELETE: method bodies, keep signatures
func (r *pgRepository) FindByID(ctx context.Context, id string) (*Entity, error) {
    // ← delete everything here
}

Rules:

  • Keep generics, unions, return types, error types — the full contract
  • Delete ALL implementation lines, not just "the complex parts"
  • If types are missing or weak (any, object), strengthen them first

S — Specs: Build the Shell

Add invariants and contracts as docstrings or JSDoc. Describe what must hold, never how.

interface PaymentGateway {
  /**
   * Charge a payment method for the given amount.
   *
   * Preconditions:
   * - amount.cents > 0
   * - method must be previously validated via validateMethod()
   *
   * Postconditions:
   * - On success: receipt.amount === amount, receipt.status === 'completed'
   * - On failure: no side effects, original payment method unchanged
   *
   * Invariants:
   * - Idempotent: same idempotency_key always returns same receipt
   * - Timeout: must resolve within 30s or return TimeoutError
   */
  charge(amount: Money, method: PaymentMethod): Promise<Result<Receipt, PaymentError>>;
}

Focus on:

  • Preconditions (what must be true before calling)
  • Postconditions (what must be true after)
  • Invariants (what must always hold)
  • Edge cases (nulls, empty inputs, concurrency, timeouts)
  • Performance constraints (if any)

V — Verification: Tests Before Code

Write tests that define what "correct" means before generating any implementation.

describe("StripeGateway.charge", () => {
  it("returns receipt for valid charge", async () => {
    const result = await gateway.charge(usd(1000), validCard);
    expect(result.isOk()).toBe(true);
    expect(result.value.amount).toEqual(usd(1000));
  });

  it("rejects zero amount", async () => {
    const result = await gateway.charge(usd(0), validCard);
    expect(result.isErr()).toBe(true);
    expect(result.error).toBeInstanceOf(InvalidAmountError);
  });

  it("is idempotent with same key", async () => {
    const r1 = await gateway.charge(usd(500), validCard, { idempotencyKey: "abc" });
    const r2 = await gateway.charge(usd(500), validCard, { idempotencyKey: "abc" });
    expect(r1).toEqual(r2);
  });

  it("returns TimeoutError after 30s", async () => {
    // simulate slow provider
    const result = await gateway.charge(usd(100), slowCard);
    expect(result.error).toBeInstanceOf(TimeoutError);
  });
});

Cover:

  • Happy path (at least one)
  • Boundary conditions (zero, max, empty)
  • Error cases (invalid input, external failures)
  • Concurrency / idempotency (if specified in Specs)

Run the tests — they must fail (confirming the hollow state).

E — Evolution: Zero-Origin Generation

Now generate implementation inside the empty bodies. With types, specs, and tests as constraints, AI operates as an architect, not a patch-worker.

Instructions for this phase:

  1. Fill each hollowed function/method one at a time
  2. Run the test suite after each fill
  3. If tests fail, share only the failure output — never re-inject old implementations
  4. Iterate until all tests pass
  5. Run a final review for readability and edge cases

Critical Rules

  1. Never leave old code in comments. AI will latch onto commented-out implementations. Delete completely.
  2. Never re-inject old code when stuck. If generation fails, add more specs or tests — not old implementations.
  3. Never hollow without types. Deleting everything including signatures leaves no constraints. Always preserve the type shell.
  4. Never skip V. Without tests, there's no way to verify the new implementation matches intent.
  5. One function at a time in Phase E. Fill, test, fix, then move to the next. Don't generate everything at once.

Progress Checklist

T-S-V-E Progress:
- [ ] T: Type signatures and interfaces defined/refined
- [ ] T: All implementation bodies deleted (Code Hollowing)
- [ ] S: Preconditions and postconditions documented
- [ ] S: Edge cases and invariants specified
- [ ] V: Happy path tests written
- [ ] V: Boundary and error tests written
- [ ] V: Tests run and fail (confirming hollow state)
- [ ] E: Implementation generated within type shell
- [ ] E: All tests pass
- [ ] E: Final readability review done

Further Reading

See references/concept.md for the theoretical foundation behind Code Hollowing and the local optimum trap.

What ships with it: 1 file

3.1 KB alongside SKILL.md

references/

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.