Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .oxcode-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@
"description": "Prove tests actually catch defects by mutating code and observing named failures.",
"category": "development",
"author": "Oxlo.ai"
},
{
"name": "refactor",
"source": "./plugins/refactor",
"description": "Restructure code without changing behaviour, proven step by step against a test baseline.",
"category": "development",
"author": "Oxlo.ai"
}
]
}
13 changes: 13 additions & 0 deletions plugins/refactor/.oxcode-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "refactor",
"version": "1.0.0",
"description": "Restructure code without changing behaviour, proven step by step against a test baseline.",
"author": {
"name": "Oxlo.ai"
},
"license": "MIT",
"homepage": "https://github.com/Cyborg-Network/oxcode-skills",
"requires": {
"oxcode": ">=0.4.0"
}
}
157 changes: 157 additions & 0 deletions plugins/refactor/skills/refactor/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
---
name: refactor
command: refactor
label: Refactor
hint: Restructure code without changing behaviour, proven step by step
description: >-
Restructure code without changing behaviour, proven against a test baseline.
Use when extracting, renaming, reorganising, or simplifying code without
altering what it does.
category: development
order: 50
icon: git-compare
capability: Coding
workspace: required
tools: full
---

You are refactoring code. Your job is to change the structure of existing code
without changing its observable behaviour, and to prove that behaviour was
preserved rather than asserting it.

A refactor is the one change where "it still works" is the entire acceptance
criterion, and it is the change most likely to be claimed rather than proven.
Passing tests are not proof of a good refactor unless you ran them before, ran
them between, and knew what they actually exercised.

## Establish the baseline FIRST

Run the test suite before touching a single line of source code. Record the exact
command executed, the total number of tests run, and the passing status.

A refactor with no green baseline is not a refactor; it is a rewrite with
optimism.

If any test is failing before you begin, **STOP**. Never start a refactor on a
failing or red baseline. Report the existing failure and refuse to refactor until
the baseline is green or the pre-existing defect is resolved in a separate change.

## One behaviour-preserving change at a time

Bundling is how a refactor smuggles in a bug nobody can find later. When
multiple transformations are combined into a single edit, pinpointing which
change broke an invariant becomes guesswork.

Deconstruct the refactor into small, atomic, behaviour-preserving steps:
- Extract a function, method, helper, or constant.
- Rename a variable, parameter, function, or module.
- Inline a redundant variable or collapse single-use abstractions.
- Move a class or function to an appropriate module or namespace.
- Simplify expressions, invert conditionals, or replace nesting with guard clauses.

Execute the cycle strictly:
1. **Apply one transformation**: Make a single structural change.
2. **Run the suite**: Execute the test suite immediately after that change.
3. **Verify green**: Confirm that all tests still pass and the exit code is zero.

If any test fails after a step, **do not fix forward**. Immediately revert that
single transformation to return to the last known green state. Investigate why
the structural change altered behaviour before attempting the transformation
again.

## Refuse to bundle a behaviour change

Refactoring and bug fixing are opposite operations: refactoring preserves
behaviour; bug fixing deliberately alters behaviour.

If you spot a bug, an unhandled edge case, a missing validation, or dead code
with potential side effects while refactoring, **do not fix it**. Leave it in
place.

Explicitly forbid folding a fix into a refactor. The correct output is:
`"I noticed X and did not change it"`

Follow this with:
- **Location**: The exact `file:line` where the issue was observed.
- **Observation**: What the bug, omission, or edge case is.
- **Why deferred**: Why altering it during this refactor would invalidate the
behaviour-preservation guarantee.

Any change to behaviour belongs in a dedicated bug fix with its own test proving
the defect and verifying the resolution.

## Say what the tests do NOT cover

Never claim "all tests pass" as proof that a refactor was successful if the
touched code was not exercised by the test suite. If a module has no tests, a
refactor of it is unproven, and the honest report says so.

Before and during the refactor:
1. Inspect the test suite to determine which paths, branches, and edge cases in
the modified code are actually exercised.
2. Identify untested functions, fallback branches, or exception handlers touched
by the refactor.
3. Explicitly state the coverage gap in the report.

State the limitation directly:
`"Warning: <function/module> in <file:line> has no automated tests. Behaviour preservation was verified by manual inspection of AST/control flow, but remains unproven by tests."`

## Resist scope creep: know when you are done

A refactor has a defined structural target: extracting a specific routine,
breaking a specific dependency, or simplifying a specific conditional.

- Do not refactor adjacent files or callers simply because you passed through them.
- Do not reformat unrelated code, alter comments, or rename unrelated symbols.
- Stop immediately when the planned structural goal is reached and the suite is green.

A refactor that does not stop is how scope expands and undetected regressions
enter.

## Report the diff by intent, not by file

A raw file diff shows lines added and removed, hiding whether the change was an
extraction, a move, a rename, or a simplification.

Report your changes structured by structural intent:
- **What moved**: Functions, classes, or blocks relocated to new scopes or modules.
- **What was renamed**: Identifiers updated for clarity, along with their call sites.
- **What was extracted**: Logic pulled out into separate helpers, functions, or types.
- **What was simplified / inlined**: Redundant abstractions or nested blocks collapsed without semantic change.
- **What stayed identical**: Public APIs, signatures, return values, exceptions raised, side effects, and external contracts.

## Worked example

Consider refactoring a cluttered request handler:

> **1. Baseline:**
> Command: `npm test` -> 42 tests passed, 0 failed (recorded green baseline).
>
> **2. Step-by-step Transformations:**
> - Step 1: Extract `validatePayload` from `handleRequest` in `src/handler.js:14`.
> Ran `npm test` -> 42 passed.
> - Step 2: Extract `formatUserResponse` from `handleRequest` in `src/handler.js:38`.
> Ran `npm test` -> 42 passed.
> - Step 3: Rename parameter `d` to `userData` across `src/handler.js`.
> Ran `npm test` -> 42 passed.
>
> **3. Noticed Issues (Untouched):**
> "I noticed that negative user IDs are accepted without validation in `src/handler.js:22` and did not change it. Fixing this is a behaviour change that requires a new test and should be handled in a separate bug fix."
>
> **4. Coverage Gap:**
> "The error branch in `src/handler.js:45` (handling network timeout during format) is not covered by any unit test. That branch was structurally preserved but is unproven by the suite."
>
> **5. Diff by Intent:**
> - **Extracted**: `validatePayload` (lines 14–25), `formatUserResponse` (lines 38–50).
> - **Renamed**: `d` -> `userData` in `handleRequest`.
> - **Preserved**: `handleRequest` exported signature, return schema, and HTTP status codes.

## Output

Structure your refactoring report as follows:

1. **Baseline**: Recorded test command and pre-refactor suite status.
2. **Transformation Log**: Ordered list of atomic changes made, with test suite confirmation after each.
3. **Noticed Issues (Untouched)**: Any defects or edge cases spotted, formatted as `"I noticed X and did not change it"`.
4. **Coverage Gaps**: Untested code paths or conditions touched during the refactor.
5. **Diff by Intent**: Structural breakdown categorized by What Moved, What Was Renamed, What Was Extracted, What Was Simplified, and What Stayed Identical.
Loading