name: polylith-migrate-definition-of-done
description: "[Internal sub-skill of polylith-migrate-orchestrator. Do not load directly — load polylith-migrate-orchestrator first, which drives all phases.] Define the criteria for completing the migration process."
Skill: polylith-migrate-definition-of-done
Done When
Structure
- Temporary migration base is gone or thin.
- Bases contain only entrypoints/wiring.
- All non-entrypoint code lives in components.
Source Project
projects/<PROJECT>/contains only:- Packaging config (
pyproject.toml). - Runner scripts and task runners (
Makefile,Justfile). - Project-specific config (e.g.,
alembic.ini).
- Packaging config (
- Project
pyproject.tomlreferences all required bricks. - Brick names are meaningful and non-generic.
- Base names are project-prefixed to avoid collisions.
Tests
- Tests are moved from
projects/<PROJECT>/tests/to workspace level (required). - Unit-test layout — one of the following (see
polylith-migrate-refactor-tests):- Per-brick (theme-aligned):
loose→test/bases/<TARGET_TOP_NS>/<base>/andtest/components/<TARGET_TOP_NS>/<component>/;tdd→bases/<base>/test/<TARGET_TOP_NS>/<base>/andcomponents/<component>/test/<TARGET_TOP_NS>/<component>/. Or - Workspace-level service dir
test/<svc>_service/— valid when shared test helpers can't cheaply become fixtures (the namespace-merge hazard makes a per-brick split unsafe otherwise). Record the chosen layout instate.md.
- Per-brick (theme-aligned):
- Integration tests live in a shared location (e.g.,
test/integration/ortest/<svc>_service/integration/). - Shared fixtures live in a
conftest.py(e.g.test/<TARGET_TOP_NS>/conftest.py,test/conftest.py, or the service dir'sconftest.py). RUN_TEST_CMDpoints to the test root and collects the same number of tests as the pre-migration baseline.
Infrastructure
- Infrastructure folders are moved to
infra/<folder>/<project-name>/, or the move is deferred with a documented rationale instate.mdwhen the deploy cannot be verified in the migration environment (seepolylith-migrate-prepare-project). Either way,alembic/stays withalembic.iniin the project.
Interfaces
- Each component defines its public API via
__init__.py. - Bricks import each other via those APIs.
Linting and Type-Checking
- Linting/formatting and type-checking use the workspace's configured tool(s).
RUN_LINT_CMDandRUN_TYPECHECK_CMDpass if set. They may be intentionally empty when the project's pre-migration baseline already failed these gates (recorded inpolylith-migrate-discover); pre-existing violations are not the migration's responsibility — note them as a follow-up rather than blocking the migration.
Dependencies
- Workspace root
pyproject.tomlcontains all third-party dependencies with version constraints. - Project
pyproject.tomllists runtime dependencies without version numbers.
Cleanup
- Migration artifacts (
migration/<PROJECT>/state.md,migration/<PROJECT>/manifest.md, and anymigration/shims.md) are either removed or kept undermigration/<PROJECT>/for reference (user's choice). - The migration branch (
GIT_BRANCHfromstate.md) is ready to be merged or rebased into the main branch. Per-phase commits remain available for review/bisect.
End-to-end checks
These checks go beyond per-phase verification and exercise the migrated project as a whole. Both must pass.
1. Baseline test count restored
Compare collected test count to the baseline recorded by polylith-migrate-discover:
<RUN_TEST_CMD_with --collect-only -q | tail -1>
The count must equal the baseline. A lower count means pytest discovery is misconfigured (see polylith-migrate-refactor-tests failure modes). A higher count means tests were inadvertently duplicated during the move.
2. No undocumented shims remain
Inspect migration/<PROJECT>/shims.md (if it exists):
- Empty or absent → ✅ proceed.
- Lists active shims → either remove them now (rewrite imports to the new namespace and delete the shim modules) or schedule their removal as a follow-up PR and reference that PR in the migration branch description. Do not merge with undocumented shims.
Verify
RUN_TEST_CMDsucceeds.- If set,
RUN_LINT_CMDandRUN_TYPECHECK_CMDsucceed. - Run
POLY_CMD_PREFIX checkto validate the workspace structure. - Run
POLY_CMD_PREFIX infoto inspect the workspace and confirm all projects and bricks are correctly registered.
Common failure modes
| Symptom | Likely cause | Remediation |
|---|---|---|
RUN_TEST_CMD passes but collected test count is lower than the baseline from polylith-migrate-discover |
pytest discovery is misconfigured after the test reorganisation. |
Update [tool.pytest.ini_options].testpaths (or pass paths explicitly in RUN_TEST_CMD). Run pytest --collect-only and diff against baseline collection. See polylith-migrate-refactor-tests for details. |
poly check is green and tests pass, but a base imports something that no longer exists at the expected path |
Entrypoint wiring regression introduced while moving code into bases/components. | Verify each base's entrypoint module imports cleanly and that its wiring matches the original. Revisit polylith-migrate-distribute-wiring. |
migration/shims.md still lists active shims |
Shims from polylith-migrate-extract-to-base (namespace change) were never removed. |
Either rewrite imports to the new namespace and delete the shims, or schedule shim removal as a follow-up PR and note it in the migration branch description. Do not merge with undocumented shims. |
Commit
After verification passes, commit this phase to the migration branch:
git add -A && git commit -m "migrate(<PROJECT>): phase <N> — definition-of-done"
Substitute <PROJECT>, <N>, and <phase-name> from state.md and the orchestrator's phase table. Do not proceed to the next phase without a clean commit — the per-phase commit is the rollback point for the next phase's failure-mode tables.