Address the two-pass review of the M2e catalog expansion (ca07c28). All gates
green: cargo test --workspace 535/0, conformance_suite scale 1, fmt + clippy
-D warnings clean, catalog PDF rebuilt (no undefined refs).
Pass 1 (doc-vs-implementation accuracy):
- Undo semantics narrowed to the prototype minted-object model (the catalog's
own UndoTransaction model + P11-C8): the new K0 sections' minting members
(insert/create) keep tombstone-the-mint undo; the non-minting ops (modify /
transpose / deletes / settings) now state they synthesize no inverse, rather
than promising rich restore/reintroduction the reducer does not implement.
- Spanner migration corrected: Tie/Slur/Beam reconstruct self-containedly while
a Spanner remains read-only/unmigratable until the v0 projection carries its
TimeAnchors (a Phase-3/Pass-12 extension); the "joins in M2" claim is removed,
in both the CreateCrossCutting section and the migration chapter.
- The reduce()/reduce_onto() agreement claim (DECISIONS + the staff_based_regions
comment) narrowed to regions represented in reducer state: op-created/deleted
regions agree, but reduce_onto additionally seeds base regions a base-free
reduce() never sees.
Pass 2 (empty-container enforcement, made real and complete):
- create_region / create_staff_instance / create_voice reject (ContainerNotEmpty)
a carried value bearing ANY typed child object — not just the structural
hierarchy. A region: no staff instances, barline-alignment groups, or graphic
objects; a staff instance: no voices or measures; a voice: no events. Each is a
distinct TypedObjectId the reducer mints separately, so a carried child would
otherwise materialize an unminted object into the graph (a graph/ledger
faithfulness gap). ClefChange/KeySignatureChange/metric-grid carry no
TypedObjectId and are values, so they are correctly not gated. The check reads
the carried value only, so reduce() and reduce_onto() agree.
- Catalog §Structural Containers states the precondition as "no typed child
object" with the per-container enumeration, matching enforcement exactly.
Coverage: new graph_reduction tests create_rejects_a_non_empty_carried_container
(hierarchy children) and create_rejects_carried_non_hierarchy_children (barline
group / graphic object / measure). DECISIONS M2c gains the create-emptiness bullet.
Stages only ops + spec; the unrelated Agent-I working tree is left untouched.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The documentation milestone deferred through M2a–M2d. Documentation only —
no Rust changes; the d93baac code gates (cargo test --workspace 533/0,
conformance_suite scale 1) are unchanged.
operation_catalog (v0.1.0 -> v0.2.0):
- Chapter K0 gains full six-part schema sections for every M2-implemented op:
ModifyEvent; Identified-Pitch Operations (insert/delete/modify, with the
note<->rest equivalence stated normatively); Transpose; DeleteCrossCutting;
ModifyCrossCutting; Structural Containers (region/staff-instance/voice
set-union mint + empty-only delete); Score Settings (advisory metadata,
structural metric grid with the staff-based + live-time-signature
preconditions, advisory page break under the resolved-position LWW key).
- Chapter K1 cleanup: the implemented groups now cross-reference their K0
sections rather than sit in "MUST reject"; the stale Phase-3 listing of
SetMetadata / SetMetricGrid / page-break advisory (implemented in M2d) is
removed, and the remaining slots are split to the genuinely-unimplemented
finer metric ops (time signature / tempo segment) and non-break layout.
- Intro, conformance-profile, and version strings updated for the expansion.
- PDF rebuilt with xelatex (18 pp, no undefined refs); .xdv removed, only
tex+pdf tracked.
epiphany-ops/DECISIONS.md: new M2c (Group 3 — empty-only structural-container
delete; live-child indices; staff-extent maintenance) and M2d (Group 4 — the
per-op disciplines as review-hardened in d93baac: advisory metadata, metric
grid with both preconditions, resolved-position break key) entries, and a note
that the dedicated 10K-envelope reducer micro-bench (criterion 5) is Agent F's
worklist F1 — the M2 value-typed ops are already exercised at 10K*scale by the
conformance reduction-determinism / convergence gates.
The unrelated Agent-I working tree is left untouched; this commit stages only
spec/ + ops DECISIONS.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Addresses four findings spanning the H (pre-pass) and K (reduction) seams plus
the Operation Catalog.
1. [High] A reduced RespellPitch is now visible to the pre-pass. The reducer
stored overrides only in MaterializedState.spellings, but Agent H's
derive_annotations resolves authored spellings from score.spelling_attachments
— so a real respelling accepted by reduce_onto was lost before annotation
derivation, violating manual-override precedence. respell_pitch now upserts a
user-chosen explicit SpellingAttachment into the materialized graph
(materialize_respell / graph_respell_pitch); DeleteIdentifiedPitch drops that
attachment (graph_delete_pitch) so none dangles (it does NOT tombstone the
pitch — the event survives a pitch delete and a later ModifyEvent may reuse
the id, which would make it both live and tombstoned). New testkit gate
assert_reduced_respell_is_honored reduces a real RespellPitch and proves
derive_annotations honors it as Authored(UserChosen); wired into run_all.
2. [Medium] PrePassProfile algorithm ids are now enforced, not just recorded.
derive_annotations ran the default logic and labeled the result with the
requested algorithm. It now runs each pre-pass only when its requested id is
the implemented "default"; an unknown/future id yields no annotations for that
pre-pass (the requested id stays in the result profile), so a future algorithm
can no longer silently alias the default in a derivation cache. Test:
unknown_algorithm_ids_are_not_honored.
3. [Medium/Low] The determinism gate now fingerprints canonical bytes, not Debug.
DerivedAnnotations gains canonical_fingerprint(): embedded graph values
(PitchSpelling, DecompositionAttachment, SpellingSourceKind — the latter two
added to the CanonicalValue surface) use their ratified bytes; counts/ids are
little-endian, length-framed. The pre-pass harness fingerprints with it. A
discrimination check confirms it is not a degenerate constant.
4. [Low] operation_catalog.tex K1 chapter reconciled with the implemented M2
work: the now-dispatched ops (event/pitch leaf-field, cross-cutting CRUD,
structural container CRUD) are listed as implemented-since-M2 (available under
the Phase-2 profile), and the "MUST reject" scope is narrowed to the genuinely
deferred slots (create score/canvas/staff, set metadata, metric-grid/time-sig/
tempo, layout/page-break). PDF rebuilt clean (0 undefined refs).
Gates: build/fmt/clippy -D warnings clean; cargo test --workspace green (criterion
1 + the pre-pass and convergence gates); conformance scale 1 passes. The unrelated
Agent-I working tree is left uncommitted.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
From the M1 review (no correctness bugs found; these are accuracy corrections to
shipped artifacts, not new feature work):
- migration gate: the `v1 == migrated` assertion's comment overclaimed a
universal inverse. It is round-trip self-consistency over the representative
corpus (which is built from the same valuegen helpers the migration
reconstructs values with); the spec-level property is the reduction-equivalence
asserted alongside it. The ReplaceWithRest rest-voice is the known
non-invertible field, recovered from the deleted event's placement at reduction.
- operation_catalog §CreateCrossCutting: document that v0→v1 migration covers the
event-anchored Tie/Slur/Beam; a Spanner (anchor-based) cannot be reconstructed
from the v0 event-reference and is reported unmigratable (read-only) under M1,
so the catalog no longer silently implies it round-trips.
Review findings deferred to M2 (per project lead): migrate.rs unit tests for the
untested reconstruction branches, and the valuegen::spelling() mod-7 domain
cleanup. Gates unchanged and green (comment + spec-text only).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Foundation milestone for Track B's Operation Catalog: shift epiphany-ops from
the v0 identifier-only payload projections to durable value-typed payloads, and
scaffold the companion spec. Scope: the representative §6.10 set (7 primitives +
2 meta-ops); the slice-driven K0 expansion follows.
Core (the K↔J seam):
- epiphany-core exposes a public `CanonicalValue` trait (canonical_bytes /
decode_canonical) delegating to the existing private `Codec` machinery, for
Event/Rest/PitchSpelling/Tie/Slur/Beam/Spanner/RegionTimeModel/TimeAnchor.
No new byte layout — a value's bytes equal what the whole-score codec emits,
so all goldens / criterion 4 stay byte-identical.
Ops (value-typed payloads, frozen reduction rules):
- InsertEventOp{staff_instance,event:Event}, RespellPitchOp{pitch,spelling:
PitchSpelling}, CreateCrossCuttingOp{structure:CrossCuttingValue},
ChangeRegionTimeModelOp{...,new_time_model:RegionTimeModel},
SetUserSystemBreakOp{...,anchor:TimeAnchor}, ReplaceWithRest{rest:Rest}.
Payloads frame each value's CanonicalValue bytes behind a u32 length prefix.
- reduce.rs: read-sites only moved onto the value (rules, conflicts, ordering,
promotion, re-anchoring, undo, transactions unchanged); reduce_onto now
materializes the real event/structure instead of the C4 placeholder.
MaterializedState.spellings now stores PitchSpelling (encode + decode updated).
- v0.rs: frozen identifier-only shapes (migration regression guard).
- migrate.rs: migrate_v0_envelope(v0, &Score) + project_v1_to_v0 + MigrationError;
deterministic and equivalence-preserving. Respell spelling recovered from the
score context; irreversible case is P12-K1.
- valuegen.rs: shared value-type builders (reused by fuzz, migration, tests,
testkit). Resolves P11-C1; P11-C10 Dismiss recorded.
Testkit (Agent F merge gate):
- migration.rs: reduce(v1)==reduce(migrate(project(v1))) byte-identical, plus
migration determinism and a non-vacuity guard; wired into acceptance.rs as
agent_k_migration_equivalence_gate. Generators/harnesses build v1 payloads.
Spec:
- spec/operation_catalog.{tex,pdf}: new companion (independent semver) — framework
+ per-primitive template, the 7+2 representative primitives, the v0→v1 migration
contract, and K1 framework slots for the remaining K0 primitives. Builds clean.
- PASS12_BATCH.md: P12-K1 (respell fingerprint irreversibility).
Gates: cargo build/fmt/clippy -D warnings clean; cargo test --workspace green
(incl. criteria 1/4/5/6 and the new K gate); conformance_suite scale 1 passes.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>