refactor
SkillDev toolsTest-first refactoring — audit coverage, add characterization tests, apply changes with safety net, run quality stack and review loop. TRIGGER when: user wants to restructure existing Python code without changing behaviour; phrases: "refactor X", "clean up Y", "extract Z", "restructure this module", "improve code quality". SKIP when: bug fixes (use `/develop:fix`); new features (use `/develop:feature`); mixed refactor+feature — run `/develop:refactor` first, then `/develop:feature`; non-Python projects.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the refactor skill
What this skill tells your AI
The instructions your AI receives, as published by borda/ai-rig in plugins/cc_develop/skills/refactor/SKILL.md and read by ahel’s review.
Test-first refactoring. Audit coverage, add characterization tests if missing, apply changes with safety net.
NOT for:
- bug fixes (use
/develop:fix) - new features (use
/develop:feature) .claude/config changes (use/foundry:manage(requires foundry plugin))- non-Python projects (JS/TS/Go/Rust) — toolchain assumes pytest; use language-native toolchain instead
- mixed refactor+feature tasks — run /develop:refactor first, then /develop:feature; do not attempt both in single skill run
Quality stack (Branch Safety Guard, Codex Pre-pass, Progressive Review) requires foundry plugin; when absent, Step 5 quality stack skipped with a visible warning — output lower quality but workflow still completes.
- MAX_INNER_CYCLES: 5 (change-test cycles per outer session — Step 4 safety break)
- Key boundary: end of Step 2 — coverage audit complete, before characterization test writing in Step 3.
- Second boundary: end of Step 4 — refactor edits applied, before review stack in Step 5.
- Preserve at boundary 1: dev-dir, target path, coverage audit summary, plan-file, --keep items.
- Preserve at boundary 2: dev-dir, changed files list, test outcomes.
Agent Resolution
export CSID="${CLAUDE_CODE_SESSION_ID:-$PPID}"
_DEV_SHARED=$(python "${CLAUDE_PLUGIN_ROOT:-plugins/cc_develop}/bin/dev_shared_resolve.py" 2>/dev/null) # timeout: 5000
[ -z "$_DEV_SHARED" ] && _DEV_SHARED="plugins/cc_develop/skills/_shared"
echo "$_DEV_SHARED" > "${TMPDIR:-/tmp}/dev-shared-${CSID}" # cold resolve — every later block warm-reads this
# loads: compaction-contract.md
cat "$_DEV_SHARED/agent-resolution.md"
Contains: foundry check + fallback table. If foundry not installed: substitute each foundry:X with general-purpose per table. Agents skill uses: foundry:sw-engineer, foundry:qa-specialist, foundry:linting-expert, foundry:challenger.
export CSID="${CLAUDE_CODE_SESSION_ID:-$PPID}"
IFS= read -r _DEV_SHARED < "${TMPDIR:-/tmp}/dev-shared-${CSID}" 2>/dev/null || _DEV_SHARED="" # timeout: 5000
[ -z "$_DEV_SHARED" ] && _DEV_SHARED="plugins/cc_develop/skills/_shared"
cat "$_DEV_SHARED/task-hygiene.md"
Project Detection
export CSID="${CLAUDE_CODE_SESSION_ID:-$PPID}"
IFS= read -r _DEV_SHARED < "${TMPDIR:-/tmp}/dev-shared-${CSID}" 2>/dev/null || _DEV_SHARED="" # timeout: 5000
[ -z "$_DEV_SHARED" ] && _DEV_SHARED="plugins/cc_develop/skills/_shared"
cat "$_DEV_SHARED/runner-detection.md"
Sets $TEST_CMD (full suite) and $PYTEST_CMD (pytest flags). Run at skill start.
Optional --plan <path>: if $ARGUMENTS contains --plan <path> (at any position), read plan file first. Extract Affected files, Risks, Suggested approach — use to inform Step 1 scope analysis. Skip redundant codebase exploration for already-classified files. Store plan path as PLAN_FILE.
export CSID="${CLAUDE_CODE_SESSION_ID:-$PPID}"
IFS= read -r _DEV_SHARED < "${TMPDIR:-/tmp}/dev-shared-${CSID}" 2>/dev/null || _DEV_SHARED="" # timeout: 5000
[ -z "$_DEV_SHARED" ] && _DEV_SHARED="plugins/cc_develop/skills/_shared"
cat "$_DEV_SHARED/preflight-helpers.md"
Execute --plan path extraction; sets $PLAN_FILE.
Checkpoint init: create .developments/<TS>/ run directory, capture path in $DEV_DIR (assigned in the block below). Write checkpoint.md inside $DEV_DIR. After each major step (1, 2, 3, 4, 5), append step: N — completed to $DEV_DIR/checkpoint.md. On skill start, check for existing .developments/*/checkpoint.md — offer resume from last completed step if found.
# persist DEV_DIR for compaction recovery — bash state lost between Bash() calls
export CSID="${CLAUDE_CODE_SESSION_ID:-$PPID}"
DEV_DIR=$(python "${CLAUDE_PLUGIN_ROOT:-plugins/cc_develop}/bin/dev_run_dir.py" 2>/dev/null) # timeout: 5000
echo "$DEV_DIR" > "${TMPDIR:-/tmp}/dev-refactor-dev-dir-${CSID}"
Flag parsing
Parse flags into actual shell variables (not prose) so downstream blocks see correct values. Persist to temp files for cross-block access (bash state lost between Bash() calls):
export CSID="${CLAUDE_CODE_SESSION_ID:-$PPID}"
KEEP_ITEMS=""
if [[ "$ARGUMENTS" =~ --keep[[:space:]]\"([^\"]+)\" ]]; then
KEEP_ITEMS="${BASH_REMATCH[1]}"
fi
echo "$KEEP_ITEMS" > "${TMPDIR:-/tmp}/dev-refactor-keep-items-${CSID}"
rm -f .temp/state/skill-contract.md # timeout: 5000
# timeout: 10000
python "${CLAUDE_PLUGIN_ROOT:-plugins/cc_develop}/bin/dev_parse_args.py" \
--skill refactor --write-files "$ARGUMENTS"
Downstream blocks read back, e.g. IFS= read -r TEAM_MODE < "${TMPDIR:-/tmp}/dev-team-mode-${CSID}" 2>/dev/null || TEAM_MODE=false.
Codemap flag parsing — derive raw flag into a real shell variable, then normalize via codemap_resolve.py. Uses skill-specific temp file (dev-refactor-codemap-raw-${CSID}) to avoid reading stale values from prior feature/debug runs:
# timeout: 5000
export CSID="${CLAUDE_CODE_SESSION_ID:-$PPID}"
CODEMAP_RAW=auto
[[ " $ARGUMENTS " == *" --no-codemap "* ]] && CODEMAP_RAW=off
[[ " $ARGUMENTS " == *" --codemap "* ]] && [[ " $ARGUMENTS " != *" --no-codemap "* ]] && CODEMAP_RAW=strict
echo "$CODEMAP_RAW" > ${TMPDIR:-/tmp}/dev-refactor-codemap-raw-${CSID}
Unsupported flag check — after all supported flags extracted, scan $ARGUMENTS for remaining --<token> tokens not in the supported list below. If found: print ! Unknown flag(s): `--<token>`. Supported: `--plan`, `--team`, `--worktree`, `--no-challenge`, `--challenge`, `--codemap`, `--no-codemap`, `--accept-no-plan`, `--semble`, `--repo`, `--keep`. then invoke AskUserQuestion — (a) Abort (stop, re-invoke with correct flags) · (b) Continue ignoring (skip unknown flags, proceed). On Abort: stop.
Worktree isolation
loads: worktree-isolation.md
When --worktree set, offload the whole run into an isolated git worktree — before codemap detection or any edit, so codemap scans + all mutations land in the worktree (per-worktree ephemeral index; parallel runs never share one index).
# timeout: 5000
export CSID="${CLAUDE_CODE_SESSION_ID:-$PPID}"
IFS= read -r WORKTREE_ENABLED < "${TMPDIR:-/tmp}/dev-refactor-worktree-${CSID}" 2>/dev/null; [ "$WORKTREE_ENABLED" = "true" ] || WORKTREE_ENABLED=false
export CSID="${CLAUDE_CODE_SESSION_ID:-$PPID}"
IFS= read -r _DEV_SHARED < "${TMPDIR:-/tmp}/dev-shared-${CSID}" 2>/dev/null || _DEV_SHARED="" # timeout: 5000
[ -z "$_DEV_SHARED" ] && _DEV_SHARED="plugins/cc_develop/skills/_shared"
cat "$_DEV_SHARED/worktree-isolation.md"
WORKTREE_ENABLED=true → follow §Enter (call EnterWorktree, warm-start codemap). Else skip — run in main tree. Remember the branch for §Exit at Final Report.
Codemap auto-detection — run after flag parsing. Behaviour differs by mode: strict (user explicitly passed --codemap) hard-fails when codemap unavailable; auto and off soft-degrade to false (do not abort skill):
# timeout: 5000
export CSID="${CLAUDE_CODE_SESSION_ID:-$PPID}"
CODEMAP_ENABLED=$(python "${CLAUDE_PLUGIN_ROOT:-plugins/cc_develop}/bin/dev_codemap_gate.py" refactor) || exit 1
# codemap: integrated-via-shared
loads: codemap-gates.md
export CSID="${CLAUDE_CODE_SESSION_ID:-$PPID}"
IFS= read -r _DEV_SHARED < "${TMPDIR:-/tmp}/dev-shared-${CSID}" 2>/dev/null || _DEV_SHARED="" # timeout: 5000
[ -z "$_DEV_SHARED" ] && _DEV_SHARED="plugins/cc_develop/skills/_shared"
cat "$_DEV_SHARED/codemap-gates.md"
Follow Gate A and Gate B.
Preflight — if CODEMAP_ENABLED=true:
export CSID="${CLAUDE_CODE_SESSION_ID:-$PPID}"
IFS= read -r _DEV_SHARED < "${TMPDIR:-/tmp}/dev-shared-${CSID}" 2>/dev/null || _DEV_SHARED="" # timeout: 5000
[ -z "$_DEV_SHARED" ] && _DEV_SHARED="plugins/cc_develop/skills/_shared"
cat "$_DEV_SHARED/preflight-helpers.md"
Execute codemap + semble preflight if respective flags set.
Step 1: Scope and understand
Read target code, build mental model before touching anything.
If <target> is directory: use Glob tool (pattern **/*.py, path <target>) to enumerate Python files.
find <target> -name '*.py' -exec wc -l {} + 2>/dev/null | tail -1
If CODEMAP_ENABLED=true or SEMBLE_ENABLED=true:
export CSID="${CLAUDE_CODE_SESSION_ID:-$PPID}"
IFS= read -r _DEV_SHARED < "${TMPDIR:-/tmp}/dev-shared-${CSID}" 2>/dev/null || _DEV_SHARED="" # timeout: 5000
[ -z "$_DEV_SHARED" ] && _DEV_SHARED="plugins/cc_develop/skills/_shared"
cat "$_DEV_SHARED/codemap-context.md"
Follow enabled sections (codemap block if CODEMAP_ENABLED, semble companion if SEMBLE_ENABLED). Skip if both false.
Multi-file / API-change scope — extended codemap scan (only when CODEMAP_ENABLED=true): if target is directory, spans multiple files, or goal mentions renaming/restructuring public API (i.e., refactoring NOT limited to internals of single function or class with unchanged public interface):
_ROOT=$(git rev-parse --show-toplevel 2>/dev/null); [ -n "$_ROOT" ] || _ROOT="$PWD" # timeout: 3000
PROJ=$(basename "$_ROOT") # raw basename — scanner writes it verbatim, never sanitized
REFACTOR_FILES=$(find <target> -name '*.py' -type f 2>/dev/null)
AFFECTED_MODULES=$(echo "$REFACTOR_FILES" | sed 's|^\./||;s|^src/||;s|\.py$||;s|/|.|g' | grep . || echo "")
_IDX="${CODEMAP_INDEX_DIR:-$_ROOT/.cache/codemap}" # root-anchored: skill may run from a subdir
if command -v codemap-py >/dev/null 2>&1 && [ -f "${_IDX}/${PROJ}.json" ] && [ -n "$AFFECTED_MODULES" ]; then
# one batch process for all module rdeps — a per-module query loop pays process spawn + coverage cost N times
_BATCH_REQ="${TMPDIR:-/tmp}/dev-refactor-rdeps-batch-${CSID:-$PPID}.json"
python "${CLAUDE_PLUGIN_ROOT:-plugins/cc_develop}/bin/build_codemap_batch.py" "$_BATCH_REQ" --modules "$(echo $AFFECTED_MODULES)" --queries rdeps
codemap-py query batch "$_BATCH_REQ" 2>/dev/null
codemap-py query coupled --top 10
fi
Include ## Scope & Reusability (codemap-py) block in foundry:sw-engineer spawn prompt. If rdeps returns callers outside refactoring scope: flag explicitly — those callers must update or refactoring silently breaks public contract. If CODEMAP_ENABLED=false and scope is multi-file: skip silently.
Spawn foundry:sw-engineer agent to analyze code and identify:
- Public API surface (functions, classes, methods external code calls)
- Internal complexity hotspots (cyclomatic complexity, deep nesting, long functions)
- Code smells relevant to stated goal
- Dependencies and coupling between modules
- Complexity smell: directory or cross-module scope — flag it; consider team mode
export CSID="${CLAUDE_CODE_SESSION_ID:-$PPID}"
IFS= read -r _DEV_SHARED < "${TMPDIR:-/tmp}/dev-shared-${CSID}" 2>/dev/null || _DEV_SHARED="" # timeout: 5000
[ -z "$_DEV_SHARED" ] && _DEV_SHARED="plugins/cc_develop/skills/_shared"
cat "$_DEV_SHARED/premise-grounding.md"
§Premise Grounding Gate. Apply using refactor context from Skill contexts table.
Goal classification gate: after sw-engineer analysis completes, scan goal text for mixed signals — if goal contains both refactor keywords (rename, extract, restructure, decouple, consolidate) AND feature keywords (add, implement, new, support), ask: "Goal mixes refactoring and feature work — split into two runs." · (a) Abort — run refactor first, then feature · (b) Continue as refactor-only — treat feature additions as out of scope.
Scope gate: if target spans 3+ modules OR 5+ files OR goal mentions any public-API rename — flag complexity smell. Ask: "Narrow scope (Recommended)" / "Proceed anyway".
Both gates evaluate after the same sw-engineer analysis — when BOTH fire, invoke AskUserQuestion ONCE with both questions in the same call (menus stay distinct verbatim; a second sequential window costs another human-idle round trip). Only one fires → single-question call as usual.
export CSID="${CLAUDE_CODE_SESSION_ID:-$PPID}"
IFS= read -r _DEV_SHARED < "${TMPDIR:-/tmp}/dev-shared-${CSID}" 2>/dev/null || _DEV_SHARED="" # timeout: 5000
[ -z "$_DEV_SHARED" ] && _DEV_SHARED="plugins/cc_develop/skills/_shared"
cat "$_DEV_SHARED/plan-inline.md"
§Inline Plan Generation Protocol. Apply using refactor context from Skill contexts table. On proceed: set PLAN_FILE=<path>; continue to Step 2. On small complexity or ACCEPT_NO_PLAN=true: skip and continue to Step 2.
Challenger gate
Decision — three states (default is NOT "skip": it runs on substantial refactors and auto-skips only small contained ones):
--no-challenge(CHALLENGE_ENABLED=false) → skip gate entirely, any size.- else
--challenge(IFS= read -r CHALLENGE_FORCED < "${TMPDIR:-/tmp}/dev-challenge-forced-${CSID}" 2>/dev/null || CHALLENGE_FORCED=false=true) → always run, even on a small change. - else default → run when refactor is substantial (spans multiple files, ≳50 lines, or changes public API / an exported symbol); auto-skip when small (single file, ≲50 lines, no API change) — a contained refactor has little design surface to challenge.
Two flags are opposites for two regimes, which is why both exist: --no-challenge suppresses gate on substantial changes where it would otherwise fire; --challenge forces it on small changes where it would otherwise auto-skip.
Spawn foundry:challenger with scope analysis from Step 1 (affected files, dependencies, coupling, risks):
"Review the refactoring scope and approach. Challenge across all 5 dimensions: Assumptions, Missing Cases, Security Risks, Architectural Concerns, Complexity Creep. Apply mandatory refutation step."
Parse result:
- Blockers found → STOP. Present findings. Don't proceed to Step 2 until user resolves each blocker or explicitly accepts risk.
- Concerns only → surface as advisory before coverage audit; continue.
- No findings / all refuted → proceed.
Step 2: Audit test coverage
Find existing tests for target code:
Use Glob tool (pattern **/test_*.py or **/*_test.py), then Grep tool (pattern <module_name>, output mode files_with_matches) to narrow to those referencing target.
(Use Glob tool —
pattern: **/test_*.py— to discover test files; checkpyproject.toml[tool.pytest.ini_options] testpathsfor configured paths)
# timeout: 600000
# ONE collection pass feeds head-5 sanity print, cov-plugin probe, and module grep — three separate --co runs re-collect the whole suite each time
_CO_OUT=$($PYTEST_CMD --co -q --cov=. 2>&1)
SKIP_COV=0
if echo "$_CO_OUT" | grep -q "ModuleNotFoundError\|No module named.*cov\|unrecognized arguments.*--cov"; then
echo "⚠ coverage tool not found — coverage gate skipped"
SKIP_COV=1
_CO_OUT=$($PYTEST_CMD --co -q 2>&1) # cov-less re-collect — the probe run errored before listing tests
fi
echo "$_CO_OUT" | head -5
echo "$_CO_OUT" | grep -i "<module_name>" || echo "No tests found for <module_name>"
[ "${SKIP_COV}" -eq 0 ] && { $PYTEST_CMD --cov=<target_module> -q --cov-report=term-missing || true; }
If SKIP_COV=1: skip coverage classification entirely — do not classify any function as UNCOVERED; note "coverage tool absent — coverage audit skipped" in audit output. Step 3 qa-specialist spawn behavior when SKIP_COV=1: spawn qa-specialist with all public functions listed as coverage: unknown and instruction to write characterization tests for every public function (cannot prioritize uncovered functions when coverage unknown — test all to ensure safety net). Proceed to Step 3 with unknown coverage state.
Classify each public function/method (only when SKIP_COV=0):
- Covered: at least one test for happy path + one edge case
- Partially covered: test exists but missing edge cases or failure paths
- Uncovered: no test
Review: Validate the coverage audit
Before writing characterization tests, evaluate audit output critically:
- Completeness: all public functions, methods, classes identified — including complex call paths?
- Classification accuracy: each item correctly classified? Partial-covered often misclassified as covered.
- Refactor relevance: uncovered/partial items in code paths refactoring will touch?
- Hidden dependencies: integration points or cross-module calls audit may have missed?
If audit incomplete: re-examine before Step 3. Gaps found mid-refactoring (Step 4) costly.
Team mode branch — if TEAM_MODE=true: Steps 1–2 complete solo (teammates need scope + coverage context). Spawn both teammates now; skip Steps 3–5, proceed to Final Report after results received.
loads: team-mode.md — gated; ~90% of runs (
--teamabsent) skip the load entirely
# timeout: 5000
export CSID="${CLAUDE_CODE_SESSION_ID:-$PPID}"
IFS= read -r TEAM_MODE < "${TMPDIR:-/tmp}/dev-team-mode-${CSID}" 2>/dev/null || TEAM_MODE=false
[ "$TEAM_MODE" = "true" ] && cat "${CLAUDE_PLUGIN_ROOT:-plugins/cc_develop}/skills/refactor/modes/team-mode.md"
Continue to Step 3 only when TEAM_MODE=false.
# boundary 1: after coverage audit, before characterization tests (compaction-contract.md)
export CSID="${CLAUDE_CODE_SESSION_ID:-$PPID}"
IFS= read -r _DEV_DIR < "${TMPDIR:-/tmp}/dev-refactor-dev-dir-${CSID}" 2>/dev/null || _DEV_DIR=""
IFS= read -r _PLAN_FILE < "${TMPDIR:-/tmp}/dev-plan-file-${CSID}" 2>/dev/null || _PLAN_FILE=""
IFS= read -r _KEEP < "${TMPDIR:-/tmp}/dev-refactor-keep-items-${CSID}" 2>/dev/null || _KEEP=""
IFS= read -r _PYTEST_CMD < "${TMPDIR:-/tmp}/dev-pytest-cmd-${CSID}" 2>/dev/null || _PYTEST_CMD=""
_PRESERVE="dev-dir=$_DEV_DIR, plan-file=${_PLAN_FILE:-none}, pytest-cmd=$_PYTEST_CMD"
[ -n "$_KEEP" ] && _PRESERVE="$_PRESERVE; user-keep: $_KEEP"
mkdir -p .temp/state # timeout: 5000
{
echo "## Active Skill Contract"
echo "- skill: develop:refactor · phase: characterize+edit (after coverage audit)"
echo "- run-dir: $_DEV_DIR"
echo "- preserve: $_PRESERVE"
echo "- next: add characterization tests (Step 3) → refactor with safety net (Step 4)"
} > .temp/state/skill-contract.md
Step 3: Add characterization tests (if needed)
For every uncovered or partially covered public API, spawn foundry:qa-specialist to generate characterization tests:
- Import function, call with representative inputs, assert current output
- Use
pytest.mark.parametrizefor multiple input/output pairs - Name tests
test_<function>_characterization_*
Spawn with context:
- Target module:
<module_path> - Coverage audit results: [paste coverage-audit output showing uncovered/partial functions]
- Uncovered public APIs to test: [list from audit]
- Current code (read target file before writing tests — tests must assert CURRENT behaviour, not desired)
- Test file target:
tests/test_<module>_characterization.py - Test naming:
test_<function>_characterization_<scenario>
# timeout: 600000
export CSID="${CLAUDE_CODE_SESSION_ID:-$PPID}"
$PYTEST_CMD <test_file> -v; GATE_EXIT=$?
echo "$GATE_EXIT" > ${TMPDIR:-/tmp}/dev-gate-exit-${CSID}
Gate: all characterization tests must pass before proceeding. Check exit code from persisted file ($? in a fresh shell is unrelated to prior pytest run):
export CSID="${CLAUDE_CODE_SESSION_ID:-$PPID}"
IFS= read -r GATE_EXIT < "${TMPDIR:-/tmp}/dev-gate-exit-${CSID}" 2>/dev/null || GATE_EXIT="1"
if [ "${GATE_EXIT}" -eq 5 ]; then
echo "GATE FAIL: no tests collected (exit 5) — characterization test file missing or not detected by pytest; cannot proceed to Step 4 without a safety net"
elif [ "$GATE_EXIT" -ne 0 ]; then
echo "GATE FAIL: characterization test(s) failed (exit $GATE_EXIT) — fix the test, not the code"
else
echo "GATE OK: all characterization tests pass on unmodified code"
fi
If GATE_EXIT -ne 0 (including exit 5): characterization tests missing or wrong — cannot proceed to Step 4 without a passing safety net. Invoke AskUserQuestion — "Characterization test gate failed (exit $GATE_EXIT). How to proceed?" · (a) Fix test collection path / fix test assertions (recommended — re-spawn qa-specialist with corrected path or assertions) · (b) Proceed without safety net (accept risk — record decision in $DEV_DIR/checkpoint.md) · (c) Abort. On (b): document explicit acceptance in checkpoint.md (step: 3 — gate exit $GATE_EXIT — proceed without safety net (user accepted)) before continuing.
Step 4: Refactor with safety net
For each change:
- One focused change (single responsibility per edit)
- Run affected tests (prefer targeted over full characterization suite):
codemap-py query test-impact "<changed_module>" 2>/dev/null- Non-empty
pytest_cmd→ run those tests; surfacenot_coveredcaveat if present; fall back to full suite if all tests pass but feel incomplete - Empty or unavailable → full suite:
# timeout: 600000 $PYTEST_CMD --tb=short <test_files> -v - Non-empty
- Tests pass: proceed to next change
- Tests fail: revert, try different approach
Safety break: track cycle count and wall time via temp files (bash state lost between Bash() calls — $INNER_CYCLE and $START_TIME declared inline are unavailable in subsequent Bash blocks; persistence is mandatory):
# timeout: 3000
export CSID="${CLAUDE_CODE_SESSION_ID:-$PPID}"
echo "0" > ${TMPDIR:-/tmp}/dev-inner-cycle-${CSID}
echo "$(date +%s)" > ${TMPDIR:-/tmp}/dev-start-time-${CSID}
MAX_WALL_SECONDS=1800 # 30 min cap (5 outer × MAX_INNER_CYCLES worst case)
At each inner iteration start, read back, increment, check:
# timeout: 3000
export CSID="${CLAUDE_CODE_SESSION_ID:-$PPID}"
IFS= read -r INNER_CYCLE < "${TMPDIR:-/tmp}/dev-inner-cycle-${CSID}" 2>/dev/null || INNER_CYCLE="0"
IFS= read -r START_TIME < "${TMPDIR:-/tmp}/dev-start-time-${CSID}" 2>/dev/null || START_TIME=$(date +%s)
INNER_CYCLE=$((INNER_CYCLE+1))
echo "$INNER_CYCLE" > ${TMPDIR:-/tmp}/dev-inner-cycle-${CSID}
MAX_INNER_CYCLES=5 # must match constants block — bash can't ref it directly
if [ "$INNER_CYCLE" -gt $MAX_INNER_CYCLES ]; then
echo "⚠ MAX_INNER_CYCLES ($MAX_INNER_CYCLES) reached — stopping refactor loop; report what succeeded, what broke, what remains"
fi
ELAPSED=$(( $(date +%s) - START_TIME ))
if [ "$ELAPSED" -ge 1800 ]; then
echo "⚠ wall-time cap reached (30 min) — stopping refactor loop"
fi
After each change-test pair: re-read counter from temp file, increment, write back. Stop when INNER_CYCLE > MAX_INNER_CYCLES or elapsed ≥ MAX_WALL_SECONDS.
Refactoring categories:
- Logic simplification: replace complex conditionals, flatten nesting, extract helpers
- API cleanup: rename for clarity, consolidate parameters, add type annotations
- Structural: extract classes/modules, reduce coupling, apply design patterns
- Performance: replace loops with vectorized ops, reduce allocations, batch I/O
- Dead code removal: remove unused imports, unreachable branches, commented-out code; scan
_-prefixed functions with no call sites; flag public methods absent from__init__.pyexports
Shortened here. Read the whole file on GitHub.
Signals
- GitHub stars
- 27
- Forks
- 4
- Last commit
- Sep 2026
- Hacker News mentions
- 20
Advanced
- Catalog kind
- skill
- Gateway key
refactor-borda- Source
- github.com/borda/ai-rig