{"abstract":"Motor commands are ratio^2 too small.","category":"Inverse kinematics solvers","checks":7,"contract":"Input [geo,off,dirs,ratio,lines,lims], all per-joint lists: IK joint angles (degrees) become encoder counts per joint as counts = floor(dirs*(geo-off)*ratio/360*lines*4 + 0.5) (quadrature gives 4 counts per line, half rounds up). lims holds inclusive [lo,hi] count limits; the first violating joint returns [\"limit\", i, counts].","evaluation_group":"w2-inverse_kinematics_solvers-joint-actuator-mapping","failed_approach":"Using the first joint ratio for every joint mis-scales the others.","family":"w2-inverse_kinematics_solvers-joint-actuator-mapping-gear-ratio-direction","id":"FA-88301","implementations":{"attempt":{"sha256":"1883cfa6584f05bfea98246ca18e8752227fd0238a9681f91ca5f8ffe198cad8","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nN = 1\nobservations = []\ndef solve(x):\n    geo,off,dirs,ratio,lines,lims=x\n    out=[]\n    for i in range(len(geo)):\n        m=dirs[i]*(geo[i]-off[i])*ratio[0]\n        cnt=math.floor(m/360.0*lines[i]*4+0.5)\n        lo,hi=lims[i]\n        if cnt<lo or cnt>hi: return ['limit',i,cnt]\n        out.append(cnt)\n    return out\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['two joints nominal', [[[10, 20], [5, -5], [1, -1], [50, 30], [100, 100], [[-100000, 100000], [-100000, 100000]]]], [278, -833]], ['half count rounding up', [[[45], [0], [1], [1], [5], [[-10, 10]]]], [3]], ['negative fractional count', [[[-45], [0], [1], [1], [5.4], [[-10, 10]]]], [-3]], ['negative half rounds up', [[[-45], [0], [1], [1], [11], [[-10, 10]]]], [-5]], ['reversed joint with offset', [[[30], [90], [-1], [2], [180], [[-10000, 10000]]]], [240]], ['limit exceeded', [[[90, 0], [0, 0], [1, 1], [100, 1], [1000, 1000], [[-1000, 1000], [-10, 10]]]], ['limit', 0, 100000]], ['within limit exactly', [[[0, 9], [0, 0], [1, 1], [1, 1], [10, 10], [[-1, 1], [-1, 1]]]], [0, 1]]], [['negative half rounds up', [[[-45], [0], [1], [1], [11], [[-10, 10]]]], [-5]], ['reversed joint with offset', [[[30], [90], [-1], [2], [180], [[-10000, 10000]]]], [240]], ['limit exceeded', [[[90, 0], [0, 0], [1, 1], [100, 1], [1000, 1000], [[-1000, 1000], [-10, 10]]]], ['limit', 0, 100000]], ['within limit exactly', [[[0, 9], [0, 0], [1, 1], [1, 1], [10, 10], [[-1, 1], [-1, 1]]]], [0, 1]], ['three joint arm', [[[45, -30, 12], [0, 10, -3], [1, -1, 1], [100, 80, 50], [500, 500, 256], [[-1000000, 1000000], [-1000000, 1000000], [-1000000, 1000000]]]], [25000, 17778, 2133]], ['gear down joint', [[[180, 45], [0, 0], [1, 1], [0.5, 4], [100, 100], [[-100000, 100000], [-100000, 100000]]]], [100, 200]], ['offset makes negative', [[[10], [40], [1], [3], [360], [[-5000, 5000]]]], [-360]]], [['two joints nominal', [[[10, 20], [5, -5], [1, -1], [50, 30], [100, 100], [[-100000, 100000], [-100000, 100000]]]], [278, -833]], ['limit exceeded', [[[90, 0], [0, 0], [1, 1], [100, 1], [1000, 1000], [[-1000, 1000], [-10, 10]]]], ['limit', 0, 100000]], ['three joint arm', [[[45, -30, 12], [0, 10, -3], [1, -1, 1], [100, 80, 50], [500, 500, 256], [[-1000000, 1000000], [-1000000, 1000000], [-1000000, 1000000]]]], [25000, 17778, 2133]], ['gear down joint', [[[180, 45], [0, 0], [1, 1], [0.5, 4], [100, 100], [[-100000, 100000], [-100000, 100000]]]], [100, 200]], ['offset makes negative', [[[10], [40], [1], [3], [360], [[-5000, 5000]]]], [-360]], ['motor degrees small counts large', [[[5], [0], [1], [100], [1000], [[-5000, 5000]]]], ['limit', 0, 5556]], ['geo within range counts out', [[[20], [0], [1], [50], [100], [[-100, 1000]]]], ['limit', 0, 1111]]], [['two joints nominal', [[[10, 20], [5, -5], [1, -1], [50, 30], [100, 100], [[-100000, 100000], [-100000, 100000]]]], [278, -833]], ['half count rounding up', [[[45], [0], [1], [1], [5], [[-10, 10]]]], [3]], ['negative fractional count', [[[-45], [0], [1], [1], [5.4], [[-10, 10]]]], [-3]], ['negative half rounds up', [[[-45], [0], [1], [1], [11], [[-10, 10]]]], [-5]], ['reversed joint with offset', [[[30], [90], [-1], [2], [180], [[-10000, 10000]]]], [240]], ['three joint arm', [[[45, -30, 12], [0, 10, -3], [1, -1, 1], [100, 80, 50], [500, 500, 256], [[-1000000, 1000000], [-1000000, 1000000], [-1000000, 1000000]]]], [25000, 17778, 2133]], ['geo within range counts out', [[[20], [0], [1], [50], [100], [[-100, 1000]]]], ['limit', 0, 1111]]], [['negative fractional count', [[[-45], [0], [1], [1], [5.4], [[-10, 10]]]], [-3]], ['negative half rounds up', [[[-45], [0], [1], [1], [11], [[-10, 10]]]], [-5]], ['reversed joint with offset', [[[30], [90], [-1], [2], [180], [[-10000, 10000]]]], [240]], ['limit exceeded', [[[90, 0], [0, 0], [1, 1], [100, 1], [1000, 1000], [[-1000, 1000], [-10, 10]]]], ['limit', 0, 100000]], ['within limit exactly', [[[0, 9], [0, 0], [1, 1], [1, 1], [10, 10], [[-1, 1], [-1, 1]]]], [0, 1]], ['three joint arm', [[[45, -30, 12], [0, 10, -3], [1, -1, 1], [100, 80, 50], [500, 500, 256], [[-1000000, 1000000], [-1000000, 1000000], [-1000000, 1000000]]]], [25000, 17778, 2133]], ['gear down joint', [[[180, 45], [0, 0], [1, 1], [0.5, 4], [100, 100], [[-100000, 100000], [-100000, 100000]]]], [100, 200]]]]\nfor label, args, expected in fixtures[N-1]:\n    check(label, 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":"494e9fd6b78f0bcf6bf36c28f4a9364c1087cd2f30750927aed4ff6a7715b509","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nN = 1\nobservations = []\ndef solve(x):\n    geo,off,dirs,ratio,lines,lims=x\n    out=[]\n    for i in range(len(geo)):\n        m=dirs[i]*(geo[i]-off[i])/ratio[i]\n        cnt=math.floor(m/360.0*lines[i]*4+0.5)\n        lo,hi=lims[i]\n        if cnt<lo or cnt>hi: return ['limit',i,cnt]\n        out.append(cnt)\n    return out\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['two joints nominal', [[[10, 20], [5, -5], [1, -1], [50, 30], [100, 100], [[-100000, 100000], [-100000, 100000]]]], [278, -833]], ['half count rounding up', [[[45], [0], [1], [1], [5], [[-10, 10]]]], [3]], ['negative fractional count', [[[-45], [0], [1], [1], [5.4], [[-10, 10]]]], [-3]], ['negative half rounds up', [[[-45], [0], [1], [1], [11], [[-10, 10]]]], [-5]], ['reversed joint with offset', [[[30], [90], [-1], [2], [180], [[-10000, 10000]]]], [240]], ['limit exceeded', [[[90, 0], [0, 0], [1, 1], [100, 1], [1000, 1000], [[-1000, 1000], [-10, 10]]]], ['limit', 0, 100000]], ['within limit exactly', [[[0, 9], [0, 0], [1, 1], [1, 1], [10, 10], [[-1, 1], [-1, 1]]]], [0, 1]]], [['negative half rounds up', [[[-45], [0], [1], [1], [11], [[-10, 10]]]], [-5]], ['reversed joint with offset', [[[30], [90], [-1], [2], [180], [[-10000, 10000]]]], [240]], ['limit exceeded', [[[90, 0], [0, 0], [1, 1], [100, 1], [1000, 1000], [[-1000, 1000], [-10, 10]]]], ['limit', 0, 100000]], ['within limit exactly', [[[0, 9], [0, 0], [1, 1], [1, 1], [10, 10], [[-1, 1], [-1, 1]]]], [0, 1]], ['three joint arm', [[[45, -30, 12], [0, 10, -3], [1, -1, 1], [100, 80, 50], [500, 500, 256], [[-1000000, 1000000], [-1000000, 1000000], [-1000000, 1000000]]]], [25000, 17778, 2133]], ['gear down joint', [[[180, 45], [0, 0], [1, 1], [0.5, 4], [100, 100], [[-100000, 100000], [-100000, 100000]]]], [100, 200]], ['offset makes negative', [[[10], [40], [1], [3], [360], [[-5000, 5000]]]], [-360]]], [['two joints nominal', [[[10, 20], [5, -5], [1, -1], [50, 30], [100, 100], [[-100000, 100000], [-100000, 100000]]]], [278, -833]], ['limit exceeded', [[[90, 0], [0, 0], [1, 1], [100, 1], [1000, 1000], [[-1000, 1000], [-10, 10]]]], ['limit', 0, 100000]], ['three joint arm', [[[45, -30, 12], [0, 10, -3], [1, -1, 1], [100, 80, 50], [500, 500, 256], [[-1000000, 1000000], [-1000000, 1000000], [-1000000, 1000000]]]], [25000, 17778, 2133]], ['gear down joint', [[[180, 45], [0, 0], [1, 1], [0.5, 4], [100, 100], [[-100000, 100000], [-100000, 100000]]]], [100, 200]], ['offset makes negative', [[[10], [40], [1], [3], [360], [[-5000, 5000]]]], [-360]], ['motor degrees small counts large', [[[5], [0], [1], [100], [1000], [[-5000, 5000]]]], ['limit', 0, 5556]], ['geo within range counts out', [[[20], [0], [1], [50], [100], [[-100, 1000]]]], ['limit', 0, 1111]]], [['two joints nominal', [[[10, 20], [5, -5], [1, -1], [50, 30], [100, 100], [[-100000, 100000], [-100000, 100000]]]], [278, -833]], ['half count rounding up', [[[45], [0], [1], [1], [5], [[-10, 10]]]], [3]], ['negative fractional count', [[[-45], [0], [1], [1], [5.4], [[-10, 10]]]], [-3]], ['negative half rounds up', [[[-45], [0], [1], [1], [11], [[-10, 10]]]], [-5]], ['reversed joint with offset', [[[30], [90], [-1], [2], [180], [[-10000, 10000]]]], [240]], ['three joint arm', [[[45, -30, 12], [0, 10, -3], [1, -1, 1], [100, 80, 50], [500, 500, 256], [[-1000000, 1000000], [-1000000, 1000000], [-1000000, 1000000]]]], [25000, 17778, 2133]], ['geo within range counts out', [[[20], [0], [1], [50], [100], [[-100, 1000]]]], ['limit', 0, 1111]]], [['negative fractional count', [[[-45], [0], [1], [1], [5.4], [[-10, 10]]]], [-3]], ['negative half rounds up', [[[-45], [0], [1], [1], [11], [[-10, 10]]]], [-5]], ['reversed joint with offset', [[[30], [90], [-1], [2], [180], [[-10000, 10000]]]], [240]], ['limit exceeded', [[[90, 0], [0, 0], [1, 1], [100, 1], [1000, 1000], [[-1000, 1000], [-10, 10]]]], ['limit', 0, 100000]], ['within limit exactly', [[[0, 9], [0, 0], [1, 1], [1, 1], [10, 10], [[-1, 1], [-1, 1]]]], [0, 1]], ['three joint arm', [[[45, -30, 12], [0, 10, -3], [1, -1, 1], [100, 80, 50], [500, 500, 256], [[-1000000, 1000000], [-1000000, 1000000], [-1000000, 1000000]]]], [25000, 17778, 2133]], ['gear down joint', [[[180, 45], [0, 0], [1, 1], [0.5, 4], [100, 100], [[-100000, 100000], [-100000, 100000]]]], [100, 200]]]]\nfor label, args, expected in fixtures[N-1]:\n    check(label, 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"},"fixed":{"sha256":"b02e45c60180ffa5796ec07c2a9cea788eb37b004170703cd502483495d847b6","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nN = 1\nobservations = []\ndef solve(x):\n    geo,off,dirs,ratio,lines,lims=x\n    out=[]\n    for i in range(len(geo)):\n        m=dirs[i]*(geo[i]-off[i])*ratio[i]\n        cnt=math.floor(m/360.0*lines[i]*4+0.5)\n        lo,hi=lims[i]\n        if cnt<lo or cnt>hi: return ['limit',i,cnt]\n        out.append(cnt)\n    return out\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['two joints nominal', [[[10, 20], [5, -5], [1, -1], [50, 30], [100, 100], [[-100000, 100000], [-100000, 100000]]]], [278, -833]], ['half count rounding up', [[[45], [0], [1], [1], [5], [[-10, 10]]]], [3]], ['negative fractional count', [[[-45], [0], [1], [1], [5.4], [[-10, 10]]]], [-3]], ['negative half rounds up', [[[-45], [0], [1], [1], [11], [[-10, 10]]]], [-5]], ['reversed joint with offset', [[[30], [90], [-1], [2], [180], [[-10000, 10000]]]], [240]], ['limit exceeded', [[[90, 0], [0, 0], [1, 1], [100, 1], [1000, 1000], [[-1000, 1000], [-10, 10]]]], ['limit', 0, 100000]], ['within limit exactly', [[[0, 9], [0, 0], [1, 1], [1, 1], [10, 10], [[-1, 1], [-1, 1]]]], [0, 1]]], [['negative half rounds up', [[[-45], [0], [1], [1], [11], [[-10, 10]]]], [-5]], ['reversed joint with offset', [[[30], [90], [-1], [2], [180], [[-10000, 10000]]]], [240]], ['limit exceeded', [[[90, 0], [0, 0], [1, 1], [100, 1], [1000, 1000], [[-1000, 1000], [-10, 10]]]], ['limit', 0, 100000]], ['within limit exactly', [[[0, 9], [0, 0], [1, 1], [1, 1], [10, 10], [[-1, 1], [-1, 1]]]], [0, 1]], ['three joint arm', [[[45, -30, 12], [0, 10, -3], [1, -1, 1], [100, 80, 50], [500, 500, 256], [[-1000000, 1000000], [-1000000, 1000000], [-1000000, 1000000]]]], [25000, 17778, 2133]], ['gear down joint', [[[180, 45], [0, 0], [1, 1], [0.5, 4], [100, 100], [[-100000, 100000], [-100000, 100000]]]], [100, 200]], ['offset makes negative', [[[10], [40], [1], [3], [360], [[-5000, 5000]]]], [-360]]], [['two joints nominal', [[[10, 20], [5, -5], [1, -1], [50, 30], [100, 100], [[-100000, 100000], [-100000, 100000]]]], [278, -833]], ['limit exceeded', [[[90, 0], [0, 0], [1, 1], [100, 1], [1000, 1000], [[-1000, 1000], [-10, 10]]]], ['limit', 0, 100000]], ['three joint arm', [[[45, -30, 12], [0, 10, -3], [1, -1, 1], [100, 80, 50], [500, 500, 256], [[-1000000, 1000000], [-1000000, 1000000], [-1000000, 1000000]]]], [25000, 17778, 2133]], ['gear down joint', [[[180, 45], [0, 0], [1, 1], [0.5, 4], [100, 100], [[-100000, 100000], [-100000, 100000]]]], [100, 200]], ['offset makes negative', [[[10], [40], [1], [3], [360], [[-5000, 5000]]]], [-360]], ['motor degrees small counts large', [[[5], [0], [1], [100], [1000], [[-5000, 5000]]]], ['limit', 0, 5556]], ['geo within range counts out', [[[20], [0], [1], [50], [100], [[-100, 1000]]]], ['limit', 0, 1111]]], [['two joints nominal', [[[10, 20], [5, -5], [1, -1], [50, 30], [100, 100], [[-100000, 100000], [-100000, 100000]]]], [278, -833]], ['half count rounding up', [[[45], [0], [1], [1], [5], [[-10, 10]]]], [3]], ['negative fractional count', [[[-45], [0], [1], [1], [5.4], [[-10, 10]]]], [-3]], ['negative half rounds up', [[[-45], [0], [1], [1], [11], [[-10, 10]]]], [-5]], ['reversed joint with offset', [[[30], [90], [-1], [2], [180], [[-10000, 10000]]]], [240]], ['three joint arm', [[[45, -30, 12], [0, 10, -3], [1, -1, 1], [100, 80, 50], [500, 500, 256], [[-1000000, 1000000], [-1000000, 1000000], [-1000000, 1000000]]]], [25000, 17778, 2133]], ['geo within range counts out', [[[20], [0], [1], [50], [100], [[-100, 1000]]]], ['limit', 0, 1111]]], [['negative fractional count', [[[-45], [0], [1], [1], [5.4], [[-10, 10]]]], [-3]], ['negative half rounds up', [[[-45], [0], [1], [1], [11], [[-10, 10]]]], [-5]], ['reversed joint with offset', [[[30], [90], [-1], [2], [180], [[-10000, 10000]]]], [240]], ['limit exceeded', [[[90, 0], [0, 0], [1, 1], [100, 1], [1000, 1000], [[-1000, 1000], [-10, 10]]]], ['limit', 0, 100000]], ['within limit exactly', [[[0, 9], [0, 0], [1, 1], [1, 1], [10, 10], [[-1, 1], [-1, 1]]]], [0, 1]], ['three joint arm', [[[45, -30, 12], [0, 10, -3], [1, -1, 1], [100, 80, 50], [500, 500, 256], [[-1000000, 1000000], [-1000000, 1000000], [-1000000, 1000000]]]], [25000, 17778, 2133]], ['gear down joint', [[[180, 45], [0, 0], [1, 1], [0.5, 4], [100, 100], [[-100000, 100000], [-100000, 100000]]]], [100, 200]]]]\nfor label, args, expected in fixtures[N-1]:\n    check(label, 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":"Deterministic planar or low-dimensional teaching model with a stipulated convention; not a general robotics library. 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-inverse_kinematics_solvers-joint-actuator-mapping-gear-ratio-direction","generated_at":"2026-09-29T14:51:06.886989+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Inverse kinematics code turns task-space goals into joint commands; a wrong branch, sign, limit or update order sends a real arm to the wrong pose.","repair":"Multiply the joint angle by its own ratio.","root_cause":"The joint-to-motor conversion divides by the gear ratio instead of multiplying.","sha256":"906f903c2eb8b8dd804dfda1a67f0e1b68b687f0aa834297693791a8941287d7","title":"Gear ratio divides the joint angle · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":42.0,"exit_code":1,"observations":[{"actual":[278,-1389],"check":"two joints nominal","expected":[278,-833],"passed":false},{"actual":[3],"check":"half count rounding up","expected":[3],"passed":true},{"actual":[-3],"check":"negative fractional count","expected":[-3],"passed":true},{"actual":[-5],"check":"negative half rounds up","expected":[-5],"passed":true},{"actual":[240],"check":"reversed joint with offset","expected":[240],"passed":true},{"actual":["limit",0,100000],"check":"limit exceeded","expected":["limit",0,100000],"passed":true},{"actual":[0,1],"check":"within limit exactly","expected":[0,1],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"two joints nominal\", \"actual\": [278, -1389], \"expected\": [278, -833], \"passed\": false}, {\"check\": \"half count rounding up\", \"actual\": [3], \"expected\": [3], \"passed\": true}, {\"check\": \"negative fractional count\", \"actual\": [-3], \"expected\": [-3], \"passed\": true}, {\"check\": \"negative half rounds up\", \"actual\": [-5], \"expected\": [-5], \"passed\": true}, {\"check\": \"reversed joint with offset\", \"actual\": [240], \"expected\": [240], \"passed\": true}, {\"check\": \"limit exceeded\", \"actual\": [\"limit\", 0, 100000], \"expected\": [\"limit\", 0, 100000], \"passed\": true}, {\"check\": \"within limit exactly\", \"actual\": [0, 1], \"expected\": [0, 1], \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":41.422,"exit_code":1,"observations":[{"actual":[0,-1],"check":"two joints nominal","expected":[278,-833],"passed":false},{"actual":[3],"check":"half count rounding up","expected":[3],"passed":true},{"actual":[-3],"check":"negative fractional count","expected":[-3],"passed":true},{"actual":[-5],"check":"negative half rounds up","expected":[-5],"passed":true},{"actual":[60],"check":"reversed joint with offset","expected":[240],"passed":false},{"actual":[10,0],"check":"limit exceeded","expected":["limit",0,100000],"passed":false},{"actual":[0,1],"check":"within limit exactly","expected":[0,1],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"two joints nominal\", \"actual\": [0, -1], \"expected\": [278, -833], \"passed\": false}, {\"check\": \"half count rounding up\", \"actual\": [3], \"expected\": [3], \"passed\": true}, {\"check\": \"negative fractional count\", \"actual\": [-3], \"expected\": [-3], \"passed\": true}, {\"check\": \"negative half rounds up\", \"actual\": [-5], \"expected\": [-5], \"passed\": true}, {\"check\": \"reversed joint with offset\", \"actual\": [60], \"expected\": [240], \"passed\": false}, {\"check\": \"limit exceeded\", \"actual\": [10, 0], \"expected\": [\"limit\", 0, 100000], \"passed\": false}, {\"check\": \"within limit exactly\", \"actual\": [0, 1], \"expected\": [0, 1], \"passed\": true}], \"passed\": false}\n"},"fixed":{"elapsed_ms":41.501,"exit_code":0,"observations":[{"actual":[278,-833],"check":"two joints nominal","expected":[278,-833],"passed":true},{"actual":[3],"check":"half count rounding up","expected":[3],"passed":true},{"actual":[-3],"check":"negative fractional count","expected":[-3],"passed":true},{"actual":[-5],"check":"negative half rounds up","expected":[-5],"passed":true},{"actual":[240],"check":"reversed joint with offset","expected":[240],"passed":true},{"actual":["limit",0,100000],"check":"limit exceeded","expected":["limit",0,100000],"passed":true},{"actual":[0,1],"check":"within limit exactly","expected":[0,1],"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"two joints nominal\", \"actual\": [278, -833], \"expected\": [278, -833], \"passed\": true}, {\"check\": \"half count rounding up\", \"actual\": [3], \"expected\": [3], \"passed\": true}, {\"check\": \"negative fractional count\", \"actual\": [-3], \"expected\": [-3], \"passed\": true}, {\"check\": \"negative half rounds up\", \"actual\": [-5], \"expected\": [-5], \"passed\": true}, {\"check\": \"reversed joint with offset\", \"actual\": [240], \"expected\": [240], \"passed\": true}, {\"check\": \"limit exceeded\", \"actual\": [\"limit\", 0, 100000], \"expected\": [\"limit\", 0, 100000], \"passed\": true}, {\"check\": \"within limit exactly\", \"actual\": [0, 1], \"expected\": [0, 1], \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}