Maintenance Execution Template PRD¶
Historical planning document. This PRD was the implementation plan for extracting the shared compaction execution template into
core.maintenance. The work is complete in 0.22.x. It is retained as engineering history, not current guidance. For the current maintenance API, see Maintenance.Successor design. The historical extraction described below is superseded as forward-looking maintenance architecture guidance by ADR-0006: Coordinated dataset maintenance guarantees. ADR-0006 records a proposed major-version redesign; it does not describe the already-completed 0.22.x implementation.
Summary¶
Extract the duplicated compaction execution orchestration from both backend
adapters into a shared execute_compaction_template in core.maintenance. The
template owns the full execution lifecycle (dry-run check, group iteration,
output path generation, file removal, stats return); backends provide a single
compact_group_fn callback for the backend-specific read/concat/write step.
Problem¶
compact_parquet_dataset_duckdb and compact_parquet_dataset_pyarrow share
~30 lines of near-byte-for-byte identical execution code surrounding the
backend-specific read/concat/write call. The only divergence is step 3: DuckDB
uses SQL COPY, PyArrow uses pq.write_table. Everything else — dry-run exit,
empty-groups exit, file removal loop, stats return — is duplicated.
Goals¶
- Extract the shared compaction execution lifecycle into
execute_compaction_templateincore/maintenance.py. - Both backends consume the template, providing only a
compact_group_fncallback. - Optimize path benefits automatically (it delegates to compaction).
- Deduplication execution stays backend-local.
- Template is testable with a fake callback and memory filesystem.
Non-Goals¶
- Do not introduce a
MaintenanceOperationPlandataclass. - Do not change planning function signatures.
- Do not extract a deduplication execution template (already exists and execution models diverge too much).
- Do not change public
BaseDatasetHandlermaintenance method signatures.
Proposed Interface¶
The callback signature:
The callback reads the group's files, concatenates them, and writes the result
to output_path. The template handles everything else.
Implementation Plan¶
Phase 1: Add the template to core/maintenance.py¶
- Implement
execute_compaction_templatewith the full lifecycle: dry-run check, empty-groups check, output path generation, group iteration, file removal, stats return. - Add unit tests with a fake
compact_group_fnand a memory filesystem.
Phase 2: DuckDB adoption¶
- Update
compact_parquet_dataset_duckdbto callexecute_compaction_template. - The
compact_group_fnclosure builds and executes the SQLCOPYquery. - Remove the duplicated boilerplate (dry-run exit, file removal loop, stats return).
Phase 3: PyArrow adoption¶
- Update
compact_parquet_dataset_pyarrowto callexecute_compaction_template. - The
compact_group_fnclosure reads tables, concatenates, and writes withpq.write_table. - Remove the duplicated boilerplate.
Phase 4: Verify¶
python scripts/check_layering.pypasses.uv run ruff checkpasses.- Existing compaction and optimize tests pass for both backends.
- New template unit tests pass.
Acceptance Criteria¶
execute_compaction_templateexists incore/maintenance.py.- Both
compact_parquet_dataset_duckdbandcompact_parquet_dataset_pyarrowconsume the template. - No duplicated dry-run/empty-groups/file-removal/stats-return boilerplate in backend compaction functions.
- Template unit tests pass with a fake callback.
python scripts/check_layering.pypasses.uv run ruff checkpasses for changed files.- Public maintenance method signatures remain compatible.
Risks¶
Risk: Behavior change during extraction¶
Mitigation: existing backend compaction tests verify the same behavior before and after the extraction. Run both DuckDB and PyArrow compaction test suites.
Risk: Output path format drift¶
Mitigation: the template generates the output path. Both backends receive the same format. No drift possible.
References¶
- ADR-0004: Maintenance Execution Template
- ADR-0002: Merge Planning Seam Before Backend Writes (unpublished)