{
  "schema": "NEXT11_V317_BROWSER_MCP_ONLY_AUTHORITY_AUDIT",
  "generatedAt": "2026-08-20T01:30:05Z",
  "root": "/mnt/data/nex_v317_final_mcp_authority_gate/NEXT11_V317_FINAL_ACTUAL_MCP_AUTHORITY_GATE_ROOT",
  "results": [
    {
      "name": "right",
      "caseId": "v94_right_full",
      "phase": "0.75",
      "url": "http://127.0.0.1:40391/assets/nexprod/nexprod01-player.html?exercise=hurdle-stretch&caseId=v94_right_full&phase=0.75&play=0&debug=0&visualMode=nex&nativeRuntimeParity=1&nativeSkin=1&skinPreset=freeridehuman&readyTimeoutMs=12000&hostLifecycle=v317-final-mcp-authority&build=NEXPROD01_RUNTIME_V317_WRIST_NODE_180_RESTART_2026_08_19&safeBoot=0&lowPower=1&pixelRatioCap=1.15&antialias=1&maxFPS=24&staticAfterReady=0&idleSleepAfterReady=0&v=V317_right",
      "navigationError": null,
      "polls": [
        {
          "i": 0,
          "hasModel": true,
          "hasGrip": true
        }
      ],
      "final": {
        "ready": "complete",
        "href": "http://127.0.0.1:40391/assets/nexprod/nexprod01-player.html?exercise=hurdle-stretch&caseId=v94_right_full&phase=0.75&play=0&debug=0&visualMode=nex&nativeRuntimeParity=1&nativeSkin=1&skinPreset=freeridehuman&readyTimeoutMs=12000&hostLifecycle=v317-final-mcp-authority&build=NEXPROD01_RUNTIME_V317_WRIST_NODE_180_RESTART_2026_08_19&safeBoot=0&lowPower=1&pixelRatioCap=1.15&antialias=1&maxFPS=24&staticAfterReady=0&idleSleepAfterReady=0&v=V317_right",
        "hasDebug": true,
        "hasModel": true,
        "boneCount": 92,
        "skinnedMeshCount": 0,
        "canvasCount": 1,
        "windowMarkers": [
          "__NEXPROD01_DEBUG_SCENE",
          "__NEXPROD01_GRIP_SOLVER_V1",
          "__NEXPROD01_PUBLISH",
          "__NEXPROD01_V100_GRIP_CAPSULE_SURFACE",
          "__NEXPROD01_V102_HEEL_TO_GLUTE_REACH",
          "__NEXPROD01_V110_DISTAL_GRIP_COUPLED",
          "__NEXPROD01_V140_GRIP_HAND_QA_TINT",
          "__NEXPROD01_V151_ACTUAL_MESH_TRUTH",
          "__NEXPROD01_V153_MESH_FEEDBACK",
          "__NEXPROD01_V157_REAL_MEDIAPIPE_HAND_FRAME",
          "__NEXPROD01_V169_LEG_CLOSER_ONLY",
          "__NEXPROD01_V175_LEG_OUT",
          "__NEXPROD01_V184_SNAP_ONLY_FEASIBILITY",
          "__NEXPROD01_V189_PRE_SNAP_NEUTRAL_APPROACH",
          "__NEXPROD01_V198_V195_DELTA_SINGLE_WRITER",
          "__NEXPROD01_V199_LOCK_GREEN_ROLL_PINK",
          "__NEXPROD01_V266_CLEAN_GRIP_CONTRACT",
          "__NEXPROD01_V297_PREFINGER_CHILD_LAYER_GATE",
          "__NEXPROD01_V301_FINGER_CHILD_LAYER_GATE",
          "__NEXPROD01_V304_ZPLUS_SEQUENTIAL_FINGER_CONTACT",
          "__NEXPROD01_V306_ACTUAL_SURFACE_PREFINGER_GATE",
          "__NEXPROD01_V306_ZPLUS_SEQUENTIAL_FINGER_CONTACT",
          "__NEXPROD01_V307_ACTUAL_MCP_PALM_PREFINGER_GATE",
          "__NEXPROD01_V308_ACTUAL_MCP_PALM_PREFINGER_GATE",
          "__NEXPROD01_V308_FINAL_PREFINGER_TRUTH",
          "__NEXPROD01_V309_ACTUAL_MCP_PALM_PREFINGER_GATE",
          "__NEXPROD01_V309_ACTUAL_MCP_WRIST_ROLL_SOLVE",
          "__NEXPROD01_V309_FINAL_PREFINGER_TRUTH",
          "__NEXPROD01_V310_ACTUAL_MCP_PALM_PREFINGER_GATE",
          "__NEXPROD01_V310_POST_COMMIT_MCP_GATE_VERIFY_NO_MUTATION",
          "__NEXPROD01_V311_ACTUAL_MCP_PALM_PREFINGER_GATE",
          "__NEXPROD01_V311_FINAL_PREFINGER_TRUTH",
          "__NEXPROD01_V313_FINAL_PREFINGER_TRUTH",
          "__NEXPROD01_V317_FINAL_PREFINGER_TRUTH",
          "__NEXPROD01_V69_SHIN_GRIP_FINGER_LAYER",
          "__NEXPROD01_V70_BIORIG_FULL_GRIP_LAYER",
          "__NEXPROD01_V93_ACTIVE_HAND_CONTROL_PROBE",
          "__NEXPROD01_V93_RIGHT_HAND_CONTROL_PROBE"
        ],
        "gripSolverV1": {
          "schema": "NEXPROD01_GRIP_SOLVER_V1",
          "version": "V317_FINAL_ACTUAL_MCP_AUTHORITY_GATE",
          "side": "R",
          "applied": true,
          "implemented": true,
          "policy": "V314: actual Index/Pinky MCP + 20mm palm-offset are the only hand contact authority. Old PalmIndexBase/PalmPinkyBase target frames, fitHandPalmPlane and palm-child CCD are bypassed for the active grip side so stale target-palm-basis cannot pull the hand back. Fingers remain blocked unless the post-commit actual MCP palm gate passes.",
          "pass": true,
          "palmContactReady": true,
          "preFingerReady": true,
          "status": "GRIP_ENTRY_CONTRACT_PREFINGER_READY",
          "ruleType": "v94_space_control_right_finger_grip",
          "targetLimb": "R_lower_shin_heel_cylinder",
          "targetSide": "outside_shifted_surface",
          "palmPoints": {
            "pointA": {
              "snap": "pinkyMcpPalm",
              "bone": "R_Pinky1",
              "offsetM": 0.02,
              "role": "first_palm_contact"
            },
            "pointB": {
              "snap": "indexMcpPalm",
              "bone": "R_Index1",
              "offsetM": 0.02,
              "role": "second_palm_contact"
            }
          },
          "limb": {
            "axisA": "R_Foot",
            "axisB": "R_Calf",
            "axisPoint": {
              "x": -0.07882,
              "y": 0.94392,
              "z": -0.32317
            },
            "outside": {
              "x": -0.99311,
              "y": 0.07015,
              "z": -0.09385
            },
            "target": {
              "x": -0.13344,
              "y": 0.94777,
              "z": -0.32833
            },
            "radiusM": 0.052,
            "clearanceM": 0.003,
            "t": 0.16
          },
          "beforeBasis": null,
          "afterAngles": {
            "palmRay_vs_forearm": 24.41,
            "mcpCenter_vs_forearm": 28.34,
            "mcpAxis_vs_forearm": 56.82,
            "palmNormal_vs_forearm": 81.4
          },
          "stages": {
            "neutralPalm": {
              "applied": true,
              "xSource": "raw_index_minus_pinky_projected",
              "beforeAngles": {
                "palmRay_vs_forearm": 68.28,
                "mcpCenter_vs_forearm": 65.66,
                "mcpAxis_vs_forearm": 134.88,
                "palmNormal_vs_forearm": 119.49
              },
              "afterAngles": {
                "palmRay_vs_forearm": 10.68,
                "mcpCenter_vs_forearm": 6.37,
                "mcpAxis_vs_forearm": 90,
                "palmNormal_vs_forearm": 90
              },
              "pass": true,
              "policy": "Solver V1 neutral palm: visible palm/MCP axis follows the forearm before object contact. This is a named solver step, not a historical patch."
            },
            "v307McpPalmSnapAfterNeutral": {
              "schema": "NEXPROD01_V307_MCP_DERIVED_PALM_SNAP_POINTS",
              "ok": true,
              "side": "R",
              "source": "Index1/Pinky1 MCP + 20mm palm-surface offset",
              "firstPalm": "pinky",
              "palmOffsetM": 0.02,
              "palmOffsetDir": {
                "x": 0.64415,
                "y": 0.23407,
                "z": -0.72821
              },
              "mcp": {
                "index": {
                  "x": -0.1867,
                  "y": 0.9006,
                  "z": -0.28355
                },
                "pinky": {
                  "x": -0.2287,
                  "y": 0.92037,
                  "z": -0.31435
                },
                "mid": {
                  "x": -0.20488,
                  "y": 0.90371,
                  "z": -0.29296
                },
                "wrist": {
                  "x": -0.20422,
                  "y": 0.98651,
                  "z": -0.26954
                }
              },
              "palm": {
                "index": {
                  "x": -0.17381,
                  "y": 0.90528,
                  "z": -0.29811
                },
                "pinky": {
                  "x": -0.21582,
                  "y": 0.92505,
                  "z": -0.32891
                }
              },
              "pointA": {
                "x": -0.21582,
                "y": 0.92505,
                "z": -0.32891
              },
              "pointB": {
                "x": -0.17381,
                "y": 0.90528,
                "z": -0.29811
              },
              "basis": {
                "x": {
                  "x": 0.76429,
                  "y": -0.23505,
                  "z": 0.60051
                },
                "y": {
                  "x": -0.03061,
                  "y": -0.94338,
                  "z": -0.3303
                },
                "z": {
                  "x": 0.64415,
                  "y": 0.23407,
                  "z": -0.72821
                },
                "center": {
                  "x": -0.20676,
                  "y": 0.90823,
                  "z": -0.29695
                },
                "handSpanM": 0.05571,
                "handLenM": 0.08298
              },
              "policy": "V307 replaces old learned pointA/pointB phantom coordinates with palm-surface contact points derived from actual Index/Pinky MCP roots plus a ~20 mm palm offset. Debug markers and contact gates must use these points so they stay attached to the real hand."
            },
            "v310PreContact180PalmFrameReset": {
              "schema": "NEXPROD01_V310_PRECONTACT_180_PALM_FRAME_RESET",
              "active": false,
              "applied": false,
              "pass": true,
              "reason": "not_required_for_this_side",
              "side": "R",
              "policy": "V310 forced 180 pre-contact reset is only active where the actual MCP gate showed wrong-way outside-shin palm orientation. No post-commit hand rotation is used."
            },
            "v297EntryFrameGate": {
              "schema": "NEXPROD01_V297_V286_ENTRY_FRAME_GATE",
              "source": "V286_NEUTRALIZE_HAND_FOR_GRIP",
              "active": true,
              "mutatesTargets": false,
              "side": "R",
              "pass": true,
              "gate": "GRIP_ENTRY_FRAME_USABLE",
              "desiredOutsideDistanceM": 0.055,
              "signedOutsideM": 0.12338,
              "palmBaseOutsideM": 0.11954,
              "requiredOutwardShiftM": 0,
              "palmAcrossOutsideDot": -0.82552,
              "limbAxisA": "R_Foot",
              "limbAxisB": "R_Calf",
              "policy": "V297 ports V286 as a non-mutating pre-contact entry-frame gate inside the V267 clean solver. It measures whether the hand MCP/palm frame approaches from the outside shell before point snap, palm roll, or finger child-layer."
            },
            "v306EntryFrameNeutralizeRotation": {
              "schema": "NEXPROD01_V306_ENTRY_FRAME_NEUTRALIZE_ROTATION",
              "active": true,
              "applied": false,
              "pass": true,
              "reason": "initial_entry_frame_pass",
              "axis": {
                "x": -0.14996,
                "y": -0.91227,
                "z": -0.38115
              },
              "before": {
                "schema": "NEXPROD01_V297_V286_ENTRY_FRAME_GATE",
                "source": "V286_NEUTRALIZE_HAND_FOR_GRIP",
                "active": true,
                "mutatesTargets": false,
                "side": "R",
                "pass": true,
                "gate": "GRIP_ENTRY_FRAME_USABLE",
                "desiredOutsideDistanceM": 0.055,
                "signedOutsideM": 0.12338,
                "palmBaseOutsideM": 0.11954,
                "requiredOutwardShiftM": 0,
                "palmAcrossOutsideDot": -0.82552,
                "limbAxisA": "R_Foot",
                "limbAxisB": "R_Calf",
                "policy": "V297 ports V286 as a non-mutating pre-contact entry-frame gate inside the V267 clean solver. It measures whether the hand MCP/palm frame approaches from the outside shell before point snap, palm roll, or finger child-layer."
              },
              "afterGate": {
                "schema": "NEXPROD01_V297_V286_ENTRY_FRAME_GATE",
                "source": "V286_NEUTRALIZE_HAND_FOR_GRIP",
                "active": true,
                "mutatesTargets": false,
                "side": "R",
                "pass": true,
                "gate": "GRIP_ENTRY_FRAME_USABLE",
                "desiredOutsideDistanceM": 0.055,
                "signedOutsideM": 0.12338,
                "palmBaseOutsideM": 0.11954,
                "requiredOutwardShiftM": 0,
                "palmAcrossOutsideDot": -0.82552,
                "limbAxisA": "R_Foot",
                "limbAxisB": "R_Calf",
                "policy": "V297 ports V286 as a non-mutating pre-contact entry-frame gate inside the V267 clean solver. It measures whether the hand MCP/palm frame approaches from the outside shell before point snap, palm roll, or finger child-layer."
              },
              "policy": "V306 state machine: a passing entry-frame gate may continue; no neutralizing rotation is applied."
            },
            "v307McpPalmSnapBeforePointSnap": {
              "schema": "NEXPROD01_V307_MCP_DERIVED_PALM_SNAP_POINTS",
              "ok": true,
              "side": "R",
              "source": "Index1/Pinky1 MCP + 20mm palm-surface offset",
              "firstPalm": "pinky",
              "palmOffsetM": 0.02,
              "palmOffsetDir": {
                "x": 0.64415,
                "y": 0.23407,
                "z": -0.72821
              },
              "mcp": {
                "index": {
                  "x": -0.1867,
                  "y": 0.9006,
                  "z": -0.28355
                },
                "pinky": {
                  "x": -0.2287,
                  "y": 0.92037,
                  "z": -0.31435
                },
                "mid": {
                  "x": -0.20488,
                  "y": 0.90371,
                  "z": -0.29296
                },
                "wrist": {
                  "x": -0.20422,
                  "y": 0.98651,
                  "z": -0.26954
                }
              },
              "palm": {
                "index": {
                  "x": -0.17381,
                  "y": 0.90528,
                  "z": -0.29811
                },
                "pinky": {
                  "x": -0.21582,
                  "y": 0.92505,
                  "z": -0.32891
                }
              },
              "pointA": {
                "x": -0.21582,
                "y": 0.92505,
                "z": -0.32891
              },
              "pointB": {
                "x": -0.17381,
                "y": 0.90528,
                "z": -0.29811
              },
              "basis": {
                "x": {
                  "x": 0.76429,
                  "y": -0.23505,
                  "z": 0.60051
                },
                "y": {
                  "x": -0.03061,
                  "y": -0.94338,
                  "z": -0.3303
                },
                "z": {
                  "x": 0.64415,
                  "y": 0.23407,
                  "z": -0.72821
                },
                "center": {
                  "x": -0.20676,
                  "y": 0.90823,
                  "z": -0.29695
                },
                "handSpanM": 0.05571,
                "handLenM": 0.08298
              },
              "policy": "V307 replaces old learned pointA/pointB phantom coordinates with palm-surface contact points derived from actual Index/Pinky MCP roots plus a ~20 mm palm offset. Debug markers and contact gates must use these points so they stay attached to the real hand."
            },
            "pointASnap": {
              "applied": true,
              "pointA0": {
                "x": -0.21582,
                "y": 0.92505,
                "z": -0.32891
              },
              "pointB0": {
                "x": -0.17381,
                "y": 0.90528,
                "z": -0.29811
              },
              "limbTargetBefore": {
                "x": -0.13344,
                "y": 0.94777,
                "z": -0.32833
              },
              "limbTargetAfter": {
                "x": -0.13344,
                "y": 0.94777,
                "z": -0.32833
              },
              "shift": {
                "x": 0.08238,
                "y": 0.02272,
                "z": 0.00058
              },
              "shiftM": 0.08546,
              "pointAAfter": {
                "x": -0.13343,
                "y": 0.94778,
                "z": -0.32833
              },
              "pointBAfter": {
                "x": -0.09143,
                "y": 0.92801,
                "z": -0.29753
              },
              "arm": {
                "ok": true,
                "distance": 0.4312953227432843,
                "minReach": 0.010498007252821183,
                "maxReach": 0.45141,
                "segmentErrorM": {
                  "upperarm": 0,
                  "forearm": 0
                },
                "clamped": false,
                "desiredDistance": 0.4313,
                "handDelta": {
                  "x": 0.08238,
                  "y": 0.02272,
                  "z": 0.00058
                },
                "legDelta": {
                  "x": 0,
                  "y": 0,
                  "z": 0
                },
                "legDeltaM": 0,
                "segmentLengths": {
                  "thighM": 0.38585,
                  "calfM": 0.39537,
                  "rawThighM": 0.30323,
                  "rawCalfM": 0.37435
                },
                "policy": "Arm reached the outside limb point without target-limb compensation."
              },
              "policy": "Step 1-2 of V300 contract: arm reach / approach places first inside-palm contact on the outside limb snap. If the arm cannot reach, object/leg-meet is the only allowed compensation; fingers/hand-only patches are not owners."
            },
            "v300ObjectMeetGate": {
              "schema": "NEXPROD01_V300_OBJECT_LEG_MEET_SHIFTED_SURFACE_GATE",
              "active": true,
              "applied": false,
              "meetM": 0,
              "maxObjectMeetM": 0.08,
              "pass": true,
              "legDelta": {
                "x": 0,
                "y": 0,
                "z": 0
              },
              "clamped": false,
              "policy": "V300 keeps neutralization in the approach/contact layer. If arm reach cannot place first palm contact, the lower-leg/object target surface may meet the hand up to 80 mm before palm-frame validation. Surface checks must then use the shifted surface, not the original one."
            },
            "v300ForearmAxisSecondPalmRoll": {
              "schema": "NEXPROD01_V300_FOREARM_AXIS_SECOND_PALM_ROLL",
              "active": true,
              "applied": true,
              "pass": true,
              "rollDeg": 61,
              "axis": {
                "x": 0.41612,
                "y": -0.8395,
                "z": -0.34939
              },
              "before": {
                "first": {
                  "radialM": 0.05499,
                  "requiredRadialM": 0.055,
                  "signedOutsideM": 0.05499,
                  "outsideScore": 1,
                  "distanceToSurfaceM": 1e-05,
                  "penetrationM": 1e-05,
                  "surfaceOk": true,
                  "sideOk": true
                },
                "second": {
                  "radialM": 0.02171,
                  "requiredRadialM": 0.055,
                  "signedOutsideM": 0.00901,
                  "outsideScore": 0.41485,
                  "distanceToSurfaceM": 0.03329,
                  "penetrationM": 0.03329,
                  "surfaceOk": false,
                  "sideOk": true
                },
                "pointA": {
                  "x": -0.13343,
                  "y": 0.94778,
                  "z": -0.32833
                },
                "pointB": {
                  "x": -0.09143,
                  "y": 0.92801,
                  "z": -0.29753
                }
              },
              "after": {
                "first": {
                  "radialM": 0.05499,
                  "requiredRadialM": 0.055,
                  "signedOutsideM": 0.05499,
                  "outsideScore": 1,
                  "distanceToSurfaceM": 1e-05,
                  "penetrationM": 1e-05,
                  "surfaceOk": true,
                  "sideOk": true
                },
                "second": {
                  "radialM": 0.05507,
                  "requiredRadialM": 0.055,
                  "signedOutsideM": 0.05197,
                  "outsideScore": 0.94368,
                  "distanceToSurfaceM": 7e-05,
                  "penetrationM": 0,
                  "surfaceOk": true,
                  "sideOk": true
                },
                "pointA": {
                  "x": -0.13343,
                  "y": 0.94778,
                  "z": -0.32833
                },
                "pointB": {
                  "x": -0.13672,
                  "y": 0.90407,
                  "z": -0.29396
                },
                "palmFacesObject": 0.99246,
                "handAcrossVerticalProxy": 0.69822,
                "grossPenetration": false,
                "arm": {
                  "ok": true,
                  "distance": 0.44758551439566524,
                  "minReach": 0.0038722305461482134,
                  "maxReach": 0.4580313693888503,
                  "segmentErrorM": {
                    "upperarm": 0,
                    "forearm": 0
                  }
                }
              },
              "policy": "V300 contract step 3: keep the first palm contact fixed, then rotate the rigid hand/palm frame around the active wrist/forearm axis to bring the second palm point toward the shifted outside limb surface. Fingers remain blocked for visual approval."
            },
            "v307McpPalmSnapAfterForearmRoll": {
              "schema": "NEXPROD01_V307_MCP_DERIVED_PALM_SNAP_POINTS",
              "ok": true,
              "side": "R",
              "source": "Index1/Pinky1 MCP + 20mm palm-surface offset",
              "firstPalm": "pinky",
              "palmOffsetM": 0.02,
              "palmOffsetDir": {
                "x": 0.98838,
                "y": 0.04068,
                "z": 0.14643
              },
              "mcp": {
                "index": {
                  "x": -0.15649,
                  "y": 0.90325,
                  "z": -0.29689
                },
                "pinky": {
                  "x": -0.1532,
                  "y": 0.94696,
                  "z": -0.33126
                },
                "mid": {
                  "x": -0.15892,
                  "y": 0.91672,
                  "z": -0.31243
                },
                "wrist": {
                  "x": -0.16709,
                  "y": 0.98162,
                  "z": -0.25652
                }
              },
              "palm": {
                "index": {
                  "x": -0.13672,
                  "y": 0.90407,
                  "z": -0.29396
                },
                "pinky": {
                  "x": -0.13343,
                  "y": 0.94778,
                  "z": -0.32833
                }
              },
              "pointA": {
                "x": -0.13343,
                "y": 0.94778,
                "z": -0.32833
              },
              "pointB": {
                "x": -0.13672,
                "y": 0.90407,
                "z": -0.29396
              },
              "basis": {
                "x": {
                  "x": -0.07671,
                  "y": -0.69822,
                  "z": 0.71176
                },
                "y": {
                  "x": 0.1312,
                  "y": -0.71473,
                  "z": -0.68699
                },
                "z": {
                  "x": 0.98838,
                  "y": 0.04068,
                  "z": 0.14643
                },
                "center": {
                  "x": -0.1562,
                  "y": 0.92231,
                  "z": -0.31353
                },
                "handSpanM": 0.05571,
                "handLenM": 0.08298
              },
              "policy": "V307 replaces old learned pointA/pointB phantom coordinates with palm-surface contact points derived from actual Index/Pinky MCP roots plus a ~20 mm palm offset. Debug markers and contact gates must use these points so they stay attached to the real hand."
            },
            "v301SideSurfaceContactGate": {
              "schema": "NEXPROD01_V301_SIDE_SURFACE_CONTACT_GATE",
              "active": true,
              "pass": true,
              "palmContactReady": true,
              "preFingerReady": true,
              "status": "GRIP_ENTRY_CONTRACT_PREFINGER_READY",
              "checks": {
                "handPalmTowardObject": true,
                "firstPalmOnShiftedSurface": true,
                "secondPalmOnShiftedSurface": true,
                "outsideContact": true,
                "noGrossPenetration": true,
                "objectMeetWithinLimit": true,
                "firstSignedOutsideM": 0.05499,
                "secondSignedOutsideM": 0.05197,
                "firstPenetrationM": 1e-05,
                "secondPenetrationM": 0,
                "firstOutsideScore": 1,
                "secondOutsideScore": 0.94368
              },
              "policy": "V301 replaces the explicit thumb-down requirement with a generic side/surface/penetration gate. The solver only checks that palm-side contact is on the intended object side, both palm points remain on the shifted outside surface, the palm faces the object, and the hand has not snapped through or penetrated the object. Thumb orientation is an emergent result of correct side contact, not a global constraint."
            }
          },
          "nextPhase": "finger_child_layer_ready_but_deferred_to_v302_integration",
          "notes": [
            "V301 side/surface/penetration gate passed without an explicit thumb-direction constraint",
            "first palm contact was held while wrist/forearm-axis roll searched the second palm point",
            "shifted-surface gate is evaluated after object/leg meet",
            "finger writes remain deferred by default so V301 only changes contact gating"
          ]
        },
        "finalTruth": {
          "schema": "NEXPROD01_V317_FINAL_PREFINGER_TRUTH",
          "active": true,
          "side": "R",
          "pass": true,
          "status": "ACTUAL_MCP_PALM_PREFINGER_READY",
          "wrongWay": false,
          "orientationFail": false,
          "solverSideStatus": "GRIP_ENTRY_CONTRACT_PREFINGER_READY",
          "solverSidePass": true,
          "actualWristRollSolve": {
            "schema": "NEXPROD01_V310_POST_COMMIT_MCP_GATE_VERIFY_NO_MUTATION",
            "active": true,
            "applied": false,
            "pass": true,
            "side": "R",
            "reason": "actual_mcp_gate_passed_after_precontact_reset",
            "after": {
              "schema": "NEXPROD01_V308_ACTUAL_MCP_PALM_ORIENTATION_GATE",
              "active": true,
              "side": "R",
              "pass": true,
              "status": "ACTUAL_MCP_PALM_CONTACT_READY",
              "orientationFail": false,
              "palmPlateTwistedThroughObject": false,
              "indexDeepInside": false,
              "pinkyDeepInside": false,
              "onePalmNearSurface": true,
              "oppositePalmDeepInside": false,
              "diagnosis": "actual MCP palm side/surface check",
              "points": {
                "index": {
                  "x": -0.13621,
                  "y": 0.70253,
                  "z": -0.29452
                },
                "pinky": {
                  "x": -0.13291,
                  "y": 0.74624,
                  "z": -0.3289
                },
                "mcpIndex": {
                  "x": -0.15597,
                  "y": 0.70172,
                  "z": -0.29745
                },
                "mcpPinky": {
                  "x": -0.15268,
                  "y": 0.74543,
                  "z": -0.33182
                },
                "mcpMid": {
                  "x": -0.1584,
                  "y": 0.71519,
                  "z": -0.31299
                },
                "wrist": {
                  "x": -0.16657,
                  "y": 0.78008,
                  "z": -0.25708
                }
              },
              "basis": {
                "x": {
                  "x": -0.07671,
                  "y": -0.69822,
                  "z": 0.71176
                },
                "y": {
                  "x": 0.1312,
                  "y": -0.71473,
                  "z": -0.68699
                },
                "z": {
                  "x": 0.98838,
                  "y": 0.04068,
                  "z": 0.14643
                },
                "palmFacesObject": 0.99246,
                "offsetM": 0.02
              },
              "limb": {
                "axisPoint": {
                  "x": -0.07883,
                  "y": 0.74301,
                  "z": -0.32287
                },
                "axis": {
                  "x": -0.09696,
                  "y": -0.94174,
                  "z": 0.32205
                },
                "outward": {
                  "x": -0.99311,
                  "y": 0.07015,
                  "z": -0.09385
                },
                "radiusM": 0.052,
                "clearanceM": 0.003
              },
              "metrics": {
                "index": {
                  "radialM": 0.05427,
                  "requiredRadialM": 0.055,
                  "signedOutsideM": 0.05148,
                  "outsideScore": 0.94866,
                  "distanceToSurfaceM": 0.00073,
                  "penetrationM": 0.00073,
                  "surfaceOk": true,
                  "sideOk": true
                },
                "pinky": {
                  "radialM": 0.05451,
                  "requiredRadialM": 0.055,
                  "signedOutsideM": 0.0545,
                  "outsideScore": 0.99981,
                  "distanceToSurfaceM": 0.00049,
                  "penetrationM": 0.00049,
                  "surfaceOk": true,
                  "sideOk": true
                },
                "noGrossPenetration": true
              },
              "policy": "V308 post-commit actual gate: use actual Index1/Pinky1 MCP roots plus 20 mm palm offset against the actual lower-leg capsule. If pinky/index asymmetrically penetrates while the other contact point is on the surface, the hand is wrong-way/twisted through the object and fingers are blocked regardless of solver-side PREFINGER_READY."
            },
            "policy": "V310 explicitly forbids the V309-style post-commit wrist/hand roll as a fix. If the actual gate fails, the next solve must go back before arm snap/contact and restart; no after-the-fact hand rotation and no finger release."
          },
          "actualGate": {
            "schema": "NEXPROD01_V317_ACTUAL_MCP_PALM_PREFINGER_GATE",
            "status": "ACTUAL_MCP_PALM_PREFINGER_READY",
            "orientationFail": false,
            "wrongWay": false,
            "active": true,
            "side": "R",
            "pass": true,
            "entryOk": true,
            "solverOk": true,
            "legacySolverOk": true,
            "actualMcpAuthorityOk": false,
            "meshPass": false,
            "palmGapOk": false,
            "palmGapM": 0.027546,
            "v307ActualMcpPalmGate": {
              "schema": "NEXPROD01_V308_ACTUAL_MCP_PALM_ORIENTATION_GATE",
              "active": true,
              "side": "R",
              "pass": true,
              "status": "ACTUAL_MCP_PALM_CONTACT_READY",
              "orientationFail": false,
              "palmPlateTwistedThroughObject": false,
              "indexDeepInside": false,
              "pinkyDeepInside": false,
              "onePalmNearSurface": true,
              "oppositePalmDeepInside": false,
              "diagnosis": "actual MCP palm side/surface check",
              "points": {
                "index": {
                  "x": -0.13621,
                  "y": 0.70253,
                  "z": -0.29452
                },
                "pinky": {
                  "x": -0.13291,
                  "y": 0.74624,
                  "z": -0.3289
                },
                "mcpIndex": {
                  "x": -0.15597,
                  "y": 0.70172,
                  "z": -0.29745
                },
                "mcpPinky": {
                  "x": -0.15268,
                  "y": 0.74543,
                  "z": -0.33182
                },
                "mcpMid": {
                  "x": -0.1584,
                  "y": 0.71519,
                  "z": -0.31299
                },
                "wrist": {
                  "x": -0.16657,
                  "y": 0.78008,
                  "z": -0.25708
                }
              },
              "basis": {
                "x": {
                  "x": -0.07671,
                  "y": -0.69822,
                  "z": 0.71176
                },
                "y": {
                  "x": 0.1312,
                  "y": -0.71473,
                  "z": -0.68699
                },
                "z": {
                  "x": 0.98838,
                  "y": 0.04068,
                  "z": 0.14643
                },
                "palmFacesObject": 0.99246,
                "offsetM": 0.02
              },
              "limb": {
                "axisPoint": {
                  "x": -0.07883,
                  "y": 0.74301,
                  "z": -0.32287
                },
                "axis": {
                  "x": -0.09696,
                  "y": -0.94174,
                  "z": 0.32205
                },
                "outward": {
                  "x": -0.99311,
                  "y": 0.07015,
                  "z": -0.09385
                },
                "radiusM": 0.052,
                "clearanceM": 0.003
              },
              "metrics": {
                "index": {
                  "radialM": 0.05427,
                  "requiredRadialM": 0.055,
                  "signedOutsideM": 0.05148,
                  "outsideScore": 0.94866,
                  "distanceToSurfaceM": 0.00073,
                  "penetrationM": 0.00073,
                  "surfaceOk": true,
                  "sideOk": true
                },
                "pinky": {
                  "radialM": 0.05451,
                  "requiredRadialM": 0.055,
                  "signedOutsideM": 0.0545,
                  "outsideScore": 0.99981,
                  "distanceToSurfaceM": 0.00049,
                  "penetrationM": 0.00049,
                  "surfaceOk": true,
                  "sideOk": true
                },
                "noGrossPenetration": true
              },
              "policy": "V308 post-commit actual gate: use actual Index1/Pinky1 MCP roots plus 20 mm palm offset against the actual lower-leg capsule. If pinky/index asymmetrically penetrates while the other contact point is on the surface, the hand is wrong-way/twisted through the object and fingers are blocked regardless of solver-side PREFINGER_READY."
            },
            "postFloorActualMcpSolve": null,
            "entryFrameGate": {
              "schema": "NEXPROD01_V297_V286_ENTRY_FRAME_GATE",
              "source": "V286_NEUTRALIZE_HAND_FOR_GRIP",
              "active": true,
              "mutatesTargets": false,
              "side": "R",
              "pass": true,
              "gate": "GRIP_ENTRY_FRAME_USABLE",
              "desiredOutsideDistanceM": 0.055,
              "signedOutsideM": 0.12338,
              "palmBaseOutsideM": 0.11954,
              "requiredOutwardShiftM": 0,
              "palmAcrossOutsideDot": -0.82552,
              "limbAxisA": "R_Foot",
              "limbAxisB": "R_Calf",
              "policy": "V297 ports V286 as a non-mutating pre-contact entry-frame gate inside the V267 clean solver. It measures whether the hand MCP/palm frame approaches from the outside shell before point snap, palm roll, or finger child-layer."
            },
            "entryRepair": {
              "schema": "NEXPROD01_V306_ENTRY_FRAME_NEUTRALIZE_ROTATION",
              "active": true,
              "applied": false,
              "pass": true,
              "reason": "initial_entry_frame_pass",
              "axis": {
                "x": -0.14996,
                "y": -0.91227,
                "z": -0.38115
              },
              "before": {
                "schema": "NEXPROD01_V297_V286_ENTRY_FRAME_GATE",
                "source": "V286_NEUTRALIZE_HAND_FOR_GRIP",
                "active": true,
                "mutatesTargets": false,
                "side": "R",
                "pass": true,
                "gate": "GRIP_ENTRY_FRAME_USABLE",
                "desiredOutsideDistanceM": 0.055,
                "signedOutsideM": 0.12338,
                "palmBaseOutsideM": 0.11954,
                "requiredOutwardShiftM": 0,
                "palmAcrossOutsideDot": -0.82552,
                "limbAxisA": "R_Foot",
                "limbAxisB": "R_Calf",
                "policy": "V297 ports V286 as a non-mutating pre-contact entry-frame gate inside the V267 clean solver. It measures whether the hand MCP/palm frame approaches from the outside shell before point snap, palm roll, or finger child-layer."
              },
              "afterGate": {
                "schema": "NEXPROD01_V297_V286_ENTRY_FRAME_GATE",
                "source": "V286_NEUTRALIZE_HAND_FOR_GRIP",
                "active": true,
                "mutatesTargets": false,
                "side": "R",
                "pass": true,
                "gate": "GRIP_ENTRY_FRAME_USABLE",
                "desiredOutsideDistanceM": 0.055,
                "signedOutsideM": 0.12338,
                "palmBaseOutsideM": 0.11954,
                "requiredOutwardShiftM": 0,
                "palmAcrossOutsideDot": -0.82552,
                "limbAxisA": "R_Foot",
                "limbAxisB": "R_Calf",
                "policy": "V297 ports V286 as a non-mutating pre-contact entry-frame gate inside the V267 clean solver. It measures whether the hand MCP/palm frame approaches from the outside shell before point snap, palm roll, or finger child-layer."
              },
              "policy": "V306 state machine: a passing entry-frame gate may continue; no neutralizing rotation is applied."
            },
            "sideSurfaceGate": {
              "pass": true,
              "status": "GRIP_ENTRY_CONTRACT_PREFINGER_READY",
              "checks": {
                "handPalmTowardObject": true,
                "firstPalmOnShiftedSurface": true,
                "secondPalmOnShiftedSurface": true,
                "outsideContact": true,
                "noGrossPenetration": true,
                "objectMeetWithinLimit": true,
                "firstSignedOutsideM": 0.05499,
                "secondSignedOutsideM": 0.05197,
                "firstPenetrationM": 1e-05,
                "secondPenetrationM": 0,
                "firstOutsideScore": 1,
                "secondOutsideScore": 0.94368
              }
            },
            "v153MeshFeedbackPass": false,
            "policy": "V317 cuts the stale solver-side gate from active left grip final authority. If the post-floor actual MCP+20mm solve passes and the current actual MCP gate passes, pre-finger readiness may pass even when old target-space sideSurfaceGate/solver status is stale. No thumb-up/down rule is used; the final authority is actual palm side/surface/penetration."
          },
          "policy": "V317 final pre-finger truth is post-commit actual MCP palm orientation/surface gate after the pre-contact 180 reset and restarted arm snap. Post-commit hand roll is disabled; if actual MCP palm contact still fails, fingers remain blocked."
        },
        "actualGate": {
          "schema": "NEXPROD01_V317_ACTUAL_MCP_PALM_PREFINGER_GATE",
          "status": "ACTUAL_MCP_PALM_PREFINGER_READY",
          "orientationFail": false,
          "wrongWay": false,
          "active": true,
          "side": "R",
          "pass": true,
          "entryOk": true,
          "solverOk": true,
          "legacySolverOk": true,
          "actualMcpAuthorityOk": false,
          "meshPass": false,
          "palmGapOk": false,
          "palmGapM": 0.027546,
          "v307ActualMcpPalmGate": {
            "schema": "NEXPROD01_V308_ACTUAL_MCP_PALM_ORIENTATION_GATE",
            "active": true,
            "side": "R",
            "pass": true,
            "status": "ACTUAL_MCP_PALM_CONTACT_READY",
            "orientationFail": false,
            "palmPlateTwistedThroughObject": false,
            "indexDeepInside": false,
            "pinkyDeepInside": false,
            "onePalmNearSurface": true,
            "oppositePalmDeepInside": false,
            "diagnosis": "actual MCP palm side/surface check",
            "points": {
              "index": {
                "x": -0.13621,
                "y": 0.70253,
                "z": -0.29452
              },
              "pinky": {
                "x": -0.13291,
                "y": 0.74624,
                "z": -0.3289
              },
              "mcpIndex": {
                "x": -0.15597,
                "y": 0.70172,
                "z": -0.29745
              },
              "mcpPinky": {
                "x": -0.15268,
                "y": 0.74543,
                "z": -0.33182
              },
              "mcpMid": {
                "x": -0.1584,
                "y": 0.71519,
                "z": -0.31299
              },
              "wrist": {
                "x": -0.16657,
                "y": 0.78008,
                "z": -0.25708
              }
            },
            "basis": {
              "x": {
                "x": -0.07671,
                "y": -0.69822,
                "z": 0.71176
              },
              "y": {
                "x": 0.1312,
                "y": -0.71473,
                "z": -0.68699
              },
              "z": {
                "x": 0.98838,
                "y": 0.04068,
                "z": 0.14643
              },
              "palmFacesObject": 0.99246,
              "offsetM": 0.02
            },
            "limb": {
              "axisPoint": {
                "x": -0.07883,
                "y": 0.74301,
                "z": -0.32287
              },
              "axis": {
                "x": -0.09696,
                "y": -0.94174,
                "z": 0.32205
              },
              "outward": {
                "x": -0.99311,
                "y": 0.07015,
                "z": -0.09385
              },
              "radiusM": 0.052,
              "clearanceM": 0.003
            },
            "metrics": {
              "index": {
                "radialM": 0.05427,
                "requiredRadialM": 0.055,
                "signedOutsideM": 0.05148,
                "outsideScore": 0.94866,
                "distanceToSurfaceM": 0.00073,
                "penetrationM": 0.00073,
                "surfaceOk": true,
                "sideOk": true
              },
              "pinky": {
                "radialM": 0.05451,
                "requiredRadialM": 0.055,
                "signedOutsideM": 0.0545,
                "outsideScore": 0.99981,
                "distanceToSurfaceM": 0.00049,
                "penetrationM": 0.00049,
                "surfaceOk": true,
                "sideOk": true
              },
              "noGrossPenetration": true
            },
            "policy": "V308 post-commit actual gate: use actual Index1/Pinky1 MCP roots plus 20 mm palm offset against the actual lower-leg capsule. If pinky/index asymmetrically penetrates while the other contact point is on the surface, the hand is wrong-way/twisted through the object and fingers are blocked regardless of solver-side PREFINGER_READY."
          },
          "postFloorActualMcpSolve": null,
          "entryFrameGate": {
            "schema": "NEXPROD01_V297_V286_ENTRY_FRAME_GATE",
            "source": "V286_NEUTRALIZE_HAND_FOR_GRIP",
            "active": true,
            "mutatesTargets": false,
            "side": "R",
            "pass": true,
            "gate": "GRIP_ENTRY_FRAME_USABLE",
            "desiredOutsideDistanceM": 0.055,
            "signedOutsideM": 0.12338,
            "palmBaseOutsideM": 0.11954,
            "requiredOutwardShiftM": 0,
            "palmAcrossOutsideDot": -0.82552,
            "limbAxisA": "R_Foot",
            "limbAxisB": "R_Calf",
            "policy": "V297 ports V286 as a non-mutating pre-contact entry-frame gate inside the V267 clean solver. It measures whether the hand MCP/palm frame approaches from the outside shell before point snap, palm roll, or finger child-layer."
          },
          "entryRepair": {
            "schema": "NEXPROD01_V306_ENTRY_FRAME_NEUTRALIZE_ROTATION",
            "active": true,
            "applied": false,
            "pass": true,
            "reason": "initial_entry_frame_pass",
            "axis": {
              "x": -0.14996,
              "y": -0.91227,
              "z": -0.38115
            },
            "before": {
              "schema": "NEXPROD01_V297_V286_ENTRY_FRAME_GATE",
              "source": "V286_NEUTRALIZE_HAND_FOR_GRIP",
              "active": true,
              "mutatesTargets": false,
              "side": "R",
              "pass": true,
              "gate": "GRIP_ENTRY_FRAME_USABLE",
              "desiredOutsideDistanceM": 0.055,
              "signedOutsideM": 0.12338,
              "palmBaseOutsideM": 0.11954,
              "requiredOutwardShiftM": 0,
              "palmAcrossOutsideDot": -0.82552,
              "limbAxisA": "R_Foot",
              "limbAxisB": "R_Calf",
              "policy": "V297 ports V286 as a non-mutating pre-contact entry-frame gate inside the V267 clean solver. It measures whether the hand MCP/palm frame approaches from the outside shell before point snap, palm roll, or finger child-layer."
            },
            "afterGate": {
              "schema": "NEXPROD01_V297_V286_ENTRY_FRAME_GATE",
              "source": "V286_NEUTRALIZE_HAND_FOR_GRIP",
              "active": true,
              "mutatesTargets": false,
              "side": "R",
              "pass": true,
              "gate": "GRIP_ENTRY_FRAME_USABLE",
              "desiredOutsideDistanceM": 0.055,
              "signedOutsideM": 0.12338,
              "palmBaseOutsideM": 0.11954,
              "requiredOutwardShiftM": 0,
              "palmAcrossOutsideDot": -0.82552,
              "limbAxisA": "R_Foot",
              "limbAxisB": "R_Calf",
              "policy": "V297 ports V286 as a non-mutating pre-contact entry-frame gate inside the V267 clean solver. It measures whether the hand MCP/palm frame approaches from the outside shell before point snap, palm roll, or finger child-layer."
            },
            "policy": "V306 state machine: a passing entry-frame gate may continue; no neutralizing rotation is applied."
          },
          "sideSurfaceGate": {
            "pass": true,
            "status": "GRIP_ENTRY_CONTRACT_PREFINGER_READY",
            "checks": {
              "handPalmTowardObject": true,
              "firstPalmOnShiftedSurface": true,
              "secondPalmOnShiftedSurface": true,
              "outsideContact": true,
              "noGrossPenetration": true,
              "objectMeetWithinLimit": true,
              "firstSignedOutsideM": 0.05499,
              "secondSignedOutsideM": 0.05197,
              "firstPenetrationM": 1e-05,
              "secondPenetrationM": 0,
              "firstOutsideScore": 1,
              "secondOutsideScore": 0.94368
            }
          },
          "v153MeshFeedbackPass": false,
          "policy": "V317 cuts the stale solver-side gate from active left grip final authority. If the post-floor actual MCP+20mm solve passes and the current actual MCP gate passes, pre-finger readiness may pass even when old target-space sideSurfaceGate/solver status is stale. No thumb-up/down rule is used; the final authority is actual palm side/surface/penetration."
        },
        "fingerLayer": {
          "schema": "NEXPROD01_V313_ZPLUS_SEQUENTIAL_FINGER_CONTACT_CHILD_LAYER",
          "active": false,
          "blocked": true,
          "ready": true,
          "releaseEnabled": false,
          "side": "R",
          "reason": "side_surface_gate_passed_finger_release_deferred_to_V302_child_only_integration",
          "contractStatus": "GRIP_ENTRY_CONTRACT_PREFINGER_READY",
          "sideGate": {
            "schema": "NEXPROD01_V301_SIDE_SURFACE_CONTACT_GATE",
            "active": true,
            "pass": true,
            "palmContactReady": true,
            "preFingerReady": true,
            "status": "GRIP_ENTRY_CONTRACT_PREFINGER_READY",
            "checks": {
              "handPalmTowardObject": true,
              "firstPalmOnShiftedSurface": true,
              "secondPalmOnShiftedSurface": true,
              "outsideContact": true,
              "noGrossPenetration": true,
              "objectMeetWithinLimit": true,
              "firstSignedOutsideM": 0.05499,
              "secondSignedOutsideM": 0.05197,
              "firstPenetrationM": 1e-05,
              "secondPenetrationM": 0,
              "firstOutsideScore": 1,
              "secondOutsideScore": 0.94368
            },
            "policy": "V301 replaces the explicit thumb-down requirement with a generic side/surface/penetration gate. The solver only checks that palm-side contact is on the intended object side, both palm points remain on the shifted outside surface, the palm faces the object, and the hand has not snapped through or penetrated the object. Thumb orientation is an emergent result of correct side contact, not a global constraint."
          },
          "policy": "V315: fingers remain child-layer and are deliberately not released unless the actual MCP side/surface/orientation gate passes after the pre-contact 180 reset and restarted arm snap. Post-commit hand roll is disabled; wrong-way palm penetration blocks fingers even if the solver-side target gate said PREFINGER_READY.",
          "v306ActualSurfacePreFingerGate": {
            "schema": "NEXPROD01_V317_ACTUAL_MCP_PALM_PREFINGER_GATE",
            "status": "ACTUAL_MCP_PALM_PREFINGER_READY",
            "orientationFail": false,
            "wrongWay": false,
            "active": true,
            "side": "R",
            "pass": true,
            "entryOk": true,
            "solverOk": true,
            "legacySolverOk": true,
            "actualMcpAuthorityOk": false,
            "meshPass": false,
            "palmGapOk": false,
            "palmGapM": 0.027546,
            "v307ActualMcpPalmGate": {
              "schema": "NEXPROD01_V308_ACTUAL_MCP_PALM_ORIENTATION_GATE",
              "active": true,
              "side": "R",
              "pass": true,
              "status": "ACTUAL_MCP_PALM_CONTACT_READY",
              "orientationFail": false,
              "palmPlateTwistedThroughObject": false,
              "indexDeepInside": false,
              "pinkyDeepInside": false,
              "onePalmNearSurface": true,
              "oppositePalmDeepInside": false,
              "diagnosis": "actual MCP palm side/surface check",
              "points": {
                "index": {
                  "x": -0.13621,
                  "y": 0.70253,
                  "z": -0.29452
                },
                "pinky": {
                  "x": -0.13291,
                  "y": 0.74624,
                  "z": -0.3289
                },
                "mcpIndex": {
                  "x": -0.15597,
                  "y": 0.70172,
                  "z": -0.29745
                },
                "mcpPinky": {
                  "x": -0.15268,
                  "y": 0.74543,
                  "z": -0.33182
                },
                "mcpMid": {
                  "x": -0.1584,
                  "y": 0.71519,
                  "z": -0.31299
                },
                "wrist": {
                  "x": -0.16657,
                  "y": 0.78008,
                  "z": -0.25708
                }
              },
              "basis": {
                "x": {
                  "x": -0.07671,
                  "y": -0.69822,
                  "z": 0.71176
                },
                "y": {
                  "x": 0.1312,
                  "y": -0.71473,
                  "z": -0.68699
                },
                "z": {
                  "x": 0.98838,
                  "y": 0.04068,
                  "z": 0.14643
                },
                "palmFacesObject": 0.99246,
                "offsetM": 0.02
              },
              "limb": {
                "axisPoint": {
                  "x": -0.07883,
                  "y": 0.74301,
                  "z": -0.32287
                },
                "axis": {
                  "x": -0.09696,
                  "y": -0.94174,
                  "z": 0.32205
                },
                "outward": {
                  "x": -0.99311,
                  "y": 0.07015,
                  "z": -0.09385
                },
                "radiusM": 0.052,
                "clearanceM": 0.003
              },
              "metrics": {
                "index": {
                  "radialM": 0.05427,
                  "requiredRadialM": 0.055,
                  "signedOutsideM": 0.05148,
                  "outsideScore": 0.94866,
                  "distanceToSurfaceM": 0.00073,
                  "penetrationM": 0.00073,
                  "surfaceOk": true,
                  "sideOk": true
                },
                "pinky": {
                  "radialM": 0.05451,
                  "requiredRadialM": 0.055,
                  "signedOutsideM": 0.0545,
                  "outsideScore": 0.99981,
                  "distanceToSurfaceM": 0.00049,
                  "penetrationM": 0.00049,
                  "surfaceOk": true,
                  "sideOk": true
                },
                "noGrossPenetration": true
              },
              "policy": "V308 post-commit actual gate: use actual Index1/Pinky1 MCP roots plus 20 mm palm offset against the actual lower-leg capsule. If pinky/index asymmetrically penetrates while the other contact point is on the surface, the hand is wrong-way/twisted through the object and fingers are blocked regardless of solver-side PREFINGER_READY."
            },
            "postFloorActualMcpSolve": null,
            "entryFrameGate": {
              "schema": "NEXPROD01_V297_V286_ENTRY_FRAME_GATE",
              "source": "V286_NEUTRALIZE_HAND_FOR_GRIP",
              "active": true,
              "mutatesTargets": false,
              "side": "R",
              "pass": true,
              "gate": "GRIP_ENTRY_FRAME_USABLE",
              "desiredOutsideDistanceM": 0.055,
              "signedOutsideM": 0.12338,
              "palmBaseOutsideM": 0.11954,
              "requiredOutwardShiftM": 0,
              "palmAcrossOutsideDot": -0.82552,
              "limbAxisA": "R_Foot",
              "limbAxisB": "R_Calf",
              "policy": "V297 ports V286 as a non-mutating pre-contact entry-frame gate inside the V267 clean solver. It measures whether the hand MCP/palm frame approaches from the outside shell before point snap, palm roll, or finger child-layer."
            },
            "entryRepair": {
              "schema": "NEXPROD01_V306_ENTRY_FRAME_NEUTRALIZE_ROTATION",
              "active": true,
              "applied": false,
              "pass": true,
              "reason": "initial_entry_frame_pass",
              "axis": {
                "x": -0.14996,
                "y": -0.91227,
                "z": -0.38115
              },
              "before": {
                "schema": "NEXPROD01_V297_V286_ENTRY_FRAME_GATE",
                "source": "V286_NEUTRALIZE_HAND_FOR_GRIP",
                "active": true,
                "mutatesTargets": false,
                "side": "R",
                "pass": true,
                "gate": "GRIP_ENTRY_FRAME_USABLE",
                "desiredOutsideDistanceM": 0.055,
                "signedOutsideM": 0.12338,
                "palmBaseOutsideM": 0.11954,
                "requiredOutwardShiftM": 0,
                "palmAcrossOutsideDot": -0.82552,
                "limbAxisA": "R_Foot",
                "limbAxisB": "R_Calf",
                "policy": "V297 ports V286 as a non-mutating pre-contact entry-frame gate inside the V267 clean solver. It measures whether the hand MCP/palm frame approaches from the outside shell before point snap, palm roll, or finger child-layer."
              },
              "afterGate": {
                "schema": "NEXPROD01_V297_V286_ENTRY_FRAME_GATE",
                "source": "V286_NEUTRALIZE_HAND_FOR_GRIP",
                "active": true,
                "mutatesTargets": false,
                "side": "R",
                "pass": true,
                "gate": "GRIP_ENTRY_FRAME_USABLE",
                "desiredOutsideDistanceM": 0.055,
                "signedOutsideM": 0.12338,
                "palmBaseOutsideM": 0.11954,
                "requiredOutwardShiftM": 0,
                "palmAcrossOutsideDot": -0.82552,
                "limbAxisA": "R_Foot",
                "limbAxisB": "R_Calf",
                "policy": "V297 ports V286 as a non-mutating pre-contact entry-frame gate inside the V267 clean solver. It measures whether the hand MCP/palm frame approaches from the outside shell before point snap, palm roll, or finger child-layer."
              },
              "policy": "V306 state machine: a passing entry-frame gate may continue; no neutralizing rotation is applied."
            },
            "sideSurfaceGate": {
              "pass": true,
              "status": "GRIP_ENTRY_CONTRACT_PREFINGER_READY",
              "checks": {
                "handPalmTowardObject": true,
                "firstPalmOnShiftedSurface": true,
                "secondPalmOnShiftedSurface": true,
                "outsideContact": true,
                "noGrossPenetration": true,
                "objectMeetWithinLimit": true,
                "firstSignedOutsideM": 0.05499,
                "secondSignedOutsideM": 0.05197,
                "firstPenetrationM": 1e-05,
                "secondPenetrationM": 0,
                "firstOutsideScore": 1,
                "secondOutsideScore": 0.94368
              }
            },
            "v153MeshFeedbackPass": false,
            "policy": "V317 cuts the stale solver-side gate from active left grip final authority. If the post-floor actual MCP+20mm solve passes and the current actual MCP gate passes, pre-finger readiness may pass even when old target-space sideSurfaceGate/solver status is stale. No thumb-up/down rule is used; the final authority is actual palm side/surface/penetration."
          }
        },
        "commitMode": null,
        "v317Step": null,
        "bones": {
          "error": "ReferenceError: THREE is not defined"
        },
        "bodyText": "NEXPROD01\none writer\nsleep\nNEXPLAYER RUNTIME\nDynamic Warm Up \u00b7 02 \u00b7 Hurdle stretch\nhurdle-stretch \u2192 warmup_hurdle_stretch_right_pose_v50_ik_v1 \u00b7 for_nex_approval \u00b7 ikHash addc0aae \u00b7 phase 0.750\nCHECK"
      },
      "summary": {
        "hasModel": true,
        "boneCount": 92,
        "skinnedMeshCount": 0,
        "runtimeVersion": "V317_FINAL_ACTUAL_MCP_AUTHORITY_GATE",
        "side": "R",
        "gripPass": true,
        "gripStatus": "GRIP_ENTRY_CONTRACT_PREFINGER_READY",
        "v317StepApplied": null,
        "v317StepPass": null,
        "v317ChangedFingerLocals": 0,
        "v317RotationDeg": null,
        "actualGatePass": true,
        "actualGateStatus": "ACTUAL_MCP_PALM_PREFINGER_READY",
        "wrongWay": false,
        "orientationFail": false,
        "indexPen": 0.00073,
        "pinkyPen": 0.00049,
        "indexDist": 0.00073,
        "pinkyDist": 0.00049,
        "fingerBlocked": true,
        "fingerActive": false,
        "fingerReady": true
      },
      "screenshotCanvas": "/mnt/data/nex_v317_final_mcp_authority_gate/NEXT11_V317_FINAL_ACTUAL_MCP_AUTHORITY_GATE_ROOT/diagnostics/v317/V317_right_canvas.png",
      "screenshotPage": "/mnt/data/nex_v317_final_mcp_authority_gate/NEXT11_V317_FINAL_ACTUAL_MCP_AUTHORITY_GATE_ROOT/diagnostics/v317/V317_right_page.png"
    },
    {
      "name": "left",
      "caseId": "v94_left_full",
      "phase": "0.25",
      "url": "http://127.0.0.1:40391/assets/nexprod/nexprod01-player.html?exercise=hurdle-stretch&caseId=v94_left_full&phase=0.25&play=0&debug=0&visualMode=nex&nativeRuntimeParity=1&nativeSkin=1&skinPreset=freeridehuman&readyTimeoutMs=12000&hostLifecycle=v317-final-mcp-authority&build=NEXPROD01_RUNTIME_V317_WRIST_NODE_180_RESTART_2026_08_19&safeBoot=0&lowPower=1&pixelRatioCap=1.15&antialias=1&maxFPS=24&staticAfterReady=0&idleSleepAfterReady=0&v=V317_left",
      "navigationError": null,
      "polls": [
        {
          "i": 0,
          "hasModel": true,
          "hasGrip": true
        }
      ],
      "final": {
        "ready": "complete",
        "href": "http://127.0.0.1:40391/assets/nexprod/nexprod01-player.html?exercise=hurdle-stretch&caseId=v94_left_full&phase=0.25&play=0&debug=0&visualMode=nex&nativeRuntimeParity=1&nativeSkin=1&skinPreset=freeridehuman&readyTimeoutMs=12000&hostLifecycle=v317-final-mcp-authority&build=NEXPROD01_RUNTIME_V317_WRIST_NODE_180_RESTART_2026_08_19&safeBoot=0&lowPower=1&pixelRatioCap=1.15&antialias=1&maxFPS=24&staticAfterReady=0&idleSleepAfterReady=0&v=V317_left",
        "hasDebug": true,
        "hasModel": true,
        "boneCount": 92,
        "skinnedMeshCount": 0,
        "canvasCount": 1,
        "windowMarkers": [
          "__NEXPROD01_DEBUG_SCENE",
          "__NEXPROD01_GRIP_SOLVER_V1",
          "__NEXPROD01_PUBLISH",
          "__NEXPROD01_V100_GRIP_CAPSULE_SURFACE",
          "__NEXPROD01_V102_HEEL_TO_GLUTE_REACH",
          "__NEXPROD01_V110_DISTAL_GRIP_COUPLED",
          "__NEXPROD01_V140_GRIP_HAND_QA_TINT",
          "__NEXPROD01_V151_ACTUAL_MESH_TRUTH",
          "__NEXPROD01_V153_MESH_FEEDBACK",
          "__NEXPROD01_V157_REAL_MEDIAPIPE_HAND_FRAME",
          "__NEXPROD01_V169_LEG_CLOSER_ONLY",
          "__NEXPROD01_V175_LEG_OUT",
          "__NEXPROD01_V184_SNAP_ONLY_FEASIBILITY",
          "__NEXPROD01_V189_PRE_SNAP_NEUTRAL_APPROACH",
          "__NEXPROD01_V198_V195_DELTA_SINGLE_WRITER",
          "__NEXPROD01_V199_LOCK_GREEN_ROLL_PINK",
          "__NEXPROD01_V266_CLEAN_GRIP_CONTRACT",
          "__NEXPROD01_V297_PREFINGER_CHILD_LAYER_GATE",
          "__NEXPROD01_V301_FINGER_CHILD_LAYER_GATE",
          "__NEXPROD01_V304_ZPLUS_SEQUENTIAL_FINGER_CONTACT",
          "__NEXPROD01_V306_ACTUAL_SURFACE_PREFINGER_GATE",
          "__NEXPROD01_V306_ZPLUS_SEQUENTIAL_FINGER_CONTACT",
          "__NEXPROD01_V307_ACTUAL_MCP_PALM_PREFINGER_GATE",
          "__NEXPROD01_V308_ACTUAL_MCP_PALM_PREFINGER_GATE",
          "__NEXPROD01_V308_FINAL_PREFINGER_TRUTH",
          "__NEXPROD01_V309_ACTUAL_MCP_PALM_PREFINGER_GATE",
          "__NEXPROD01_V309_ACTUAL_MCP_WRIST_ROLL_SOLVE",
          "__NEXPROD01_V309_FINAL_PREFINGER_TRUTH",
          "__NEXPROD01_V310_ACTUAL_MCP_PALM_PREFINGER_GATE",
          "__NEXPROD01_V310_POST_COMMIT_MCP_GATE_VERIFY_NO_MUTATION",
          "__NEXPROD01_V311_ACTUAL_MCP_PALM_PREFINGER_GATE",
          "__NEXPROD01_V311_FINAL_PREFINGER_TRUTH",
          "__NEXPROD01_V312_WRIST_NODE_180_RESTART",
          "__NEXPROD01_V313_FINAL_PREFINGER_TRUTH",
          "__NEXPROD01_V315_ACTUAL_MCP_SECOND_PALM_SOLVE",
          "__NEXPROD01_V316_POST_FLOOR_ACTUAL_MCP_SECOND_PALM_SOLVE",
          "__NEXPROD01_V317_FINAL_PREFINGER_TRUTH",
          "__NEXPROD01_V69_SHIN_GRIP_FINGER_LAYER",
          "__NEXPROD01_V70_BIORIG_FULL_GRIP_LAYER",
          "__NEXPROD01_V93_ACTIVE_HAND_CONTROL_PROBE"
        ],
        "gripSolverV1": {
          "schema": "NEXPROD01_GRIP_SOLVER_V1",
          "version": "V317_FINAL_ACTUAL_MCP_AUTHORITY_GATE",
          "side": "L",
          "applied": true,
          "implemented": true,
          "policy": "V314: actual Index/Pinky MCP + 20mm palm-offset are the only hand contact authority. Old PalmIndexBase/PalmPinkyBase target frames, fitHandPalmPlane and palm-child CCD are bypassed for the active grip side so stale target-palm-basis cannot pull the hand back. Fingers remain blocked unless the post-commit actual MCP palm gate passes.",
          "pass": true,
          "ruleType": "v94_space_control_left_finger_grip",
          "targetLimb": "L_lower_shin_heel_cylinder",
          "targetSide": "outside",
          "palmPoints": {
            "pointA": {
              "snap": "pinkyMcpPalm",
              "bone": "L_Pinky1",
              "offsetM": 0.02,
              "role": "first_palm_contact"
            },
            "pointB": {
              "snap": "indexMcpPalm",
              "bone": "L_Index1",
              "offsetM": 0.02,
              "role": "second_palm_contact"
            }
          },
          "limb": {
            "axisA": "L_Foot",
            "axisB": "L_Calf",
            "axisPoint": {
              "x": 0.12867,
              "y": 0.9924,
              "z": -0.35107
            },
            "outside": {
              "x": 0.99445,
              "y": -0.09524,
              "z": -0.04478
            },
            "target": {
              "x": 0.18336,
              "y": 0.98716,
              "z": -0.35353
            },
            "radiusM": 0.052,
            "clearanceM": 0.003,
            "t": 0.16
          },
          "beforeBasis": null,
          "afterAngles": {
            "palmRay_vs_forearm": 30.04,
            "mcpCenter_vs_forearm": 29.32,
            "mcpAxis_vs_forearm": 72.21,
            "palmNormal_vs_forearm": 118.54
          },
          "stages": {
            "neutralPalm": {
              "applied": true,
              "xSource": "raw_index_minus_pinky_projected",
              "beforeAngles": {
                "palmRay_vs_forearm": 63.25,
                "mcpCenter_vs_forearm": 60.87,
                "mcpAxis_vs_forearm": 129.3,
                "palmNormal_vs_forearm": 58.85
              },
              "afterAngles": {
                "palmRay_vs_forearm": 10.53,
                "mcpCenter_vs_forearm": 6.09,
                "mcpAxis_vs_forearm": 90,
                "palmNormal_vs_forearm": 90
              },
              "pass": true,
              "policy": "Solver V1 neutral palm: visible palm/MCP axis follows the forearm before object contact. This is a named solver step, not a historical patch."
            },
            "v307McpPalmSnapAfterNeutral": {
              "schema": "NEXPROD01_V307_MCP_DERIVED_PALM_SNAP_POINTS",
              "ok": true,
              "side": "L",
              "source": "Index1/Pinky1 MCP + 20mm palm-surface offset",
              "firstPalm": "pinky",
              "palmOffsetM": 0.02,
              "palmOffsetDir": {
                "x": 0.61776,
                "y": -0.25758,
                "z": 0.74299
              },
              "mcp": {
                "index": {
                  "x": 0.14169,
                  "y": 0.93999,
                  "z": -0.27119
                },
                "pinky": {
                  "x": 0.18512,
                  "y": 0.95911,
                  "z": -0.30068
                },
                "mid": {
                  "x": 0.16017,
                  "y": 0.94279,
                  "z": -0.27989
                },
                "wrist": {
                  "x": 0.1606,
                  "y": 1.02401,
                  "z": -0.25589
                }
              },
              "palm": {
                "index": {
                  "x": 0.15404,
                  "y": 0.93483,
                  "z": -0.25633
                },
                "pinky": {
                  "x": 0.19748,
                  "y": 0.95396,
                  "z": -0.28582
                }
              },
              "pointA": {
                "x": 0.19748,
                "y": 0.95396,
                "z": -0.28582
              },
              "pointB": {
                "x": 0.15404,
                "y": 0.93483,
                "z": -0.25633
              },
              "basis": {
                "x": {
                  "x": -0.78608,
                  "y": -0.22766,
                  "z": 0.57467
                },
                "y": {
                  "x": 0.02113,
                  "y": -0.93906,
                  "z": -0.34312
                },
                "z": {
                  "x": 0.61776,
                  "y": -0.25758,
                  "z": 0.74299
                },
                "center": {
                  "x": 0.16233,
                  "y": 0.94729,
                  "z": -0.28392
                },
                "handSpanM": 0.05588,
                "handLenM": 0.08169
              },
              "policy": "V307 replaces old learned pointA/pointB phantom coordinates with palm-surface contact points derived from actual Index/Pinky MCP roots plus a ~20 mm palm offset. Debug markers and contact gates must use these points so they stay attached to the real hand."
            },
            "v310PreContact180PalmFrameReset": {
              "schema": "NEXPROD01_V310_PRECONTACT_180_PALM_FRAME_RESET",
              "active": true,
              "applied": true,
              "pass": true,
              "side": "L",
              "rotationDeg": 180,
              "axis": {
                "x": 0.1393,
                "y": -0.91181,
                "z": -0.38625
              },
              "pivot": {
                "x": 0.1606,
                "y": 1.02401,
                "z": -0.25589
              },
              "before": {
                "entryFrameGate": {
                  "schema": "NEXPROD01_V297_V286_ENTRY_FRAME_GATE",
                  "source": "V286_NEUTRALIZE_HAND_FOR_GRIP",
                  "active": true,
                  "mutatesTargets": false,
                  "side": "L",
                  "pass": false,
                  "gate": "NEEDS_NEUTRALIZE_BEFORE_SOLVE_GRIP",
                  "desiredOutsideDistanceM": 0.055,
                  "signedOutsideM": 0.02508,
                  "palmBaseOutsideM": 0.02224,
                  "requiredOutwardShiftM": 0.02992,
                  "palmAcrossOutsideDot": -0.76411,
                  "limbAxisA": "L_Foot",
                  "limbAxisB": "L_Calf",
                  "policy": "V297 ports V286 as a non-mutating pre-contact entry-frame gate inside the V267 clean solver. It measures whether the hand MCP/palm frame approaches from the outside shell before point snap, palm roll, or finger child-layer."
                },
                "points": {
                  "schema": "NEXPROD01_V307_MCP_DERIVED_PALM_SNAP_POINTS",
                  "ok": true,
                  "side": "L",
                  "source": "Index1/Pinky1 MCP + 20mm palm-surface offset",
                  "firstPalm": "pinky",
                  "palmOffsetM": 0.02,
                  "palmOffsetDir": {
                    "x": 0.61776,
                    "y": -0.25758,
                    "z": 0.74299
                  },
                  "mcp": {
                    "index": {
                      "x": 0.14169,
                      "y": 0.93999,
                      "z": -0.27119
                    },
                    "pinky": {
                      "x": 0.18512,
                      "y": 0.95911,
                      "z": -0.30068
                    },
                    "mid": {
                      "x": 0.16017,
                      "y": 0.94279,
                      "z": -0.27989
                    },
                    "wrist": {
                      "x": 0.1606,
                      "y": 1.02401,
                      "z": -0.25589
                    }
                  },
                  "palm": {
                    "index": {
                      "x": 0.15404,
                      "y": 0.93483,
                      "z": -0.25633
                    },
                    "pinky": {
                      "x": 0.19748,
                      "y": 0.95396,
                      "z": -0.28582
                    }
                  },
                  "pointA": {
                    "x": 0.19748,
                    "y": 0.95396,
                    "z": -0.28582
                  },
                  "pointB": {
                    "x": 0.15404,
                    "y": 0.93483,
                    "z": -0.25633
                  },
                  "basis": {
                    "x": {
                      "x": -0.78608,
                      "y": -0.22766,
                      "z": 0.57467
                    },
                    "y": {
                      "x": 0.02113,
                      "y": -0.93906,
                      "z": -0.34312
                    },
                    "z": {
                      "x": 0.61776,
                      "y": -0.25758,
                      "z": 0.74299
                    },
                    "center": {
                      "x": 0.16233,
                      "y": 0.94729,
                      "z": -0.28392
                    },
                    "handSpanM": 0.05588,
                    "handLenM": 0.08169
                  },
                  "policy": "V307 replaces old learned pointA/pointB phantom coordinates with palm-surface contact points derived from actual Index/Pinky MCP roots plus a ~20 mm palm offset. Debug markers and contact gates must use these points so they stay attached to the real hand."
                },
                "angles": {
                  "palmRay_vs_forearm": 10.53,
                  "mcpCenter_vs_forearm": 6.09,
                  "mcpAxis_vs_forearm": 90,
                  "palmNormal_vs_forearm": 90
                }
              },
              "after": {
                "entryFrameGate": {
                  "schema": "NEXPROD01_V297_V286_ENTRY_FRAME_GATE",
                  "source": "V286_NEUTRALIZE_HAND_FOR_GRIP",
                  "active": true,
                  "mutatesTargets": false,
                  "side": "L",
                  "pass": false,
                  "gate": "NEEDS_NEUTRALIZE_BEFORE_SOLVE_GRIP",
                  "desiredOutsideDistanceM": 0.055,
                  "signedOutsideM": 0.0414,
                  "palmBaseOutsideM": 0.04588,
                  "requiredOutwardShiftM": 0.0136,
                  "palmAcrossOutsideDot": 0.76411,
                  "limbAxisA": "L_Foot",
                  "limbAxisB": "L_Calf",
                  "policy": "V297 ports V286 as a non-mutating pre-contact entry-frame gate inside the V267 clean solver. It measures whether the hand MCP/palm frame approaches from the outside shell before point snap, palm roll, or finger child-layer."
                },
                "points": {
                  "schema": "NEXPROD01_V307_MCP_DERIVED_PALM_SNAP_POINTS",
                  "ok": true,
                  "side": "L",
                  "source": "Index1/Pinky1 MCP + 20mm palm-surface offset",
                  "firstPalm": "pinky",
                  "palmOffsetM": 0.02,
                  "palmOffsetDir": {
                    "x": -0.6083,
                    "y": 0.19569,
                    "z": -0.7692
                  },
                  "mcp": {
                    "index": {
                      "x": 0.20178,
                      "y": 0.96234,
                      "z": -0.3023
                    },
                    "pinky": {
                      "x": 0.15834,
                      "y": 0.94322,
                      "z": -0.27282
                    },
                    "mid": {
                      "x": 0.18423,
                      "y": 0.95338,
                      "z": -0.29622
                    },
                    "wrist": {
                      "x": 0.1606,
                      "y": 1.02401,
                      "z": -0.25589
                    }
                  },
                  "palm": {
                    "index": {
                      "x": 0.18961,
                      "y": 0.96626,
                      "z": -0.31768
                    },
                    "pinky": {
                      "x": 0.14617,
                      "y": 0.94713,
                      "z": -0.2882
                    }
                  },
                  "pointA": {
                    "x": 0.14617,
                    "y": 0.94713,
                    "z": -0.2882
                  },
                  "pointB": {
                    "x": 0.18961,
                    "y": 0.96626,
                    "z": -0.31768
                  },
                  "basis": {
                    "x": {
                      "x": 0.75157,
                      "y": 0.45359,
                      "z": -0.47896
                    },
                    "y": {
                      "x": 0.25517,
                      "y": -0.86946,
                      "z": -0.42299
                    },
                    "z": {
                      "x": -0.6083,
                      "y": 0.19569,
                      "z": -0.7692
                    },
                    "center": {
                      "x": 0.18145,
                      "y": 0.95298,
                      "z": -0.29044
                    },
                    "handSpanM": 0.05588,
                    "handLenM": 0.08169
                  },
                  "policy": "V307 replaces old learned pointA/pointB phantom coordinates with palm-surface contact points derived from actual Index/Pinky MCP roots plus a ~20 mm palm offset. Debug markers and contact gates must use these points so they stay attached to the real hand."
                },
                "angles": {
                  "palmRay_vs_forearm": 10.53,
                  "mcpCenter_vs_forearm": 6.09,
                  "mcpAxis_vs_forearm": 90,
                  "palmNormal_vs_forearm": 90
                }
              },
              "policy": "V310 implements the user correction: when the outside-shin hand is wrong-way/thumb-up, reset the hand/palm frame 180 degrees before point snap. Then redo arm reach, first-palm lock, object/leg meet, second-palm roll, and actual MCP gate from the reset orientation. This is pre-contact target-space authority, not a post-commit hand patch."
            },
            "v297EntryFrameGate": {
              "schema": "NEXPROD01_V297_V286_ENTRY_FRAME_GATE",
              "source": "V286_NEUTRALIZE_HAND_FOR_GRIP",
              "active": true,
              "mutatesTargets": false,
              "side": "L",
              "pass": false,
              "gate": "NEEDS_NEUTRALIZE_BEFORE_SOLVE_GRIP",
              "desiredOutsideDistanceM": 0.055,
              "signedOutsideM": 0.0414,
              "palmBaseOutsideM": 0.04588,
              "requiredOutwardShiftM": 0.0136,
              "palmAcrossOutsideDot": 0.76411,
              "limbAxisA": "L_Foot",
              "limbAxisB": "L_Calf",
              "policy": "V297 ports V286 as a non-mutating pre-contact entry-frame gate inside the V267 clean solver. It measures whether the hand MCP/palm frame approaches from the outside shell before point snap, palm roll, or finger child-layer."
            },
            "v306EntryFrameNeutralizeRotation": {
              "schema": "NEXPROD01_V306_ENTRY_FRAME_NEUTRALIZE_ROTATION",
              "active": false,
              "applied": false,
              "pass": true,
              "reason": "skipped_after_V311_locked_180_reset",
              "side": "L",
              "afterGate": {
                "schema": "NEXPROD01_V297_V286_ENTRY_FRAME_GATE",
                "source": "V286_NEUTRALIZE_HAND_FOR_GRIP",
                "active": true,
                "mutatesTargets": false,
                "side": "L",
                "pass": false,
                "gate": "NEEDS_NEUTRALIZE_BEFORE_SOLVE_GRIP",
                "desiredOutsideDistanceM": 0.055,
                "signedOutsideM": 0.0414,
                "palmBaseOutsideM": 0.04588,
                "requiredOutwardShiftM": 0.0136,
                "palmAcrossOutsideDot": 0.76411,
                "limbAxisA": "L_Foot",
                "limbAxisB": "L_Calf",
                "policy": "V297 ports V286 as a non-mutating pre-contact entry-frame gate inside the V267 clean solver. It measures whether the hand MCP/palm frame approaches from the outside shell before point snap, palm roll, or finger child-layer."
              },
              "policy": "V311: once the wrong-way left palm frame has been reset by the forced 180 degree pre-contact rotation, do not run another neutralizer that can rotate it back. Residual distance is handled by first-palm arm snap / object-meet."
            },
            "v307McpPalmSnapBeforePointSnap": {
              "schema": "NEXPROD01_V307_MCP_DERIVED_PALM_SNAP_POINTS",
              "ok": true,
              "side": "L",
              "source": "Index1/Pinky1 MCP + 20mm palm-surface offset",
              "firstPalm": "pinky",
              "palmOffsetM": 0.02,
              "palmOffsetDir": {
                "x": -0.6083,
                "y": 0.19569,
                "z": -0.7692
              },
              "mcp": {
                "index": {
                  "x": 0.20178,
                  "y": 0.96234,
                  "z": -0.3023
                },
                "pinky": {
                  "x": 0.15834,
                  "y": 0.94322,
                  "z": -0.27282
                },
                "mid": {
                  "x": 0.18423,
                  "y": 0.95338,
                  "z": -0.29622
                },
                "wrist": {
                  "x": 0.1606,
                  "y": 1.02401,
                  "z": -0.25589
                }
              },
              "palm": {
                "index": {
                  "x": 0.18961,
                  "y": 0.96626,
                  "z": -0.31768
                },
                "pinky": {
                  "x": 0.14617,
                  "y": 0.94713,
                  "z": -0.2882
                }
              },
              "pointA": {
                "x": 0.14617,
                "y": 0.94713,
                "z": -0.2882
              },
              "pointB": {
                "x": 0.18961,
                "y": 0.96626,
                "z": -0.31768
              },
              "basis": {
                "x": {
                  "x": 0.75157,
                  "y": 0.45359,
                  "z": -0.47896
                },
                "y": {
                  "x": 0.25517,
                  "y": -0.86946,
                  "z": -0.42299
                },
                "z": {
                  "x": -0.6083,
                  "y": 0.19569,
                  "z": -0.7692
                },
                "center": {
                  "x": 0.18145,
                  "y": 0.95298,
                  "z": -0.29044
                },
                "handSpanM": 0.05588,
                "handLenM": 0.08169
              },
              "policy": "V307 replaces old learned pointA/pointB phantom coordinates with palm-surface contact points derived from actual Index/Pinky MCP roots plus a ~20 mm palm offset. Debug markers and contact gates must use these points so they stay attached to the real hand."
            },
            "pointASnap": {
              "applied": true,
              "pointA0": {
                "x": 0.14617,
                "y": 0.94713,
                "z": -0.2882
              },
              "pointB0": {
                "x": 0.18961,
                "y": 0.96626,
                "z": -0.31768
              },
              "limbTargetBefore": {
                "x": 0.18943,
                "y": 0.95093,
                "z": -0.3791
              },
              "limbTargetAfter": {
                "x": 0.18336,
                "y": 0.98716,
                "z": -0.35353
              },
              "shift": {
                "x": 0.04326,
                "y": 0.0038,
                "z": -0.0909
              },
              "shiftM": 0.10074,
              "pointAAfter": {
                "x": 0.18337,
                "y": 0.98716,
                "z": -0.35353
              },
              "pointBAfter": {
                "x": 0.2268,
                "y": 1.00629,
                "z": -0.38302
              },
              "arm": {
                "ok": true,
                "distance": 0.4525241164794084,
                "minReach": 0.014049215156796717,
                "maxReach": 0.45253,
                "segmentErrorM": {
                  "upperarm": 0,
                  "forearm": 0
                },
                "clamped": true,
                "desiredDistance": 0.49729,
                "handDelta": {
                  "x": 0.03719,
                  "y": 0.04003,
                  "z": -0.06533
                },
                "legDelta": {
                  "x": -0.00607,
                  "y": 0.03623,
                  "z": 0.02557
                },
                "legDeltaM": 0.04476,
                "segmentLengths": {
                  "thighM": 0.34135,
                  "calfM": 0.39526,
                  "rawThighM": 0.30323,
                  "rawCalfM": 0.37435
                },
                "policy": "Arm could not reach the one outside limb point; move the target limb contact body by the residual instead of inventing a hand point. This encodes the prior learning explicitly inside the solver."
              },
              "policy": "Step 1-2 of V300 contract: arm reach / approach places first inside-palm contact on the outside limb snap. If the arm cannot reach, object/leg-meet is the only allowed compensation; fingers/hand-only patches are not owners."
            },
            "v300ObjectMeetGate": {
              "schema": "NEXPROD01_V300_OBJECT_LEG_MEET_SHIFTED_SURFACE_GATE",
              "active": true,
              "applied": true,
              "meetM": 0.04476,
              "maxObjectMeetM": 0.08,
              "pass": true,
              "legDelta": {
                "x": -0.00607,
                "y": 0.03623,
                "z": 0.02557
              },
              "clamped": true,
              "policy": "V300 keeps neutralization in the approach/contact layer. If arm reach cannot place first palm contact, the lower-leg/object target surface may meet the hand up to 80 mm before palm-frame validation. Surface checks must then use the shifted surface, not the original one."
            },
            "v300ForearmAxisSecondPalmRoll": {
              "schema": "NEXPROD01_V300_FOREARM_AXIS_SECOND_PALM_ROLL",
              "active": true,
              "applied": true,
              "pass": false,
              "rollDeg": -45,
              "axis": {
                "x": 0.14119,
                "y": -0.80622,
                "z": -0.57452
              },
              "before": {
                "first": {
                  "radialM": 0.05501,
                  "requiredRadialM": 0.055,
                  "signedOutsideM": 0.05501,
                  "outsideScore": 1,
                  "distanceToSurfaceM": 1e-05,
                  "penetrationM": 0,
                  "surfaceOk": true,
                  "sideOk": true
                },
                "second": {
                  "radialM": 0.099,
                  "requiredRadialM": 0.055,
                  "signedOutsideM": 0.0977,
                  "outsideScore": 0.98687,
                  "distanceToSurfaceM": 0.044,
                  "penetrationM": 0,
                  "surfaceOk": false,
                  "sideOk": true
                },
                "pointA": {
                  "x": 0.18337,
                  "y": 0.98716,
                  "z": -0.35353
                },
                "pointB": {
                  "x": 0.2268,
                  "y": 1.00629,
                  "z": -0.38302
                }
              },
              "after": {
                "first": {
                  "radialM": 0.05501,
                  "requiredRadialM": 0.055,
                  "signedOutsideM": 0.05501,
                  "outsideScore": 1,
                  "distanceToSurfaceM": 1e-05,
                  "penetrationM": 0,
                  "surfaceOk": true,
                  "sideOk": true
                },
                "second": {
                  "radialM": 0.06978,
                  "requiredRadialM": 0.055,
                  "signedOutsideM": 0.06109,
                  "outsideScore": 0.87555,
                  "distanceToSurfaceM": 0.01478,
                  "penetrationM": 0,
                  "surfaceOk": false,
                  "sideOk": true
                },
                "pointA": {
                  "x": 0.18337,
                  "y": 0.98716,
                  "z": -0.35353
                },
                "pointB": {
                  "x": 0.18982,
                  "y": 1.01358,
                  "z": -0.40234
                },
                "palmFacesObject": 0.9014,
                "handAcrossVerticalProxy": -0.57456,
                "grossPenetration": false,
                "arm": {
                  "ok": true,
                  "distance": 0.45322665914817384,
                  "minReach": 0.01271873030081899,
                  "maxReach": 0.45386460133538614,
                  "segmentErrorM": {
                    "upperarm": 0,
                    "forearm": 0
                  }
                }
              },
              "policy": "V300 contract step 3: keep the first palm contact fixed, then rotate the rigid hand/palm frame around the active wrist/forearm axis to bring the second palm point toward the shifted outside limb surface. Fingers remain blocked for visual approval."
            },
            "v307McpPalmSnapAfterForearmRoll": {
              "schema": "NEXPROD01_V307_MCP_DERIVED_PALM_SNAP_POINTS",
              "ok": true,
              "side": "L",
              "source": "Index1/Pinky1 MCP + 20mm palm-surface offset",
              "firstPalm": "pinky",
              "palmOffsetM": 0.02,
              "palmOffsetDir": {
                "x": -0.93994,
                "y": -0.23236,
                "z": -0.25003
              },
              "mcp": {
                "index": {
                  "x": 0.20862,
                  "y": 1.01823,
                  "z": -0.39734
                },
                "pinky": {
                  "x": 0.20216,
                  "y": 0.99181,
                  "z": -0.34853
                },
                "mid": {
                  "x": 0.20337,
                  "y": 1.00507,
                  "z": -0.38235
                },
                "wrist": {
                  "x": 0.17751,
                  "y": 1.06915,
                  "z": -0.33337
                }
              },
              "palm": {
                "index": {
                  "x": 0.18982,
                  "y": 1.01358,
                  "z": -0.40234
                },
                "pinky": {
                  "x": 0.18337,
                  "y": 0.98716,
                  "z": -0.35353
                }
              },
              "pointA": {
                "x": 0.18337,
                "y": 0.98716,
                "z": -0.35353
              },
              "pointB": {
                "x": 0.18982,
                "y": 1.01358,
                "z": -0.40234
              },
              "basis": {
                "x": {
                  "x": 0.07477,
                  "y": 0.57456,
                  "z": -0.81504
                },
                "y": {
                  "x": 0.33304,
                  "y": -0.78479,
                  "z": -0.52268
                },
                "z": {
                  "x": -0.93994,
                  "y": -0.23236,
                  "z": -0.25003
                },
                "center": {
                  "x": 0.20472,
                  "y": 1.00504,
                  "z": -0.37607
                },
                "handSpanM": 0.05588,
                "handLenM": 0.08169
              },
              "policy": "V307 replaces old learned pointA/pointB phantom coordinates with palm-surface contact points derived from actual Index/Pinky MCP roots plus a ~20 mm palm offset. Debug markers and contact gates must use these points so they stay attached to the real hand."
            },
            "v301SideSurfaceContactGate": {
              "schema": "NEXPROD01_V301_SIDE_SURFACE_CONTACT_GATE",
              "active": true,
              "pass": false,
              "palmContactReady": false,
              "preFingerReady": false,
              "status": "GRIP_ENTRY_CONTRACT_HOLD_WRONG_SIDE_OR_PENETRATION",
              "checks": {
                "handPalmTowardObject": true,
                "firstPalmOnShiftedSurface": true,
                "secondPalmOnShiftedSurface": false,
                "outsideContact": true,
                "noGrossPenetration": true,
                "objectMeetWithinLimit": true,
                "firstSignedOutsideM": 0.05501,
                "secondSignedOutsideM": 0.06109,
                "firstPenetrationM": 0,
                "secondPenetrationM": 0,
                "firstOutsideScore": 1,
                "secondOutsideScore": 0.87555
              },
              "policy": "V301 replaces the explicit thumb-down requirement with a generic side/surface/penetration gate. The solver only checks that palm-side contact is on the intended object side, both palm points remain on the shifted outside surface, the palm faces the object, and the hand has not snapped through or penetrated the object. Thumb orientation is an emergent result of correct side contact, not a global constraint."
            },
            "palmLineAlign": {
              "applied": true,
              "rotationAxis": {
                "x": -0.28864,
                "y": 0.93952,
                "z": 0.18438
              },
              "rotationDeg": 42.244,
              "pointAAfter": {
                "x": 0.18337,
                "y": 0.98716,
                "z": -0.35352
              },
              "pointBAfter": {
                "x": 0.15299,
                "y": 1.00145,
                "z": -0.39819
              },
              "objectAxis": {
                "x": -0.06945,
                "y": -0.91358,
                "z": 0.40069
              },
              "desiredLine": {
                "x": 0.12371,
                "y": 0.15333,
                "z": -0.58764
              },
              "arm": {
                "ok": true,
                "distance": 0.45966240824500937,
                "minReach": 0.005613551531804233,
                "maxReach": 0.46096978010440054,
                "segmentErrorM": {
                  "upperarm": 0,
                  "forearm": 0
                }
              },
              "policy": "Keep the single object snap point and rotate the whole rigid hand frame so the two inside-palm points run in the same line as the limb axis."
            },
            "palmNormalRoll": {
              "applied": true,
              "rollDeg": 17.497,
              "axis": {
                "x": -0.54367,
                "y": 0.25573,
                "z": -0.79939
              },
              "pointAAfter": {
                "x": 0.18337,
                "y": 0.98716,
                "z": -0.35352
              },
              "pointBAfter": {
                "x": 0.15299,
                "y": 1.00145,
                "z": -0.39819
              },
              "pointAErrorM": 1e-05,
              "pointBRadialM": 0.04541,
              "requiredRadialM": 0.055,
              "pointBContactErrorM": 0.00959,
              "pointBOutsideScore": 0.5601,
              "policy": "Roll the palm plane around the inside-palm contact line toward the outside limb surface. Point B must be both on the outside side and near the capsule surface; if it only points outward but is far away, the palm contract fails."
            }
          },
          "nextPhase": "finger_child_layer_allowed_by_contract",
          "notes": [
            "old V-patches are not called by this active path",
            "learned constants are documented as palm homology, not treated as world snap coordinates",
            "camera truth remains mandatory for approval"
          ]
        },
        "finalTruth": {
          "schema": "NEXPROD01_V317_FINAL_PREFINGER_TRUTH",
          "active": true,
          "side": "L",
          "pass": true,
          "status": "ACTUAL_MCP_PALM_PREFINGER_READY",
          "wrongWay": false,
          "orientationFail": false,
          "solverSideStatus": null,
          "solverSidePass": true,
          "actualWristRollSolve": {
            "schema": "NEXPROD01_V310_POST_COMMIT_MCP_GATE_VERIFY_NO_MUTATION",
            "active": true,
            "applied": false,
            "pass": true,
            "side": "L",
            "reason": "actual_mcp_gate_passed_after_precontact_reset",
            "after": {
              "schema": "NEXPROD01_V308_ACTUAL_MCP_PALM_ORIENTATION_GATE",
              "active": true,
              "side": "L",
              "pass": true,
              "status": "ACTUAL_MCP_PALM_CONTACT_READY",
              "orientationFail": false,
              "palmPlateTwistedThroughObject": false,
              "indexDeepInside": false,
              "pinkyDeepInside": false,
              "onePalmNearSurface": true,
              "oppositePalmDeepInside": false,
              "diagnosis": "actual MCP palm side/surface check",
              "points": {
                "index": {
                  "x": 0.17507,
                  "y": 0.76743,
                  "z": -0.45185
                },
                "pinky": {
                  "x": 0.19051,
                  "y": 0.74874,
                  "z": -0.40151
                },
                "mcpIndex": {
                  "x": 0.18614,
                  "y": 0.78386,
                  "z": -0.44915
                },
                "mcpPinky": {
                  "x": 0.20158,
                  "y": 0.76517,
                  "z": -0.3988
                },
                "mcpMid": {
                  "x": 0.19184,
                  "y": 0.77222,
                  "z": -0.43311
                },
                "wrist": {
                  "x": 0.1323,
                  "y": 0.80776,
                  "z": -0.38448
                }
              },
              "basis": {
                "x": {
                  "x": -0.37161,
                  "y": 0.38907,
                  "z": -0.84293
                },
                "y": {
                  "x": 0.74533,
                  "y": -0.41631,
                  "z": -0.52074
                },
                "z": {
                  "x": -0.55352,
                  "y": -0.82177,
                  "z": -0.13528
                },
                "palmFacesObject": 0.46613,
                "offsetM": 0.02
              },
              "limb": {
                "axisPoint": {
                  "x": 0.1332,
                  "y": 0.69332,
                  "z": -0.37981
                },
                "axis": {
                  "x": -0.06945,
                  "y": -0.91358,
                  "z": 0.40069
                },
                "outward": {
                  "x": 0.99445,
                  "y": -0.09524,
                  "z": -0.04478
                },
                "radiusM": 0.052,
                "clearanceM": 0.003
              },
              "metrics": {
                "index": {
                  "radialM": 0.05039,
                  "requiredRadialM": 0.055,
                  "signedOutsideM": 0.0378,
                  "outsideScore": 0.75016,
                  "distanceToSurfaceM": 0.00461,
                  "penetrationM": 0.00461,
                  "surfaceOk": true,
                  "sideOk": true
                },
                "pinky": {
                  "radialM": 0.05309,
                  "requiredRadialM": 0.055,
                  "signedOutsideM": 0.05268,
                  "outsideScore": 0.99228,
                  "distanceToSurfaceM": 0.00191,
                  "penetrationM": 0.00191,
                  "surfaceOk": true,
                  "sideOk": true
                },
                "noGrossPenetration": true
              },
              "policy": "V308 post-commit actual gate: use actual Index1/Pinky1 MCP roots plus 20 mm palm offset against the actual lower-leg capsule. If pinky/index asymmetrically penetrates while the other contact point is on the surface, the hand is wrong-way/twisted through the object and fingers are blocked regardless of solver-side PREFINGER_READY."
            },
            "policy": "V310 explicitly forbids the V309-style post-commit wrist/hand roll as a fix. If the actual gate fails, the next solve must go back before arm snap/contact and restart; no after-the-fact hand rotation and no finger release."
          },
          "actualGate": {
            "schema": "NEXPROD01_V317_ACTUAL_MCP_PALM_PREFINGER_GATE",
            "status": "ACTUAL_MCP_PALM_PREFINGER_READY",
            "orientationFail": false,
            "wrongWay": false,
            "active": true,
            "side": "L",
            "pass": true,
            "entryOk": true,
            "solverOk": true,
            "legacySolverOk": false,
            "actualMcpAuthorityOk": true,
            "meshPass": false,
            "palmGapOk": true,
            "palmGapM": 0,
            "v307ActualMcpPalmGate": {
              "schema": "NEXPROD01_V308_ACTUAL_MCP_PALM_ORIENTATION_GATE",
              "active": true,
              "side": "L",
              "pass": true,
              "status": "ACTUAL_MCP_PALM_CONTACT_READY",
              "orientationFail": false,
              "palmPlateTwistedThroughObject": false,
              "indexDeepInside": false,
              "pinkyDeepInside": false,
              "onePalmNearSurface": true,
              "oppositePalmDeepInside": false,
              "diagnosis": "actual MCP palm side/surface check",
              "points": {
                "index": {
                  "x": 0.17507,
                  "y": 0.76743,
                  "z": -0.45185
                },
                "pinky": {
                  "x": 0.19051,
                  "y": 0.74874,
                  "z": -0.40151
                },
                "mcpIndex": {
                  "x": 0.18614,
                  "y": 0.78386,
                  "z": -0.44915
                },
                "mcpPinky": {
                  "x": 0.20158,
                  "y": 0.76517,
                  "z": -0.3988
                },
                "mcpMid": {
                  "x": 0.19184,
                  "y": 0.77222,
                  "z": -0.43311
                },
                "wrist": {
                  "x": 0.1323,
                  "y": 0.80776,
                  "z": -0.38448
                }
              },
              "basis": {
                "x": {
                  "x": -0.37161,
                  "y": 0.38907,
                  "z": -0.84293
                },
                "y": {
                  "x": 0.74533,
                  "y": -0.41631,
                  "z": -0.52074
                },
                "z": {
                  "x": -0.55352,
                  "y": -0.82177,
                  "z": -0.13528
                },
                "palmFacesObject": 0.46613,
                "offsetM": 0.02
              },
              "limb": {
                "axisPoint": {
                  "x": 0.1332,
                  "y": 0.69332,
                  "z": -0.37981
                },
                "axis": {
                  "x": -0.06945,
                  "y": -0.91358,
                  "z": 0.40069
                },
                "outward": {
                  "x": 0.99445,
                  "y": -0.09524,
                  "z": -0.04478
                },
                "radiusM": 0.052,
                "clearanceM": 0.003
              },
              "metrics": {
                "index": {
                  "radialM": 0.05039,
                  "requiredRadialM": 0.055,
                  "signedOutsideM": 0.0378,
                  "outsideScore": 0.75016,
                  "distanceToSurfaceM": 0.00461,
                  "penetrationM": 0.00461,
                  "surfaceOk": true,
                  "sideOk": true
                },
                "pinky": {
                  "radialM": 0.05309,
                  "requiredRadialM": 0.055,
                  "signedOutsideM": 0.05268,
                  "outsideScore": 0.99228,
                  "distanceToSurfaceM": 0.00191,
                  "penetrationM": 0.00191,
                  "surfaceOk": true,
                  "sideOk": true
                },
                "noGrossPenetration": true
              },
              "policy": "V308 post-commit actual gate: use actual Index1/Pinky1 MCP roots plus 20 mm palm offset against the actual lower-leg capsule. If pinky/index asymmetrically penetrates while the other contact point is on the surface, the hand is wrong-way/twisted through the object and fingers are blocked regardless of solver-side PREFINGER_READY."
            },
            "postFloorActualMcpSolve": {
              "schema": "NEXPROD01_V316_POST_FLOOR_ACTUAL_MCP_SECOND_PALM_SOLVE",
              "pass": true,
              "applied": true,
              "firstPalm": "pinky",
              "rollDeg": 15,
              "metrics": {
                "index": {
                  "radialM": 0.05039,
                  "requiredRadialM": 0.055,
                  "signedOutsideM": 0.0378,
                  "outsideScore": 0.75016,
                  "distanceToSurfaceM": 0.00461,
                  "penetrationM": 0.00461,
                  "surfaceOk": true,
                  "sideOk": true
                },
                "pinky": {
                  "radialM": 0.05309,
                  "requiredRadialM": 0.055,
                  "signedOutsideM": 0.05268,
                  "outsideScore": 0.99228,
                  "distanceToSurfaceM": 0.00191,
                  "penetrationM": 0.00191,
                  "surfaceOk": true,
                  "sideOk": true
                }
              }
            },
            "entryFrameGate": {
              "schema": "NEXPROD01_V297_V286_ENTRY_FRAME_GATE",
              "source": "V286_NEUTRALIZE_HAND_FOR_GRIP",
              "active": true,
              "mutatesTargets": false,
              "side": "L",
              "pass": false,
              "gate": "NEEDS_NEUTRALIZE_BEFORE_SOLVE_GRIP",
              "desiredOutsideDistanceM": 0.055,
              "signedOutsideM": 0.0414,
              "palmBaseOutsideM": 0.04588,
              "requiredOutwardShiftM": 0.0136,
              "palmAcrossOutsideDot": 0.76411,
              "limbAxisA": "L_Foot",
              "limbAxisB": "L_Calf",
              "policy": "V297 ports V286 as a non-mutating pre-contact entry-frame gate inside the V267 clean solver. It measures whether the hand MCP/palm frame approaches from the outside shell before point snap, palm roll, or finger child-layer."
            },
            "entryRepair": {
              "schema": "NEXPROD01_V306_ENTRY_FRAME_NEUTRALIZE_ROTATION",
              "active": false,
              "applied": false,
              "pass": true,
              "reason": "skipped_after_V311_locked_180_reset",
              "side": "L",
              "afterGate": {
                "schema": "NEXPROD01_V297_V286_ENTRY_FRAME_GATE",
                "source": "V286_NEUTRALIZE_HAND_FOR_GRIP",
                "active": true,
                "mutatesTargets": false,
                "side": "L",
                "pass": false,
                "gate": "NEEDS_NEUTRALIZE_BEFORE_SOLVE_GRIP",
                "desiredOutsideDistanceM": 0.055,
                "signedOutsideM": 0.0414,
                "palmBaseOutsideM": 0.04588,
                "requiredOutwardShiftM": 0.0136,
                "palmAcrossOutsideDot": 0.76411,
                "limbAxisA": "L_Foot",
                "limbAxisB": "L_Calf",
                "policy": "V297 ports V286 as a non-mutating pre-contact entry-frame gate inside the V267 clean solver. It measures whether the hand MCP/palm frame approaches from the outside shell before point snap, palm roll, or finger child-layer."
              },
              "policy": "V311: once the wrong-way left palm frame has been reset by the forced 180 degree pre-contact rotation, do not run another neutralizer that can rotate it back. Residual distance is handled by first-palm arm snap / object-meet."
            },
            "sideSurfaceGate": {
              "pass": false,
              "status": "GRIP_ENTRY_CONTRACT_HOLD_WRONG_SIDE_OR_PENETRATION",
              "checks": {
                "handPalmTowardObject": true,
                "firstPalmOnShiftedSurface": true,
                "secondPalmOnShiftedSurface": false,
                "outsideContact": true,
                "noGrossPenetration": true,
                "objectMeetWithinLimit": true,
                "firstSignedOutsideM": 0.05501,
                "secondSignedOutsideM": 0.06109,
                "firstPenetrationM": 0,
                "secondPenetrationM": 0,
                "firstOutsideScore": 1,
                "secondOutsideScore": 0.87555
              }
            },
            "v153MeshFeedbackPass": false,
            "policy": "V317 cuts the stale solver-side gate from active left grip final authority. If the post-floor actual MCP+20mm solve passes and the current actual MCP gate passes, pre-finger readiness may pass even when old target-space sideSurfaceGate/solver status is stale. No thumb-up/down rule is used; the final authority is actual palm side/surface/penetration."
          },
          "policy": "V317 final pre-finger truth is post-commit actual MCP palm orientation/surface gate after the pre-contact 180 reset and restarted arm snap. Post-commit hand roll is disabled; if actual MCP palm contact still fails, fingers remain blocked."
        },
        "actualGate": {
          "schema": "NEXPROD01_V317_ACTUAL_MCP_PALM_PREFINGER_GATE",
          "status": "ACTUAL_MCP_PALM_PREFINGER_READY",
          "orientationFail": false,
          "wrongWay": false,
          "active": true,
          "side": "L",
          "pass": true,
          "entryOk": true,
          "solverOk": true,
          "legacySolverOk": false,
          "actualMcpAuthorityOk": true,
          "meshPass": false,
          "palmGapOk": true,
          "palmGapM": 0,
          "v307ActualMcpPalmGate": {
            "schema": "NEXPROD01_V308_ACTUAL_MCP_PALM_ORIENTATION_GATE",
            "active": true,
            "side": "L",
            "pass": true,
            "status": "ACTUAL_MCP_PALM_CONTACT_READY",
            "orientationFail": false,
            "palmPlateTwistedThroughObject": false,
            "indexDeepInside": false,
            "pinkyDeepInside": false,
            "onePalmNearSurface": true,
            "oppositePalmDeepInside": false,
            "diagnosis": "actual MCP palm side/surface check",
            "points": {
              "index": {
                "x": 0.17507,
                "y": 0.76743,
                "z": -0.45185
              },
              "pinky": {
                "x": 0.19051,
                "y": 0.74874,
                "z": -0.40151
              },
              "mcpIndex": {
                "x": 0.18614,
                "y": 0.78386,
                "z": -0.44915
              },
              "mcpPinky": {
                "x": 0.20158,
                "y": 0.76517,
                "z": -0.3988
              },
              "mcpMid": {
                "x": 0.19184,
                "y": 0.77222,
                "z": -0.43311
              },
              "wrist": {
                "x": 0.1323,
                "y": 0.80776,
                "z": -0.38448
              }
            },
            "basis": {
              "x": {
                "x": -0.37161,
                "y": 0.38907,
                "z": -0.84293
              },
              "y": {
                "x": 0.74533,
                "y": -0.41631,
                "z": -0.52074
              },
              "z": {
                "x": -0.55352,
                "y": -0.82177,
                "z": -0.13528
              },
              "palmFacesObject": 0.46613,
              "offsetM": 0.02
            },
            "limb": {
              "axisPoint": {
                "x": 0.1332,
                "y": 0.69332,
                "z": -0.37981
              },
              "axis": {
                "x": -0.06945,
                "y": -0.91358,
                "z": 0.40069
              },
              "outward": {
                "x": 0.99445,
                "y": -0.09524,
                "z": -0.04478
              },
              "radiusM": 0.052,
              "clearanceM": 0.003
            },
            "metrics": {
              "index": {
                "radialM": 0.05039,
                "requiredRadialM": 0.055,
                "signedOutsideM": 0.0378,
                "outsideScore": 0.75016,
                "distanceToSurfaceM": 0.00461,
                "penetrationM": 0.00461,
                "surfaceOk": true,
                "sideOk": true
              },
              "pinky": {
                "radialM": 0.05309,
                "requiredRadialM": 0.055,
                "signedOutsideM": 0.05268,
                "outsideScore": 0.99228,
                "distanceToSurfaceM": 0.00191,
                "penetrationM": 0.00191,
                "surfaceOk": true,
                "sideOk": true
              },
              "noGrossPenetration": true
            },
            "policy": "V308 post-commit actual gate: use actual Index1/Pinky1 MCP roots plus 20 mm palm offset against the actual lower-leg capsule. If pinky/index asymmetrically penetrates while the other contact point is on the surface, the hand is wrong-way/twisted through the object and fingers are blocked regardless of solver-side PREFINGER_READY."
          },
          "postFloorActualMcpSolve": {
            "schema": "NEXPROD01_V316_POST_FLOOR_ACTUAL_MCP_SECOND_PALM_SOLVE",
            "pass": true,
            "applied": true,
            "firstPalm": "pinky",
            "rollDeg": 15,
            "metrics": {
              "index": {
                "radialM": 0.05039,
                "requiredRadialM": 0.055,
                "signedOutsideM": 0.0378,
                "outsideScore": 0.75016,
                "distanceToSurfaceM": 0.00461,
                "penetrationM": 0.00461,
                "surfaceOk": true,
                "sideOk": true
              },
              "pinky": {
                "radialM": 0.05309,
                "requiredRadialM": 0.055,
                "signedOutsideM": 0.05268,
                "outsideScore": 0.99228,
                "distanceToSurfaceM": 0.00191,
                "penetrationM": 0.00191,
                "surfaceOk": true,
                "sideOk": true
              }
            }
          },
          "entryFrameGate": {
            "schema": "NEXPROD01_V297_V286_ENTRY_FRAME_GATE",
            "source": "V286_NEUTRALIZE_HAND_FOR_GRIP",
            "active": true,
            "mutatesTargets": false,
            "side": "L",
            "pass": false,
            "gate": "NEEDS_NEUTRALIZE_BEFORE_SOLVE_GRIP",
            "desiredOutsideDistanceM": 0.055,
            "signedOutsideM": 0.0414,
            "palmBaseOutsideM": 0.04588,
            "requiredOutwardShiftM": 0.0136,
            "palmAcrossOutsideDot": 0.76411,
            "limbAxisA": "L_Foot",
            "limbAxisB": "L_Calf",
            "policy": "V297 ports V286 as a non-mutating pre-contact entry-frame gate inside the V267 clean solver. It measures whether the hand MCP/palm frame approaches from the outside shell before point snap, palm roll, or finger child-layer."
          },
          "entryRepair": {
            "schema": "NEXPROD01_V306_ENTRY_FRAME_NEUTRALIZE_ROTATION",
            "active": false,
            "applied": false,
            "pass": true,
            "reason": "skipped_after_V311_locked_180_reset",
            "side": "L",
            "afterGate": {
              "schema": "NEXPROD01_V297_V286_ENTRY_FRAME_GATE",
              "source": "V286_NEUTRALIZE_HAND_FOR_GRIP",
              "active": true,
              "mutatesTargets": false,
              "side": "L",
              "pass": false,
              "gate": "NEEDS_NEUTRALIZE_BEFORE_SOLVE_GRIP",
              "desiredOutsideDistanceM": 0.055,
              "signedOutsideM": 0.0414,
              "palmBaseOutsideM": 0.04588,
              "requiredOutwardShiftM": 0.0136,
              "palmAcrossOutsideDot": 0.76411,
              "limbAxisA": "L_Foot",
              "limbAxisB": "L_Calf",
              "policy": "V297 ports V286 as a non-mutating pre-contact entry-frame gate inside the V267 clean solver. It measures whether the hand MCP/palm frame approaches from the outside shell before point snap, palm roll, or finger child-layer."
            },
            "policy": "V311: once the wrong-way left palm frame has been reset by the forced 180 degree pre-contact rotation, do not run another neutralizer that can rotate it back. Residual distance is handled by first-palm arm snap / object-meet."
          },
          "sideSurfaceGate": {
            "pass": false,
            "status": "GRIP_ENTRY_CONTRACT_HOLD_WRONG_SIDE_OR_PENETRATION",
            "checks": {
              "handPalmTowardObject": true,
              "firstPalmOnShiftedSurface": true,
              "secondPalmOnShiftedSurface": false,
              "outsideContact": true,
              "noGrossPenetration": true,
              "objectMeetWithinLimit": true,
              "firstSignedOutsideM": 0.05501,
              "secondSignedOutsideM": 0.06109,
              "firstPenetrationM": 0,
              "secondPenetrationM": 0,
              "firstOutsideScore": 1,
              "secondOutsideScore": 0.87555
            }
          },
          "v153MeshFeedbackPass": false,
          "policy": "V317 cuts the stale solver-side gate from active left grip final authority. If the post-floor actual MCP+20mm solve passes and the current actual MCP gate passes, pre-finger readiness may pass even when old target-space sideSurfaceGate/solver status is stale. No thumb-up/down rule is used; the final authority is actual palm side/surface/penetration."
        },
        "fingerLayer": {
          "schema": "NEXPROD01_V313_ZPLUS_SEQUENTIAL_FINGER_CONTACT_CHILD_LAYER",
          "active": false,
          "blocked": true,
          "ready": true,
          "releaseEnabled": false,
          "side": "L",
          "reason": "side_surface_gate_passed_finger_release_deferred_to_V302_child_only_integration",
          "contractStatus": null,
          "sideGate": {
            "schema": "NEXPROD01_V301_SIDE_SURFACE_CONTACT_GATE",
            "active": true,
            "pass": false,
            "palmContactReady": false,
            "preFingerReady": false,
            "status": "GRIP_ENTRY_CONTRACT_HOLD_WRONG_SIDE_OR_PENETRATION",
            "checks": {
              "handPalmTowardObject": true,
              "firstPalmOnShiftedSurface": true,
              "secondPalmOnShiftedSurface": false,
              "outsideContact": true,
              "noGrossPenetration": true,
              "objectMeetWithinLimit": true,
              "firstSignedOutsideM": 0.05501,
              "secondSignedOutsideM": 0.06109,
              "firstPenetrationM": 0,
              "secondPenetrationM": 0,
              "firstOutsideScore": 1,
              "secondOutsideScore": 0.87555
            },
            "policy": "V301 replaces the explicit thumb-down requirement with a generic side/surface/penetration gate. The solver only checks that palm-side contact is on the intended object side, both palm points remain on the shifted outside surface, the palm faces the object, and the hand has not snapped through or penetrated the object. Thumb orientation is an emergent result of correct side contact, not a global constraint."
          },
          "policy": "V315: fingers remain child-layer and are deliberately not released unless the actual MCP side/surface/orientation gate passes after the pre-contact 180 reset and restarted arm snap. Post-commit hand roll is disabled; wrong-way palm penetration blocks fingers even if the solver-side target gate said PREFINGER_READY.",
          "v306ActualSurfacePreFingerGate": {
            "schema": "NEXPROD01_V317_ACTUAL_MCP_PALM_PREFINGER_GATE",
            "status": "ACTUAL_MCP_PALM_PREFINGER_READY",
            "orientationFail": false,
            "wrongWay": false,
            "active": true,
            "side": "L",
            "pass": true,
            "entryOk": true,
            "solverOk": true,
            "legacySolverOk": false,
            "actualMcpAuthorityOk": true,
            "meshPass": false,
            "palmGapOk": true,
            "palmGapM": 0,
            "v307ActualMcpPalmGate": {
              "schema": "NEXPROD01_V308_ACTUAL_MCP_PALM_ORIENTATION_GATE",
              "active": true,
              "side": "L",
              "pass": true,
              "status": "ACTUAL_MCP_PALM_CONTACT_READY",
              "orientationFail": false,
              "palmPlateTwistedThroughObject": false,
              "indexDeepInside": false,
              "pinkyDeepInside": false,
              "onePalmNearSurface": true,
              "oppositePalmDeepInside": false,
              "diagnosis": "actual MCP palm side/surface check",
              "points": {
                "index": {
                  "x": 0.17507,
                  "y": 0.76743,
                  "z": -0.45185
                },
                "pinky": {
                  "x": 0.19051,
                  "y": 0.74874,
                  "z": -0.40151
                },
                "mcpIndex": {
                  "x": 0.18614,
                  "y": 0.78386,
                  "z": -0.44915
                },
                "mcpPinky": {
                  "x": 0.20158,
                  "y": 0.76517,
                  "z": -0.3988
                },
                "mcpMid": {
                  "x": 0.19184,
                  "y": 0.77222,
                  "z": -0.43311
                },
                "wrist": {
                  "x": 0.1323,
                  "y": 0.80776,
                  "z": -0.38448
                }
              },
              "basis": {
                "x": {
                  "x": -0.37161,
                  "y": 0.38907,
                  "z": -0.84293
                },
                "y": {
                  "x": 0.74533,
                  "y": -0.41631,
                  "z": -0.52074
                },
                "z": {
                  "x": -0.55352,
                  "y": -0.82177,
                  "z": -0.13528
                },
                "palmFacesObject": 0.46613,
                "offsetM": 0.02
              },
              "limb": {
                "axisPoint": {
                  "x": 0.1332,
                  "y": 0.69332,
                  "z": -0.37981
                },
                "axis": {
                  "x": -0.06945,
                  "y": -0.91358,
                  "z": 0.40069
                },
                "outward": {
                  "x": 0.99445,
                  "y": -0.09524,
                  "z": -0.04478
                },
                "radiusM": 0.052,
                "clearanceM": 0.003
              },
              "metrics": {
                "index": {
                  "radialM": 0.05039,
                  "requiredRadialM": 0.055,
                  "signedOutsideM": 0.0378,
                  "outsideScore": 0.75016,
                  "distanceToSurfaceM": 0.00461,
                  "penetrationM": 0.00461,
                  "surfaceOk": true,
                  "sideOk": true
                },
                "pinky": {
                  "radialM": 0.05309,
                  "requiredRadialM": 0.055,
                  "signedOutsideM": 0.05268,
                  "outsideScore": 0.99228,
                  "distanceToSurfaceM": 0.00191,
                  "penetrationM": 0.00191,
                  "surfaceOk": true,
                  "sideOk": true
                },
                "noGrossPenetration": true
              },
              "policy": "V308 post-commit actual gate: use actual Index1/Pinky1 MCP roots plus 20 mm palm offset against the actual lower-leg capsule. If pinky/index asymmetrically penetrates while the other contact point is on the surface, the hand is wrong-way/twisted through the object and fingers are blocked regardless of solver-side PREFINGER_READY."
            },
            "postFloorActualMcpSolve": {
              "schema": "NEXPROD01_V316_POST_FLOOR_ACTUAL_MCP_SECOND_PALM_SOLVE",
              "pass": true,
              "applied": true,
              "firstPalm": "pinky",
              "rollDeg": 15,
              "metrics": {
                "index": {
                  "radialM": 0.05039,
                  "requiredRadialM": 0.055,
                  "signedOutsideM": 0.0378,
                  "outsideScore": 0.75016,
                  "distanceToSurfaceM": 0.00461,
                  "penetrationM": 0.00461,
                  "surfaceOk": true,
                  "sideOk": true
                },
                "pinky": {
                  "radialM": 0.05309,
                  "requiredRadialM": 0.055,
                  "signedOutsideM": 0.05268,
                  "outsideScore": 0.99228,
                  "distanceToSurfaceM": 0.00191,
                  "penetrationM": 0.00191,
                  "surfaceOk": true,
                  "sideOk": true
                }
              }
            },
            "entryFrameGate": {
              "schema": "NEXPROD01_V297_V286_ENTRY_FRAME_GATE",
              "source": "V286_NEUTRALIZE_HAND_FOR_GRIP",
              "active": true,
              "mutatesTargets": false,
              "side": "L",
              "pass": false,
              "gate": "NEEDS_NEUTRALIZE_BEFORE_SOLVE_GRIP",
              "desiredOutsideDistanceM": 0.055,
              "signedOutsideM": 0.0414,
              "palmBaseOutsideM": 0.04588,
              "requiredOutwardShiftM": 0.0136,
              "palmAcrossOutsideDot": 0.76411,
              "limbAxisA": "L_Foot",
              "limbAxisB": "L_Calf",
              "policy": "V297 ports V286 as a non-mutating pre-contact entry-frame gate inside the V267 clean solver. It measures whether the hand MCP/palm frame approaches from the outside shell before point snap, palm roll, or finger child-layer."
            },
            "entryRepair": {
              "schema": "NEXPROD01_V306_ENTRY_FRAME_NEUTRALIZE_ROTATION",
              "active": false,
              "applied": false,
              "pass": true,
              "reason": "skipped_after_V311_locked_180_reset",
              "side": "L",
              "afterGate": {
                "schema": "NEXPROD01_V297_V286_ENTRY_FRAME_GATE",
                "source": "V286_NEUTRALIZE_HAND_FOR_GRIP",
                "active": true,
                "mutatesTargets": false,
                "side": "L",
                "pass": false,
                "gate": "NEEDS_NEUTRALIZE_BEFORE_SOLVE_GRIP",
                "desiredOutsideDistanceM": 0.055,
                "signedOutsideM": 0.0414,
                "palmBaseOutsideM": 0.04588,
                "requiredOutwardShiftM": 0.0136,
                "palmAcrossOutsideDot": 0.76411,
                "limbAxisA": "L_Foot",
                "limbAxisB": "L_Calf",
                "policy": "V297 ports V286 as a non-mutating pre-contact entry-frame gate inside the V267 clean solver. It measures whether the hand MCP/palm frame approaches from the outside shell before point snap, palm roll, or finger child-layer."
              },
              "policy": "V311: once the wrong-way left palm frame has been reset by the forced 180 degree pre-contact rotation, do not run another neutralizer that can rotate it back. Residual distance is handled by first-palm arm snap / object-meet."
            },
            "sideSurfaceGate": {
              "pass": false,
              "status": "GRIP_ENTRY_CONTRACT_HOLD_WRONG_SIDE_OR_PENETRATION",
              "checks": {
                "handPalmTowardObject": true,
                "firstPalmOnShiftedSurface": true,
                "secondPalmOnShiftedSurface": false,
                "outsideContact": true,
                "noGrossPenetration": true,
                "objectMeetWithinLimit": true,
                "firstSignedOutsideM": 0.05501,
                "secondSignedOutsideM": 0.06109,
                "firstPenetrationM": 0,
                "secondPenetrationM": 0,
                "firstOutsideScore": 1,
                "secondOutsideScore": 0.87555
              }
            },
            "v153MeshFeedbackPass": false,
            "policy": "V317 cuts the stale solver-side gate from active left grip final authority. If the post-floor actual MCP+20mm solve passes and the current actual MCP gate passes, pre-finger readiness may pass even when old target-space sideSurfaceGate/solver status is stale. No thumb-up/down rule is used; the final authority is actual palm side/surface/penetration."
          }
        },
        "commitMode": null,
        "v317Step": {
          "schema": "NEXPROD01_V316_POST_FLOOR_ACTUAL_MCP_SECOND_PALM_SOLVE",
          "active": true,
          "applied": true,
          "pass": true,
          "side": "L",
          "before": {
            "schema": "NEXPROD01_V308_ACTUAL_MCP_PALM_ORIENTATION_GATE",
            "active": true,
            "side": "L",
            "pass": false,
            "status": "PALM_FRAME_WRONG_WAY_THROUGH_OBJECT",
            "orientationFail": true,
            "palmPlateTwistedThroughObject": true,
            "indexDeepInside": true,
            "pinkyDeepInside": false,
            "onePalmNearSurface": true,
            "oppositePalmDeepInside": true,
            "diagnosis": "One MCP-derived palm point is near/on the surface while the other penetrates the leg capsule. This means the hand/palm frame is rolled the wrong way through the object; thumb-up here is a visual symptom, not a generic rule.",
            "points": {
              "index": {
                "x": 0.15992,
                "y": 0.7872,
                "z": -0.42263
              },
              "pinky": {
                "x": 0.18751,
                "y": 0.7707,
                "z": -0.37693
              },
              "mcpIndex": {
                "x": 0.16823,
                "y": 0.80533,
                "z": -0.4211
              },
              "mcpPinky": {
                "x": 0.19581,
                "y": 0.78882,
                "z": -0.3754
              },
              "mcpMid": {
                "x": 0.17877,
                "y": 0.79463,
                "z": -0.40698
              },
              "wrist": {
                "x": 0.12399,
                "y": 0.81772,
                "z": -0.34665
              }
            },
            "basis": {
              "x": {
                "x": -0.58461,
                "y": 0.33053,
                "z": -0.74094
              },
              "y": {
                "x": 0.69704,
                "y": -0.26271,
                "z": -0.66717
              },
              "z": {
                "x": -0.41517,
                "y": -0.90649,
                "z": -0.07681
              },
              "palmFacesObject": 0.32309,
              "offsetM": 0.02
            },
            "limb": {
              "axisPoint": {
                "x": 0.1332,
                "y": 0.69332,
                "z": -0.37981
              },
              "axis": {
                "x": -0.06945,
                "y": -0.91358,
                "z": 0.40069
              },
              "outward": {
                "x": 0.99445,
                "y": -0.09524,
                "z": -0.04478
              },
              "radiusM": 0.052,
              "clearanceM": 0.003
            },
            "metrics": {
              "index": {
                "radialM": 0.01955,
                "requiredRadialM": 0.055,
                "signedOutsideM": 0.01955,
                "outsideScore": 1,
                "distanceToSurfaceM": 0.03545,
                "penetrationM": 0.03545,
                "surfaceOk": false,
                "sideOk": true
              },
              "pinky": {
                "radialM": 0.05975,
                "requiredRadialM": 0.055,
                "signedOutsideM": 0.0465,
                "outsideScore": 0.7783,
                "distanceToSurfaceM": 0.00475,
                "penetrationM": 0,
                "surfaceOk": true,
                "sideOk": true
              },
              "noGrossPenetration": false
            },
            "policy": "V308 post-commit actual gate: use actual Index1/Pinky1 MCP roots plus 20 mm palm offset against the actual lower-leg capsule. If pinky/index asymmetrically penetrates while the other contact point is on the surface, the hand is wrong-way/twisted through the object and fingers are blocked regardless of solver-side PREFINGER_READY."
          },
          "after": {
            "schema": "NEXPROD01_V308_ACTUAL_MCP_PALM_ORIENTATION_GATE",
            "active": true,
            "side": "L",
            "pass": true,
            "status": "ACTUAL_MCP_PALM_CONTACT_READY",
            "orientationFail": false,
            "palmPlateTwistedThroughObject": false,
            "indexDeepInside": false,
            "pinkyDeepInside": false,
            "onePalmNearSurface": true,
            "oppositePalmDeepInside": false,
            "diagnosis": "actual MCP palm side/surface check",
            "points": {
              "index": {
                "x": 0.17507,
                "y": 0.76743,
                "z": -0.45185
              },
              "pinky": {
                "x": 0.19051,
                "y": 0.74874,
                "z": -0.40151
              },
              "mcpIndex": {
                "x": 0.18614,
                "y": 0.78386,
                "z": -0.44915
              },
              "mcpPinky": {
                "x": 0.20158,
                "y": 0.76517,
                "z": -0.3988
              },
              "mcpMid": {
                "x": 0.19184,
                "y": 0.77222,
                "z": -0.43311
              },
              "wrist": {
                "x": 0.1323,
                "y": 0.80776,
                "z": -0.38448
              }
            },
            "basis": {
              "x": {
                "x": -0.37161,
                "y": 0.38907,
                "z": -0.84293
              },
              "y": {
                "x": 0.74533,
                "y": -0.41631,
                "z": -0.52074
              },
              "z": {
                "x": -0.55352,
                "y": -0.82177,
                "z": -0.13528
              },
              "palmFacesObject": 0.46613,
              "offsetM": 0.02
            },
            "limb": {
              "axisPoint": {
                "x": 0.1332,
                "y": 0.69332,
                "z": -0.37981
              },
              "axis": {
                "x": -0.06945,
                "y": -0.91358,
                "z": 0.40069
              },
              "outward": {
                "x": 0.99445,
                "y": -0.09524,
                "z": -0.04478
              },
              "radiusM": 0.052,
              "clearanceM": 0.003
            },
            "metrics": {
              "index": {
                "radialM": 0.05039,
                "requiredRadialM": 0.055,
                "signedOutsideM": 0.0378,
                "outsideScore": 0.75016,
                "distanceToSurfaceM": 0.00461,
                "penetrationM": 0.00461,
                "surfaceOk": true,
                "sideOk": true
              },
              "pinky": {
                "radialM": 0.05309,
                "requiredRadialM": 0.055,
                "signedOutsideM": 0.05268,
                "outsideScore": 0.99228,
                "distanceToSurfaceM": 0.00191,
                "penetrationM": 0.00191,
                "surfaceOk": true,
                "sideOk": true
              },
              "noGrossPenetration": true
            },
            "policy": "V308 post-commit actual gate: use actual Index1/Pinky1 MCP roots plus 20 mm palm offset against the actual lower-leg capsule. If pinky/index asymmetrically penetrates while the other contact point is on the surface, the hand is wrong-way/twisted through the object and fingers are blocked regardless of solver-side PREFINGER_READY."
          },
          "rollDeg": 15,
          "firstPalm": "pinky",
          "beforeScore": 2672.727,
          "bestScore": -99765.852129,
          "afterScore": -99765.8513,
          "candidateCount": 276,
          "passCandidateCount": 43,
          "bestCandidate": {
            "deg": 15,
            "firstPalm": "pinky",
            "score": -99765.852129,
            "pass": true,
            "status": "ACTUAL_MCP_PALM_CONTACT_READY",
            "firstErrM": 0.00698,
            "firstTarget": {
              "x": 0.19229,
              "y": 0.74592,
              "z": -0.40764
            },
            "metrics": {
              "index": {
                "radialM": 0.05039,
                "requiredRadialM": 0.055,
                "signedOutsideM": 0.0378,
                "outsideScore": 0.75016,
                "distanceToSurfaceM": 0.00461,
                "penetrationM": 0.00461,
                "surfaceOk": true,
                "sideOk": true
              },
              "pinky": {
                "radialM": 0.05309,
                "requiredRadialM": 0.055,
                "signedOutsideM": 0.05268,
                "outsideScore": 0.99228,
                "distanceToSurfaceM": 0.00191,
                "penetrationM": 0.00191,
                "surfaceOk": true,
                "sideOk": true
              },
              "noGrossPenetration": true
            },
            "basis": {
              "x": {
                "x": -0.37161,
                "y": 0.38907,
                "z": -0.84293
              },
              "y": {
                "x": 0.74533,
                "y": -0.41631,
                "z": -0.52074
              },
              "z": {
                "x": -0.55352,
                "y": -0.82177,
                "z": -0.13528
              },
              "palmFacesObject": 0.46613,
              "offsetM": 0.02
            },
            "arm1": {
              "ok": true,
              "finalError": 0.01251,
              "iterations": 24
            },
            "arm2": {
              "ok": true,
              "finalError": 0.00739,
              "iterations": 10
            }
          },
          "metrics": {
            "index": {
              "radialM": 0.05039,
              "requiredRadialM": 0.055,
              "signedOutsideM": 0.0378,
              "outsideScore": 0.75016,
              "distanceToSurfaceM": 0.00461,
              "penetrationM": 0.00461,
              "surfaceOk": true,
              "sideOk": true
            },
            "pinky": {
              "radialM": 0.05309,
              "requiredRadialM": 0.055,
              "signedOutsideM": 0.05268,
              "outsideScore": 0.99228,
              "distanceToSurfaceM": 0.00191,
              "penetrationM": 0.00191,
              "surfaceOk": true,
              "sideOk": true
            }
          },
          "changedFingerLocals": [],
          "policy": "V316 reruns the actual MCP-only first-contact lock and second-palm wrist solve after knee aim and floor alignment. V315 proved the solve could pass before later body/floor steps invalidated it; V316 gives actual palm contact the final pre-finger authority.",
          "stage": "v316_post_floor_actual_mcp_second_palm_solve",
          "postFloor": true
        },
        "bones": {
          "error": "ReferenceError: THREE is not defined"
        },
        "bodyText": "NEXPROD01\nwriter check\nsleep\nNEXPLAYER RUNTIME\nDynamic Warm Up \u00b7 02 \u00b7 Hurdle stretch\nhurdle-stretch \u2192 warmup_hurdle_stretch_right_pose_v50_ik_v1 \u00b7 for_nex_approval \u00b7 ikHash addc0aae \u00b7 phase 0.250\nCHECK"
      },
      "summary": {
        "hasModel": true,
        "boneCount": 92,
        "skinnedMeshCount": 0,
        "runtimeVersion": "V317_FINAL_ACTUAL_MCP_AUTHORITY_GATE",
        "side": "L",
        "gripPass": true,
        "gripStatus": null,
        "v317StepApplied": true,
        "v317StepPass": true,
        "v317ChangedFingerLocals": 0,
        "v317RotationDeg": null,
        "actualGatePass": true,
        "actualGateStatus": "ACTUAL_MCP_PALM_PREFINGER_READY",
        "wrongWay": false,
        "orientationFail": false,
        "indexPen": 0.00461,
        "pinkyPen": 0.00191,
        "indexDist": 0.00461,
        "pinkyDist": 0.00191,
        "fingerBlocked": true,
        "fingerActive": false,
        "fingerReady": true
      },
      "screenshotCanvas": "/mnt/data/nex_v317_final_mcp_authority_gate/NEXT11_V317_FINAL_ACTUAL_MCP_AUTHORITY_GATE_ROOT/diagnostics/v317/V317_left_canvas.png",
      "screenshotPage": "/mnt/data/nex_v317_final_mcp_authority_gate/NEXT11_V317_FINAL_ACTUAL_MCP_AUTHORITY_GATE_ROOT/diagnostics/v317/V317_left_page.png"
    }
  ],
  "summaries": [
    {
      "hasModel": true,
      "boneCount": 92,
      "skinnedMeshCount": 0,
      "runtimeVersion": "V317_FINAL_ACTUAL_MCP_AUTHORITY_GATE",
      "side": "R",
      "gripPass": true,
      "gripStatus": "GRIP_ENTRY_CONTRACT_PREFINGER_READY",
      "v317StepApplied": null,
      "v317StepPass": null,
      "v317ChangedFingerLocals": 0,
      "v317RotationDeg": null,
      "actualGatePass": true,
      "actualGateStatus": "ACTUAL_MCP_PALM_PREFINGER_READY",
      "wrongWay": false,
      "orientationFail": false,
      "indexPen": 0.00073,
      "pinkyPen": 0.00049,
      "indexDist": 0.00073,
      "pinkyDist": 0.00049,
      "fingerBlocked": true,
      "fingerActive": false,
      "fingerReady": true
    },
    {
      "hasModel": true,
      "boneCount": 92,
      "skinnedMeshCount": 0,
      "runtimeVersion": "V317_FINAL_ACTUAL_MCP_AUTHORITY_GATE",
      "side": "L",
      "gripPass": true,
      "gripStatus": null,
      "v317StepApplied": true,
      "v317StepPass": true,
      "v317ChangedFingerLocals": 0,
      "v317RotationDeg": null,
      "actualGatePass": true,
      "actualGateStatus": "ACTUAL_MCP_PALM_PREFINGER_READY",
      "wrongWay": false,
      "orientationFail": false,
      "indexPen": 0.00461,
      "pinkyPen": 0.00191,
      "indexDist": 0.00461,
      "pinkyDist": 0.00191,
      "fingerBlocked": true,
      "fingerActive": false,
      "fingerReady": true
    }
  ],
  "passBrowserRuntime": true,
  "leftFinalAuthorityObserved": true,
  "noFingerRelease": true,
  "noFingerLocalRotationInV317Step": true,
  "passActualMcpPrefingerGate": true,
  "passNoFingerRelease": true
}