{
  "schema": "V307_MCP_PALM_VIEW_AUDIT",
  "generatedAt": "2026-08-19T20:23:10Z",
  "audit": [
    {
      "label": "left",
      "side": "L",
      "init": {
        "ok": true,
        "side": "L",
        "gate": {
          "schema": "NEXPROD01_V307_ACTUAL_MCP_PALM_SURFACE_GATE",
          "active": true,
          "side": "L",
          "pass": false,
          "status": "ACTUAL_MCP_PALM_CONTACT_FAIL",
          "points": {
            "index": {
              "x": 0.16882,
              "y": 0.74379,
              "z": -0.40259
            },
            "pinky": {
              "x": 0.18319,
              "y": 0.72094,
              "z": -0.35367
            },
            "mcpIndex": {
              "x": 0.18672,
              "y": 0.75265,
              "z": -0.40371
            },
            "mcpPinky": {
              "x": 0.20109,
              "y": 0.72979,
              "z": -0.35479
            },
            "mcpMid": {
              "x": 0.18923,
              "y": 0.74004,
              "z": -0.38759
            },
            "wrist": {
              "x": 0.16539,
              "y": 0.80137,
              "z": -0.33427
            }
          },
          "basis": {
            "x": {
              "x": -0.30033,
              "y": 0.50479,
              "z": -0.80931
            },
            "y": {
              "x": 0.32991,
              "y": -0.74114,
              "z": -0.5847
            },
            "z": {
              "x": -0.89497,
              "y": -0.4426,
              "z": 0.05605
            },
            "palmFacesObject": 0.85035,
            "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.03169,
              "requiredRadialM": 0.055,
              "signedOutsideM": 0.03163,
              "outsideScore": 0.99816,
              "distanceToSurfaceM": 0.02331,
              "penetrationM": 0.02331,
              "surfaceOk": false,
              "sideOk": true
            },
            "pinky": {
              "radialM": 0.0601,
              "requiredRadialM": 0.055,
              "signedOutsideM": 0.0459,
              "outsideScore": 0.76381,
              "distanceToSurfaceM": 0.0051,
              "penetrationM": 0,
              "surfaceOk": true,
              "sideOk": true
            },
            "noGrossPenetration": false
          },
          "policy": "Post-commit actual gate: use actual Index1/Pinky1 MCP roots plus 20 mm palm offset against the actual lower-leg capsule. This is the authority for visual palm-side contact; old phantom pointA/pointB target-space landmarks cannot pass this gate."
        },
        "grip": {
          "schema": "NEXPROD01_GRIP_SOLVER_V1",
          "version": "V307_ACTUAL_MCP_PALM_SNAP",
          "side": "L",
          "applied": true,
          "implemented": true,
          "policy": "V307: entry-frame gate remains a hard state machine, but palm contacts are now actual MCP-derived points: Index1/Pinky1 plus ~20 mm palm-surface offset. Old phantom pointA/pointB landmarks are disabled as contact authority; fingers remain blocked unless the post-commit actual MCP palm gate passes and finger release is explicitly enabled.",
          "pass": true,
          "palmContactReady": true,
          "preFingerReady": true,
          "status": "GRIP_ENTRY_CONTRACT_PREFINGER_READY",
          "ruleType": "v94_space_control_left_finger_grip",
          "targetLimb": "L_lower_shin_heel_cylinder",
          "targetSide": "outside_shifted_surface",
          "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": 16.82,
            "mcpCenter_vs_forearm": 21.2,
            "mcpAxis_vs_forearm": 76.7,
            "palmNormal_vs_forearm": 73.5
          },
          "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."
            },
            "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": true,
              "applied": true,
              "pass": true,
              "reason": "rotated_entry_frame_repaired_orientation_continue_to_point_snap",
              "rollDeg": -180,
              "axis": {
                "x": 0.1393,
                "y": -0.91181,
                "z": -0.38625
              },
              "pivot": {
                "x": 0.1606,
                "y": 1.02401,
                "z": -0.25589
              },
              "before": {
                "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."
              },
              "bestCandidate": {
                "deg": -180,
                "score": -986.04,
                "gate": {
                  "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."
                }
              },
              "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": "V306 implements the recovered contract: when V297 says NEEDS_NEUTRALIZE_BEFORE_SOLVE_GRIP, rotate the handframe around the active forearm/wrist axis and re-run the entry-frame gate before point snap. If orientation/outside approach is repaired but residual reach remains, object/leg-meet may handle that in the next stage; if repair fails, stop."
            },
            "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": true,
              "rollDeg": -67,
              "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.05494,
                  "requiredRadialM": 0.055,
                  "signedOutsideM": 0.04073,
                  "outsideScore": 0.74139,
                  "distanceToSurfaceM": 6e-05,
                  "penetrationM": 6e-05,
                  "surfaceOk": true,
                  "sideOk": true
                },
                "pointA": {
                  "x": 0.18337,
                  "y": 0.98716,
                  "z": -0.35353
                },
                "pointB": {
                  "x": 0.169,
                  "y": 1.01001,
                  "z": -0.40245
                },
                "palmFacesObject": 0.85035,
                "handAcrossVerticalProxy": -0.50479,
                "grossPenetration": false,
                "arm": {
                  "ok": true,
                  "distance": 0.4539920092537044,
                  "minReach": 0.011290533223480169,
                  "maxReach": 0.4552927984127249,
                  "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.89497,
                "y": -0.4426,
                "z": 0.05605
              },
              "mcp": {
                "index": {
                  "x": 0.1869,
                  "y": 1.01887,
                  "z": -0.40357
                },
                "pinky": {
                  "x": 0.20127,
                  "y": 0.99601,
                  "z": -0.35465
                },
                "mid": {
                  "x": 0.18941,
                  "y": 1.00626,
                  "z": -0.38744
                },
                "wrist": {
                  "x": 0.16557,
                  "y": 1.06759,
                  "z": -0.33412
                }
              },
              "palm": {
                "index": {
                  "x": 0.169,
                  "y": 1.01001,
                  "z": -0.40245
                },
                "pinky": {
                  "x": 0.18337,
                  "y": 0.98716,
                  "z": -0.35353
                }
              },
              "pointA": {
                "x": 0.18337,
                "y": 0.98716,
                "z": -0.35353
              },
              "pointB": {
                "x": 0.169,
                "y": 1.01001,
                "z": -0.40245
              },
              "basis": {
                "x": {
                  "x": -0.30033,
                  "y": 0.50479,
                  "z": -0.80931
                },
                "y": {
                  "x": 0.32991,
                  "y": -0.74114,
                  "z": -0.5847
                },
                "z": {
                  "x": -0.89497,
                  "y": -0.4426,
                  "z": 0.05605
                },
                "center": {
                  "x": 0.19252,
                  "y": 1.00704,
                  "z": -0.38189
                },
                "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": 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.05501,
                "secondSignedOutsideM": 0.04073,
                "firstPenetrationM": 0,
                "secondPenetrationM": 6e-05,
                "firstOutsideScore": 1,
                "secondOutsideScore": 0.74139
              },
              "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"
          ]
        }
      },
      "shots": {
        "outside_clean": {
          "path": "/mnt/data/v307_mcp_palm_views/V307_left_outside_clean.png",
          "meta": {
            "ok": true,
            "kind": "outside",
            "marked": false,
            "gatePass": false,
            "metrics": {
              "index": {
                "radialM": 0.03169,
                "requiredRadialM": 0.055,
                "signedOutsideM": 0.03163,
                "outsideScore": 0.99816,
                "distanceToSurfaceM": 0.02331,
                "penetrationM": 0.02331,
                "surfaceOk": false,
                "sideOk": true
              },
              "pinky": {
                "radialM": 0.0601,
                "requiredRadialM": 0.055,
                "signedOutsideM": 0.0459,
                "outsideScore": 0.76381,
                "distanceToSurfaceM": 0.0051,
                "penetrationM": 0,
                "surfaceOk": true,
                "sideOk": true
              },
              "noGrossPenetration": false
            },
            "gripPass": true
          }
        },
        "tangent_clean": {
          "path": "/mnt/data/v307_mcp_palm_views/V307_left_tangent_clean.png",
          "meta": {
            "ok": true,
            "kind": "tangent",
            "marked": false,
            "gatePass": false,
            "metrics": {
              "index": {
                "radialM": 0.03169,
                "requiredRadialM": 0.055,
                "signedOutsideM": 0.03163,
                "outsideScore": 0.99816,
                "distanceToSurfaceM": 0.02331,
                "penetrationM": 0.02331,
                "surfaceOk": false,
                "sideOk": true
              },
              "pinky": {
                "radialM": 0.0601,
                "requiredRadialM": 0.055,
                "signedOutsideM": 0.0459,
                "outsideScore": 0.76381,
                "distanceToSurfaceM": 0.0051,
                "penetrationM": 0,
                "surfaceOk": true,
                "sideOk": true
              },
              "noGrossPenetration": false
            },
            "gripPass": true
          }
        },
        "oblique_clean": {
          "path": "/mnt/data/v307_mcp_palm_views/V307_left_oblique_clean.png",
          "meta": {
            "ok": true,
            "kind": "oblique",
            "marked": false,
            "gatePass": false,
            "metrics": {
              "index": {
                "radialM": 0.03169,
                "requiredRadialM": 0.055,
                "signedOutsideM": 0.03163,
                "outsideScore": 0.99816,
                "distanceToSurfaceM": 0.02331,
                "penetrationM": 0.02331,
                "surfaceOk": false,
                "sideOk": true
              },
              "pinky": {
                "radialM": 0.0601,
                "requiredRadialM": 0.055,
                "signedOutsideM": 0.0459,
                "outsideScore": 0.76381,
                "distanceToSurfaceM": 0.0051,
                "penetrationM": 0,
                "surfaceOk": true,
                "sideOk": true
              },
              "noGrossPenetration": false
            },
            "gripPass": true
          }
        },
        "outside_marked": {
          "path": "/mnt/data/v307_mcp_palm_views/V307_left_outside_marked.png",
          "meta": {
            "ok": true,
            "kind": "outside",
            "marked": true,
            "gatePass": false,
            "metrics": {
              "index": {
                "radialM": 0.03169,
                "requiredRadialM": 0.055,
                "signedOutsideM": 0.03163,
                "outsideScore": 0.99816,
                "distanceToSurfaceM": 0.02331,
                "penetrationM": 0.02331,
                "surfaceOk": false,
                "sideOk": true
              },
              "pinky": {
                "radialM": 0.0601,
                "requiredRadialM": 0.055,
                "signedOutsideM": 0.0459,
                "outsideScore": 0.76381,
                "distanceToSurfaceM": 0.0051,
                "penetrationM": 0,
                "surfaceOk": true,
                "sideOk": true
              },
              "noGrossPenetration": false
            },
            "gripPass": true
          }
        },
        "tangent_marked": {
          "path": "/mnt/data/v307_mcp_palm_views/V307_left_tangent_marked.png",
          "meta": {
            "ok": true,
            "kind": "tangent",
            "marked": true,
            "gatePass": false,
            "metrics": {
              "index": {
                "radialM": 0.03169,
                "requiredRadialM": 0.055,
                "signedOutsideM": 0.03163,
                "outsideScore": 0.99816,
                "distanceToSurfaceM": 0.02331,
                "penetrationM": 0.02331,
                "surfaceOk": false,
                "sideOk": true
              },
              "pinky": {
                "radialM": 0.0601,
                "requiredRadialM": 0.055,
                "signedOutsideM": 0.0459,
                "outsideScore": 0.76381,
                "distanceToSurfaceM": 0.0051,
                "penetrationM": 0,
                "surfaceOk": true,
                "sideOk": true
              },
              "noGrossPenetration": false
            },
            "gripPass": true
          }
        },
        "oblique_marked": {
          "path": "/mnt/data/v307_mcp_palm_views/V307_left_oblique_marked.png",
          "meta": {
            "ok": true,
            "kind": "oblique",
            "marked": true,
            "gatePass": false,
            "metrics": {
              "index": {
                "radialM": 0.03169,
                "requiredRadialM": 0.055,
                "signedOutsideM": 0.03163,
                "outsideScore": 0.99816,
                "distanceToSurfaceM": 0.02331,
                "penetrationM": 0.02331,
                "surfaceOk": false,
                "sideOk": true
              },
              "pinky": {
                "radialM": 0.0601,
                "requiredRadialM": 0.055,
                "signedOutsideM": 0.0459,
                "outsideScore": 0.76381,
                "distanceToSurfaceM": 0.0051,
                "penetrationM": 0,
                "surfaceOk": true,
                "sideOk": true
              },
              "noGrossPenetration": false
            },
            "gripPass": true
          }
        }
      }
    },
    {
      "label": "right",
      "side": "R",
      "init": {
        "ok": true,
        "side": "R",
        "gate": {
          "schema": "NEXPROD01_V307_ACTUAL_MCP_PALM_SURFACE_GATE",
          "active": true,
          "side": "R",
          "pass": true,
          "status": "ACTUAL_MCP_PALM_CONTACT_READY",
          "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": "Post-commit actual gate: use actual Index1/Pinky1 MCP roots plus 20 mm palm offset against the actual lower-leg capsule. This is the authority for visual palm-side contact; old phantom pointA/pointB target-space landmarks cannot pass this gate."
        },
        "grip": {
          "schema": "NEXPROD01_GRIP_SOLVER_V1",
          "version": "V307_ACTUAL_MCP_PALM_SNAP",
          "side": "R",
          "applied": true,
          "implemented": true,
          "policy": "V307: entry-frame gate remains a hard state machine, but palm contacts are now actual MCP-derived points: Index1/Pinky1 plus ~20 mm palm-surface offset. Old phantom pointA/pointB landmarks are disabled as contact authority; fingers remain blocked unless the post-commit actual MCP palm gate passes and finger release is explicitly enabled.",
          "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."
            },
            "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"
          ]
        }
      },
      "shots": {
        "outside_clean": {
          "path": "/mnt/data/v307_mcp_palm_views/V307_right_outside_clean.png",
          "meta": {
            "ok": true,
            "kind": "outside",
            "marked": false,
            "gatePass": true,
            "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
            },
            "gripPass": true
          }
        },
        "tangent_clean": {
          "path": "/mnt/data/v307_mcp_palm_views/V307_right_tangent_clean.png",
          "meta": {
            "ok": true,
            "kind": "tangent",
            "marked": false,
            "gatePass": true,
            "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
            },
            "gripPass": true
          }
        },
        "oblique_clean": {
          "path": "/mnt/data/v307_mcp_palm_views/V307_right_oblique_clean.png",
          "meta": {
            "ok": true,
            "kind": "oblique",
            "marked": false,
            "gatePass": true,
            "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
            },
            "gripPass": true
          }
        },
        "outside_marked": {
          "path": "/mnt/data/v307_mcp_palm_views/V307_right_outside_marked.png",
          "meta": {
            "ok": true,
            "kind": "outside",
            "marked": true,
            "gatePass": true,
            "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
            },
            "gripPass": true
          }
        },
        "tangent_marked": {
          "path": "/mnt/data/v307_mcp_palm_views/V307_right_tangent_marked.png",
          "meta": {
            "ok": true,
            "kind": "tangent",
            "marked": true,
            "gatePass": true,
            "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
            },
            "gripPass": true
          }
        },
        "oblique_marked": {
          "path": "/mnt/data/v307_mcp_palm_views/V307_right_oblique_marked.png",
          "meta": {
            "ok": true,
            "kind": "oblique",
            "marked": true,
            "gatePass": true,
            "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
            },
            "gripPass": true
          }
        }
      }
    }
  ]
}