# Spoof Gate + PEC Feedback — Integration Notes for Opus

These notes tell you **exactly** what to add to existing files.
Do not touch anything else.

---

## 1. `src/config.h` — append two MSG_TYPE defines

Add after `#define MSG_TYPE_BLUE_FORCE 0x09` (line ~179):

```c
#define MSG_TYPE_SPOOF_SCORE   0x11  // T2 -> T1: per-track spoof probability from rid_spoof_gate.py
#define MSG_TYPE_PEC_FEEDBACK  0x12  // T2 -> T1: PEC-cleaned class probability vector from mitigation.py
```

---

## 2. `src/main.cpp` — includes (top of file)

Add after the existing include block (before `static const char* TAG`):

```cpp
#include "spoof_gate_client.h"
#include "pec_feedback.h"
```

---

## 3. `src/main.cpp` — `setup()` init calls

Add inside `setup()`, alongside the other `*_init()` calls:

```cpp
spoof_gate_init();
pec_feedback_init();
```

---

## 4. `src/main.cpp` — dispatch switch (~line 280, inside `loop()`)

Add two new cases **before** the `default:` case in the `switch (msg_type)` block:

```cpp
case MSG_TYPE_SPOOF_SCORE:            // 0x11
    spoof_gate_handle_packet(rx_buf, (size_t)rx_len);
    break;

case MSG_TYPE_PEC_FEEDBACK:           // 0x12
    pec_feedback_handle_packet(rx_buf, (size_t)rx_len);
    break;
```

---

## 5. `src/threat_correlator.cpp` — `correlator_run()` score overlay

### Required includes (add at top of threat_correlator.cpp):

```cpp
#include "spoof_gate_client.h"
#include "pec_feedback.h"
```

### Integration point in `build_composite()` or just after `correlator_feed()` lookup:

The correlator does not currently carry a `track_id` through the pipeline.
The most surgical wiring is to apply the spoof penalty **inside `correlator_run()`
immediately after `build_composite()` fills `threats[found]`**, before the
`mark_emitted()` call.  Pseudocode for each composite block:

```cpp
// --- AFTER build_composite(threats[found], ...) ---

// 1. Spoof-gate confidence penalty
//    track_id convention: use the composite's first constituent slot_id
//    cast to uint32_t as a proxy until a proper track_id field is plumbed.
//    Replace 0 with the real track_id when available in the pipeline.
{
    uint32_t track_id = (uint32_t)threats[found].constituent_slots[0]; // placeholder
    uint8_t spoof_q8 = spoof_gate_score_for_track(track_id);
    if (spoof_q8 > 0) {
        float spoof_factor = 1.0f - (float)spoof_q8 / 255.0f;
        threats[found].combined_confidence *= spoof_factor;
    }
}

// 2. PEC feedback probability overlay
//    If we have a fresh PEC vector for this track, replace the geometric-mean
//    confidence with the top PEC probability for the matched composite class.
{
    uint32_t track_id = (uint32_t)threats[found].constituent_slots[0]; // placeholder
    float pec_probs[MODEL_MAX_OUTPUT_CLASSES];
    uint8_t pec_n = 0;
    if (pec_feedback_get_latest(track_id, pec_probs, &pec_n, 5000 /*ms*/)) {
        // Map composite class index to PEC output class (0..pec_n-1 clamp)
        uint8_t cls_idx = (uint8_t)threats[found].threat_class;
        if (cls_idx < pec_n) {
            // Blend: keep geometric mean as floor, overlay PEC as ceiling
            float pec_conf = pec_probs[cls_idx];
            if (pec_conf > threats[found].combined_confidence) {
                threats[found].combined_confidence = pec_conf;
            }
        }
    }
}
```

**Note on track_id plumbing:** The T2 gateway's `rid_spoof_gate.py` and
`mitigation.py` both emit a `source_track_id` / `track_id` field.  Once
`DetectionEvent` or `CorrelatorDetection` carries a proper 32-bit track
identifier derived from the RID MAC/serial, replace the `constituent_slots[0]`
proxy above with that field.

---

## 6. `platformio.ini` — expose test filter for native env

The `[env:native]` section currently pins `test_filter = test_command_handler`.
Change it to run both suites:

```ini
test_filter = test_command_handler|test_spoof_pec
```

Or run only the new suite ad-hoc:

```
pio test -e native -f test_spoof_pec
```

---

## 7. Wire-up verification checklist

- [ ] `pio build -e heltec_wifi_lora_v4` passes with new includes
- [ ] `pio test -e native -f test_spoof_pec` → 17/17 pass
- [ ] `pio test -e native -f test_command_handler` → still passes (no regressions)
- [ ] On-sensor: confirm MSG_TYPE_SPOOF_SCORE and MSG_TYPE_PEC_FEEDBACK log lines
      appear when T2 Python scripts send test packets
