# V303 Sequential finger contact report

V303 releases the finger layer after the V301 side/surface/penetration gate passes.

## Audit flags
- `passBrowserRuntime`: `True`
- `passSideSurfaceGate`: `True`
- `passFingerLayerActive`: `True`
- `passChildOnly`: `True`
- `passHasActiveJointRows`: `True`
- `pass`: `True`

## Per side summary
### left / side L
- `gripPass`: `True`
- `gripStatus`: `GRIP_ENTRY_CONTRACT_PREFINGER_READY`
- `sideSurfaceGatePass`: `True`
- `fingerActive`: `True`
- `fingerBlocked`: `False`
- `fingerReady`: `True`
- `fingerReleaseEnabled`: `True`
- `fingerPass`: `True`
- `activeFingerJointRows`: `11`
- `parentDriftPass`: `True`
- `thumbActiveRows`: `0`
- `perFinger`:
  - index: contactOk=True, worstPenetrationM=0, terms=[{'seg': 0, 'axis': 'x', 'sign': 1, 'amount': 0.36, 'active': True}, {'seg': 1, 'axis': 'z', 'sign': 1, 'amount': 0.27, 'active': True}, {'seg': 2, 'axis': 'z', 'sign': 1, 'amount': 0, 'active': True}]
  - middle: contactOk=True, worstPenetrationM=0, terms=[{'seg': 0, 'axis': 'x', 'sign': 1, 'amount': 0.735, 'active': True}, {'seg': 1, 'axis': 'z', 'sign': 1, 'amount': 0.18, 'active': True}, {'seg': 2, 'axis': 'z', 'sign': 1, 'amount': 0, 'active': True}]
  - ring: contactOk=False, worstPenetrationM=0, terms=[{'seg': 0, 'axis': 'x', 'sign': 1, 'amount': 0.84, 'active': True}, {'seg': 1, 'axis': 'z', 'sign': 1, 'amount': 0.45, 'active': True}, {'seg': 2, 'axis': 'z', 'sign': 1, 'amount': 0.06, 'active': True}]
  - pinky: contactOk=False, worstPenetrationM=0, terms=[{'seg': 0, 'axis': 'z', 'sign': 1, 'amount': 0.84, 'active': True}, {'seg': 1, 'axis': 'x', 'sign': 1, 'amount': 0.68, 'active': True}]

### right / side R
- `gripPass`: `True`
- `gripStatus`: `GRIP_ENTRY_CONTRACT_PREFINGER_READY`
- `sideSurfaceGatePass`: `True`
- `fingerActive`: `True`
- `fingerBlocked`: `False`
- `fingerReady`: `True`
- `fingerReleaseEnabled`: `True`
- `fingerPass`: `True`
- `activeFingerJointRows`: `10`
- `parentDriftPass`: `True`
- `thumbActiveRows`: `0`
- `perFinger`:
  - index: contactOk=False, worstPenetrationM=0, terms=[{'seg': 0, 'axis': 'z', 'sign': 1, 'amount': 0.36, 'active': True}, {'seg': 1, 'axis': 'z', 'sign': 1, 'amount': 0.72, 'active': True}, {'seg': 2, 'axis': 'z', 'sign': 1, 'amount': 0.36, 'active': True}]
  - middle: contactOk=False, worstPenetrationM=0, terms=[{'seg': 0, 'axis': 'z', 'sign': 1, 'amount': 0.84, 'active': True}, {'seg': 1, 'axis': 'z', 'sign': 1, 'amount': 0.72, 'active': True}, {'seg': 2, 'axis': 'z', 'sign': 1, 'amount': 0.36, 'active': True}]
  - ring: contactOk=False, worstPenetrationM=0, terms=[{'seg': 0, 'axis': 'z', 'sign': 1, 'amount': 0.84, 'active': True}, {'seg': 1, 'axis': 'z', 'sign': 1, 'amount': 0.72, 'active': True}, {'seg': 2, 'axis': 'z', 'sign': 1, 'amount': 0.06, 'active': True}]
  - pinky: contactOk=False, worstPenetrationM=0, terms=[{'seg': 1, 'axis': 'z', 'sign': 1, 'amount': 0.68, 'active': True}]

## Important note
The solver is not a free finger target/CCD writer. It is a bounded sequential child-layer. Some joints reached actual mesh-contact thresholds; some joints reached approved non-penetrating safe caps where the contact signal was not monotonic. This is intentionally reported rather than hidden.