Deferred from #59, which shipped export --depth/--space.
Re-exporting a tree into a destination that already has one leaves behind a file for every page that has since been deleted, moved out of the subtree, or renamed — a rename changes the slug, so the old file stays and a new one appears beside it. Nothing reports this: the export succeeds, and the stale file looks exactly like a page that was skipped because it was already there. Someone reading the tree, or publishing it back with create, has no way to tell.
--clean would remove what the export did not write. That is removal, so it is bound by the three safety guarantees in docs/guarantees.md that are currently all Vacuous — nothing in markfluence removes anything today, so this would be the first thing to exercise them:
- S4 (
no-removal-as-side-effect) — removal has to be the command's stated purpose. So a flag, never implied by --force.
- S5 (
remove-only-ours) — only what markfluence created. A tree exported into a directory that also holds hand-written notes must not lose them, and an export knows exactly which paths it wrote, so the rule is expressible.
- S6 (
removal-is-previewable) — it says what it will remove before doing it, and honours --dry-run.
Making those three non-vacuous is most of the work here, and it wants its own spec rather than a flag bolted onto the export loop.
Some questions that spec would need to answer:
- What counts as "ours"? The paths this run wrote is the easy half. The hard half is a file from a previous export of the same tree, which this run did not write and cannot distinguish from something a human added — unless the export records a manifest, which is state on disk that everything else in markfluence has so far avoided.
- Attachments too, or only page files? An attachment whose page was deleted is as stale as the page, but a recorded
path= can point anywhere under the destination, including at a shared asset another page still references.
- What about a partial run? A walk that failed halfway, or a page that failed to export, means "not written by this run" does not mean "gone upstream". Cleaning after anything less than a complete successful export would delete live content.
That last one may be the deciding constraint: --clean might only be safe when the run exported everything it walked, with no failures.
Deferred from #59, which shipped
export --depth/--space.Re-exporting a tree into a destination that already has one leaves behind a file for every page that has since been deleted, moved out of the subtree, or renamed — a rename changes the slug, so the old file stays and a new one appears beside it. Nothing reports this: the export succeeds, and the stale file looks exactly like a page that was skipped because it was already there. Someone reading the tree, or publishing it back with
create, has no way to tell.--cleanwould remove what the export did not write. That is removal, so it is bound by the three safety guarantees in docs/guarantees.md that are currently all Vacuous — nothing in markfluence removes anything today, so this would be the first thing to exercise them:no-removal-as-side-effect) — removal has to be the command's stated purpose. So a flag, never implied by--force.remove-only-ours) — only what markfluence created. A tree exported into a directory that also holds hand-written notes must not lose them, and an export knows exactly which paths it wrote, so the rule is expressible.removal-is-previewable) — it says what it will remove before doing it, and honours--dry-run.Making those three non-vacuous is most of the work here, and it wants its own spec rather than a flag bolted onto the export loop.
Some questions that spec would need to answer:
path=can point anywhere under the destination, including at a shared asset another page still references.That last one may be the deciding constraint:
--cleanmight only be safe when the run exported everything it walked, with no failures.