{
  "schema": "fermata.technical-cases.v4",
  "date": "2026-10-24",
  "cases": [
    {
      "id": "window-mismatch",
      "title": "The classifier was seeing a different window",
      "failure": "Manual-window RF scored macro F1 0.929 on 45 retrospective clips, but matched 0/8 target groups in continuous replay. One group changed from a 3.810 s manual crop / 0.866 twist score to a 2.010 s automatic window / 0.438 score.",
      "diagnosis": "Automatic boundaries and manual training crops produced different representations. Three other test twists produced no valid candidate, so a downstream classifier could not recover them.",
      "change": "Generate training and replay candidates with the same causal WindowStream and 58-feature function; add partial and cross-group negative windows; split by whole recording; weight correlated views and perform one training-only hard-negative pass.",
      "outcome": "Aligned pipeline matched 7/8 historical target groups; 3 unassigned positive-session outputs remained.",
      "limit": "Segmentation, window labels and fitting changed together. Previously inspected recordings; no blind generalization or isolated classifier-cause claim. Original motor masks are retained; counterfactual motor effects are not simulated.",
      "metrics": {
        "manual_rf": {
          "annotated_groups": 8,
          "matched_groups": 0,
          "missed_groups": 8,
          "accepted_events": 0,
          "duplicate_events": 0,
          "wrong_class_events": 0,
          "unassigned_events": 0,
          "negative_false_triggers": 0,
          "negative_seconds": 59.952148,
          "negative_false_triggers_per_minute": 0.0,
          "marker_relative_delay_median_ms": null,
          "group_recall": 0.0
        },
        "aligned_rf": {
          "annotated_groups": 8,
          "matched_groups": 7,
          "missed_groups": 1,
          "accepted_events": 10,
          "duplicate_events": 0,
          "wrong_class_events": 0,
          "unassigned_events": 3,
          "negative_false_triggers": 0,
          "negative_seconds": 59.952148,
          "negative_false_triggers_per_minute": 0.0,
          "marker_relative_delay_median_ms": 250.508,
          "group_recall": 0.875,
          "first_cycle_only_events": 0
        },
        "diagnostic_group": {
          "group": 1,
          "target_label": "twist_twice",
          "manual_window_diagnostic_only": {
            "duration_seconds": 3.810156,
            "probabilities": [
              0.1344378405036515,
              0.8655621594963485,
              0.0
            ],
            "choice": "twist_twice"
          },
          "automatic_windows": [
            {
              "candidate_us": 322190429.0,
              "start_us": 318895507.0,
              "motion_end_us": 320905273.0,
              "probabilities": [
                0.5622553748807343,
                0.43774462511926565,
                0.0
              ],
              "choice": "none",
              "quality_rejection": null,
              "duration_seconds": 2.009766
            }
          ],
          "no_automatic_candidate": false
        }
      },
      "code": {
        "language": "python",
        "source": {
          "path": "04_固件与手势识别/Fermata_ML_Training/aligned_windows.py",
          "sha256": "6ca1005a1ba4b7aebdf4b5724a68f502a98b61cfa5dd58fd7d745fc578dccc6a"
        },
        "symbol": "proposal_features",
        "excerpt": "grid=np.linspace(tt[0],tt[-1],FRAMES)\nresampled=np.stack([np.interp(grid,tt,vv[:,d]) for d in range(6)])\ncentered=resampled-resampled.mean(1,keepdims=True)\ncentered[:3]/=400."
      },
      "sources": [
        {
          "path": "04_固件与手势识别/Fermata_ML_Training/README.md",
          "sha256": "d4654dc99eb7b2b747e1e191cf08a58381226c42c582e223ea38c50cd4b0d906"
        },
        {
          "path": "04_固件与手势识别/Fermata_ML_Training/results/continuous_comparison/comparison.json",
          "sha256": "2be83dcea95e0f15b0ab2d4d26d25a89c6dbbad7d122644654ced0a87b0a14e9"
        },
        {
          "path": "04_固件与手势识别/Fermata_ML_Training/results/aligned_rf/comparison.json",
          "sha256": "dc9a74dd087cbaf4efd9184a44c7ab22c9d776572f16d07f07d79f294989abbb"
        },
        {
          "path": "04_固件与手势识别/Fermata_ML_Training/aligned_windows.py",
          "sha256": "6ca1005a1ba4b7aebdf4b5724a68f502a98b61cfa5dd58fd7d745fc578dccc6a"
        },
        {
          "path": "04_固件与手势识别/Fermata_ML_Training/train_aligned.py",
          "sha256": "8b261b9f257aa051cfd4beddfd25e774c4bee78da99e59c3e1f3b3fc84b86b35"
        }
      ]
    },
    {
      "id": "motor-mask",
      "title": "Keep recording when feedback moves the sensor",
      "failure": "A co-located actuator can contaminate motion input. In v316, only one live twist was accepted; the user confirmed vibration while later attempts were rejected. The evidence does not establish motor vibration as the cause of those misses.",
      "diagnosis": "The 120 s v316 record contains 12,513 raw samples and 54 masked samples. Later rejections occurred after the mask ended. Clearing the mask flags in replay did not create additional detections.",
      "change": "Playback and its 200 ms recovery interval mark samples as unavailable to recognition. The raw stream retains those samples and flags; the recognition core resets contaminated windows. v316 retained this guard while adding local gesture haptics.",
      "outcome": "v316 masked and unmasked replay logs are identical: one accepted twist in each. The current selected v326 excerpt retains all 729 raw samples, including 53 masked samples, while recording haptic start and finish.",
      "limit": "A preventive guard and observability result, not evidence of improved accuracy. v316 is a historical DTW-era experiment; the current v322 core preserves the same raw-recording/masking separation. This recording has no complete action annotations.",
      "metrics": {
        "historical_samples": 12513,
        "historical_masked": 54,
        "historical_masked_us": [
          213629882,
          214134765
        ],
        "masked_replay_accepts": 1,
        "unmasked_replay_accepts": 1,
        "replay_logs_identical": true,
        "current_excerpt_samples": 729,
        "current_excerpt_masked": 53
      },
      "code": {
        "language": "cpp",
        "source": {
          "path": "04_固件与手势识别/Fermata_Pair_v0.3.28/FermataBand/Hardware.h",
          "sha256": "ea94a4e84aefb3046c2a1f2518f44cdf4a300c9fa707f41b03a43d77aa899b41"
        },
        "symbol": "Haptic::masked",
        "excerpt": "bool masked(uint32_t now) const{return busy_||!Fermata::elapsed(now,ended_,200);}"
      },
      "sources": [
        {
          "path": "04_固件与手势识别/Fermata_Gesture_v0.3.16/results/验证记录.md",
          "sha256": "84dd09219c13eec4f36b8e361b8612208739eba92293ee1a7de53c0c4eb59798"
        },
        {
          "path": "04_固件与手势识别/Fermata_Gesture_v0.3.16/results/STATUS.json",
          "sha256": "4ac466784cb2cc2a1040f50b3f75e64496170ae671f8e2691dab64f22a5374dc"
        },
        {
          "path": "04_固件与手势识别/Fermata_Gesture_v0.3.16/results/gesture_haptic_imu.csv",
          "sha256": "df16b89a7a74af6738187c1519dede5b42ce3b07b6e46a3a47d66dbb8232731d"
        },
        {
          "path": "04_固件与手势识别/Fermata_Gesture_v0.3.16/results/replay_haptic_masked.log",
          "sha256": "80703ce46185d40e58c01048eff0285ba5420222f2e1bf5103fa2b481e29aefa"
        },
        {
          "path": "04_固件与手势识别/Fermata_Gesture_v0.3.16/results/replay_haptic_unmasked.log",
          "sha256": "80703ce46185d40e58c01048eff0285ba5420222f2e1bf5103fa2b481e29aefa"
        },
        {
          "path": "04_固件与手势识别/Fermata_Pair_v0.3.28/FermataBand/Hardware.h",
          "sha256": "ea94a4e84aefb3046c2a1f2518f44cdf4a300c9fa707f41b03a43d77aa899b41"
        },
        {
          "path": "04_固件与手势识别/Fermata_Pair_v0.3.28/FermataBand/Hardware.cpp",
          "sha256": "7e0778d6e3e1d33478e1b1999e3fb7cd3cad162bb13465ed6496ded8ea825e50"
        },
        {
          "path": "04_固件与手势识别/Fermata_Pair_v0.3.28/FermataBand/RfCore.h",
          "sha256": "74ec820b3c4efe34fcb42112f3ec8145e1f3f679560ee0786994e20d883dae88"
        }
      ]
    },
    {
      "id": "delivery-versus-feeling",
      "title": "A delivery receipt is not a felt cue or a reply",
      "failure": "In v309, three Attention requests received device ACKs. The user confirmed blue light for two formal actions, but ACK flags=2 reported NO_HAPTIC: B was not ready to vibrate.",
      "diagnosis": "Transport acceptance, driver readiness/playback, perceived sensation and intentional acknowledgement are separate states. A successful radio event could coexist with an unavailable motor.",
      "change": "v326 updated both bands, added WAIT support to B, retained calibration requirements, keyed receive/haptic/light logs by session/sequence/code, and kept the physical Received button distinct from automatic ACK. Duplicate packets are acknowledged without replaying feedback.",
      "outcome": "At the 19 October v326 test, A logged 3 physical Received presses and B logged 4. All seven matched peer receive, ACK, haptic start/finish and light start evidence; the user confirmed vibration and green light in both directions.",
      "limit": "Different dates and firmware, not a controlled gesture-recognition comparison or user study. The seven button tests do not prove every gesture cue was felt. Unkeyed HAPTIC_FINISHED is associated with the preceding matched start within one second.",
      "metrics": {
        "earlier_attention_requests": 3,
        "earlier_ack_no_haptic_flag": 2,
        "physical_received_presses_A": 3,
        "physical_received_presses_B": 4,
        "both_directions_human_confirmation": true
      },
      "code": {
        "language": "cpp",
        "source": {
          "path": "04_固件与手势识别/Fermata_Pair_v0.3.28/FermataBand/FermataBand.ino",
          "sha256": "49d4df16ed834cdca77783c8247b42a2fc8b13df2d975ee7b01f9be4506f042b"
        },
        "symbol": "ACK acceptance versus physical-button request",
        "excerpts": [
          "sendAck(f, flags);  // 接受/入队后就确认，不声称佩戴者已经感受到反馈。",
          "if (b == Button::SHORT) { logEvent(\"BUTTON_RECEIVED\",RECEIVED); requestSignal(RECEIVED); }"
        ]
      },
      "sources": [
        {
          "path": "05_测试数据与开发日志/2026-10-11_v309_转腕控制B/测试记录.md",
          "sha256": "185e1ca565856a555fb5385ae6cd9e7f1dc579880e2f45ce72f1b7a5aeeb6d9e"
        },
        {
          "path": "04_固件与手势识别/Fermata_Pair_v0.3.26/README.md",
          "sha256": "c38ad70b22ba639e82b54d615cdfd2560334e4c35cd5d7512f81ace121ab4893"
        },
        {
          "path": "04_固件与手势识别/Fermata_Pair_v0.3.26/results/hardware_20261019/all_physical_presses.json",
          "sha256": "dcdef2010d2764029f3cf8c30a8147c0243c319818d282c54acb42e8400b4bda"
        },
        {
          "path": "04_固件与手势识别/Fermata_Pair_v0.3.26/results/hardware_20261019/human_confirmation.json",
          "sha256": "39100297f62c496d0cd90f5a989cd581cdeb64c2ec5cfad518cd0b6a1242e597"
        },
        {
          "path": "04_固件与手势识别/Fermata_Pair_v0.3.28/FermataBand/FermataBand.ino",
          "sha256": "49d4df16ed834cdca77783c8247b42a2fc8b13df2d975ee7b01f9be4506f042b"
        }
      ]
    }
  ],
  "global_limits": [
    "No new experiment was performed for this portfolio.",
    "A v326 / B v328 use recognizer v322; v325 remains an unflashed candidate."
  ]
}
