{"abstract":"D dorian is spelled with F# and C# because the step pattern is rotated right, yielding the locrian-side pattern order.","category":"Music interval and transposition theory","checks":8,"contract":"Input [tonic, mode]: tonic is a letter plus optional accidental from \"\", #, b, x, bb; mode is one of the seven church modes ionian..locrian. The step pattern is the major pattern 2 2 1 2 2 2 1 rotated left by the mode index. Each degree uses the next letter; its alteration is the pitch-class difference from the natural letter folded into -6..5. Return the seven names, or None if any alteration exceeds two or input is invalid.","contract_signature":"x","evaluation_group":"w2-music-interval-modal-scale-spelling","failed_approach":"Rotating left by one extra position treats ionian as dorian, so every mode is off by one.","family":"w2-music-interval-modal-scale-spelling-mode-rotation","id":"FA-81006","implementations":{"attempt":{"sha256":"875af2989737072ed504e4971bee2f3fcf5b3aa6608b78990f1bbbd41097eb55","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    base = {'C': 0, 'D': 2, 'E': 4, 'F': 5, 'G': 7, 'A': 9, 'B': 11}\n    modes = ['ionian', 'dorian', 'phrygian', 'lydian', 'mixolydian', 'aeolian', 'locrian']\n    if not isinstance(x, list) or len(x) != 2:\n        return None\n    tonic, mode = x\n    if mode not in modes or not isinstance(tonic, str) or not tonic or tonic[0] not in base:\n        return None\n    signs = {'': 0, '#': 1, 'b': -1, 'x': 2, 'bb': -2}\n    if tonic[1:] not in signs:\n        return None\n    steps = [2, 2, 1, 2, 2, 2, 1]\n    k = modes.index(mode)\n    steps = steps[k + 1:] + steps[:k + 1]\n    pc = base[tonic[0]] + signs[tonic[1:]]\n    li = 'CDEFGAB'.index(tonic[0])\n    out = []\n    for step in steps:\n        letter = 'CDEFGAB'[li % 7]\n        alter = (pc - base[letter] + 6) % 12 - 6\n        if abs(alter) > 2:\n            return None\n        out.append(letter + {0: '', 1: '#', -1: 'b', 2: 'x', -2: 'bb'}[alter])\n        pc += step\n        li += 1\n    return out\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[(['C', 'ionian'], ['C', 'D', 'E', 'F', 'G', 'A', 'B']), (['D', 'dorian'], ['D', 'E', 'F', 'G', 'A', 'B', 'C']), (['E', 'phrygian'], ['E', 'F', 'G', 'A', 'B', 'C', 'D']), (['F', 'lydian'], ['F', 'G', 'A', 'B', 'C', 'D', 'E']), (['G', 'mixolydian'], ['G', 'A', 'B', 'C', 'D', 'E', 'F']), (['D', 'major'], None), (['H', 'ionian'], None), (['Cq', 'ionian'], None)], [(['C', 'ionian'], ['C', 'D', 'E', 'F', 'G', 'A', 'B']), (['D', 'dorian'], ['D', 'E', 'F', 'G', 'A', 'B', 'C']), (['E', 'phrygian'], ['E', 'F', 'G', 'A', 'B', 'C', 'D']), (['F', 'lydian'], ['F', 'G', 'A', 'B', 'C', 'D', 'E']), (['G', 'mixolydian'], ['G', 'A', 'B', 'C', 'D', 'E', 'F']), (['A', 'aeolian'], ['A', 'B', 'C', 'D', 'E', 'F', 'G']), (['B', 'locrian'], ['B', 'C', 'D', 'E', 'F', 'G', 'A']), (['C', 'dorian'], ['C', 'D', 'Eb', 'F', 'G', 'A', 'Bb'])], [(['E', 'phrygian'], ['E', 'F', 'G', 'A', 'B', 'C', 'D']), (['F', 'lydian'], ['F', 'G', 'A', 'B', 'C', 'D', 'E']), (['G', 'mixolydian'], ['G', 'A', 'B', 'C', 'D', 'E', 'F']), (['A', 'aeolian'], ['A', 'B', 'C', 'D', 'E', 'F', 'G']), (['B', 'locrian'], ['B', 'C', 'D', 'E', 'F', 'G', 'A']), (['C', 'dorian'], ['C', 'D', 'Eb', 'F', 'G', 'A', 'Bb']), (['C', 'phrygian'], ['C', 'Db', 'Eb', 'F', 'G', 'Ab', 'Bb']), (['C', 'lydian'], ['C', 'D', 'E', 'F#', 'G', 'A', 'B'])], [(['F', 'lydian'], ['F', 'G', 'A', 'B', 'C', 'D', 'E']), (['G', 'mixolydian'], ['G', 'A', 'B', 'C', 'D', 'E', 'F']), (['B', 'locrian'], ['B', 'C', 'D', 'E', 'F', 'G', 'A']), (['C', 'dorian'], ['C', 'D', 'Eb', 'F', 'G', 'A', 'Bb']), (['C', 'phrygian'], ['C', 'Db', 'Eb', 'F', 'G', 'Ab', 'Bb']), (['C', 'lydian'], ['C', 'D', 'E', 'F#', 'G', 'A', 'B']), (['C', 'locrian'], ['C', 'Db', 'Eb', 'F', 'Gb', 'Ab', 'Bb']), (['Eb', 'aeolian'], ['Eb', 'F', 'Gb', 'Ab', 'Bb', 'Cb', 'Db'])], [(['G', 'mixolydian'], ['G', 'A', 'B', 'C', 'D', 'E', 'F']), (['A', 'aeolian'], ['A', 'B', 'C', 'D', 'E', 'F', 'G']), (['C', 'dorian'], ['C', 'D', 'Eb', 'F', 'G', 'A', 'Bb']), (['C', 'lydian'], ['C', 'D', 'E', 'F#', 'G', 'A', 'B']), (['C', 'locrian'], ['C', 'Db', 'Eb', 'F', 'Gb', 'Ab', 'Bb']), (['Eb', 'aeolian'], ['Eb', 'F', 'Gb', 'Ab', 'Bb', 'Cb', 'Db']), (['F#', 'ionian'], ['F#', 'G#', 'A#', 'B', 'C#', 'D#', 'E#']), (['Bb', 'mixolydian'], ['Bb', 'C', 'D', 'Eb', 'F', 'G', 'Ab'])]]\nfor i, (args, expected) in enumerate(fixtures[N-1]):\n    check(\"oracle %d\" % i, solve(args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"},"broken":{"sha256":"61bd5830bdaa3862e8da4b11690dea47943444df1e9c0b5ab17312fed88352dc","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    base = {'C': 0, 'D': 2, 'E': 4, 'F': 5, 'G': 7, 'A': 9, 'B': 11}\n    modes = ['ionian', 'dorian', 'phrygian', 'lydian', 'mixolydian', 'aeolian', 'locrian']\n    if not isinstance(x, list) or len(x) != 2:\n        return None\n    tonic, mode = x\n    if mode not in modes or not isinstance(tonic, str) or not tonic or tonic[0] not in base:\n        return None\n    signs = {'': 0, '#': 1, 'b': -1, 'x': 2, 'bb': -2}\n    if tonic[1:] not in signs:\n        return None\n    steps = [2, 2, 1, 2, 2, 2, 1]\n    k = modes.index(mode)\n    steps = steps[-k:] + steps[:-k]\n    pc = base[tonic[0]] + signs[tonic[1:]]\n    li = 'CDEFGAB'.index(tonic[0])\n    out = []\n    for step in steps:\n        letter = 'CDEFGAB'[li % 7]\n        alter = (pc - base[letter] + 6) % 12 - 6\n        if abs(alter) > 2:\n            return None\n        out.append(letter + {0: '', 1: '#', -1: 'b', 2: 'x', -2: 'bb'}[alter])\n        pc += step\n        li += 1\n    return out\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[(['C', 'ionian'], ['C', 'D', 'E', 'F', 'G', 'A', 'B']), (['D', 'dorian'], ['D', 'E', 'F', 'G', 'A', 'B', 'C']), (['E', 'phrygian'], ['E', 'F', 'G', 'A', 'B', 'C', 'D']), (['F', 'lydian'], ['F', 'G', 'A', 'B', 'C', 'D', 'E']), (['G', 'mixolydian'], ['G', 'A', 'B', 'C', 'D', 'E', 'F']), (['D', 'major'], None), (['H', 'ionian'], None), (['Cq', 'ionian'], None)], [(['C', 'ionian'], ['C', 'D', 'E', 'F', 'G', 'A', 'B']), (['D', 'dorian'], ['D', 'E', 'F', 'G', 'A', 'B', 'C']), (['E', 'phrygian'], ['E', 'F', 'G', 'A', 'B', 'C', 'D']), (['F', 'lydian'], ['F', 'G', 'A', 'B', 'C', 'D', 'E']), (['G', 'mixolydian'], ['G', 'A', 'B', 'C', 'D', 'E', 'F']), (['A', 'aeolian'], ['A', 'B', 'C', 'D', 'E', 'F', 'G']), (['B', 'locrian'], ['B', 'C', 'D', 'E', 'F', 'G', 'A']), (['C', 'dorian'], ['C', 'D', 'Eb', 'F', 'G', 'A', 'Bb'])], [(['E', 'phrygian'], ['E', 'F', 'G', 'A', 'B', 'C', 'D']), (['F', 'lydian'], ['F', 'G', 'A', 'B', 'C', 'D', 'E']), (['G', 'mixolydian'], ['G', 'A', 'B', 'C', 'D', 'E', 'F']), (['A', 'aeolian'], ['A', 'B', 'C', 'D', 'E', 'F', 'G']), (['B', 'locrian'], ['B', 'C', 'D', 'E', 'F', 'G', 'A']), (['C', 'dorian'], ['C', 'D', 'Eb', 'F', 'G', 'A', 'Bb']), (['C', 'phrygian'], ['C', 'Db', 'Eb', 'F', 'G', 'Ab', 'Bb']), (['C', 'lydian'], ['C', 'D', 'E', 'F#', 'G', 'A', 'B'])], [(['F', 'lydian'], ['F', 'G', 'A', 'B', 'C', 'D', 'E']), (['G', 'mixolydian'], ['G', 'A', 'B', 'C', 'D', 'E', 'F']), (['B', 'locrian'], ['B', 'C', 'D', 'E', 'F', 'G', 'A']), (['C', 'dorian'], ['C', 'D', 'Eb', 'F', 'G', 'A', 'Bb']), (['C', 'phrygian'], ['C', 'Db', 'Eb', 'F', 'G', 'Ab', 'Bb']), (['C', 'lydian'], ['C', 'D', 'E', 'F#', 'G', 'A', 'B']), (['C', 'locrian'], ['C', 'Db', 'Eb', 'F', 'Gb', 'Ab', 'Bb']), (['Eb', 'aeolian'], ['Eb', 'F', 'Gb', 'Ab', 'Bb', 'Cb', 'Db'])], [(['G', 'mixolydian'], ['G', 'A', 'B', 'C', 'D', 'E', 'F']), (['A', 'aeolian'], ['A', 'B', 'C', 'D', 'E', 'F', 'G']), (['C', 'dorian'], ['C', 'D', 'Eb', 'F', 'G', 'A', 'Bb']), (['C', 'lydian'], ['C', 'D', 'E', 'F#', 'G', 'A', 'B']), (['C', 'locrian'], ['C', 'Db', 'Eb', 'F', 'Gb', 'Ab', 'Bb']), (['Eb', 'aeolian'], ['Eb', 'F', 'Gb', 'Ab', 'Bb', 'Cb', 'Db']), (['F#', 'ionian'], ['F#', 'G#', 'A#', 'B', 'C#', 'D#', 'E#']), (['Bb', 'mixolydian'], ['Bb', 'C', 'D', 'Eb', 'F', 'G', 'Ab'])]]\nfor i, (args, expected) in enumerate(fixtures[N-1]):\n    check(\"oracle %d\" % i, solve(args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"}},"limitations":"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.","method":"Deterministic executable model with adversarial boundary fixtures.","provenance":{"created_by":"Failure Map","dependencies":"Python standard library","family":"w2-music-interval-modal-scale-spelling-mode-rotation","generated_at":"2026-09-29T14:49:59.208430+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Pitch spelling and interval arithmetic decide the notes that notation, transposition and analysis tools display or play.","root_cause":"The major step pattern is rotated right by the mode index instead of left.","sha256":"75d56261162bd9280a672afbf04d194ef3ab76d8ee0dc116279c03f165ef876d","title":"Modal scale spelling from a tonic: mode pattern rotated the wrong way · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verified":true,"visibility":"public","verification":{"attempt":{"elapsed_ms":41.387,"exit_code":1,"observations":[{"actual":["C","D","Eb","F","G","A","Bb"],"check":"oracle 0","expected":["C","D","E","F","G","A","B"],"passed":false},{"actual":["D","Eb","F","G","A","Bb","C"],"check":"oracle 1","expected":["D","E","F","G","A","B","C"],"passed":false},{"actual":["E","F#","G#","A#","B","C#","D#"],"check":"oracle 2","expected":["E","F","G","A","B","C","D"],"passed":false},{"actual":["F","G","A","Bb","C","D","Eb"],"check":"oracle 3","expected":["F","G","A","B","C","D","E"],"passed":false},{"actual":["G","A","Bb","C","D","Eb","F"],"check":"oracle 4","expected":["G","A","B","C","D","E","F"],"passed":false},{"actual":null,"check":"oracle 5","expected":null,"passed":true},{"actual":null,"check":"oracle 6","expected":null,"passed":true},{"actual":null,"check":"oracle 7","expected":null,"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"oracle 0\", \"actual\": [\"C\", \"D\", \"Eb\", \"F\", \"G\", \"A\", \"Bb\"], \"expected\": [\"C\", \"D\", \"E\", \"F\", \"G\", \"A\", \"B\"], \"passed\": false}, {\"check\": \"oracle 1\", \"actual\": [\"D\", \"Eb\", \"F\", \"G\", \"A\", \"Bb\", \"C\"], \"expected\": [\"D\", \"E\", \"F\", \"G\", \"A\", \"B\", \"C\"], \"passed\": false}, {\"check\": \"oracle 2\", \"actual\": [\"E\", \"F#\", \"G#\", \"A#\", \"B\", \"C#\", \"D#\"], \"expected\": [\"E\", \"F\", \"G\", \"A\", \"B\", \"C\", \"D\"], \"passed\": false}, {\"check\": \"oracle 3\", \"actual\": [\"F\", \"G\", \"A\", \"Bb\", \"C\", \"D\", \"Eb\"], \"expected\": [\"F\", \"G\", \"A\", \"B\", \"C\", \"D\", \"E\"], \"passed\": false}, {\"check\": \"oracle 4\", \"actual\": [\"G\", \"A\", \"Bb\", \"C\", \"D\", \"Eb\", \"F\"], \"expected\": [\"G\", \"A\", \"B\", \"C\", \"D\", \"E\", \"F\"], \"passed\": false}, {\"check\": \"oracle 5\", \"actual\": null, \"expected\": null, \"passed\": true}, {\"check\": \"oracle 6\", \"actual\": null, \"expected\": null, \"passed\": true}, {\"check\": \"oracle 7\", \"actual\": null, \"expected\": null, \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":44.303,"exit_code":1,"observations":[{"actual":["C","D","E","F","G","A","B"],"check":"oracle 0","expected":["C","D","E","F","G","A","B"],"passed":true},{"actual":["D","Eb","F","G","Ab","Bb","C"],"check":"oracle 1","expected":["D","E","F","G","A","B","C"],"passed":false},{"actual":["E","F#","G","A","B","C","D"],"check":"oracle 2","expected":["E","F","G","A","B","C","D"],"passed":false},{"actual":["F","G","A","Bb","C","D","Eb"],"check":"oracle 3","expected":["F","G","A","B","C","D","E"],"passed":false},{"actual":["G","A","B","C#","D","E","F#"],"check":"oracle 4","expected":["G","A","B","C","D","E","F"],"passed":false},{"actual":null,"check":"oracle 5","expected":null,"passed":true},{"actual":null,"check":"oracle 6","expected":null,"passed":true},{"actual":null,"check":"oracle 7","expected":null,"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"oracle 0\", \"actual\": [\"C\", \"D\", \"E\", \"F\", \"G\", \"A\", \"B\"], \"expected\": [\"C\", \"D\", \"E\", \"F\", \"G\", \"A\", \"B\"], \"passed\": true}, {\"check\": \"oracle 1\", \"actual\": [\"D\", \"Eb\", \"F\", \"G\", \"Ab\", \"Bb\", \"C\"], \"expected\": [\"D\", \"E\", \"F\", \"G\", \"A\", \"B\", \"C\"], \"passed\": false}, {\"check\": \"oracle 2\", \"actual\": [\"E\", \"F#\", \"G\", \"A\", \"B\", \"C\", \"D\"], \"expected\": [\"E\", \"F\", \"G\", \"A\", \"B\", \"C\", \"D\"], \"passed\": false}, {\"check\": \"oracle 3\", \"actual\": [\"F\", \"G\", \"A\", \"Bb\", \"C\", \"D\", \"Eb\"], \"expected\": [\"F\", \"G\", \"A\", \"B\", \"C\", \"D\", \"E\"], \"passed\": false}, {\"check\": \"oracle 4\", \"actual\": [\"G\", \"A\", \"B\", \"C#\", \"D\", \"E\", \"F#\"], \"expected\": [\"G\", \"A\", \"B\", \"C\", \"D\", \"E\", \"F\"], \"passed\": false}, {\"check\": \"oracle 5\", \"actual\": null, \"expected\": null, \"passed\": true}, {\"check\": \"oracle 6\", \"actual\": null, \"expected\": null, \"passed\": true}, {\"check\": \"oracle 7\", \"actual\": null, \"expected\": null, \"passed\": true}], \"passed\": false}\n"}},"member_only":{"stages":["fixed"],"fields":["implementations.fixed","verification.fixed","harness","repair"],"note":"The verified repair, its recorded checks, the repair description, and the scoring harness are available to members."}}