ADR-0003 — Hard deprecation stance for pre-1.0 breaks
| Number | 0003 |
| Title | Hard deprecation stance (no experimental namespace, no runtime shims) |
| Status | Accepted |
| Author | @NoeFontana |
| Created | 2026-04-21 |
| Updated | 2026-04-21 |
| Tag | ADR-0003 |
| Supersedes | ADR-0001 Part (i) — deprecation policy clauses only |
Context
ADR-0001 Part (i) set a soft-deprecation policy for the 0.9.x stability line:
CopyPasteTransform was to move to a new segpaste.experimental sub-package
with a top-level re-export that emits DeprecationWarning; DetectionTarget
was to remain as a runtime-compatible subclass shim forwarding to
DenseSample. Both symbols were scheduled for removal in 0.10.0.
Since that ADR landed, two observations changed the calculus:
- The project is pre-1.0 and solo + agentic. The SemVer disclaimer in
pyproject.tomlandREADME.mdalready warns that breaking changes may land without notice below 1.0.0. Soft-deprecation infrastructure (segpaste.experimental, runtimeDeprecationWarningshims, subclass forwarders) buys nothing for a user base of zero and costs a full 0.9.x test-matrix entry plus a migration obligation that has to be carried on every refactor in P1. - P1 (dense-sample composites) churns every transform. Keeping a
runtime-compatible
DetectionTargetshim means every internal refactor must either preserve the subclass contract or route carefully around it. That is the opposite of what pre-1.0 is for.
The pre-1.0 free-break window closes at 1.0.0. Using it to actually remove code is cheaper than using it to build more scaffolding.
Decision
This ADR supersedes only the deprecation policy clauses of ADR-0001 Part
(i). The rest of ADR-0001 — invariants (Part ii), type-system decisions
(Part iii), seed and replay policy (Part iv), the __version__ requirement,
the _internal namespace, the blend_mode tightening, and the ambiguous
integrations exports resolution — remains in force.
CopyPasteTransform — delete outright in 0.9.0
- No
segpaste.experimentalsub-package is created. - No top-level re-export with
DeprecationWarning. - The symbol, its module-level definition, and every reference in docs, README, CLAUDE.md, and the example scripts are removed in one commit.
- Consumers who need the old behavior pin
segpaste<0.9on PyPI. That is the documented migration path and it is sufficient. - Removal is logged under
### RemovedinCHANGELOG.mdfor the 0.9.0 release.
DetectionTarget — close the public surface in 0.9.0, remove the type in 0.9.1
DetectionTargetis removed fromsegpaste.__all__andsegpaste.types.__all__in 0.9.0.segpaste.DetectionTargetbecomes anAttributeError.- The class itself remains importable via its full internal path during
0.9.0 because P1's W1 workstream still threads it through the augmentation
pipeline. This is not a runtime-compatible shim: no subclass
relationship with
DenseSample, noDeprecationWarningon construction, no__getattr__magic onsegpasteorsegpaste.types. - Conversion between the two types uses the bidirectional static methods
already present on
DenseSample:DenseSample.from_detection_target(...)andDenseSample.to_detection_target(...). No new classmethod is added. - An
xfail(strict=True)test asserts that the class is gone fromsegpaste.typesby 0.9.1. P1's W1 completes the type-level migration, deletes the class, and flips the test green.
segpaste.experimental — not created
ADR-0001 Part (i)'s segpaste.experimental sub-package is not created.
The rationale for it was CopyPasteTransform; with CopyPasteTransform
deleted there is no inaugural resident. If a future unstable surface needs
to be exposed, a new ADR introduces the namespace then.
Consequences
- Breaking change on upgrade from 0.8.x to 0.9.0.
segpaste.CopyPasteTransformandsegpaste.DetectionTargetboth disappear from the top level. Memorialized in the 0.9.0CHANGELOG.mdand in the existing pre-1.0 SemVer disclaimer. - Simpler P1. No experimental namespace to maintain, no subclass-shim contract to preserve while refactoring transforms.
- Surface-lock enforcement becomes load-bearing. The
__all__match tests introduced in P0.E step (iii) are the forcing function that prevents the surface from re-accreting during P1 churn. Adding a public name now requires an ADR amendment.
Canonical example: W5 (ADR-0008)
W5 / ADR-0008 is the canonical hard-deprecation
application of this policy. In one commit (C7 in the ADR-0008 sequencing),
the following are deleted outright — no experimental namespace, no
DeprecationWarning shim, no subclass forwarder — and replaced by
BatchCopyPaste + PaddedBatchedDenseSample:
CopyPasteCollator(public),CopyPasteAugmentation(internal), the four modality wrappers (InstancePaste,PanopticPaste,DepthAwarePaste,ClassMix), bothplacement.pymodules.- Four
tests/fixtures/*_baseline.ptparity fixtures; the three parity tests they anchor; six unit / fuzz tests that exercise the deleted classes. - Three
scripts/gen_*_baseline.pygenerators; fourbenchmarks/bench_*.pyper-wrapper benches;benchmarks/_fixture.py.
Users who need the old behavior pin segpaste<0.10 (same migration
path as §CopyPasteTransform). The single-commit deletion is the
forcing function that prevents a half-migrated main:
BatchCopyPaste.from_dataloader(loader, max_instances) is the
documented migration helper, landed in the same commit.
Numerical equivalence between the pre-deletion CPU path and the GPU-resident replacement is defended by a 30-day soft-report KS gate (ADR-0008 §6), not by a DeprecationWarning window. Surface stability and numerical equivalence are separate concerns; only the latter warrants a grace period pre-1.0.
Status and supersession
- Accepted when this file lands on
mainwithStatus: Accepted. - ADR-0001's header is updated in the same commit to
Status: Superseded in part by ADR-0003with a scope note pointing back here ("Part (i) deprecation policy only — invariants, types, and seed policy remain in force"). - Any later decision that reintroduces soft-deprecation for pre-1.0 removals requires a new ADR that explicitly supersedes this one.
Verification
uv run mkdocs build --strictpasses with this ADR in the nav.- ADR-0001 renders with the updated
Statuscross-linking this ADR.