FA-80966 / Music interval and transposition theory / Open access
Key signature size for a named tonic: minor key shifted sharpward · case 01
A minor reports three sharps and D minor two sharps instead of zero and one flat.
ROOT CAUSE
The relative-major offset for minor keys is applied three fifths sharpward instead of flatward.
VERIFIED REPAIR
Restore the relative minor direction step so that it reads `fifths -= 3`.
Unsuccessful approach: Applying the offset only to natural-letter tonics leaves C# minor and Eb minor at their parallel-major signatures.
Case contract
Input [tonic, mode] with tonic a letter optionally followed by one # or b, and mode major or minor. The signature is the letter position on the line of fifths (F -1, C 0, G 1, D 2, A 3, E 4, B 5) plus 7 per sharp and minus 7 per flat; minor keys use the relative major, three fifths flatward. Return the count (positive sharps, negative flats) or None if it lies outside -7..7 or the input is invalid.
Why this case matters
Pitch spelling and interval arithmetic decide the notes that notation, transposition and analysis tools display or play.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
base = {'F': -1, 'C': 0, 'G': 1, 'D': 2, 'A': 3, 'E': 4, 'B': 5}
if not isinstance(x, list) or len(x) != 2:
return None
tonic, mode = x
if mode not in ('major', 'minor'):
return None
if not isinstance(tonic, str) or not tonic or tonic[0] not in base:
return None
rest = tonic[1:]
if rest not in ('', '#', 'b'):
return None
acc = {'': 0, '#': 1, 'b': -1}[rest]
fifths = base[tonic[0]] + 7 * acc
if mode == 'minor':
fifths += 3
if fifths < -7 or fifths > 7:
return None
return fifths
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[(['C', 'major'], 0), (['G', 'major'], 1), (['F', 'major'], -1), (['F#', 'major'], 6), (['A', 'minor'], 0), (['D', 'minor'], -1), (['C#', 'minor'], 4), (['G#', 'minor'], 5)], [(['F#', 'major'], 6), (['Gb', 'major'], -6), (['C#', 'major'], 7), (['Cb', 'major'], -7), (['E', 'minor'], 1), (['C#', 'minor'], 4), (['Eb', 'minor'], -6), (['D#', 'minor'], 6)], [(['Cb', 'major'], -7), (['Db', 'major'], -5), (['B', 'major'], 5), (['D', 'minor'], -1), (['Eb', 'minor'], -6), (['Ab', 'minor'], -7), (['A#', 'minor'], 7), (['Fb', 'major'], None)], [(['C#', 'minor'], 4), (['Ab', 'minor'], -7), (['G#', 'minor'], 5), (['Fb', 'major'], None), (['B#', 'major'], None), (['Bb', 'minor'], -5), (['C', 'dorian'], None), (['C', 'Major'], None)], [(['Eb', 'minor'], -6), (['G#', 'minor'], 5), (['D#', 'minor'], 6), (['C', 'Major'], None), (['H', 'major'], None), (['Cx', 'major'], None), (['E#', 'major'], None), (['Gb', 'minor'], None)]]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("oracle %d" % i, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| oracle 0 | 0 | 0 | Passed |
| oracle 1 | 1 | 1 | Passed |
| oracle 2 | -1 | -1 | Passed |
| oracle 3 | 6 | 6 | Passed |
| oracle 4 | 6 | 0 | Failed |
| oracle 5 | 5 | -1 | Failed |
| oracle 6 | None | 4 | Failed |
| oracle 7 | None | 5 | Failed |
SHA-256 / 90582b2c3d0c73261c77e6effcc04ebbca81792210ef796427d317154f832358
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
base = {'F': -1, 'C': 0, 'G': 1, 'D': 2, 'A': 3, 'E': 4, 'B': 5}
if not isinstance(x, list) or len(x) != 2:
return None
tonic, mode = x
if mode not in ('major', 'minor'):
return None
if not isinstance(tonic, str) or not tonic or tonic[0] not in base:
return None
rest = tonic[1:]
if rest not in ('', '#', 'b'):
return None
acc = {'': 0, '#': 1, 'b': -1}[rest]
fifths = base[tonic[0]] + 7 * acc
if mode == 'minor':
fifths -= 3 if acc == 0 else 0
if fifths < -7 or fifths > 7:
return None
return fifths
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[(['C', 'major'], 0), (['G', 'major'], 1), (['F', 'major'], -1), (['F#', 'major'], 6), (['A', 'minor'], 0), (['D', 'minor'], -1), (['C#', 'minor'], 4), (['G#', 'minor'], 5)], [(['F#', 'major'], 6), (['Gb', 'major'], -6), (['C#', 'major'], 7), (['Cb', 'major'], -7), (['E', 'minor'], 1), (['C#', 'minor'], 4), (['Eb', 'minor'], -6), (['D#', 'minor'], 6)], [(['Cb', 'major'], -7), (['Db', 'major'], -5), (['B', 'major'], 5), (['D', 'minor'], -1), (['Eb', 'minor'], -6), (['Ab', 'minor'], -7), (['A#', 'minor'], 7), (['Fb', 'major'], None)], [(['C#', 'minor'], 4), (['Ab', 'minor'], -7), (['G#', 'minor'], 5), (['Fb', 'major'], None), (['B#', 'major'], None), (['Bb', 'minor'], -5), (['C', 'dorian'], None), (['C', 'Major'], None)], [(['Eb', 'minor'], -6), (['G#', 'minor'], 5), (['D#', 'minor'], 6), (['C', 'Major'], None), (['H', 'major'], None), (['Cx', 'major'], None), (['E#', 'major'], None), (['Gb', 'minor'], None)]]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("oracle %d" % i, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| oracle 0 | 0 | 0 | Passed |
| oracle 1 | 1 | 1 | Passed |
| oracle 2 | -1 | -1 | Passed |
| oracle 3 | 6 | 6 | Passed |
| oracle 4 | 0 | 0 | Passed |
| oracle 5 | -1 | -1 | Passed |
| oracle 6 | 7 | 4 | Failed |
| oracle 7 | None | 5 | Failed |
SHA-256 / 9bcc1e1fa4c6253858edf492729d27323be51c94283abdfdb9eb48190d4433cc
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
base = {'F': -1, 'C': 0, 'G': 1, 'D': 2, 'A': 3, 'E': 4, 'B': 5}
if not isinstance(x, list) or len(x) != 2:
return None
tonic, mode = x
if mode not in ('major', 'minor'):
return None
if not isinstance(tonic, str) or not tonic or tonic[0] not in base:
return None
rest = tonic[1:]
if rest not in ('', '#', 'b'):
return None
acc = {'': 0, '#': 1, 'b': -1}[rest]
fifths = base[tonic[0]] + 7 * acc
if mode == 'minor':
fifths -= 3
if fifths < -7 or fifths > 7:
return None
return fifths
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[(['C', 'major'], 0), (['G', 'major'], 1), (['F', 'major'], -1), (['F#', 'major'], 6), (['A', 'minor'], 0), (['D', 'minor'], -1), (['C#', 'minor'], 4), (['G#', 'minor'], 5)], [(['F#', 'major'], 6), (['Gb', 'major'], -6), (['C#', 'major'], 7), (['Cb', 'major'], -7), (['E', 'minor'], 1), (['C#', 'minor'], 4), (['Eb', 'minor'], -6), (['D#', 'minor'], 6)], [(['Cb', 'major'], -7), (['Db', 'major'], -5), (['B', 'major'], 5), (['D', 'minor'], -1), (['Eb', 'minor'], -6), (['Ab', 'minor'], -7), (['A#', 'minor'], 7), (['Fb', 'major'], None)], [(['C#', 'minor'], 4), (['Ab', 'minor'], -7), (['G#', 'minor'], 5), (['Fb', 'major'], None), (['B#', 'major'], None), (['Bb', 'minor'], -5), (['C', 'dorian'], None), (['C', 'Major'], None)], [(['Eb', 'minor'], -6), (['G#', 'minor'], 5), (['D#', 'minor'], 6), (['C', 'Major'], None), (['H', 'major'], None), (['Cx', 'major'], None), (['E#', 'major'], None), (['Gb', 'minor'], None)]]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("oracle %d" % i, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| oracle 0 | 0 | 0 | Passed |
| oracle 1 | 1 | 1 | Passed |
| oracle 2 | -1 | -1 | Passed |
| oracle 3 | 6 | 6 | Passed |
| oracle 4 | 0 | 0 | Passed |
| oracle 5 | -1 | -1 | Passed |
| oracle 6 | 4 | 4 | Passed |
| oracle 7 | 5 | 5 | Passed |
SHA-256 / 8055cffd85afb650ed2e87443c2178dc2e84fff49c0459056f3586d424554051
Verification & scope
A deterministic bounded teaching model with a stipulated toy contract; it is not a complete music notation or theory engine. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.
Observations recorded using Python 3.12.14 at 2026-09-29T14:49:58.653076+00:00.
Case digest / 85d971a811c30b57ca48c0817a93126569ffe9208d47f336062cfb32a980e5e5