Skip to content
12 changes: 10 additions & 2 deletions docs/audit/2026-05-stage-label-reconciliation.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@ forward.
transport refactor · `S3` Guitar Pro import · `S4` phrase boundary detection ·
`S5` corpus + schema · `S6` rule generator v0 · `S7` graph layer · `S8`
preview app · `S9` feedback layer · `S10` CLAP MVP · `S11` region
regeneration · `S12` neural assistance.
regeneration · `S12` neural assistance · `S13` complementary part generation ·
`S14` structure controls and metrics · `S15` tonal context and harmonic control.

S13 and later stages are append-only additions. Their logical dependency order
may place them beside or before an earlier-numbered future stage; existing stage
numbers are never repurposed or renumbered to make the list look prettier.

## Mislabel mapping

Expand All @@ -43,14 +48,17 @@ baseline**. It is the input to:

## Rules from here

1. New commits use canonical `S0…S12` numbering per the glossary only.
1. New commits use canonical stage numbers per the glossary and this roadmap.
2. A stage is "closed" only when its acceptance criterion (its stage doc) is
met, tested, and documented.
3. Earlier mislabeled work is **not** re-closed under its old number; relevant
pieces are re-credited to their true stage in the stage docs' "See also".
4. New cross-cutting stages take the next free number. Existing S-numbers are
never reassigned, even when the logical execution order differs.

## See also

- [`../glossary.md`](../glossary.md) §0, §17
- [`../SPEC.md`](../SPEC.md)
- [`../stages/S0-baseline-and-tests.md`](../stages/S0-baseline-and-tests.md)
- [`../stages/S15-tonal-context-and-harmonic-control.md`](../stages/S15-tonal-context-and-harmonic-control.md)
238 changes: 238 additions & 0 deletions docs/audit/2026-07-symbolic-harmony-and-evolution-research.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
# Research: symbolic harmony, global paths, and interactive evolution (2026-07)

Status: accepted as roadmap input; no dependency adoption
Decision: map the useful ideas onto S7/S8/S9/S12/S15 rather than create a
repository-per-stage roadmap

## Executive verdict

The strongest common pattern is:

```text
enumerate feasible local possibilities
→ assign explainable local / transition costs
→ optimise globally
→ return diverse top-k paths
→ let the human choose
→ retain feedback and lineage
```

The responsibilities are intentionally split:

- **S15** defines tonal/harmonic meaning and uncertainty;
- **S7** optimises multi-step paths;
- **S8** displays alternatives and provenance;
- **S9** captures selection and experiments with structural evolution;
- **S12** remains the owner of future neural assistance.

No reviewed repository is adopted as a production dependency by this decision.

## Source assessment

| Source | Value now | Later | What to take | Owner |
|---|---:|---:|---|---|
| [`ekzhang/harmony`](https://github.com/ekzhang/harmony) | 8/10 | 8/10 | layered DP, transition costs, path reconstruction | S7 |
| [`napulen/romanyh`](https://github.com/napulen/romanyh) | 8/10 | 9/10 | alternative harmonisations, k-best global paths, RomanText fixtures | S7 + S15 |
| [`napulen/AugmentedNet`](https://github.com/napulen/AugmentedNet) | 4/10 | 9/10 | decomposed harmonic targets, uncertainty, synthetic labelled examples | S15 + S12 radar |
| [`perfect-shuffle-music`](https://github.com/kroger66/perfect-shuffle-music) | 6/10 concept | 7/10 | human-in-the-loop generations, crossover concept, lineage | S9, surfaced by S8 |
| [`napulen/harmalysis`](https://github.com/napulen/harmalysis) | 4/10 | 7/10 | external harmonic fixture DSL inspiration | S15 |
| [`ekzhang/composing.studio`](https://github.com/ekzhang/composing.studio) | 3/10 | 6/10 | textual playground, live preview/playback, inspectable edits | S8 |
| [`ekzhang/crepe`](https://github.com/ekzhang/crepe) | 5/10 | 6/10 | possible declarative rule engine when rule closure/explanations justify it | S7/S15 radar |

The ratings describe architectural relevance to `griff`, not general project
quality.

## 1. `ekzhang/harmony`: global path shape

The useful lesson is not classical four-part harmony itself. It is the layered
optimisation shape:

1. enumerate valid states for each musical position;
2. calculate local and adjacent-state costs;
3. use dynamic programming to select a globally coherent path;
4. reconstruct the selected path with an inspectable total cost.

This is directly relevant to S7's multi-bar candidate chain. Potential Griff
transition terms include:

- phrase / contour continuity;
- register continuity;
- rhythm continuity or complement;
- repeated-technique penalties;
- playability / fret travel;
- harmonic fit supplied by S15;
- repetition and mud penalties.

Do **not** copy SATB-specific prohibitions or doubling/resolution rules as
swancore policy. Transfer the algorithmic form; make costs Griff-specific and
explainable.

The earlier idea of making a new generic `RegisterPlanner` the first client is
superseded: the register track is already accepted and closed after generator
semantics were repaired. Reopen register planning only when a new measured
multi-bar problem justifies it.

## 2. `napulen/romanyh`: k-best paths

The important extension is returning several ranked global alternatives rather
than one optimum. For Griff this supports:

- globally coherent alternatives without seed-only noise;
- several complementary-guitar trajectories;
- controlled register/harmonic alternatives;
- human selection feeding S9;
- explicit diversity constraints and fixed tie-breaking.

S7 should first extract a concrete layered-path contract from a real multi-bar
client, then add deterministic k-best enumeration. Avoid a universal
`MusicDPGodObject`; specialised state/cost modules share only the small engine.

## 3. Nápoles ecosystem: harmonic decomposition and fixtures

### `AugmentedNet`

Do not introduce its Python/TensorFlow/MusicXML runtime into Griff. Useful ideas:

- decompose harmonic analysis into tonal centre, mode, chord root, quality,
inversion, and related targets;
- expose distributions/alternatives rather than one unquestioned label;
- create labelled synthetic examples and vary their texture.

S15 should grow incrementally from its accepted tonic/mode estimate. Full Roman
numeral analysis is not the next task.

### `harmalysis` and RomanText

Use a small text language only as an external fixture/debugging surface:

```text
C: I | vi | IV | V
C: I | V/V | V | I
a: i | VI | III | VII
```

Core representation stays typed. The fixture pipeline can generate
transpositions, omissions, inversions, passing tones, pedal textures, and
modulations with known labels for calibration tests.

### Audio key detection

Audio chroma/HMM approaches are deferred. Griff currently receives symbolic
MIDI/Guitar Pro evidence; rendering it to audio/chroma and guessing the lost
symbolic information back would be an avoidable information-loss loop. Revisit
only with a real audio-input stage.

## 4. `perfect-shuffle-music`: concept, not code

The implementation is too note-array-centric for Griff. Do not port its genome
or crossover code.

The useful experiment is structural evolution over Griff objects:

```text
candidate set
→ human selects parents
→ bar/motif/parameter crossover
→ mutation
→ normalisation and validators
→ existing rerank as a safety/quality guard
→ next generation
```

Candidate operators for an S9 experiment:

```rust
pub enum EvolutionOperator {
AlternateBars,
AlternateMotifs,
RhythmFromAContourFromB,
PrefixSuffixCrossover,
ParameterBlend,
}
```

Lineage must record parents, operator, mutations, generation, and session. Track
population collapse, strategy diversity, operator survival, and repeated-parent
dominance. This remains an **Evolution Lab** experiment under S9; create a new
stage only if it later becomes a standalone persistent workflow.

## 5. `composing.studio`: S8 playground direction

The transferable UI idea is editable text plus immediate visual/audio feedback.
A Griff playground should expose:

- textual request / constraints / future harmonic fixture input;
- piano roll / tab / playback;
- candidate list and score axes;
- register, novelty, playability, and tonal diagnostics;
- path and transition explanations;
- like/dislike/favourite controls;
- parent/child lineage for the Evolution Lab.

S8 supplies the surface; it does not own tonal inference, path optimisation, or
preference semantics.

## 6. `crepe`: parked implementation option

A Datalog-like rule engine may become useful when Griff has all of:

- many independently maintained rules;
- recursive graph closure;
- a need to explain derivations;
- frequent rule additions that make imperative orchestration brittle.

Until then, typed Rust remains simpler. A pleasant macro is not evidence that the
generator needs an expert-system runtime.

## Roadmap mapping

### S7 — graph layer

- concrete layered-path contract from the first multi-bar client;
- global candidate-chain DP/Viterbi;
- deterministic k-best diverse paths;
- later harmonic/complement/cadence clients using S15 states.

### S8 — preview app / cockpit

- textual playground;
- candidate, tonal, path, and lineage inspectors;
- UI for S9 feedback/evolution experiments.

### S9 — human feedback

- feedback capture and preference reranking first;
- Evolution Lab second;
- diversity/collapse controls before productisation.

### S12 — neural assistance

- AugmentedNet/MiniBach remain decomposition and synthetic-data research inputs;
- no runtime model before the existing corpus, baseline, and feedback gates.

### S15 — tonal context and harmonic control

- Phase 0 evidence audit: accepted/closed;
- Phase 1 shared tonal core: accepted/closed;
- Phase 2 explicit scoped context: next;
- later calibration, fixture DSL, soft harmonic generation, local context and
cadence.

## Immediate actions

1. Maintain S15 as the owner of tonal meaning and confidence.
2. Implement S15 Phase 2 without changing generated output.
3. Write the S7 layered-path design against a concrete multi-bar candidate-chain
client before extracting a generic engine.
4. Add harmonic synthetic-fixture planning to S15 Phase 3/4.
5. Add Evolution Lab to the S9 backlog, not the production API.
6. Add the textual/candidate/tonal/lineage playground to the S8 backlog.

## Explicit non-decisions

- no automatic highest-margin track selection;
- no hard inferred-scale pitch whitelist;
- no generic register planner without new evidence;
- no classical harmony rule transplant;
- no neural or Datalog dependency;
- no new Evolution stage yet.
21 changes: 21 additions & 0 deletions docs/stages/S12-neural-assistance.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,38 @@ from scratch".
- Models suited to fixed-region control / infilling (e.g. anticipatory /
masked-LM style on MIDI tokens).
- Inference in Rust via `candle` or ONNX (`ort`); training offline.
- Harmonic-analysis research such as AugmentedNet is useful for **task
decomposition** (tonal centre, mode, chord root, quality, inversion) and
synthetic labelled examples, not as a Phase-1 runtime dependency.
- Symbolic generation projects such as MiniBach remain research references only;
they do not replace the S6/S7 deterministic baseline or S15 calibrated tonal
context.

## Preconditions (hard gate)

- Corpus ≥ ~100 phrases; working S6 baseline; S9 feedback integration.
- Not started before all three hold (glossary §17.5).
- Any harmonic neural proposal must also compare against the accepted S15
symbolic estimator/fixtures and preserve uncertainty/abstention rather than
emit one unquestioned label.
Comment on lines 32 to +38

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Make the S15 prerequisite explicit.

S15’s labelled controls and harmonic fixture DSL are future Phase 3/4 work, but this hard gate requires “accepted S15 ... fixtures” without adding the required S15 phase to S12’s prerequisites. Require the relevant S15 phases explicitly, or distinguish the currently available estimator from future fixtures.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/stages/S12-neural-assistance.md` around lines 32 - 38, The S12
preconditions reference accepted S15 fixtures without explicitly requiring the
S15 work that produces them. Update the Preconditions hard gate to name the
required S15 phases for the labelled controls and harmonic fixture DSL, or
clearly distinguish the currently available S15 estimator from future fixtures
while preserving the comparison and uncertainty/abstention requirements.


## Acceptance criteria

- Neural suggestions beat S6/S7 on the quality score in a blind comparison.
- Deterministic given a fixed seed and model checkpoint.
- Harmonic assistance, when attempted, beats or complements the S15 symbolic
baseline on a labelled test set and reports calibrated uncertainty.
Comment on lines 40 to +45

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Make harmonic acceptance measurable.

“Beats or complements” the S15 baseline is not a testable acceptance criterion. Define the labelled evaluation set, comparison metrics, calibration target, and what qualifies as a complementary result.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/stages/S12-neural-assistance.md` around lines 40 - 45, Make the harmonic
assistance criterion in the Acceptance criteria section measurable by specifying
the labelled evaluation-set scope, baseline comparison metrics,
calibrated-uncertainty target, and explicit thresholds or conditions for both
beating and complementing the S15 symbolic baseline.


## Non-goals

- No Python/TensorFlow/MusicXML service in the core runtime merely because a
research implementation uses that stack.
- No rendering symbolic input to audio/chroma and guessing its lost semantics
back while native symbolic evidence is available.

## See also

- [`../audit/2026-07-symbolic-harmony-and-evolution-research.md`](../audit/2026-07-symbolic-harmony-and-evolution-research.md)
- [`S9-feedback-layer.md`](S9-feedback-layer.md)
- [`S15-tonal-context-and-harmonic-control.md`](S15-tonal-context-and-harmonic-control.md)
- [`../glossary.md`](../glossary.md) §8, §17.5
14 changes: 12 additions & 2 deletions docs/stages/S13-complementary-part-generation.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ ADRs: ADR-0012, ADR-0011
> `ConstrainedRandomWalk` line over a request derived from A; typed
> `NonUniformTimeline` on mid-score meter changes). `ModeNotImplemented` is
> gone — every `RelationMode` arranges.
>
> Ownership update (2026-07): the original private winner-only key estimate was
> generalised into the accepted shared `core::tonal` layer. S13 keeps the
> backwards-compatible `PartProfile::harmony` projection and complement-specific
> use of it; **S15** owns scoped tonal evidence, uncertainty, calibration,
> harmonic fixtures, and future soft harmonic/cadence policy. **S7** owns any
> later multi-bar global optimisation or k-best complementary trajectories.

## Remaining work (follow-up increments)

Expand All @@ -42,7 +49,8 @@ ADRs: ADR-0012, ADR-0011
`PartProfile::harmony` (tonic, major/natural minor, `scale_fit` as a
fact); B's substitution material becomes A's literal pitch classes
*plus* the inferred key's scale, so a sparse part no longer collapses
B onto one pitch per band (2026-06-11).
B onto one pitch per band (2026-06-11). The estimator now delegates to
S15's shared `core::tonal` implementation.

> Roadmap note: appended as the next free stage number (append-only, per the
> stage-label audit). Logically it sits between the single-part generator (S6)
Expand Down Expand Up @@ -103,14 +111,16 @@ Generative-first: B is derived from A by rule; no corpus pair mining. `ChunkMeta
## Open questions

- Harmonic-compatibility thresholds (allowed coincident intervals) — calibrate
on the corpus.
on the corpus and S15 labelled fixtures.
- Default per-axis ratios (e.g. support-layer density factor) before S9 feedback
exists to tune them.
- Where the part profile lives: extend the feature layer vs a dedicated
`PartProfile` type in the canonical model.

## See also

- [`S15-tonal-context-and-harmonic-control.md`](S15-tonal-context-and-harmonic-control.md)
- [`../audit/2026-07-symbolic-harmony-and-evolution-research.md`](../audit/2026-07-symbolic-harmony-and-evolution-research.md)
- [`../glossary.md`](../glossary.md) §8 (Complementary part, Complement relation,
Relation mode), §9 (Complement hyperedge), §10 (Relation preference)
- [`../adr/0012-complementary-part-generation.md`](../adr/0012-complementary-part-generation.md)
Expand Down
Loading