diff --git a/README.md b/README.md index ab9936b..44e9eab 100644 --- a/README.md +++ b/README.md @@ -59,3 +59,4 @@ Decisions that were expensive to reach, each with the evidence behind it: | [ADR 0004](docs/adr/0004-detection-proposes-the-human-disposes.md) | No unattended mode: detection suggests, a human confirms. | | [ADR 0005](docs/adr/0005-pymupdf-for-all-pdf-access.md) | PyMuPDF for all PDF access, accepting AGPL. | | [ADR 0006](docs/adr/0006-systems-are-found-by-brackets-not-row-gaps.md) | Systems are found by vertical brackets; row-darkness gaps get it wrong. | +| [ADR 0007](docs/adr/0007-a-project-is-spent-once-exported.md) | A project is spent once exported; reopening starts fresh. Reverses an earlier decision. | diff --git a/docs/adr/0002-raster-only-svg-renderer-deferred.md b/docs/adr/0002-raster-only-svg-renderer-deferred.md index 1400311..e46f772 100644 --- a/docs/adr/0002-raster-only-svg-renderer-deferred.md +++ b/docs/adr/0002-raster-only-svg-renderer-deferred.md @@ -54,8 +54,11 @@ degraded fallback. - The geometry model stays **renderer-agnostic**, in normalised page coordinates, so adding the SVG renderer later is an output stage rather than a redesign. -- **Re-export from the project file** regenerates every song's bundle without +- ~~**Re-export from the project file** regenerates every song's bundle without repeating human work, so songs cut before the SVG renderer exists are not - stranded. + stranded.~~ **No longer true** — see + [ADR 0007](0007-a-project-is-spent-once-exported.md). A project is spent once + its song has been exported, so songs cut before the SVG renderer ships stay + WebP unless they are cut again by hand. - noteman needs no SVG support (`image/svg+xml`, `.svg` content type, CSP header on SVG responses) until the renderer ships. diff --git a/docs/adr/0007-a-project-is-spent-once-exported.md b/docs/adr/0007-a-project-is-spent-once-exported.md new file mode 100644 index 0000000..7af3641 --- /dev/null +++ b/docs/adr/0007-a-project-is-spent-once-exported.md @@ -0,0 +1,45 @@ +# A project is spent once its song has been exported + +Exporting a song marks its project file spent. Opening the PDF again starts a +**fresh session from detection** — no cuts, no discards, no metadata carried +over — rather than resuming. `--resume` on `edit`, `export` and `project` +overrides it when the old state really is wanted. + +This **reverses an earlier decision**, which is the reason it needs recording: +the project file was introduced specifically so that state would persist, and +`docs/spec.md` and `CONTEXT.md` promised resume-across-sessions and re-export +until this ADR was written. + +## What was decided before, and why it changed + +The project file was chosen over "bundle only" for three benefits: crash safety, +resume across sessions, and re-export. The third was the strongest argument — +change the width cap, fix one cut, or add the SVG renderer later, and every +song's bundle regenerates without repeating any human work. ADR 0002 leans on it +explicitly when deferring the SVG renderer: "re-export from the project file +regenerates every song's bundle without repeating human work, so songs cut +before the SVG renderer exists are not stranded." + +In use, persistence was the wrong default. Re-opening an exported song silently +resurrected old decisions, so a deliberate re-cut began from stale state instead +of a clean page — and because autosave writes that state straight back, closing +the window did not clear it either. An export is a natural end of a unit of +work; carrying its decisions past that point makes "start over" impossible to +express. + +Crash safety and resume within a session are untouched, and those are what the +day-to-day authoring loop actually depends on: a session interrupted halfway +through a 12-page scan still picks up where it stopped. + +## Consequences + +- **Re-export is no longer free.** Changing the 1920px cap, changing the encoder, + or adding the SVG renderer means re-cutting each song by hand. ADR 0002's + "not stranded" reasoning no longer holds; if the SVG renderer ships, already + exported songs stay WebP unless they are cut again. +- The flag is written in `bundle.write`, not in its callers, so no export path + can forget it. +- The project file is kept rather than deleted, so `--resume` remains possible + and the state is still there to inspect after the fact. +- A CLI export from a PDF with no project file now writes one, marked spent. + That is the record that this PDF has already been exported.