4 Commits
Author SHA1 Message Date
Esa Kataja b6847a06ee Treat a project as spent once its song has been exported
Opening an exported song starts a fresh session from detection instead
of resuming: cuts, discards and metadata do not carry over, so a re-cut
never inherits decisions that have already shipped. --resume overrides
it on edit, export and project.

This reverses what was agreed in planning and written into docs/spec.md
and CONTEXT.md, which promised resume-across-sessions and re-export.
Both are corrected. The cost is deliberate and worth stating: changing
the width cap or adding the SVG renderer later now means re-cutting each
song by hand rather than regenerating every bundle from its project
file.

Export records the flag in bundle.write, so no caller can forget it.

Also removed --refit and the Auto-fit buttons, which were added without
being asked for and whose only purpose - migrating projects made before
the content rectangle was proposed - disappears once exported projects
start fresh. Reset now restores detection's proposal rather than the
whole page: clearing to full width would undo the thing the rectangle
exists for, so one button covers it.

open_project() replaces four copies of load-or-detect across the CLI
and the editor.
2026-07-28 23:49:03 +03:00
Esa Kataja 01227b3382 Model cuts as polylines, not horizontal lines
Page 1 of Engel (Bosse/Partitura) has a boxed VERSE 1 label in the left
margin at the same rows as the preceding system's bass lyric line — ink
on both sides of the page throughout the band, so no horizontal line
separates them. The label belongs to system 2, the lyrics to system 1.

A cut is therefore a polyline spanning the page, two points being the
ordinary straight case. A slice bounded by a non-straight cut is not
rectangular: its image is the region's bounding box with everything
outside made transparent, which composites invisibly on the viewer's
sheet. Masking paints transparency, never white.
2026-07-28 22:22:03 +03:00
Esa Kataja 46ae7e813a Replace the handoff notes with a durable spec and ADRs
The handoff was written as a message to relay information; several
decisions lived only there. Split into permanent homes:

- docs/spec.md — scope, geometry model, pipeline order, detection,
  levels, editor, project file, markers, bundle format, noteman's
  changes, reference values
- ADR 0002 — raster only in release 1; SVG slices measured at 40x WebP
  naive, 2.6x with a bounding-box cull, deferred on risk not size
- ADR 0003 — lossless WebP with levels and 16-level alpha; every lossy
  option and alternative format measured larger for line art
- ADR 0004 — detection proposes, the human disposes; no unattended mode
- ADR 0005 — PyMuPDF for all PDF access, accepting AGPL
- ADR 0006 — systems are found by vertical brackets, not row-darkness
  gaps, which miscount every page of a 6-voice score

Also from testing against the hardest score in the repertoire: scanned
PDFs carry their scan as an embedded image and must be extracted at
native resolution rather than re-rendered at 600 DPI, and per-page
deskew is mandatory (skew varies -2.6 to +1.2 within one PDF).
2026-07-28 22:05:09 +03:00
Esa Kataja efc920fdc5 Add design docs: glossary, ADR 0001, and project scaffolding
Records the outcome of the design review that reworked the original
handoff notes:

- CONTEXT.md — ubiquitous language for the slicer (slice, cut, discard,
  content rectangle, trim, song scale, bundle, project, jump source)
- docs/adr/0001 — the slicer owns all image processing and the bundle is
  the only channel to noteman; noteman's sharp pipeline goes away
- pyproject renamed to noteman-slicer
- .gitignore keeps scores and bundles out of the repo (copyright, size)
2026-07-28 21:33:14 +03:00