git:20261018.e05a5c3 to git:20261020.a157858

33 added, 61 removed. Audit A to A.

---
name: engineering-refactor
- description: Restructure modules, consolidate shallow wrappers, align package layout, and add tests at module interfaces to move a codebase toward the house stack (uv + ruff + pyrefly) and deep-module architecture. Use when the user asks to refactor, restructure, reorganize, clean up architecture, tidy up code, modernize a Python project, or adapt a repo to these practices.
+ description: Refactor an existing codebase in small, tested slices while keeping its local conventions, using botica for the rules and the upstream codebase-design skill for the architecture vocabulary. Use when the user asks to refactor, restructure, reorganize, clean up architecture, tidy up code, modernize a project, or adapt a repo to these practices.
---
# Engineering Refactor
- Move an existing codebase toward the house engineering standard **without bulldozing local
- project contracts**.
-
- ## Required: the ruleset
-
- This skill carries the **workflow**, not the rules. The rules live in the `engineering-rules`
- skill — the Python toolchain, package layout, deep-module architecture (Matt Pocock's
- vocabulary), testing, and the stack-specific patterns (FastAPI, Prefect, LLM/AI, ASR, Next.js,
- k8s).
-
- **Invoke `engineering-rules` first** and follow its reading protocol. Every rule id cited below
- resolves through it — including its `applies-to` / `status` fields, which decide whether a rule
- applies to this repo at all.
-
- > If `engineering-rules` is not available, **stop and say so**. Do not refactor from a
- > remembered standard. Install it with
- > `npx skills add collectiveai-team/botica --skill engineering-rules`.
-
- **Follow the local repo over the direction** unless the user explicitly asked to modernize.
-
- ## Workflow
-
- ### 1. Establish the baseline
-
- Read the `engineering-rules` index, then inspect the repo's local contracts: `pyproject.toml`,
- lockfiles, Makefiles, CI workflows, existing tests, package layout, `README`, `GLOSSARY.md` (or legacy `CONTEXT.md`),
- and ADRs if present. Determine, citing evidence:
+ Move an existing codebase toward a better structure without overriding the deliberate choices of
+ the repository. This skill is a workflow and states no rule of its own: the rules are in botica,
+ and the architecture vocabulary is the one of the upstream `codebase-design` skill.
- - Package manager + build backend (`py-package-manager`, `py-build-backend`).
- - Toolchain era — the house stack (uv + ruff + ruff-format + pyrefly + botica via prek) or a legacy poetry+black/isort/mypy setup (`py-ruff-format-modern`, `py-legacy-lint-migration`).
- - Python version, package layout, test layout, logging, runtime entrypoints, frontend (if any).
+ ## 1. Baseline
- Preserve the existing toolchain unless the user asked to migrate it (`general-respect-local-repo`).
+ Read `AGENTS.md` (its standards index and the judgment rules between `<!-- botica:rules -->` and
+ `<!-- /botica:rules -->`), `GLOSSARY.md` and the ADRs under `docs/adr/`. Then read the local
+ contracts and write down, with the file that shows each:
- ### 2. Find refactor targets
+ - package manager, lockfile and build backend;
+ - lint, format and type-check tools, and where they run (prek, CI);
+ - language versions, package layout, test layout and entry points.
- Read the architecture rules — `arch-deep-modules`, `arch-deletion-test`,
- `arch-adapter-discipline` — and the `spaghetti-*` rules. Look for:
+ Keep that toolchain unless the user asked to migrate it, as the standard on respecting the local
+ repository in the `AGENTS.md` index says. Run `botica lint` once and keep its output as the baseline.
- - Shallow wrappers whose interface is nearly as complex as their implementation (apply the **deletion test**).
- - Logic spread across callers that should live behind one module interface.
- - Files over 400 lines receiving unrelated behavior; files over 700 lines (`file-size-guard`).
- - Orchestration mixing transport, validation, domain logic, persistence, formatting (`spaghetti-mixed-concerns`).
- - Slices that don't match the conventions (`pylayout-meta-slice`, `pylayout-adapters-slices`, `log-get-logger`).
- - Tests asserting internals instead of behavior at the interface (`test-through-interface`).
+ ## 2. Targets
- Use the exact vocabulary from `arch-deep-modules`: module, interface, implementation, depth,
- seam, adapter, leverage, locality.
+ If the user named a module or a pain point, start there. Otherwise ask the user whether to run the
+ upstream `improve-codebase-architecture` skill, which scans the codebase for deepening candidates;
+ an agent cannot invoke it on its own.
- ### 3. Refactor in small slices
+ Invoke `codebase-design` and use its terms (module, interface, implementation, depth, seam,
+ adapter, leverage, locality) in every proposal. Add the findings of the baseline that touch the
+ target. For each rule involved, `botica explain <slug>` gives its text and
+ `botica refs show <slug>` the code it expects.
- - Keep behavior stable unless the user asked for a behavior change.
- - Move code toward domain-named modules / existing package slices; replace shallow layers with one deeper module rather than adding another abstraction (`arch-adapter-discipline`).
- - Add or update tests at the module interface before risky movement (`test-in-memory-adapters`).
- - No formatting churn outside touched code (`py-no-formatter-churn`).
- - Keep public imports and entrypoints compatible unless the task includes a breaking change.
- - For stack-specific code, pull the matching rules: `prefect-*`, `llm-*`, `asr-*`, `api-*`, `fe-*`, `k8s-*`.
+ ## 3. Slices
- ### 4. Verify
+ - Keep behaviour stable unless the user asked for a change.
+ - Before moving code, cover the behaviour with tests at the interface that callers use.
+ - Change one seam per slice; run the tests after each.
+ - Keep public imports and entry points compatible unless the task includes a breaking change.
+ - Leave the formatting of untouched code as it is.
- Run the narrowest useful checks first, then broaden (`pr-run-checks`). Note that Makefiles here
- are docker-only — run linters/pytest directly (`infra-makefile-docker`).
+ ## 4. Verify
- - House stack: `ruff check`, `ruff format --check`, `pyrefly check`, `botica lint`, `pytest`
- (via `uv run` / `uvx`), or the whole hook set with `uvx prek run --all-files`.
- - Legacy repos: run what the repo actually has (`black`, `isort`, `pylint`/`flake8`, `mypy`,
- `pytest`) — don't introduce the house stack mid-refactor (`py-legacy-lint-migration`).
- - Always run relevant pytest tests for behavior changes; report checks that could not run.
+ Run the narrowest checks first, then broaden: the tests of the touched code, `botica lint` on the
+ changed files, the type checker, then the hooks of the repository (`uvx prek run --all-files` when
+ it uses prek). Compare the findings with the baseline. Report the checks that could not run.
## Output
- When finished, report: what changed, which rules drove each change (cite rule ids), which
- tests/checks ran and their results, and any remaining architecture risks (large files,
- shallow modules, missing tests) left behind.
+ Report what changed, which finding or proposal drove each change (cite the slug of the rule), the
+ checks that ran and their results, and the risks left: large files, shallow modules, missing tests.
Credits and sources: [`references/CREDITS.md`](references/CREDITS.md).