Skip to content

contract(shared): reject impossible transcription intervals before rehearsal rendering #1255

Description

@seonghobae

Finding

The shared TranscriptionNote contract admitted finite but impossible audio-relative intervals after #1253 fixed only non-finite representation. GrooveMap uses onset as horizontal position and offset - onset as note width, so negative onset or non-positive duration reaches buyer-visible rehearsal geometry.

Protected producer evidence closes the domain decision: _note_events_from_frames() derives start time from non-negative frame indices and drops events with duration below MIN_NOTE_DURATION_SECONDS = 0.05. The repository-owned producer does not intentionally emit negative starts or non-positive durations.

Canonical repair / single-writer succession

No parallel shared-contract branch was created. Draft PR #1254 owns validateTranscriptionNote() and remains the timing-policy writer.

Current #1254 exact head: c21c18ccd630614feee1fef3e0b7e5cf4fdce658, stacked by ordinary ancestry on formatter prerequisite #1176 8fe6b6d99c009527ef0bcba419e6f6debdb23c23.

  • RED 9a27a87f8c2c74614d84acb23458845949f948a0 adds hostile finite intervals through both isRehearsalSong() and parseRehearsalSong(): negative onset, zero-duration interval, inverted interval, plus zero/negative-zero and ordinary positive controls.
  • Causal repair 95356c11a76716dde927bfe311dffb5eec4cf9e1 requires finite onset >= 0 and finite offset > onset in the shared validator.
  • Doctoring 02e85d3150bfd32472a23793b36af577fd55e331 records producer evidence, rendering consequence, persistence/recovery boundary and rejected alternatives.
  • Two-parent descendant c21c18... makes repair(ci): format consolidated supply-chain policy test #1176 actual ancestry without duplicating its formatter source delta.

Velocity policy remains separate because repository evidence does not yet establish one canonical scale/range.

Persistence / recovery boundary

Desktop saveProject() parses before native persistence and loadProject() parses the native response before returning a RehearsalSong. Malformed durable project timing therefore fails closed at the shared parser boundary; this repair does not silently clamp, swap, reorder or normalize durable timing.

A separate persisted analysis final-result cache consumer in #970 was found to be out of sync: _valid_transcription_note() accepted any finite onset/offset pair. #970 now has #1254 as actual ancestry and carries a focused downstream consumer RED 3314730077b7c24c077e2f15cec73eb627b8d75e for negative, zero-duration and inverted intervals, followed by causal repair 3dfd77e11187211e9b7ed2317b8f559e5e1fb018 adding only onset >= 0 and offset > onset after the existing finite checks. That is a consumer adaptation, not a second timing-policy owner.

If a historical project or cache carrying malformed note intervals is discovered, recovery/migration must classify it explicitly rather than weakening the shared invariant.

Evidence boundary

Before #1176 stacking, #1254 semantic head 02e85d... had build-baseline, Security Scan, Semgrep and SBOM terminal SUCCESS. Repository CI failed only on protected-base test_supply_chain_policy.py Ruff formatting, now owned by #1176. The current stacked #1254 head has no repository-owned workflow generation; zero runs is absence of evidence, not GREEN. The #970 downstream stacked head likewise has no hosted generation after its timing consumer repair.

No predecessor GREEN is promoted to either current stacked head. No no-op freshness commit, blind rerun, force push, destructive rebase, self-approval or gate weakening is used.

Acceptance

Do not close this issue merely because source deltas exist. Protected integration or verified complete succession remains required.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions