🛡 M141-6 — cross-language parity gate

Mechanical guarantee that @orchestkit/hook-contract (npm) and orchestkit-hook-contract (PyPI) emit semantically identical contracts. Closes the loop on M141-2 + M141-3.

What the gate checks

CheckWhat fails it
Event name set equalityOne side has an event the other doesn't
Per-event payload.required field namesSet difference between sides
Per-event payload.properties field namesSet difference between sides
Per-event field JSON Schema type categorye.g. npm says string while PyPI says object

Why both per-side drift gates AND a cross-language gate

             ┌───────────────────────────────────┐
             │  spec/hook-events.spec.yml        │
             └────────┬────────────────┬─────────┘
                      │                │
            (codegen.mjs) ✓     (codegen-py.py) ✓
                      │                │
                      ▼                ▼
         ┌────────────────┐  ┌────────────────┐
         │ npm emit       │  │ PyPI emit      │
         └────┬───────────┘  └──┬─────────────┘
              │                 │
              │  per-side       │  per-side
              │  drift gate     │  drift gate
              │  (--check) ✓    │  (--check) ✓
              │                 │
              └──────┬──────────┘
                     ▼
              ┌──────────────────────────┐
              │ M141-6 PARITY GATE       │
              │ (this PR)                │
              │                          │
              │ "are npm and PyPI emits  │
              │  semantically equal?"    │
              └──────────────────────────┘

A subtle bug in either codegen could let both --check gates pass while npm and PyPI diverge (e.g. one emits a field as type: string and the other as type: object). The cross-language gate catches that case mechanically.

What ships in this PR

Verified locally

$ npm run --workspace=@orchestkit/hook-contract build
$ cd packages/hook-contract-py && .venv/bin/pip install -e . pyyaml
$ python3 scripts/parity-check.py
[parity-check] OK: npm + PyPI emit identical contract (19 events, 13 with typed payloads).
exit 0 ✓

What a real failure would look like

[parity-check] FAILED: npm and PyPI hook-contract emit diverge.

PreToolUse:
  required only in npm: ['session_id']
  field 'tool_input' type mismatch: npm=object vs PyPI=string

Fix: identify which codegen drifted from the other, regenerate, and
commit. Both should emit identical schemas from spec/hook-events.spec.yml.