Skip to content

ADR-341: Add ModifierStage/RandomizedModifierStage base classes (TDD) - #256

Draft
jodavis-claude wants to merge 1 commit into
dev/claude/ADR-340-randomization-primitivesfrom
dev/claude/ADR-341-modifier-stage-base-classes
Draft

ADR-341: Add ModifierStage/RandomizedModifierStage base classes (TDD)#256
jodavis-claude wants to merge 1 commit into
dev/claude/ADR-340-randomization-primitivesfrom
dev/claude/ADR-341-modifier-stage-base-classes

Conversation

@jodavis-claude

Copy link
Copy Markdown
Collaborator

Seedless two-case skip/regenerate + GC base (ModifierStage) and a seeded three-case skip/regen-with-stored-seed/new-sample extension (RandomizedModifierStage), per ml/_spec_OopPipeline.md. RandomizedModifierStage narrows T_out to AudioSample and gives its inherited _compute_applied_values/_generate_output hooks NotImplementedError stubs rather than overriding them with a wider signature, keeping every override mypy --strict clean with no [override] suppressions. Adds ml/pipeline/core/_doc_core.md now that this is the last task touching ml/pipeline/core/.


Stack created with GitHub Stacks CLIGive Feedback 💬

Seedless two-case skip/regenerate + GC base (ModifierStage) and a seeded three-case skip/regen-with-stored-seed/new-sample extension (RandomizedModifierStage), per ml/_spec_OopPipeline.md. RandomizedModifierStage narrows T_out to AudioSample and gives its inherited _compute_applied_values/_generate_output hooks NotImplementedError stubs rather than overriding them with a wider signature, keeping every override mypy --strict clean with no [override] suppressions. Adds ml/pipeline/core/_doc_core.md now that this is the last task touching ml/pipeline/core/.

@jodavis-claude jodavis-claude left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed ADR-341 (ModifierStage/RandomizedModifierStage base classes). Implementation closely follows the spec's skip/regen/GC algorithm at both levels, mypy --strict passes cleanly (zero [override] suppressions), and all 87 tests pass including the required GC-scope regression test and the RandomizedModifierStage partial-update case. Two broken relative links found in the new _doc_core.md, plus one minor design note about synchronous manifest I/O inside async def transform(). See inline comments.

present in the stage's own output directory, so it can never enumerate or delete anything from
a different stage's directory — even when a passthrough sample's `.path` points at an ancestor
stage's directory. Covered by a dedicated regression test in
[`test_modifier_stage.py`](../../../test/pipeline/core/test_modifier_stage.py).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Broken relative link. This file lives at ml/pipeline/core/_doc_core.md, so 3 levels up (../../../) lands at the repo root, not ml/. The actual test file is at ml/test/pipeline/core/test_modifier_stage.py, which is 2 levels up from here, not 3. ../../../test/pipeline/core/test_modifier_stage.py resolves to a non-existent <repo-root>/test/pipeline/core/test_modifier_stage.py. Should be ../../test/pipeline/core/test_modifier_stage.py. Verified: ls ml/pipeline/core/../../../test/pipeline/core/ fails; ls ml/pipeline/core/../../test/pipeline/core/ succeeds.

## Testability

Every class in this subpackage is Testable-tier and covered test-first in
[`ml/test/pipeline/core/`](../../../test/pipeline/core/), mirroring this directory's layout

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same broken-link issue as the other _doc_core.md comment: ../../../test/pipeline/core/ should be ../../test/pipeline/core/ (2 levels up from ml/pipeline/core/_doc_core.md to reach ml/, not 3).


output_manifest = Manifest(outputs)
self._garbage_collect(output_manifest)
self._manifest_store.write(output_manifest, self._output_dir / "manifest.json")

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor/non-blocking: ManifestStore.write/.read (and Path.exists() in _read_previous_by_parent_hash) run synchronously inside async def transform(), blocking the event loop while writing/reading manifest.json. This is the same class of concern the sibling io subpackage's _doc_io.md calls out explicitly ("async seam, offloaded to a thread pool ... must not block it on synchronous file I/O"). I'm not blocking on this since it's a pre-existing ManifestStore API from ADR-339 that this task's brief explicitly said to reuse as-is, and it only runs once per stage invocation (not per-sample, unlike future AudioReader/AudioWriter calls), so the practical impact here is negligible given transform() is the only task in its event loop. Worth a look if ModifierStageEntryPoint (ADR-345) ever needs to run multiple stages concurrently in one process.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants