alunduil / alunduil/blog.alunduil.com

Separating what the code decides from what it runs

Open
#531 0 comments 0 reactions 0 assignees View on GitHub
idea
Dominant language
Astro
Stars
1
Forks
1
Avg merge
7h 10m
Merged PRs (30d)
106

Description

## Spark

Digest, week of 2026-08-08: zfs-replicate #457 asked for `snapshot.send`'s
pipeline assembly to be unit-tested apart from subprocess execution, and the
split that satisfied it (#626) turned into a run of adjacent refactors — config
travelling as one value through the task layer (#602, opened and closed the same
week), `generate()` stating the task graph it already computes (#603), and the
CLI grouping snapshots once then dispatching actions by table (#620).

## Why it could be interesting

The activity is "I refactored a replication tool." The claim is that
untestability is usually a *seam* problem rather than a mocking problem: the
reason `snapshot.send` needed a subprocess mock was that deciding the command
and running the command lived in one function, and once those separate, the
interesting half is a pure value you can assert on directly. The tests that were
previously expensive and brittle become cheap and total.

The generalisation worth defending: in any tool that shells out — replication,
deploys, build wrappers — the command you're about to run is a data structure,
and treating it as one is what makes the tool testable, inspectable, and
dry-runnable for free. `generate()` stating the task graph it already computes
is the same move applied to planning rather than execution.

## Open questions

- [ ] Is the payoff actually realised? Compare the test for `snapshot.send`
before and after — if the after still mocks a subprocess, the claim is
overstated.
- [ ] Does the dry-run/inspection benefit exist here, or is it hypothetical? A
real `--dry-run` that falls out of the split would be the strongest
evidence.
- [ ] How much of this is Python-shaped versus general? The dispatch-by-table
step in #620 reads as language-agnostic; the rest may not be.
- [ ] Does the uv migration (#619) and the Nix removal (#617) belong in this
story at all, or are they a separate "modernising a dormant tool" post?
- [ ] Relationship to #602's single-config-value change — is "one value through
the layer" the same claim as "separate decision from execution", or a
second one?

## Source material

- alunduil/zfs-replicate#457 (closed) — snapshot.send's pipeline assembly is unit-tested apart from subprocess execution
- alunduil/zfs-replicate#626 — refactor: split snapshot.send into assembly and execution
- alunduil/zfs-replicate#602 (opened and closed this window) — the replication configuration travels as one value through the task layer
- alunduil/zfs-replicate#620 — the CLI pipeline groups snapshots once, separates planning from execution, and dispatches actions by table
- alunduil/zfs-replicate#603 — generate() states the task graph it already computes
- alunduil/zfs-replicate#604 — a silently dropped SSH connection ends the run instead of hanging it
- alunduil/zfs-replicate#605 — replication is verified against real ZFS pools end to end
- Context, not necessarily in scope: #619 (uv replaces Poetry), #617 / #430 (repo-local Nix expressions removed)

Contributor guide

No contributing guide indexed for this repository

Research direction

Compare the snapshot.send tests before and after #626, using #457 as the starting point, and inspect generate() and the CLI dispatch changes in #603 and #620. Check whether the refactors remove subprocess mocking or provide a real dry-run benefit, then decide which related changes belong in the story and document the supported claim.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
content
Issue type
Documentation
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.