Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Refactor workflow

paredit refactor separates deciding, previewing, writing, and verifying so that automation can stop at any gate. The full lifecycle for a cross-file rename looks like this:

# 1. Plan: gates, risk summary, and an ordered step list.
paredit refactor plan --symbol old-name src/core.lisp src/util.lisp

# 2. Preview: exact rewrites, no files touched. --manifest-out writes the
#    manifest file and prints its hash, so no extra `status` call is needed.
paredit refactor preview --from old-name --to new-name \
  --manifest-out preview.json src/core.lisp src/util.lisp

# 3. Review the manifest without writing.
paredit refactor check --manifest preview.json
paredit refactor status --manifest preview.json
paredit refactor diff --manifest preview.json

# 4. Apply the reviewed manifest with hash guards (hash printed by step 2).
paredit refactor apply --manifest preview.json \
  --expect-manifest-hash "$HASH" --write

# 5. Verify post-conditions.
paredit refactor verify --symbol old-name --new-symbol new-name \
  --phase post src/core.lisp src/util.lisp

Plan output is a contract

paredit refactor plan emits JSON with a decision block (status, next_action, safe_to_automate), gates with blocks_automation flags, a risk_summary, and an ordered steps array whose entries carry runnable command strings. An agent can execute the plan literally: run each step in order and stop when a gate blocks automation or a step exits non-zero.

Policy flags such as --require-definitions, --require-references, and --fail-on-blocking-gate turn advisory checks into hard failures, which makes plan usable as a CI gate on its own.

Preview manifests and hash guards

preview and workspace-preview print a manifest describing every byte-exact edit. apply refuses to write when:

  • the manifest hash does not match --expect-manifest-hash;
  • a target file changed on disk since the preview was generated; or
  • any rewritten output no longer parses.

This means a manifest can be produced in one CI job, reviewed as an artifact, and applied in a separate controlled job without trusting the intermediate steps.

Direct refactorings still gate writes

Named refactorings such as rename-function, extract-function, or add-function-parameter run in plan mode by default and only modify files when --write is passed after their own validation gates pass. Symbol-oriented rewrites never touch strings or comments, and Common Lisp scope-aware refactors preserve flet/labels/macrolet/symbol-macrolet binding boundaries.

Workspace scope

For repository-wide changes, start with discovery and stay inside the same lifecycle:

paredit inspect workspace --output json .
paredit refactor workspace-plan --symbol old-name .
paredit refactor workspace-preview --from old-name --to new-name . > preview.json
paredit refactor workspace-execute --from old-name --to new-name --write .

workspace-execute wraps preview gates and post-write verification into one command for cases where a human already reviewed the plan.