epiphany/crates/epiphany-render-svg
Levi Neuwirth 41cd8bf58b Agent I-4b: a trace-free render declares itself display-only
`RenderOptions::emit_provenance = false` dropped every data-prov trace silently,
so the output was indistinguishable from an archival render even though it no
longer satisfies the renderer's "every element traces to its source" contract.

Now the SVG's metadata comment declares the provenance state, so suppression is
announced rather than silent:

  - archival (default):    "...; every glyph and stroke carries a data-prov trace
                            to its score-graph source"
  - display-only (false):  "...; provenance traces suppressed (display-only
                            output, not archival)"

A shared `provenance_note(emit_provenance)` helper feeds both the main render and
the empty-canvas path, so an empty trace-free layout is held to the same honesty
contract as a full one (neither can drift). The module doc and the render-svg
DECISIONS.md non-overreach rule now frame data-prov as the default archival
contract plus an explicit, declared display-only mode. Tests assert the suppressed
marker (full and empty layouts) and that the default render declares traces
present.

Goldens regenerated: the default (archival) render's metadata comment now carries
the new "every glyph and stroke carries a data-prov trace" clause, so the four
`.svg` goldens change by that one line (the snapshots, which omit the comment, do
not). Full gate green: build, fmt, clippy, 581 tests, conformance scale 1.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 09:47:35 -04:00
..
examples Phase 2 (Agent I): visible-slice scaffold — Bravura SVG renderer vs stub 2026-06-23 20:01:40 -04:00
src Agent I-4b: a trace-free render declares itself display-only 2026-06-27 09:47:35 -04:00
tests Agent I-4b: a trace-free render declares itself display-only 2026-06-27 09:47:35 -04:00
tools Agent I-4a: reconcile the Bravura metrics with the 1.392 outlines 2026-06-26 22:45:33 -04:00
Cargo.toml Phase 2 (Agent I): visible-slice scaffold — Bravura SVG renderer vs stub 2026-06-23 20:01:40 -04:00
DECISIONS.md Agent I-4b: a trace-free render declares itself display-only 2026-06-27 09:47:35 -04:00
README.md Phase 2 (Agent I): visible-slice scaffold — Bravura SVG renderer vs stub 2026-06-23 20:01:40 -04:00

README.md

epiphany-render-svg

Agent I's SVG renderer behind the Epiphany RenderIR interface (spec Chapter 7): turns a ResolvedLayoutIR into well-formed SVG 1.1, drawing each glyph as a genuine Bravura SMuFL outline <path>. It is the visible end of the v0 Score → layout IR pipeline.

Status: renderer against the stub solver

This phase builds and golden-locks the renderer against the stub solver's output (the QUICKSTART development pattern), before the real engraving solver and the score→real-notation engraving pass land. The stub returns the IR geometry verbatim — a structural projection (each object becomes one arbitrary glyph in a row), not yet recognizable notation — so what is proven here is renderer correctness and faithfulness: real outlines, provenance preserved, output XML-valid and deterministic. The renderer consumes any solver's output, so the picture improves with no renderer change once epiphany-engrave lands.

Demo

# Render a fixture to SVG (stub solver by default):
cargo run -p epiphany-render-svg --example render_fixture -- \
    ten_measure_single_staff > out.svg

# Drive Agent I's engrave solver instead, to bisect renderer-vs-solver:
cargo run -p epiphany-render-svg --example render_fixture -- \
    ten_measure_single_staff --solver=real > out.svg

Fixtures: ten_measure_single_staff, valid_score_rich, valid_score. Stats and diagnostics go to stderr; the SVG goes to stdout.

Library

use epiphany_render_svg::{render, RenderOptions};

let out = render(&resolved_layout_ir, &RenderOptions::default());
assert!(out.is_well_formed());
println!("{}", out.svg);

render is pure and deterministic. RenderOptions controls SVG-encoding choices only (display scale, margin, provenance attributes) — nothing that changes engraving.

Bundled outlines

The glyph outlines in src/outlines_generated.rs are extracted from the official OFL Bravura.otf by tools/extract_bravura_outlines.py. The font is not vendored; only the generated Rust is committed. Bravura is © Steinberg Media Technologies GmbH under the SIL Open Font License 1.1 (tools/OFL.txt); the extracted outlines are redistributed under the same license. To regenerate:

cd crates/epiphany-render-svg/tools
python3 -m venv .venv && . .venv/bin/activate && pip install fonttools
python3 extract_bravura_outlines.py > ../src/outlines_generated.rs