Skip to content

Add VariationControl: deterministic pitch-spread knob for grid-locked… - #64

Merged
PhysShell merged 4 commits into
mainfrom
claude/modest-maxwell-0zecwn
Jun 16, 2026
Merged

Add VariationControl: deterministic pitch-spread knob for grid-locked…#64
PhysShell merged 4 commits into
mainfrom
claude/modest-maxwell-0zecwn

Conversation

@PhysShell

@PhysShell PhysShell commented Jun 16, 2026

Copy link
Copy Markdown
Owner

… complements

ADR-0023 records the decision: a pitch-variability ask orthogonal to RelationMode, the GestureControl/StructureControl duality (ADR-0012/0015), compiled over the arranger as a separate entry point — never a ComplementSpec change (35 construction sites) — and shaping pitch only, so a grid-locked mode stays grid-locked (rhythm_similarity stays 1.0).

First axis pitch_spread in [0,1] windows the band's scale ladder: 0 pins B to the band's anchor degree (a static line on A's grid), 1 uses the whole band — the identity window, so arrange_complement stays byte-identical and the corpus / goldens / CLI snapshots are unaffected. arrange_complement_varied returns a VariedComplement carrying the control (ask) and B's realised ambitus fraction (is); out-of-range is the typed VariationError::InvalidControl. Deterministic (SPEC §6): the window only narrows the existing seeded pitch hash, no new RNG.

Applies to the ladder-substitution modes (rhythm_lock, register_contrast, call_response). Red→green tests pin identity at full spread, single-pitch collapse at zero, determinism, the typed rejection, and ask-vs-is provenance.

https://claude.ai/code/session_01TTUbGjzD8ysnVnCJnZJE95

Summary by CodeRabbit

  • New Features
    • Added VariationControl to tune pitch spread for complementary-part generation in grid-locked ladder-substitution modes.
    • Introduced a new varied-complement entry point returning provenance, including realized_spread.
  • Bug Fixes
    • Improved validation of pitch_spread, returning a typed error for invalid (out-of-range/NaN/∞) values.
  • Documentation
    • Added an ADR documenting pitch-only behavior, determinism guarantees, and error semantics.
  • Tests
    • Expanded coverage for varied pitch spread, determinism, and provenance behavior.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 2640d4b3-4e90-4d3c-8bd6-933b082af64b

📥 Commits

Reviewing files that changed from the base of the PR and between 69cfb33 and 0703d25.

📒 Files selected for processing (2)
  • core/tests/complement.rs
  • docs/adr/0023-variation-control-for-complement.md
✅ Files skipped from review due to trivial changes (1)
  • docs/adr/0023-variation-control-for-complement.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • core/tests/complement.rs

📝 Walkthrough

Walkthrough

Adds a VariationControl struct with a pitch_spread field ([0.0, 1.0]) to the complement generation system. A new arrange_complement_varied entry point validates the control and returns a VariedComplement with provenance. A spread_window helper narrows the ladder pitch window for RhythmLock, RegisterContrast, and CallResponse modes. Tests and ADR-0023 document the design.

Changes

Pitch Variability Control for Complement Generation

Layer / File(s) Summary
Public API types: VariationControl, VariedComplement, VariationError
core/src/complement.rs
Defines VariationControl { pitch_spread: f64 } with FULL/LOCKED constants and is_valid, VariedComplement carrying complement + control + realized spread, and VariationError wrapping InvalidControl or a forwarded ComplementError.
Entry points: arrange_complement_varied, inner arranger, realized_band_spread
core/src/complement.rs
arrange_complement_varied validates VariationControl, delegates to a shared inner arranger, and wraps the result in VariedComplement via realized_band_spread; existing arrange_complement now delegates to the same inner arranger with VariationControl::FULL.
Ladder mode wiring: spread_window, grid_locked_groups, RhythmLock, RegisterContrast, CallResponse
core/src/complement.rs
Adds spread_window to map pitch_spread onto a bounded ladder index window; updates grid_locked_groups, arrange_rhythm_lock, arrange_register_contrast, and arrange_call_response to accept VariationControl and use the narrowed window for deterministic pitch-degree selection.
Variation control tests
core/tests/complement.rs
Adds S13 tests covering: FULL reproduces plain arrange_complement output, LOCKED collapses B to one pitch while preserving onsets, determinism for fixed seed, rejection of invalid pitch_spread values (out-of-range, NaN, ±∞), and provenance (realized_spread non-zero for FULL, zero for LOCKED).
ADR-0023 documentation
docs/adr/0023-variation-control-for-complement.md, docs/adr/README.md
Documents the VariationControl design contract, mode applicability, provenance/error semantics, byte-identical default behavior, and follow-up CLI ideas; adds ADR-0023 to the index.

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant arrange_complement_varied
  participant inner_arranger
  participant spread_window
  participant grid_locked_groups
  participant realized_band_spread

  Caller->>arrange_complement_varied: score, spec, seed, VariationControl{pitch_spread}
  arrange_complement_varied->>arrange_complement_varied: is_valid(control)
  arrange_complement_varied->>inner_arranger: control (threaded)
  inner_arranger->>spread_window: pitch_spread + ladder_len
  spread_window-->>inner_arranger: window_size
  inner_arranger->>grid_locked_groups: window_size for pitch_index modulo
  grid_locked_groups-->>inner_arranger: ComplementCandidate
  inner_arranger-->>arrange_complement_varied: ComplementCandidate
  arrange_complement_varied->>realized_band_spread: B track + register band
  realized_band_spread-->>arrange_complement_varied: f64 spread fraction
  arrange_complement_varied-->>Caller: VariedComplement{complement, control, realized_spread}
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • PhysShell/griff#63: Modifies the same pitch-selection paths in core/src/complement.rsgrid_locked_groups and arrange_call_response gap/answer mapping—switching toward ladder-based degree indexing that this PR further narrows via spread_window and VariationControl.

Poem

🐇 A spread from zero to one,
The pitches now play or stay still,
Grid-locked rhythms never run,
But tones may wander as you will.
LOCKED hums one note with glee,
FULL lets the ladder roam free! 🎵

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically identifies the main change: introducing a VariationControl feature that provides a deterministic pitch-spread knob for grid-locked complement arrangements.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/modest-maxwell-0zecwn

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with 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.

Inline comments:
In `@core/src/complement.rs`:
- Around line 89-134: The public API additions (VariationControl,
VariedComplement, VariationError structs/enums and arrange_complement_varied
function) were committed together with their test coverage, violating the
requirement to commit tests before implementation. Reorganize the commit history
by first creating a commit containing only the test functions for variation
control in core/tests/complement.rs (tests like
variation_full_spread_equals_plain_arrange,
variation_zero_spread_collapses_b_to_a_single_pitch, etc.), then create a second
separate commit with the public API implementation in core/src/complement.rs
containing the VariationControl struct, VariedComplement struct, VariationError
enum, and the arrange_complement_varied function.

In `@core/tests/complement.rs`:
- Around line 341-355: The test variation_rejects_out_of_range_control checks
for positive infinity (f64::INFINITY) in the invalid control rejection matrix
but does not check for negative infinity, which contradicts the contract
requirement to reject ±∞. Add f64::NEG_INFINITY to the array of bad values in
the for loop alongside the existing test cases (1.5_f64, -0.1, f64::NAN, and
f64::INFINITY).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f0a098cf-cfd2-40e3-a6f8-d88d4ce0b9d1

📥 Commits

Reviewing files that changed from the base of the PR and between 33f2595 and 386f57d.

📒 Files selected for processing (4)
  • core/src/complement.rs
  • core/tests/complement.rs
  • docs/adr/0023-variation-control-for-complement.md
  • docs/adr/README.md

Comment thread core/src/complement.rs
Comment on lines +89 to +134
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct VariationControl {
/// Fraction of the band's scale ladder B may use, `0.0..=1.0`. `0.0` pins
/// every note to the band's anchor degree (a static line, still locked to
/// A's grid); `1.0` uses the whole band — the unconstrained default that
/// matches [`arrange_complement`].
pub pitch_spread: f64,
}

impl VariationControl {
/// The identity control: the whole band, i.e. [`arrange_complement`]'s
/// behaviour.
pub const FULL: Self = Self { pitch_spread: 1.0 };
/// A static line: B collapses onto the band's anchor degree.
pub const LOCKED: Self = Self { pitch_spread: 0.0 };

/// Whether the control is in range: a finite `pitch_spread` within
/// `0.0..=1.0`.
#[must_use]
pub fn is_valid(self) -> bool {
self.pitch_spread.is_finite() && (0.0..=1.0).contains(&self.pitch_spread)
}
}

/// A varied complement: the arranged candidate plus provenance — the control
/// that asked for it (ask) and B's realised pitch spread (is).
#[derive(Debug, Clone)]
pub struct VariedComplement {
/// The arranged candidate (A's score with B appended).
pub complement: ComplementCandidate,
/// The control this candidate was arranged against.
pub control: VariationControl,
/// B's realised pitch ambitus as a fraction of the target band,
/// `0.0..=1.0` — what the spread actually *is*, not what was asked.
pub realized_spread: f64,
}

/// Errors the varied arrangement entry point can emit.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum VariationError {
/// The [`VariationControl`] is out of range (non-finite or outside
/// `0.0..=1.0`).
InvalidControl,
/// The underlying arrangement failed.
Arrange(ComplementError),
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Commits touching implementation/tests =="
git log --reverse --format='%h %ad %s' --date=short -- core/src/complement.rs core/tests/complement.rs

echo
echo "== Commits that introduce new public variation API in core/src/complement.rs =="
for c in $(git rev-list --reverse HEAD -- core/src/complement.rs); do
  if git show --pretty='' --unified=0 "$c" -- core/src/complement.rs | \
    rg -n '^\+pub (struct VariationControl|struct VariedComplement|enum VariationError|fn arrange_complement_varied)'; then
    echo "api_commit=$c"
  fi
done

echo
echo "== Commits that add variation-control tests in core/tests/complement.rs =="
for c in $(git rev-list --reverse HEAD -- core/tests/complement.rs); do
  if git show --pretty='' --unified=0 "$c" -- core/tests/complement.rs | \
    rg -n '^\+fn variation_|VariationControl::(FULL|LOCKED)|arrange_complement_varied|VariationError::InvalidControl'; then
    echo "test_commit=$c"
  fi
done

Repository: PhysShell/griff

Length of output: 1843


Public API implementation and tests must be in separate commits.

The new VariationControl struct, VariedComplement struct, VariationError enum, and arrange_complement_varied function were introduced in the same commit (386f57d) as their test coverage. Per coding guidelines, public API implementation must never be committed together with tests that cover it. Tests should be committed first (TDD red phase), followed by implementation commits (green/refactor phases) in separate commits.

Please reorganize the commit history:

  1. Commit 1: Add test functions for variation control (variation_full_spread_equals_plain_arrange, variation_zero_spread_collapses_b_to_a_single_pitch, etc.) in core/tests/complement.rs only
  2. Commit 2: Implement the public API additions in core/src/complement.rs
🤖 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 `@core/src/complement.rs` around lines 89 - 134, The public API additions
(VariationControl, VariedComplement, VariationError structs/enums and
arrange_complement_varied function) were committed together with their test
coverage, violating the requirement to commit tests before implementation.
Reorganize the commit history by first creating a commit containing only the
test functions for variation control in core/tests/complement.rs (tests like
variation_full_spread_equals_plain_arrange,
variation_zero_spread_collapses_b_to_a_single_pitch, etc.), then create a second
separate commit with the public API implementation in core/src/complement.rs
containing the VariationControl struct, VariedComplement struct, VariationError
enum, and the arrange_complement_varied function.

Source: Coding guidelines

Comment thread core/tests/complement.rs
claude added 2 commits June 16, 2026 16:15
Pin the ADR-0023 ask — arrange_complement_varied, VariationControl,
VariationError — before the implementation exists. The suite references symbols
that aren't defined yet, so it fails to compile: the red step.

https://claude.ai/code/session_01TTUbGjzD8ysnVnCJnZJE95
ADR-0023 records the decision: a pitch-variability *ask* orthogonal to
RelationMode, the GestureControl/StructureControl duality (ADR-0012/0015),
compiled over the arranger as a separate entry point — never a ComplementSpec
change (35 construction sites) — and shaping pitch only, so a grid-locked mode
stays grid-locked (rhythm_similarity stays 1.0).

First axis `pitch_spread` in [0,1] windows the band's scale ladder: 0 pins B to
the band's anchor degree (a static line on A's grid), 1 uses the whole band —
the identity window, so `arrange_complement` stays byte-identical and the
corpus / goldens / CLI snapshots are unaffected. `arrange_complement_varied`
returns a `VariedComplement` carrying the control (ask) and B's realised ambitus
fraction (is); out-of-range is the typed `VariationError::InvalidControl`.
Deterministic (SPEC §6): the window only narrows the existing seeded pitch hash.

Applies to the ladder-substitution modes (rhythm_lock, register_contrast,
call_response). Tests (committed first, red) pin identity at full spread,
single-pitch collapse at zero, determinism, the typed rejection, and ask-vs-is
provenance.

https://claude.ai/code/session_01TTUbGjzD8ysnVnCJnZJE95
@PhysShell
PhysShell force-pushed the claude/modest-maxwell-0zecwn branch from 386f57d to 69cfb33 Compare June 16, 2026 16:16
`is_valid()` rejects ±∞ via `is_finite()`; the rejection test only exercised
`+∞`. Add `f64::NEG_INFINITY` to the invalid-input matrix (CodeRabbit #64).

https://claude.ai/code/session_01TTUbGjzD8ysnVnCJnZJE95

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
docs/adr/0023-variation-control-for-complement.md (1)

68-68: ⚡ Quick win

Standardize spelling: "realised" → "realized" to match the struct field identifier.

Line 68 uses "realised" (British variant), but the struct field identifier and surrounding text use "realized" (American). For consistency with code identifiers and document conventions, change the prose to match.

📝 Proposed fix
   `VariedComplement { complement, control,
-  realized_spread }` carries the control that asked and B's realised pitch
+  realized_spread }` carries the control that asked and B's realized pitch
   ambitus as a fraction of the target band — the `GesturedCandidate` duality.
🤖 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/adr/0023-variation-control-for-complement.md` at line 68, Change the
spelling of "realised" to "realized" in the prose where it appears alongside the
struct field identifier. The struct field uses the American spelling variant
"realized_spread", so update all instances of "realised" in the surrounding text
to match this convention for consistency throughout the document.
🤖 Prompt for all review comments with 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.

Nitpick comments:
In `@docs/adr/0023-variation-control-for-complement.md`:
- Line 68: Change the spelling of "realised" to "realized" in the prose where it
appears alongside the struct field identifier. The struct field uses the
American spelling variant "realized_spread", so update all instances of
"realised" in the surrounding text to match this convention for consistency
throughout the document.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 69a78fc8-3137-4bac-8af1-73677635cabd

📥 Commits

Reviewing files that changed from the base of the PR and between 386f57d and 69cfb33.

📒 Files selected for processing (4)
  • core/src/complement.rs
  • core/tests/complement.rs
  • docs/adr/0023-variation-control-for-complement.md
  • docs/adr/README.md
✅ Files skipped from review due to trivial changes (1)
  • docs/adr/README.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • core/tests/complement.rs
  • core/src/complement.rs

CodeRabbit nitpick #64: the prose used the British "realised" next to the
American `realized_spread` identifier.

https://claude.ai/code/session_01TTUbGjzD8ysnVnCJnZJE95
@PhysShell
PhysShell merged commit c1178d4 into main Jun 16, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants