{"abstract":"Hash join emits matched keys instead of build row IDs.","category":"Data systems","checks":7,"contract":"Probe a toy hash join whose hash bucket is integer key modulo bucket-count. Return left/right IDs for ordinary equal non-null keys AND right score>=left floor. Preserve all matching build rows and probe order. Hash equality alone never establishes row equality.","evaluation_group":"s3-data-systems-hash-join-residual","failed_approach":"Replacing the probe identity instead still changes result identity.","family":"s3-data-systems-hash-join-residual-pair-identity","id":"FA-44966","implementations":{"attempt":{"sha256":"b8c65767ad70196f94a8e946e4e40b528f29f4432cf52b14404d6a5f607607cf","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(d):\n    try:\n        left,right,buckets=d\n        table={}\n        for ident,key,score in right:\n            if key is None: continue\n            table.setdefault(key%buckets,[]).append([ident,key,score])\n        out=[]\n        for ident,key,floor in left:\n            if key is None: continue\n            for other,k,score in table.get(key%buckets,[]):\n                if k==key and score>=floor: out.append([key,other])\n        return out\n    except (IndexError, KeyError, ValueError, StopIteration) as exc:\n        return {\"representation_error\": type(exc).__name__}\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nif N == 1:\n    check('colliding keys', solve([[[10, 1, 1]], [[20, 1, 1], [21, 4, 1]], 3]), [[10, 20]])\n    check('residual rejects', solve([[[10, 1, 2]], [[20, 1, 1]], 3]), [])\n    check('build multiplicity', solve([[[10, 1, 1]], [[20, 1, 1], [21, 1, 2]], 3]), [[10, 20], [10, 21]])\n    check('probe bucket', solve([[[11, 4, 6]], [[20, 4, 7]], 3]), [[11, 20]])\n    check('null keys', solve([[[10, None, 1]], [[20, None, 1]], 3]), [])\n    check('empty build', solve([[[10, 1, 1]], [], 3]), [])\n    check('empty probe', solve([[], [[20, 1, 1]], 3]), [])\nelif N == 2:\n    check('colliding keys', solve([[[10, 1, 2]], [[20, 1, 2], [21, 4, 2]], 3]), [[10, 20]])\n    check('residual rejects', solve([[[10, 1, 3]], [[20, 1, 2]], 3]), [])\n    check('build multiplicity', solve([[[10, 1, 2]], [[20, 1, 2], [21, 1, 3]], 3]), [[10, 20], [10, 21]])\n    check('probe bucket', solve([[[11, 4, 7]], [[20, 4, 8]], 3]), [[11, 20]])\n    check('null keys', solve([[[10, None, 2]], [[20, None, 2]], 3]), [])\n    check('empty build', solve([[[10, 1, 2]], [], 3]), [])\n    check('empty probe', solve([[], [[20, 1, 2]], 3]), [])\nelif N == 3:\n    check('colliding keys', solve([[[10, 1, 3]], [[20, 1, 3], [21, 4, 3]], 3]), [[10, 20]])\n    check('residual rejects', solve([[[10, 1, 4]], [[20, 1, 3]], 3]), [])\n    check('build multiplicity', solve([[[10, 1, 3]], [[20, 1, 3], [21, 1, 4]], 3]), [[10, 20], [10, 21]])\n    check('probe bucket', solve([[[11, 4, 8]], [[20, 4, 9]], 3]), [[11, 20]])\n    check('null keys', solve([[[10, None, 3]], [[20, None, 3]], 3]), [])\n    check('empty build', solve([[[10, 1, 3]], [], 3]), [])\n    check('empty probe', solve([[], [[20, 1, 3]], 3]), [])\nelif N == 4:\n    check('colliding keys', solve([[[10, 1, 4]], [[20, 1, 4], [21, 4, 4]], 3]), [[10, 20]])\n    check('residual rejects', solve([[[10, 1, 5]], [[20, 1, 4]], 3]), [])\n    check('build multiplicity', solve([[[10, 1, 4]], [[20, 1, 4], [21, 1, 5]], 3]), [[10, 20], [10, 21]])\n    check('probe bucket', solve([[[11, 4, 9]], [[20, 4, 10]], 3]), [[11, 20]])\n    check('null keys', solve([[[10, None, 4]], [[20, None, 4]], 3]), [])\n    check('empty build', solve([[[10, 1, 4]], [], 3]), [])\n    check('empty probe', solve([[], [[20, 1, 4]], 3]), [])\nelif N == 5:\n    check('colliding keys', solve([[[10, 1, 5]], [[20, 1, 5], [21, 4, 5]], 3]), [[10, 20]])\n    check('residual rejects', solve([[[10, 1, 6]], [[20, 1, 5]], 3]), [])\n    check('build multiplicity', solve([[[10, 1, 5]], [[20, 1, 5], [21, 1, 6]], 3]), [[10, 20], [10, 21]])\n    check('probe bucket', solve([[[11, 4, 10]], [[20, 4, 11]], 3]), [[11, 20]])\n    check('null keys', solve([[[10, None, 5]], [[20, None, 5]], 3]), [])\n    check('empty build', solve([[[10, 1, 5]], [], 3]), [])\n    check('empty probe', solve([[], [[20, 1, 5]], 3]), [])\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":"5b534a9704877b6016b289b6aeffbab286017a00a1b4e281707604f4aead6b8b","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(d):\n    try:\n        left,right,buckets=d\n        table={}\n        for ident,key,score in right:\n            if key is None: continue\n            table.setdefault(key%buckets,[]).append([ident,key,score])\n        out=[]\n        for ident,key,floor in left:\n            if key is None: continue\n            for other,k,score in table.get(key%buckets,[]):\n                if k==key and score>=floor: out.append([ident,k])\n        return out\n    except (IndexError, KeyError, ValueError, StopIteration) as exc:\n        return {\"representation_error\": type(exc).__name__}\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nif N == 1:\n    check('colliding keys', solve([[[10, 1, 1]], [[20, 1, 1], [21, 4, 1]], 3]), [[10, 20]])\n    check('residual rejects', solve([[[10, 1, 2]], [[20, 1, 1]], 3]), [])\n    check('build multiplicity', solve([[[10, 1, 1]], [[20, 1, 1], [21, 1, 2]], 3]), [[10, 20], [10, 21]])\n    check('probe bucket', solve([[[11, 4, 6]], [[20, 4, 7]], 3]), [[11, 20]])\n    check('null keys', solve([[[10, None, 1]], [[20, None, 1]], 3]), [])\n    check('empty build', solve([[[10, 1, 1]], [], 3]), [])\n    check('empty probe', solve([[], [[20, 1, 1]], 3]), [])\nelif N == 2:\n    check('colliding keys', solve([[[10, 1, 2]], [[20, 1, 2], [21, 4, 2]], 3]), [[10, 20]])\n    check('residual rejects', solve([[[10, 1, 3]], [[20, 1, 2]], 3]), [])\n    check('build multiplicity', solve([[[10, 1, 2]], [[20, 1, 2], [21, 1, 3]], 3]), [[10, 20], [10, 21]])\n    check('probe bucket', solve([[[11, 4, 7]], [[20, 4, 8]], 3]), [[11, 20]])\n    check('null keys', solve([[[10, None, 2]], [[20, None, 2]], 3]), [])\n    check('empty build', solve([[[10, 1, 2]], [], 3]), [])\n    check('empty probe', solve([[], [[20, 1, 2]], 3]), [])\nelif N == 3:\n    check('colliding keys', solve([[[10, 1, 3]], [[20, 1, 3], [21, 4, 3]], 3]), [[10, 20]])\n    check('residual rejects', solve([[[10, 1, 4]], [[20, 1, 3]], 3]), [])\n    check('build multiplicity', solve([[[10, 1, 3]], [[20, 1, 3], [21, 1, 4]], 3]), [[10, 20], [10, 21]])\n    check('probe bucket', solve([[[11, 4, 8]], [[20, 4, 9]], 3]), [[11, 20]])\n    check('null keys', solve([[[10, None, 3]], [[20, None, 3]], 3]), [])\n    check('empty build', solve([[[10, 1, 3]], [], 3]), [])\n    check('empty probe', solve([[], [[20, 1, 3]], 3]), [])\nelif N == 4:\n    check('colliding keys', solve([[[10, 1, 4]], [[20, 1, 4], [21, 4, 4]], 3]), [[10, 20]])\n    check('residual rejects', solve([[[10, 1, 5]], [[20, 1, 4]], 3]), [])\n    check('build multiplicity', solve([[[10, 1, 4]], [[20, 1, 4], [21, 1, 5]], 3]), [[10, 20], [10, 21]])\n    check('probe bucket', solve([[[11, 4, 9]], [[20, 4, 10]], 3]), [[11, 20]])\n    check('null keys', solve([[[10, None, 4]], [[20, None, 4]], 3]), [])\n    check('empty build', solve([[[10, 1, 4]], [], 3]), [])\n    check('empty probe', solve([[], [[20, 1, 4]], 3]), [])\nelif N == 5:\n    check('colliding keys', solve([[[10, 1, 5]], [[20, 1, 5], [21, 4, 5]], 3]), [[10, 20]])\n    check('residual rejects', solve([[[10, 1, 6]], [[20, 1, 5]], 3]), [])\n    check('build multiplicity', solve([[[10, 1, 5]], [[20, 1, 5], [21, 1, 6]], 3]), [[10, 20], [10, 21]])\n    check('probe bucket', solve([[[11, 4, 10]], [[20, 4, 11]], 3]), [[11, 20]])\n    check('null keys', solve([[[10, None, 5]], [[20, None, 5]], 3]), [])\n    check('empty build', solve([[[10, 1, 5]], [], 3]), [])\n    check('empty probe', solve([[], [[20, 1, 5]], 3]), [])\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"},"fixed":{"sha256":"508738571753ebae91fc3f3393289d3951c8f3fb58c6830546ffb74e51fcf9d6","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(d):\n    try:\n        left,right,buckets=d\n        table={}\n        for ident,key,score in right:\n            if key is None: continue\n            table.setdefault(key%buckets,[]).append([ident,key,score])\n        out=[]\n        for ident,key,floor in left:\n            if key is None: continue\n            for other,k,score in table.get(key%buckets,[]):\n                if k==key and score>=floor: out.append([ident,other])\n        return out\n    except (IndexError, KeyError, ValueError, StopIteration) as exc:\n        return {\"representation_error\": type(exc).__name__}\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nif N == 1:\n    check('colliding keys', solve([[[10, 1, 1]], [[20, 1, 1], [21, 4, 1]], 3]), [[10, 20]])\n    check('residual rejects', solve([[[10, 1, 2]], [[20, 1, 1]], 3]), [])\n    check('build multiplicity', solve([[[10, 1, 1]], [[20, 1, 1], [21, 1, 2]], 3]), [[10, 20], [10, 21]])\n    check('probe bucket', solve([[[11, 4, 6]], [[20, 4, 7]], 3]), [[11, 20]])\n    check('null keys', solve([[[10, None, 1]], [[20, None, 1]], 3]), [])\n    check('empty build', solve([[[10, 1, 1]], [], 3]), [])\n    check('empty probe', solve([[], [[20, 1, 1]], 3]), [])\nelif N == 2:\n    check('colliding keys', solve([[[10, 1, 2]], [[20, 1, 2], [21, 4, 2]], 3]), [[10, 20]])\n    check('residual rejects', solve([[[10, 1, 3]], [[20, 1, 2]], 3]), [])\n    check('build multiplicity', solve([[[10, 1, 2]], [[20, 1, 2], [21, 1, 3]], 3]), [[10, 20], [10, 21]])\n    check('probe bucket', solve([[[11, 4, 7]], [[20, 4, 8]], 3]), [[11, 20]])\n    check('null keys', solve([[[10, None, 2]], [[20, None, 2]], 3]), [])\n    check('empty build', solve([[[10, 1, 2]], [], 3]), [])\n    check('empty probe', solve([[], [[20, 1, 2]], 3]), [])\nelif N == 3:\n    check('colliding keys', solve([[[10, 1, 3]], [[20, 1, 3], [21, 4, 3]], 3]), [[10, 20]])\n    check('residual rejects', solve([[[10, 1, 4]], [[20, 1, 3]], 3]), [])\n    check('build multiplicity', solve([[[10, 1, 3]], [[20, 1, 3], [21, 1, 4]], 3]), [[10, 20], [10, 21]])\n    check('probe bucket', solve([[[11, 4, 8]], [[20, 4, 9]], 3]), [[11, 20]])\n    check('null keys', solve([[[10, None, 3]], [[20, None, 3]], 3]), [])\n    check('empty build', solve([[[10, 1, 3]], [], 3]), [])\n    check('empty probe', solve([[], [[20, 1, 3]], 3]), [])\nelif N == 4:\n    check('colliding keys', solve([[[10, 1, 4]], [[20, 1, 4], [21, 4, 4]], 3]), [[10, 20]])\n    check('residual rejects', solve([[[10, 1, 5]], [[20, 1, 4]], 3]), [])\n    check('build multiplicity', solve([[[10, 1, 4]], [[20, 1, 4], [21, 1, 5]], 3]), [[10, 20], [10, 21]])\n    check('probe bucket', solve([[[11, 4, 9]], [[20, 4, 10]], 3]), [[11, 20]])\n    check('null keys', solve([[[10, None, 4]], [[20, None, 4]], 3]), [])\n    check('empty build', solve([[[10, 1, 4]], [], 3]), [])\n    check('empty probe', solve([[], [[20, 1, 4]], 3]), [])\nelif N == 5:\n    check('colliding keys', solve([[[10, 1, 5]], [[20, 1, 5], [21, 4, 5]], 3]), [[10, 20]])\n    check('residual rejects', solve([[[10, 1, 6]], [[20, 1, 5]], 3]), [])\n    check('build multiplicity', solve([[[10, 1, 5]], [[20, 1, 5], [21, 1, 6]], 3]), [[10, 20], [10, 21]])\n    check('probe bucket', solve([[[11, 4, 10]], [[20, 4, 11]], 3]), [[11, 20]])\n    check('null keys', solve([[[10, None, 5]], [[20, None, 5]], 3]), [])\n    check('empty build', solve([[[10, 1, 5]], [], 3]), [])\n    check('empty probe', solve([[], [[20, 1, 5]], 3]), [])\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":"Offline stipulated semantics over valid small inputs; no performance, concurrency, or production-engine conformance claim. 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":"s3-data-systems-hash-join-residual-pair-identity","generated_at":"2026-09-29T14:44:17.322532+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"A bounded deterministic data engine model makes representation and changelog faults reproducible.","repair":"Preserve the stated physical representation and operation order: Probe a toy hash join whose hash bucket is integer key modulo bucket-count. Return left/right IDs for ordinary equal non-null keys AND right score>=left floor. Preserve all matching build rows and probe order. Hash equality alone never establishes row equality.","root_cause":"hash-join-residual: Hash join emits matched keys instead of build row IDs.","sha256":"22ed1db4452b2a2f5968e1b160540cdd9dfb08e355299a9a2e89a6217eb24413","title":"Hash join emits matched keys instead of build row IDs · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":44.841,"exit_code":1,"observations":[{"actual":[[1,20]],"check":"colliding keys","expected":[[10,20]],"passed":false},{"actual":[],"check":"residual rejects","expected":[],"passed":true},{"actual":[[1,20],[1,21]],"check":"build multiplicity","expected":[[10,20],[10,21]],"passed":false},{"actual":[[4,20]],"check":"probe bucket","expected":[[11,20]],"passed":false},{"actual":[],"check":"null keys","expected":[],"passed":true},{"actual":[],"check":"empty build","expected":[],"passed":true},{"actual":[],"check":"empty probe","expected":[],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"colliding keys\", \"actual\": [[1, 20]], \"expected\": [[10, 20]], \"passed\": false}, {\"check\": \"residual rejects\", \"actual\": [], \"expected\": [], \"passed\": true}, {\"check\": \"build multiplicity\", \"actual\": [[1, 20], [1, 21]], \"expected\": [[10, 20], [10, 21]], \"passed\": false}, {\"check\": \"probe bucket\", \"actual\": [[4, 20]], \"expected\": [[11, 20]], \"passed\": false}, {\"check\": \"null keys\", \"actual\": [], \"expected\": [], \"passed\": true}, {\"check\": \"empty build\", \"actual\": [], \"expected\": [], \"passed\": true}, {\"check\": \"empty probe\", \"actual\": [], \"expected\": [], \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":41.064,"exit_code":1,"observations":[{"actual":[[10,1]],"check":"colliding keys","expected":[[10,20]],"passed":false},{"actual":[],"check":"residual rejects","expected":[],"passed":true},{"actual":[[10,1],[10,1]],"check":"build multiplicity","expected":[[10,20],[10,21]],"passed":false},{"actual":[[11,4]],"check":"probe bucket","expected":[[11,20]],"passed":false},{"actual":[],"check":"null keys","expected":[],"passed":true},{"actual":[],"check":"empty build","expected":[],"passed":true},{"actual":[],"check":"empty probe","expected":[],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"colliding keys\", \"actual\": [[10, 1]], \"expected\": [[10, 20]], \"passed\": false}, {\"check\": \"residual rejects\", \"actual\": [], \"expected\": [], \"passed\": true}, {\"check\": \"build multiplicity\", \"actual\": [[10, 1], [10, 1]], \"expected\": [[10, 20], [10, 21]], \"passed\": false}, {\"check\": \"probe bucket\", \"actual\": [[11, 4]], \"expected\": [[11, 20]], \"passed\": false}, {\"check\": \"null keys\", \"actual\": [], \"expected\": [], \"passed\": true}, {\"check\": \"empty build\", \"actual\": [], \"expected\": [], \"passed\": true}, {\"check\": \"empty probe\", \"actual\": [], \"expected\": [], \"passed\": true}], \"passed\": false}\n"},"fixed":{"elapsed_ms":44.312,"exit_code":0,"observations":[{"actual":[[10,20]],"check":"colliding keys","expected":[[10,20]],"passed":true},{"actual":[],"check":"residual rejects","expected":[],"passed":true},{"actual":[[10,20],[10,21]],"check":"build multiplicity","expected":[[10,20],[10,21]],"passed":true},{"actual":[[11,20]],"check":"probe bucket","expected":[[11,20]],"passed":true},{"actual":[],"check":"null keys","expected":[],"passed":true},{"actual":[],"check":"empty build","expected":[],"passed":true},{"actual":[],"check":"empty probe","expected":[],"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"colliding keys\", \"actual\": [[10, 20]], \"expected\": [[10, 20]], \"passed\": true}, {\"check\": \"residual rejects\", \"actual\": [], \"expected\": [], \"passed\": true}, {\"check\": \"build multiplicity\", \"actual\": [[10, 20], [10, 21]], \"expected\": [[10, 20], [10, 21]], \"passed\": true}, {\"check\": \"probe bucket\", \"actual\": [[11, 20]], \"expected\": [[11, 20]], \"passed\": true}, {\"check\": \"null keys\", \"actual\": [], \"expected\": [], \"passed\": true}, {\"check\": \"empty build\", \"actual\": [], \"expected\": [], \"passed\": true}, {\"check\": \"empty probe\", \"actual\": [], \"expected\": [], \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}