Purpose: single source of truth for terms used by humans and LLM agents working on
griff.Rule of use: if a term appears in the spec, an ADR, a stage doc, code, or an agent task, check this file first. Do not invent competing definitions. If a term is missing or ambiguous, extend this file rather than creating synonyms in code.
The guitar riff engine project: a system to analyze, slice, generate, and regenerate guitar riffs, targeted at swancore / DGD-like clean / prog / post-hardcore parts. Internally it works on a structured musical model, not on raw MIDI bytes.
Naming etymology: "griff" = "guitar riff" (English). Also a multilingual pun: Russian "гриф" (grif) means the guitar fretboard/neck; "гриф" also denotes a griffon (the mythical bird). The project mascot contrast: swan (soft, expressive, flowing) vs griffon (aggressive, intense, soaring). Marketing slogan: "soft as swan & aggressive as griffon". Future brand variant: "Griff-On" (the griffon bird, full name reveal).
An engine that treats guitar riffs as musical objects — phrases, motifs, rhythm cells, techniques, fretboard positions, transitions, variations — rather than emitting random notes.
Architectural principle: design features for expressive clean / prog / swancore guitar parts first, not for "music generation in general". Drives the data model, features, generator, corpus, and UI.
Use structural traits similar to Dance Gavin Dance (fast clean riffs, syncopation, register jumps, melodic intervals, tapping / legato-like motion, unconventional phrasing) to produce original ideas — not to copy songs.
Minimum Viable Product. In griff: a minimal working vertical slice —
import → internal model → analysis/slicing → generation/export → tests. Not
"a quick throwaway".
An end-to-end piece of functionality through every layer of the system.
A development stage S0, S1, … Each stage has a goal, tasks, acceptance
criteria, tests, and constraints.
Baseline stage. Freeze current behavior via characterization tests, golden snapshots, and smoke tests before refactoring.
Canonical score model stage. Introduce Score / MasterBar / Track / Voice / EventGroup without breaking existing code in one stroke.
MIDI transport refactor stage. Move MIDI import/export onto the master timeline and canonical score model.
Guitar Pro import stage. Add Guitar Pro as a first-class data source, especially for techniques and guitar specifics.
Phrase boundary detection stage. Detect phrase boundaries automatically with explainable heuristics and manual override.
Corpus and schema stage. Build a micro-corpus and an annotation schema for phrases, techniques, tags, and quality.
Rule-based generator v0 stage. First controlled, non-neural phrase generator.
Graph layer stage. Add a graph of phrases, motifs, rhythm cells, transitions.
Preview app stage. Standalone app to view, listen, compare, and hand-annotate.
Feedback layer stage. Human-in-the-loop: like/dislike, favorites, preferences, reranking.
CLAP MVP stage. MIDI-oriented CLAP plugin, once core is stable enough.
Region regeneration stage. Regenerate selected ranges while preserving anchors / frozen regions.
Neural assistance stage. Neural layer for continuation / infilling / variation, only after corpus and rule-based baseline exist.
Complementary part generation stage (ComplementArranger). Generate a second
part related to an existing one on chosen axes and contrasting on others.
Depends on S6; appended as the next free number rather than renumbering
S7…S12 (ADR-0012; see docs/audit/2026-05-s13-complementary-arranger.md).
Structure controls and metrics stage. Make time-organisation controllable — target span, pattern period, repeatability/variation, complexity profile — as a constraint compiler over S6. Depends on S6/S4; appended as the next free number. Feeds the graph layer but does not depend on it or on DP/Viterbi (ADR-0015).
Tonal context and harmonic control stage. Make tonal/harmonic context explicit, uncertain, scoped, and reusable before it may influence generation; observed evidence stays distinct from inferred meaning, and abstention is a valid result. Phase 0–1 accepted and closed 2026-07-12; confidence thresholds, automatic scope selection, and generation integration remain frozen until their own acceptance. Depends on S1/S5/S6; appended as the next free number.
Swang language and verified lifting stage. A deterministic, versioned musical
DSL over the canonical model: bounded pattern algebra (fractalize,
traversals, budgets), recipes, exact canonical escape hatches, and verified
lifting of imported scores into executable programs with explicit residuals
(ADR-0029; normative semantics in docs/swang/spec.md). Depends on
S1/S2/S3/S4/S6, building on S13/S14 and on S15 contracts once accepted;
appended as the next free number.
Single internal model into which MIDI, Guitar Pro, MusicXML, and other formats are imported. Not a copy of MIDI or Guitar Pro — a normalized model of its own.
The target score-level model: Score -> MasterBar -> Track -> Voice -> EventGroup -> AtomEvent. Needed for tempo map, polyphony, chords, Guitar Pro
effects, and generation.
Top-level musical document: master timeline, tracks, metadata, source info, tuning, global parameters.
Score-level bar. Holds bar parameters shared by all tracks: time signature, tempo changes, repeats, markers, bar index, absolute tick range. Prevents re-deriving tempo per track.
An instrument part or logical layer (clean guitar, rhythm guitar, lead guitar, bass).
An independent event stream inside a track. Needed for polyphony, overlapping notes, ringing notes, chords, multiple rhythmic lines.
A group of events bound by time or musical role: chord, arpeggio group, tuplet, grace cluster, sequential fragment. Fixes the "Event::Note/Rest is too linear" problem.
The minimal event in the canonical model: note, rest, tie, control/expression event, or a service unit. The atom that groups are built from.
The (string, fret) location of a note under the track's Tuning, carried
optionally on a note as part of the rich note model (ADR-0018, superseding
ADR-0014): Guitar Pro import supplies it directly, MIDI import leaves it absent
or inferred. Pitch alone cannot express hand position; position is what makes
fret_jump_penalty and human-plausible parts possible.
Assigning a plausible (string, fret) to each pitch of MIDI-sourced material —
the guitar fingering problem — via a small, local, deterministic DP over
per-note candidates, minimising hand movement / stretch / string changes under
the track Tuning (ADR-0019). VI-independent geometry (distinct from the parked
MIDI technique inference); output is marked InferredFromMidi with confidence.
GP positions stay Explicit and are not inferred.
Playability facts of one part's melodic line (highest pitch per onset),
measured on the position-inference DP's optimal path under the track's
Tuning (fretboard::measure_playability): line notes measured, notes with
no playable (string, fret), and the largest fret travel between
consecutively positioned notes. The verdict is reachability — a part with
an unreachable line note is not playable; fret travel is a fact, not a
verdict (jump thresholds are calibration data). The S13 pair validator's
per-part filter, and the seed of the S7 playability / fret_jump_penalty
cost terms. Chord voicing playability is deferred (ADR-0019 §7).
A sounding note (AtomNote): pitch, duration, velocity, an optional
FretboardPosition, and a set of NoteMarks, each technique carrying
TechniqueEvidence. The flat Option<Articulation> is superseded by the marks
set plus TechniqueSpans (ADR-0018).
A musically significant silence of a given duration. Distinct from "no event".
Current enum in griff-core holding Note and Rest. In the target
architecture it becomes a compatibility layer or part of a richer model.
Current single-bar event container. In the target model it links to
MasterBar or becomes a view/projection.
A musical phrase: a sequence of events/bars perceived as a complete unit. The base unit of analysis, generation, and corpus.
A fragment extracted from a source and stored in the corpus. Has boundaries, tags, features, source reference, quality flags.
Provenance label on a corpus chunk relative to the swancore-first scope:
core (swancore) or adjacent (neighbouring genres admitted for coverage
and graph mass). Consumed as per-consumer slices (decisions 2026-06-11):
statistical gates and the style centroid read core only; the graph layer
reads everything with per-cohort transition statistics; novelty references
and taste ignore cohorts. Schema v4 (ChunkMeta.style_cohort); absent =
unlabeled pre-v4 record.
Several single-part chunks curated from one source span (e.g. the two
role-fluid guitars of a DGD section), linked by a shared group id and a
manifest-level group record carrying measured pairwise relation axes
(measure_pair_axes) — the corpus-side complement hyperedge (§9). No role
labels by design: the per-phrase relation axes are the role information.
Schema v4 (ChunkMeta.ensemble, CorpusManifest.groups); written by
griff curate --ensemble.
A short recognizable musical idea: a rhythmic figure, an interval shape, or a repeated phrasal cell. The generator must vary motifs, not shuffle notes.
A small rhythmic unit: an onset/duration/rest pattern. Used in the graph layer and rule-based generator.
A set of pitch constraints: scale, mode, pitch set, anchor notes, allowed intervals, register range.
The time axis of a piece, expressed through ticks, tempo map, and master bars.
The global time structure of a score. Single source of truth for tempo, meter, bar positions, and transport-level markers.
Metadata from the source format: Guitar Pro effects, string/fret, MIDI CC evidence, original track name, importer warnings. Must not be dropped silently.
Importer warning: data read partially, approximately, or lost.
A report of losses during import/export. Especially important for MIDI ↔ Guitar Pro, which store different semantics.
A layer letting the old Phrase/Bar/Event API live during the transition to
the canonical score model.
A representation of the rich model in a simpler form (e.g. polyphonic score → monophonic phrase view).
A read-only representation for a specific use case: monophonic phrase view, track summary, CLI summary, debug dump.
An abstract unit of musical time. In MIDI it depends on PPQN. Typed as
Ticks.
Rust newtype around a tick count, so musical time is not confused with bytes, indices, or milliseconds.
Pulses Per Quarter Note. Ticks per quarter note (e.g. 480 PPQN = 480 ticks per quarter).
MIDI timing based on ticks per beat/quarter. The path griff supports today.
Frame-based MIDI timing. Not supported yet; would need
TransportTimebase::{Ppqn, Timecode} or an absolute-time conversion layer.
Time as hours/minutes/seconds/frames. Less convenient than PPQN for a generator, but appears in MIDI/film/video workflows.
Music speed, usually BPM. Currently Tempo(pub f64).
Beats Per Minute (120 BPM = 120 beats per minute).
MIDI tempo representation: microseconds per beat (500000 µs/beat = 120 BPM).
A sequence of tempo changes along the timeline. Lives in the master timeline, not scattered across tracks.
Bar meter (4/4, 7/8, 5/4). Typed as TimeSignature.
Same meaning as time signature, used more as a musical category.
Bar length in ticks; depends on PPQN and time signature.
Range [start, end): start included, end excluded. Important for TickRange,
slicing, and boundary logic.
A tick range used for slicing, selection, region regeneration, boundary detection.
An event with absolute start and source indexes; used for analysis, slicing, regeneration.
Snapping events to a time grid. Useful for MIDI import but dangerous if it destroys human micro-timing.
Rhythmic offset of beats producing groove. Less central for swancore than syncopation but relevant for groove-aware generation.
An accent or event on a weak/unexpected beat. A key swancore/prog feel marker.
A sense of phrase completion: harmonic, rhythmic, or melodic.
A new rhythmic pattern starting after dense/syncopated motion. A useful phrase boundary signal.
Event density over time: notes/attacks/changes per region.
The start moment of a sounding event. Onset patterns matter for rhythm analysis.
Musical Instrument Digital Interface. An event format/protocol (note on/off, velocity, CC, pitch bend, program change). MIDI does not encode "hammer-on" as full guitar semantics.
Standard MIDI File — the .mid file format.
Rust crate for reading/writing MIDI. Currently used by griff.
MIDI note-start event. Velocity > 0 usually means note start.
MIDI note-end event. NoteOn velocity=0 is a common NoteOff equivalent.
Note intensity, 0–127. A dedicated type in griff.
MIDI pitch number, 0–127. 60 = middle C.
MIDI channel 0–15. A track currently gets the dominant channel by majority of note events.
A midly MIDI track event: delta time + payload.
A service MIDI event: tempo, time signature, track name, end of track, etc.
MIDI meta event with the track name; imported as an optional name.
MIDI meta event ending a track. Required for correct export.
MIDI controller events (pedals, modulation, expression). Not always unambiguous musically.
MIDI pitch-bend event. Evidence for bend/vibrato, not equal to a symbolic Guitar Pro technique without context.
Channel-level aftertouch. Possible expression evidence.
Per-note aftertouch. Useful for expression/MPE.
MIDI Polyphonic Expression — per-note pitch bend/pressure/timbre. Not MVP, but potentially useful for a future expression layer.
Conversion of .mid into the canonical score model, preserving as much
evidence as possible.
Conversion of the canonical score model into .mid, built from the master
timeline and tracks — not from a random first track.
Import MIDI → export MIDI → re-import → compare normalized result. An important integration/golden test.
Low-level MIDI events from which articulations or expression can be inferred, but which cannot be claimed as symbolic technique.
Tablature formats .gp3, .gp4, .gp5, .gpx, .gp. Important because they
carry guitar semantics: strings, frets, techniques, effects.
Binary Guitar Pro 3/4/5 formats. MVP import candidates.
Guitar Pro 6 format — a proprietary container with GPIF/XML-like content. Harder than GP3–GP5.
Newer archive/zip-like Guitar Pro formats with score.gpif plus extra files.
Mark as experimental.
XML-like internal representation used by Guitar Pro 6+; can be easier to import than binary parsing.
Python library for GP3/GP4/GP5; usable as a sidecar adapter if pure Rust is immature.
Rust crate for Guitar Pro; candidate for a Rust-native GP import pipeline.
Tablature render/parse ecosystem including Guitar Pro; a reference model and possible adapter inspiration.
Open notation interchange format. Possible fallback/interchange, but does not replace Guitar Pro for guitar techniques.
Guitar notation by strings and frets. Matters for playability, string/fret movement, position shifts.
A guitar string. Stored separately from pitch (one pitch is playable on several strings).
A guitar fret. With string, defines the physical position of a note.
Guitar tuning (standard, drop D, alternate). A first-class model type carried
per Track (default Standard E, ADR-0006), the reference that maps pitch ↔
(string, fret) (ADR-0018). Distinct from the coarse corpus tuning string tag.
A playing technique: hammer-on, pull-off, slide, bend, vibrato, palm mute, tapping, harmonic, etc.
A spanning guitar technique over a tick (later: note) range — slide, legato
(hammer-on/pull-off), bend, vibrato, palm-mute, let-ring, tremolo, sweep. Holds a
SpanTechnique kind plus TechniqueEvidence. The relational / time-extended
half of the technique model; the per-note half is NoteMark (ADR-0018).
An articulation from a format that stores it explicitly (e.g. Guitar Pro), as opposed to inferred from MIDI.
A technique guessed by heuristics from MIDI evidence. Carries TechniqueEvidence
(InferredFromMidi + confidence < 1.0), so it never masquerades as a
source-of-truth (Explicit) technique (ADR-0018).
Import without losing important semantics. Possible for much of Guitar Pro if the model is rich enough.
Export losing information (e.g. Guitar Pro techniques → MIDI is almost always lossy).
Renamed to SpanTechnique (ADR-0018 Slice 2b). The dominant-label projection
over a note's marks and spans is deferred until a consumer needs it (none does
yet): feature reads marks, complement reads a technique-label set.
A per-note guitar technique that is intrinsic to one note and co-occurs with
others: accent, ghost, staccato, dead/muted, natural/pinch harmonic, tap. A note
carries a set of marks (NoteMarks, a Copy bitset) replacing the old
Option<Articulation>. Evidence-free — provenance lives on spans/positions
(ADR-0018).
The kind of a TechniqueSpan — a technique that relates notes or covers a range:
slide, bend, legato (hammer-on/pull-off), palm-mute, vibrato. The renamed former
Articulation enum, without the harmonic variants (those are NoteMarks), so
"a span is a harmonic" is unrepresentable (ADR-0018 Slice 2b).
Provenance on a TechniqueSpan: a TechniqueSource
(Explicit = read from a source-of-truth format like Guitar Pro, confidence 1.0;
InferredFromMidi = guessed from MIDI evidence, confidence < 1.0) plus the
confidence (f64). Keeps inferred techniques from masquerading as fact
(ADR-0018). Position evidence is deferred until position inference exists. The
import-side sense of evidence reserved by ADR-0017 (distinct from a scoring
rationale).
Where a technique came from: Explicit (source-of-truth format) or
InferredFromMidi (heuristic cue). The source field of TechniqueEvidence
(ADR-0018).
A lightweight stable note identifier, so a TechniqueSpan can pin specific
endpoints (a legato pair, which chord note bends) and survive region
regeneration. Part of the target rich note model; phased in after the initial
tick-range spans (ADR-0018).
Sliding between notes/positions. In MIDI only indirectly via pitch bend; in Guitar Pro an explicit effect.
String bend. A symbolic Guitar Pro technique, or MIDI pitch-bend evidence.
Connected playing; on guitar often hammer-on/pull-off.
Next note sounded by a fretting-hand finger strike, no new pick attack.
Next note produced by pulling a finger off the string.
String muting with the palm edge. Important in heavier/prog contexts; usually not stored explicitly in plain MIDI.
Pitch oscillation. MIDI: pitch bend/modulation evidence; Guitar Pro: explicit technique.
A natural harmonic. Explicit in Guitar Pro; usually absent in MIDI.
Pick/artificial harmonic. Almost impossible to recover reliably from MIDI without the source.
A note sounded by tapping a fretboard. Can matter for swancore. Not stored directly in MIDI.
Fast repeated picking. Detectable via dense repeated onsets.
Notes ringing over following events. Needs polyphony/voices.
A quiet/muted note. May be velocity/technique-driven; interpret carefully.
An accented note. May be high velocity in MIDI, but velocity ≠ musical accent.
A short auxiliary note before a main note. Needs its own model or an EventGroup.
A rhythmic subdivision off the regular grid (triplets, quintuplets, …).
A chord stroke across strings with micro-offsets. Needs an EventGroup, not a single chord timestamp.
A broken chord: chord notes sounded sequentially.
A boundary between phrases. May coincide with a pause, cadence, bar boundary, or a change in rhythmic/melodic behavior.
An algorithm proposing likely phrase boundaries.
A numeric boundary likelihood, e.g. pause + cadence + rhythm_reset + motif_boundary + register_jump + density_change.
An explanation of why a boundary was placed (pause, rhythmic reset, register jump, harmonic resolution, …).
A user correction of boundaries. Mandatory for the corpus; fully automatic labelling will confidently err.
Boundary signal from a long pause or rest.
Completion signal from harmonic/melodic/rhythmic resolution.
Boundary signal from a sharp register jump.
Boundary signal from a sharp change in event density.
Boundary signal from a motif ending/repeat/change.
A sense of tension resolving to a stable point; may be heuristic when harmonic context is poor.
Local Boundary Detection Model. Segmentation by local parameter changes. Inspiration for an explainable heuristic detector.
Information Dynamics of Music — an expectation/surprise model. Not MVP; theoretical reference for predictive boundary cues.
Extraction of numeric/categorical phrase features: pitch range, density, intervals, syncopation, articulation ratio, etc.
Current griff struct computing basic phrase features. Must be extended.
Min and max note pitch in a phrase.
Min and max velocity.
Number of notes.
Number of rests.
Number of notes carrying articulation.
Fraction of rests in a phrase. Useful for boundary detection and generator style.
Distance between two pitches (melodic or harmonic).
Distribution of intervals. Useful for similarity and style constraints.
Shape of pitch motion: up, down, wave, leaps, repeats.
Pitch region (low/mid/high). For guitar, related to fretboard position.
Motion between registers. Often significant in swancore.
The rhythmic pattern of note onsets.
The pattern of durations.
A measure of syncopation strength.
Fraction of notes/spans with a given technique.
How physically playable a phrase is on guitar.
Motion across the fretboard: position shifts, string changes, fret distance. A key swancore-specific feature.
Similarity of phrases/motifs; may consider rhythm, contour, intervals, techniques, register, tags.
A distance function between objects. Music rarely needs only one.
The perceptual sense that a phrase is finished rather than broken off
(Meyer / Narmour; survey in audit/2026-06-melodic-closure-research.md). In
griff it is a scored axis set under the ADR-0017 vocabulary
(core/src/closure.rs): internal_continuity (the S4 boundary detector
re-used as the generation-side referee), ending_stability
(Krumhansl-inspired tiers over the pitch material), final_lengthening, and
gap_fill (implication-realization mini-rules), weighted by the uniform
closure v1 policy. Ambiguity warning: always the music-cognition term here,
never a Rust closure.
The measure that keeps corpus learning at the schema level: how much of a
candidate is a verbatim quote of reference material
(core/src/novelty.rs). Compares (interval, normalised IOI) transition
sequences of the melodic line — so a quote is caught through transposition
and tick-resolution changes — and reports the longest common run plus n-gram
overlap. Gives the §8 "Quality score" novelty axis its concrete measure
(quote_novelty / ngram_novelty, ADR-0017); the rejection threshold (e.g.
quotes longer than 1–2 bars) is the caller's cut, not code.
The distributions that describe burst-and-rest writing without its content
(core/src/gesture.rs; melodic-closure note §3.5 — the DGD case): burst
length (maximal melodic-line runs between gesture rests), rest length and
quarter-grid placement (a rest reads as part of the gesture when metrically
predictable, as a hole when not), the share of bursts landing on the line's
modal pitch class, and burst-final lengthening (closure-v1 normalisation). A
gesture rest is at least one quarter of line silence after a sounded note;
sub-quarter holes are phrasing. Persisted per chunk as ChunkMeta.gesture
(corpus schema v3); the intensive distributions feed the chunk-similarity
edge (§9), and the stats derive a Gesture control (§8) — the S6 constraint
input they were measured for.
A component that creates new phrases, variations, or regions.
A generator driven by rules and heuristics. Must precede the neural layer.
Same seed/input → same result. Required for tests.
The RNG seed; needed for reproducibility.
One generated phrase variant.
A set of variants for the user or reranker to choose from.
Re-sorting candidates by quality score, user preferences, similarity, constraints.
A modified version of a source phrase or motif.
A continuation of a given phrase.
Filling a missing/selected span between two contexts.
Re-generating a selected span, usually preserving some context.
Regenerating a specific TickRange or selection.
A span that must not change during regeneration.
An event/note/boundary that must be preserved (e.g. first and last note of a region).
A generation constraint: scale, range, rhythm density, max fret distance, preserve contour, allowed techniques.
Strategy: take rhythm from a source, replace pitch material.
Strategy: keep rhythm, replace pitches by rules.
Strategy: keep a recognizable motif shape, change details.
A random walk over pitch/fretboard space with constraints, to avoid meaningless output.
Generating a phrase ending with a sense of completion.
A filter discarding physically awkward or impossible phrases.
The aggregate of a quality axis-vector — similarity, novelty, playability, density, user preference, style fit — not a primitive scalar (ADR-0017). The axes are the truth; the aggregate is a derived convenience for sort/UI.
The shared output shape Scored<T>: a produced value (candidate, boundary,
part) plus its score axes, rationale, and provenance. Replaces ad-hoc
{ score, reason } shapes so boundary, complement, structure, and DP scores
share one form (ADR-0017).
The named, normalised per-axis measurements behind a score, carried as labelled
data rather than a fixed struct (e.g. complement rhythm_similarity / register_overlap / density_ratio / technique_overlap, a ComplexityProfile, or
the DP cost terms). The source of truth; never discarded in favour of the
aggregate (ADR-0017).
The data-valued policy vector that reduces axes to an aggregate — the surface the feedback layer (S9) tunes. Kept separate from the code that computes axes so weights change without touching scoring (ADR-0013, ADR-0017).
The explainable trace of a score: which axes fired or contributed, which
thresholds were crossed (the generalisation of BoundaryReason). The "why".
Distinct from evidence, which is reserved for import-side provenance
(ADR-0017).
The derived scalar aggregate(axes, weights) used for sorting and display.
Reproducible only relative to (seed, weights-version); ties break by a fixed,
documented rule so ordering is total and stable (ADR-0017, extends SPEC §6).
How different a candidate is from the source. Balance: too low = copy, too high = noise.
How well a candidate matches swancore-first constraints.
A part (part B) generated to accompany an existing part (part A): related to A on chosen musical axes (rhythm, harmony, register, technique, density, contour) and deliberately contrasting on others. Arrangement, not duplication.
The rule-based engine that produces a complementary part. A constraint compiler over the S6 generator, not a new generator: it analyses part A, picks a relation mode, derives an S6 request for part B, and validates the pair. Named for the relation, not a fixed part count (S13, ADR-0012).
The typed, multi-axis relation between two parts. Exists in three distinct roles
that must not be conflated: spec (input ComplementSpec/relation mode),
fact (a mined hyperedge in the graph layer, §9), and provenance (metadata on
a produced candidate).
A named complementarity preset chosen for generating part B: rhythm_lock,
register_contrast, call_response, support_layer, octave_double,
counter_melody.
The per-part feature summary ComplementArranger derives from part A: onset/rhythm
grid, accent pattern, register band, contour, normalised density, technique
multiset, harmonic context. Richer than PhraseFeatures.
The estimated key of a part — tonic pitch class plus major/natural-minor mode — together with its scale fit: the duration-weighted fraction of notes on that key's scale. Estimated with the Krumhansl–Schmuckler key-finding algorithm (Krumhansl–Kessler profiles over the part's pitch-class histogram). A fact carried by the part profile, not a verdict; fit thresholds are corpus/S9 calibration.
A post-generation check over the (A, B) pair: per-part playability plus harmonic compatibility — no dissonant clashes on coincident onsets, no register mud. Distinct from the single-part playability filter.
The region of the timeline to fill — a TickRange (or bar count). The physical
length of the result; says nothing about the material inside (S14, ADR-0015).
The length of the base repeating idea inside a span (e.g. 1/2 bar, 1 bar, 2
bars), possibly sub-bar. Distinct from target span and from complexity: a short
period can carry hard material. None = through-composed (no strong repeat).
How strictly the material repeats across pattern periods: identical copies → high; recurring-but-transformed → medium; always-new → low.
How much repeats mutate (the complement of strict repeatability). High variation with a recognisable period = "A A' A'' A'''".
How seamlessly a span can be looped — the smoothness of the wrap-around seam. Distinct from repeatability (internal self-similarity vs seam continuity).
A vector, not a scalar: rhythmic / pitch / technical / harmonic / playability / structural complexity, each normalised. Orthogonal to length and period — a
short loop may be technically hard; a long line may be trivial.
The input spec for S14 generation: target span, pattern period,
repeatability, variation rate, loopability, complexity profile. Compiled
into S6 generation constraints (ADR-0015).
The measured counterpart of a structure control over a produced or imported span: detected pattern period, repeatability, variation, loopability, structural complexity. Used to rerank candidates and — later — as graph node attributes. Computed by self-similarity / autocorrelation analysis; does not depend on the graph layer or DP/Viterbi (ADR-0015).
The ask counterpart of the measured gesture statistics (§7) — the structure
control duality applied to burst/rest writing: burst notes (notes per burst)
and rest quarters (minimum gesture-rest length), derivable from a measured
corpus chunk (GestureControl::from_stats). Compiled over the S6 generator
(generate_gestured, core/src/gesture.rs): plain S6 writes wall-to-wall,
then gesture rests are carved deterministically — after every burst notes
kept notes, following notes are dropped until at least rest quarters of
line silence opens; survivors keep their absolute onsets, so the master
timeline is untouched and bursts span barlines. The candidate carries the
re-measured gesture statistics as provenance (ask vs is).
A graph representation of phrases, motifs, rhythm cells, and transitions.
A graph node: phrase, motif, rhythm cell, or technique pattern.
A relation between nodes: similarity, transition, harmonic compatibility, or user preference.
The relation weight, used in traversal/generation/reranking.
The first concrete S7 edge (core/src/similarity.rs): per-axis agreement
between two corpus chunks over facts already persisted in ChunkMeta —
detected pattern period (min/max bar ratio; through-composed pairs agree),
repeatability / loopability / structural complexity (1 − |Δ|), tag-set
Jaccard, and the five intensive gesture distributions (mean burst / rest
length as min/max ratios — two restless chunks agree; rest-grid, modal
landing, and final-lengthening shares as 1 − |Δ|) — as named ADR-0017 axes
under the uniform similarity v2 policy. The extensive gesture counts are
deliberately not axes (a length echo would shadow the style facts).
find_similar_chunks is the brute-force query over the edge (no ANN at
micro-corpus scale; decisions.log 2026-06-10 AudioMuse entry, idea (a));
measured means structure and gesture, so schema-v1/v2 records cannot
sit on the edge until re-curated.
A graph whose nodes are phrases or phrase chunks.
A graph of motifs and their variations.
A graph of allowed phrase transitions.
Walking the graph to pick a continuation, variation, or candidate chain.
Assembling a new phrase from parts of existing phrases/motifs.
The documentation/semantic graph of concepts, files, decisions, stages, and dependencies. Not the runtime phrase graph.
A graph edge linking two phrases/parts by a set of per-axis relations (rhythm, harmony, register, technique, density, contour) at once, not a single similarity weight. The concrete case that makes the graph layer a hypergraph rather than a similarity graph. Generative-first in S13; mined from real two-part corpus material later in the graph layer.
The separation between the hypergraph (the map — what is connected / possible) and traversal (the route — which sequence is best). They must not be conflated; the graph stores musical relations, DP selects a path through them.
Dynamic-programming selection of the optimal candidate sequence across bars, the primary S7 traversal mechanism (ADR-0013). Deterministic by construction (no RNG needed; ties break by a fixed rule), so it satisfies SPEC §6, and it optimises the whole sequence instead of picking the locally-best candidate per bar. Beam search is an approximation for graphs too large for exact DP.
The running context carried through traversal: current candidate, fretboard
position, last technique, energy level (EnergyState), and rhythmic similarity
to part A. Kept small so exact DP stays tractable.
The inspectable transition cost DP minimises:
harmonic_fit + rhythm_complement + style_fit + playability + phrase_continuity − mud_penalty − repetition_penalty − fret_jump_penalty. Exposed as data
(weights), because it is the same surface the feedback layer (S9) tunes.
A graph node / DP-state component representing the local energy level of a passage (e.g. verse below chorus). Used to shape the global arc of a generated part.
The user rates candidates, corrects boundaries, picks good fragments, and thereby steers the system.
The minimal feedback signal. Used for reranking and the preference profile.
A stronger signal than a like: save a candidate as a good example.
A model of user preferences: which features, tags, styles are liked more.
A feature weight adjusted by user ratings.
The user does not just press "generate" but builds a micro-corpus and marks the best results.
A human decision on a chunk/candidate: accepted, rejected, needs edit, favorite, boundary corrected.
Learned preference over complement-relation axes (rhythm_similarity, technique_overlap, register_overlap, density_ratio), as opposed to preference over single-phrase features. The feedback layer can weight these once ComplementArranger emits per-axis relation scores.
Command Line Interface. griff already has import, inspect, export. The
CLI stays the first debugging surface.
Reads a file and prints a short summary.
Detailed bar-by-bar view.
Roundtrip/export.
A standalone app for viewing phrases, candidates, boundaries, graph, and feedback. Comes before CLAP.
A pure, renderer-agnostic projection of a Score for display (e.g.
PianoRollView, Analysis). No rendering, no I/O. The shared input every
frontend draws from. See ADR-0016.
The shared, frontend-independent layers behind every griff GUI: the
view-model, the interaction core (Viewport/Intent), and the scene.
Frontends (ratatui, egui) are thin adapters over it. See ADR-0016.
The interactive UI-core state: scroll, zoom, pitch offset, section selection, playback position, inspector toggle. Renderer-agnostic; mutated only by the reducer. See ADR-0016.
A semantic, device-independent UI action (e.g. TogglePlay, ScrollRight,
NextSection). Frontends translate raw input (keys, mouse) into intents; the
reducer Viewport::apply is the only place that interprets them. See ADR-0016.
A resolved, renderer-agnostic placement of a frame: a grid of placed cells (note
blocks, bar/section lines, playhead, section band, gutter labels) in abstract
cells with semantic style. Produced by resolve(view, analysis, viewport, size); each renderer maps it to glyphs/pixels. Carries placement only —
toolkit-specific text (header, footer, inspector) is rendered per-frontend from
the same view-model, never resolved into the scene. See ADR-0016.
A thin frontend backend (ratatui or egui) that maps a Scene to its toolkit and
raw input to Intents. Holds no interaction logic and no layout math. See
ADR-0016.
A Rust immediate-mode GUI library. Candidate for the preview app.
A framework around egui for desktop apps.
CLever Audio Plugin API. The target plugin format for griff at S10.
A Rust framework for VST3/CLAP plugins. Candidate for the CLAP MVP.
A plugin that outputs MIDI events into the DAW rather than synthesizing audio.
Digital Audio Workstation (Ableton, Reaper, Logic, Bitwig, …).
The DAW or app loading the plugin.
Tempo, play/stop, timeline position, bar/beat info from the DAW host.
Dragging a generated MIDI fragment from the plugin/preview into the DAW.
A configurable plugin parameter: density, variation amount, style mode, seed, phrase length, etc.
A group of crates in one repo. In griff: core, cli, plugin.
A Rust package/library/binary unit.
Core crate: musical model, import/export, slicing, features, generation.
CLI crate: user commands and a test debugging surface.
Plugin crate: empty until S10.
Rust crate/workspace manifest: dependencies, package metadata, profiles, lints.
Pins the toolchain and components: stable, rustfmt, clippy.
Minimum Supported Rust Version. griff targets Rust 1.92 — the floor egui /
eframe 0.34 impose on the cockpit, verified by a CI job that builds the
workspace on it. Do not use newer syntax/features without a decision.
The Rust linter, configured strictly in griff.
The Rust code formatter.
Unsafe code is forbidden. A key architectural rule.
The code-quality rule set. griff has a strict workspace-wide policy.
Rust crate for ergonomic error types.
Rust crate for CLI arguments.
Rust success/error type. All fallible operations return errors, not panic.
Rust optional-value type (e.g. optional articulation or track name).
A wrapper around a primitive: Pitch(u8), Ticks(u32). Provides type safety.
Test-Driven Development: red → green → refactor. Behavior tests first, code second.
A test fails because the feature is not implemented or a bug is confirmed.
A minimal implementation makes the test pass.
Improving structure without changing behavior.
A test that pins existing/legacy behavior. Required before refactoring.
A test against a reference file/output.
A test comparing output to a stored snapshot. Good for CLI output, debug dumps, normalized score dumps.
Like snapshot/golden: a human approves the reference result.
A test of a small function/module.
A test of several components together: import → model → export, CLI → output, GP file → score.
Testing properties over generated inputs (e.g. duration(a+b) == duration(a) + duration(b), roundtrip invariants).
Rust crate for property-based testing.
Rust crate for snapshot testing.
A fast test runner for a Rust workspace.
Mutation testing for Rust: checks whether tests catch injected bugs.
Test-quality check via small code mutations. If tests do not fail, they are weak.
Feeding many automatically generated inputs to a target to find panics,
hangs, unbounded allocation, or invalid internal models. In griff a
mandatory robustness/security layer for format adapters and selected core
transforms — never a correctness proof (ADR-0010, fuzzing.md).
A small entry point a fuzzer drives, with an oracle. In griff:
fuzz/fuzz_targets/*.rs (e.g. midi_import, midi_roundtrip).
The standard Rust fuzzing harness around libFuzzer. griff's chosen tool;
lives in the isolated nightly fuzz/ crate.
Rust bindings exposing the libFuzzer engine; the fuzz_target! macro crate.
Rust crate turning raw bytes into typed structures, for structure-aware
fuzzing (canonical Score, generation requests) rather than only raw bytes.
Fuzzing typed inputs (via arbitrary) instead of raw byte slices. Used for
score_projection, phrase_boundary, generation targets.
The committed input set for a target: fuzz/corpus/<target>/.
Hand-picked starting inputs (minimal valid files) that bootstrap a target.
Minimized crash/hang inputs committed permanently so a fixed bug stays
fixed. The first one is hang_ppqn1_eighth.mid (finding F-001).
The pass/fail contract for a target: no panic/hang/unbounded alloc, typed error xor success, plus target-specific normalized invariants.
Input that makes the target not return (infinite loop / pathological work).
Detected by libFuzzer -timeout. Distinct from a panic.
Input that drives unbounded memory growth (e.g. zip bomb, degenerate
loop). Bounded by libFuzzer -rss_limit_mb / -malloc_limit_mb.
Code coverage tool for Rust. Coverage ≠ test quality.
A file or object used by a test (minimal MIDI fixture, GP5 fixture, score JSON dump).
A minimal corpus slice for tests, not the full corpus.
A fast "the system starts and does not crash" test.
A test for a previously found bug.
A test of import → export → import, or format A → canonical → format A.
A property that must always hold (e.g. TickRange.start <= TickRange.end).
The source of truth for the expected result: snapshot, manual labelling, fixture, formal property.
A condition required to accept a PR: tests green, clippy green, format green, snapshots reviewed.
Instruction file for AI agents in the repo. Short, concrete, links to docs.
Agent instruction file for Claude-style tooling. May alias/bridge to
AGENTS.md.
The main project spec: what griff does, does not do, and which architectural
rules are mandatory.
Architecture Decision Record: a short doc fixing an important decision — context, decision, consequences.
A per-stage doc: goal, tasks, tests, acceptance criteria, risks.
A doc about the model, dataflow, boundaries, modules.
A doc describing the corpus annotation format.
An LLM-agent task with context, files to touch, constraints, tests to run, definition of done.
Task completion criteria. For griff: tests green, docs updated, loss report
considered, no hidden behavior changes.
When long instructions go stale and start to harm. Cured by short docs, ADRs, stage files.
The limited text an LLM can hold in a request. Hence a glossary, not an endless scroll.
The set of docs, glossary, ADRs, specs, and stage files an agent relies on.
Documentation linking terms, decisions, stages, and modules. Distinct from the runtime phrase graph.
Debt in code/architecture that speeds up now and slows down later.
Risk that the chosen model will not survive future use cases (e.g. linear
Event::Note/Rest vs polyphony/chords).
Risk that an external format stores data differently or richer than the internal model.
Loss of meaning during conversion (e.g. Guitar Pro palm mute → MIDI velocity is not full preservation).
Preserving old behavior/API while changing the architecture.
A plan to move from old to new model without a total rewrite.
A switch for experimental functionality (e.g. GP7/GP8 or SMPTE support).
A feature exists, but API/behavior stability is not promised.
A feature covered by tests, docs, fixtures, and acceptance criteria.
Fail quickly and explicitly on unsupported input instead of silently corrupting data.
Partial support with a warning/loss report when full support is impossible.
The ability to understand what happened: debug dumps, summaries, import warnings, loss reports.
A normalized text/JSON dump of the internal model for tests and analysis.
A dump without unstable details (absolute paths, random ids, map iteration order). Needed for snapshot tests.
Score,MasterBar,Track,Voice,EventGroup→griff-core, future canonical model.Pitch,Ticks,Velocity,Tempo,TimeSignature→ scalar musical types.MIDI,SMF,PPQN,Tempo map→ format adapter + transport.Guitar Pro,GP3/4/5,GPX,GPIF→ format adapter + source metadata.Phrase,Motif,RhythmCell→ analysis, corpus, generation.Boundary score,BoundaryReason→ phrase boundary detection.Feature extraction,Similarity,Playability→ analysis/generator/reranking.Candidate,Variation,Regeneration,Frozen region,Anchor→ generation workflows.Graph layer,Phrase graph,Motif graph→ S7+ recombination.Like/dislike,Preference profile→ S9 feedback layer.CLAP,NIH-plug,Host transport→ S10 plugin.TDD,Snapshot,Property test,Mutation testing→ development process.Fuzz testing,cargo-fuzz,Fuzz corpus,Fuzz oracle→ robustness/security layer (ADR-0010,fuzzing.md), isolatedfuzz/.ADR,SPEC.md,AGENTS.md→ documentation/process.
- Do not use
MIDIas the internal model. MIDI is an adapter boundary. - Do not treat
Event::Note/Restas the final guitar model. - Do not promise recovery of Guitar Pro articulations from plain MIDI without confidence/evidence.
- Do not add CLAP before the core model and format adapters are stable.
- Do not add neural generation before corpus, features, and a rule-based baseline.
- Every new format adapter must produce a loss report.
- Every refactor must start with characterization tests.
- Every new generation must be deterministic under a fixed seed.
- Every stage task must have tests, docs, and acceptance criteria.
- If a term is unclear, extend this glossary rather than spawning synonyms in code.
Use these as defaults until an ADR decides otherwise:
Score, MasterBar, Track, Voice, EventGroup, AtomEvent,
TechniqueSpan, SourceMeta, ImportWarning, LossReport, PhraseBoundary,
BoundaryReason, BoundaryScore, PhraseChunk, FeatureVector,
GenerationRequest, GenerationCandidate, GenerationSeed,
RegenerationRegion, FrozenRegion, AnchorPoint, PreferenceProfile,
Scored, ScoreAxes, ScoreWeights, Rationale (ADR-0017),
FretboardPosition, Tuning, NoteMark, SpanTechnique, TechniqueEvidence,
NoteId (ADR-0018).
Not a plan. A neural net does not replace the data model, corpus, tests, and generator.
Banned as self-soothing. If it "works fine", show tests, fixtures, and acceptance criteria.
A danger sign. Spikes/prototypes are allowed but must be marked as spikes and not dragged into production core without cleanup.
Dangerous term. Prefer MIDI expression evidence or inferred articulation from MIDI evidence.
Do not use "evidence" for a scoring rationale. "Evidence" is reserved for
import-side articulation provenance (why a technique is believed — MIDI / Guitar
Pro, §3 / §5). For "why this score" use rationale; for output metadata use
provenance (ADR-0017).
Always qualify: GP3/4/5, GPX/GP6, GP7/GP8, read-only or export, stable or experimental.
Always qualify: simultaneous notes, voices, chords, overlapping notes, let-ring, strum timing.
A glossary.md change is done if:
- the new term has a short definition;
- it states how the term is used in
griff; - if ambiguous, a warning is added;
- if it replaces an old name, the preferred name is stated;
- agent/stage docs do not use contradicting definitions.