{
  "ok": true,
  "mode": "JS8",
  "tool": "webftr-js8-frame-recover",
  "tool_version": "step42-direct-primary-bounded-repair",
  "input_wav": "/decoders/js8_decoder/runtime/quick_prefilter_windows/js8_quick_selected_window.wav",
  "rx_only": true,
  "safety": {
    "tx": false,
    "ptt": false,
    "tune": false,
    "send": false,
    "js8call_runtime_control": false
  },
  "implementation_stage": "step42_frame_recovery_guard_no_message_unpack",
  "wav": {
    "sample_rate": 12000,
    "duration_seconds": 60.0,
    "frames": 720000,
    "rms_dbfs": -9.127580437334753,
    "peak_dbfs": -0.7246929351669301,
    "clipped": false
  },
  "frame_requirements": {
    "expected_bits": 174,
    "expected_data_symbols": 58,
    "leading_costas_symbols": 7,
    "minimum_symbols_for_174bit_candidate": 65,
    "full_ft8_like_symbols_reference": 79
  },
  "profile_scan": {
    "ok": true,
    "mode": "JS8",
    "tool": "webftr-js8-profile-scan",
    "tool_version": "step42-direct-primary-bounded-repair",
    "input_wav": "/decoders/js8_decoder/runtime/quick_prefilter_windows/js8_quick_selected_window.wav",
    "rx_only": true,
    "safety": {
      "tx": false,
      "ptt": false,
      "tune": false,
      "send": false,
      "js8call_runtime_control": false
    },
    "implementation_stage": "step42_fast_profile_scan_guard_no_message_unpack",
    "wav": {
      "sample_rate": 12000,
      "duration_seconds": 60.0,
      "frames": 720000
    },
    "profile_count": 6,
    "scan_limits": {
      "max_seconds": 60.0,
      "max_starts": 14,
      "max_base_candidates": 8,
      "deep": true
    },
    "profiles": [
      {
        "profile": "js8_near_6000",
        "nsps": 6000,
        "symbol_duration_seconds": 0.5,
        "tone_spacing_hz": 2.0,
        "note": "0.500 s timing guard candidate",
        "ok": true,
        "sync": {
          "start_seconds": 8.25,
          "base_freq_hz": 1010.0,
          "candidate_score": 49.22,
          "costas_hits": 4,
          "avg_margin_db": 3.86,
          "candidate_count": 12
        },
        "frame": {
          "symbols_available_after_start": 103,
          "data_symbol_count_estimate": 58,
          "expected_data_symbols_candidate": 58
        },
        "fec": {
          "soft_bit_count_estimate": 174,
          "missing_soft_bits_estimate": 0,
          "complete_ldpc_input_candidate_estimate": true
        },
        "rank_score": 231.861
      },
      {
        "profile": "ft8_like_fast_1920",
        "nsps": 1920,
        "symbol_duration_seconds": 0.16,
        "tone_spacing_hz": 6.25,
        "note": "0.160 s symbols, 6.25 Hz spacing candidate",
        "ok": true,
        "sync": {
          "start_seconds": 29.68,
          "base_freq_hz": 980.0,
          "candidate_score": 47.58,
          "costas_hits": 3,
          "avg_margin_db": 5.94,
          "candidate_count": 12
        },
        "frame": {
          "symbols_available_after_start": 189,
          "data_symbol_count_estimate": 58,
          "expected_data_symbols_candidate": 58
        },
        "fec": {
          "soft_bit_count_estimate": 174,
          "missing_soft_bits_estimate": 0,
          "complete_ldpc_input_candidate_estimate": true
        },
        "rank_score": 228.079
      },
      {
        "profile": "js8_normal_6192",
        "nsps": 6192,
        "symbol_duration_seconds": 0.516,
        "tone_spacing_hz": 1.937984,
        "note": "0.516 s symbols, 1.938 Hz spacing candidate used in earlier lab steps",
        "ok": true,
        "sync": {
          "start_seconds": 33.024,
          "base_freq_hz": 1020.0,
          "candidate_score": 46.67,
          "costas_hits": 3,
          "avg_margin_db": 3.13,
          "candidate_count": 12
        },
        "frame": {
          "symbols_available_after_start": 52,
          "data_symbol_count_estimate": 45,
          "expected_data_symbols_candidate": 58
        },
        "fec": {
          "soft_bit_count_estimate": 135,
          "missing_soft_bits_estimate": 39,
          "complete_ldpc_input_candidate_estimate": false
        },
        "rank_score": 154.466948
      },
      {
        "profile": "mid_3840",
        "nsps": 3840,
        "symbol_duration_seconds": 0.32,
        "tone_spacing_hz": 3.125,
        "note": "0.320 s symbols, 3.125 Hz spacing candidate",
        "ok": true,
        "sync": {
          "start_seconds": 45.76,
          "base_freq_hz": 1005.0,
          "candidate_score": 44.86,
          "costas_hits": 2,
          "avg_margin_db": 5.02,
          "candidate_count": 12
        },
        "frame": {
          "symbols_available_after_start": 44,
          "data_symbol_count_estimate": 37,
          "expected_data_symbols_candidate": 58
        },
        "fec": {
          "soft_bit_count_estimate": 111,
          "missing_soft_bits_estimate": 63,
          "complete_ldpc_input_candidate_estimate": false
        },
        "rank_score": 131.754724
      },
      {
        "profile": "js8_near_6400",
        "nsps": 6400,
        "symbol_duration_seconds": 0.533333,
        "tone_spacing_hz": 1.875,
        "note": "0.533 s timing guard candidate",
        "ok": true,
        "sync": {
          "start_seconds": 45.466667,
          "base_freq_hz": 1000.0,
          "candidate_score": 40.55,
          "costas_hits": 2,
          "avg_margin_db": 8.4,
          "candidate_count": 12
        },
        "frame": {
          "symbols_available_after_start": 27,
          "data_symbol_count_estimate": 20,
          "expected_data_symbols_candidate": 58
        },
        "fec": {
          "soft_bit_count_estimate": 60,
          "missing_soft_bits_estimate": 114,
          "complete_ldpc_input_candidate_estimate": false
        },
        "rank_score": 95.03181
      },
      {
        "profile": "slow_7680",
        "nsps": 7680,
        "symbol_duration_seconds": 0.64,
        "tone_spacing_hz": 1.5625,
        "note": "0.640 s symbols, 1.5625 Hz spacing candidate",
        "ok": true,
        "sync": {
          "start_seconds": 52.0,
          "base_freq_hz": 1017.5,
          "candidate_score": 46.55,
          "costas_hits": 4,
          "avg_margin_db": 1.01,
          "candidate_count": 12
        },
        "frame": {
          "symbols_available_after_start": 12,
          "data_symbol_count_estimate": 5,
          "expected_data_symbols_candidate": 58
        },
        "fec": {
          "soft_bit_count_estimate": 15,
          "missing_soft_bits_estimate": 159,
          "complete_ldpc_input_candidate_estimate": false
        },
        "rank_score": 64.462328
      }
    ],
    "selected_profile": {
      "profile": "js8_near_6000",
      "nsps": 6000,
      "rank_score": 231.861,
      "complete_ldpc_input_candidate_estimate": true,
      "soft_bit_count_estimate": 174,
      "missing_soft_bits_estimate": 0
    },
    "decodes": [],
    "warnings": [
      "Step 42 selects the best timing/profile candidate only. It still does not decode final JS8 text."
    ],
    "next_action": "Run auto-ldpc-probe on the same WAV so the selected timing profile is fed into the LDPC probe harness."
  },
  "profile_guards": [
    {
      "profile": "js8_near_6000",
      "nsps": 6000,
      "protocol_family": "js8_normal_candidate",
      "symbol_duration_seconds": 0.5,
      "tone_spacing_hz": 2.0,
      "sync": {
        "start_seconds": 8.25,
        "base_freq_hz": 1010.0,
        "candidate_score": 49.22,
        "costas_hits": 4,
        "avg_margin_db": 3.86,
        "candidate_count": 12
      },
      "frame": {
        "symbols_available_after_start": 103,
        "data_symbol_count_estimate": 58,
        "expected_data_symbols_candidate": 58
      },
      "fec": {
        "soft_bit_count_estimate": 174,
        "missing_soft_bits_estimate": 0,
        "complete_ldpc_input_candidate_estimate": true
      },
      "rank_score": 231.861,
      "guard_score": 306.861,
      "available_after_start_seconds": 51.75,
      "minimum_symbols_for_174bit_candidate": 65,
      "minimum_seconds_after_start_for_174bit_candidate": 32.5,
      "missing_seconds_for_174bit_candidate": 0.0,
      "full_frame_symbols_reference": 79,
      "missing_seconds_for_full_ft8_like_frame": 0.0,
      "soft_bit_count_estimate": 174,
      "missing_soft_bits_estimate": 0,
      "enough_audio_for_174bit_candidate": true,
      "enough_audio_for_full_frame_reference": true,
      "guard_note": "Protocol-realistic JS8 timing candidate."
    },
    {
      "profile": "ft8_like_fast_1920",
      "nsps": 1920,
      "protocol_family": "fast_diagnostic_candidate",
      "symbol_duration_seconds": 0.16,
      "tone_spacing_hz": 6.25,
      "sync": {
        "start_seconds": 29.68,
        "base_freq_hz": 980.0,
        "candidate_score": 47.58,
        "costas_hits": 3,
        "avg_margin_db": 5.94,
        "candidate_count": 12
      },
      "frame": {
        "symbols_available_after_start": 189,
        "data_symbol_count_estimate": 58,
        "expected_data_symbols_candidate": 58
      },
      "fec": {
        "soft_bit_count_estimate": 174,
        "missing_soft_bits_estimate": 0,
        "complete_ldpc_input_candidate_estimate": true
      },
      "rank_score": 228.079,
      "guard_score": 230.079,
      "available_after_start_seconds": 30.32,
      "minimum_symbols_for_174bit_candidate": 65,
      "minimum_seconds_after_start_for_174bit_candidate": 10.4,
      "missing_seconds_for_174bit_candidate": 0.0,
      "full_frame_symbols_reference": 79,
      "missing_seconds_for_full_ft8_like_frame": 0.0,
      "soft_bit_count_estimate": 174,
      "missing_soft_bits_estimate": 0,
      "enough_audio_for_174bit_candidate": true,
      "enough_audio_for_full_frame_reference": true,
      "guard_note": "Diagnostic timing candidate. A short WAV can make this look better than real JS8 timing."
    },
    {
      "profile": "js8_normal_6192",
      "nsps": 6192,
      "protocol_family": "js8_normal_candidate",
      "symbol_duration_seconds": 0.516,
      "tone_spacing_hz": 1.937984,
      "sync": {
        "start_seconds": 33.024,
        "base_freq_hz": 1020.0,
        "candidate_score": 46.67,
        "costas_hits": 3,
        "avg_margin_db": 3.13,
        "candidate_count": 12
      },
      "frame": {
        "symbols_available_after_start": 52,
        "data_symbol_count_estimate": 45,
        "expected_data_symbols_candidate": 58
      },
      "fec": {
        "soft_bit_count_estimate": 135,
        "missing_soft_bits_estimate": 39,
        "complete_ldpc_input_candidate_estimate": false
      },
      "rank_score": 154.466948,
      "guard_score": 209.61481,
      "available_after_start_seconds": 26.976,
      "minimum_symbols_for_174bit_candidate": 65,
      "minimum_seconds_after_start_for_174bit_candidate": 33.54,
      "missing_seconds_for_174bit_candidate": 6.564,
      "full_frame_symbols_reference": 79,
      "missing_seconds_for_full_ft8_like_frame": 13.788,
      "soft_bit_count_estimate": 135,
      "missing_soft_bits_estimate": 39,
      "enough_audio_for_174bit_candidate": false,
      "enough_audio_for_full_frame_reference": false,
      "guard_note": "Protocol-realistic JS8 timing candidate."
    },
    {
      "profile": "mid_3840",
      "nsps": 3840,
      "protocol_family": "mid_speed_diagnostic_candidate",
      "symbol_duration_seconds": 0.32,
      "tone_spacing_hz": 3.125,
      "sync": {
        "start_seconds": 45.76,
        "base_freq_hz": 1005.0,
        "candidate_score": 44.86,
        "costas_hits": 2,
        "avg_margin_db": 5.02,
        "candidate_count": 12
      },
      "frame": {
        "symbols_available_after_start": 44,
        "data_symbol_count_estimate": 37,
        "expected_data_symbols_candidate": 58
      },
      "fec": {
        "soft_bit_count_estimate": 111,
        "missing_soft_bits_estimate": 63,
        "complete_ldpc_input_candidate_estimate": false
      },
      "rank_score": 131.754724,
      "guard_score": 119.772655,
      "available_after_start_seconds": 14.24,
      "minimum_symbols_for_174bit_candidate": 65,
      "minimum_seconds_after_start_for_174bit_candidate": 20.8,
      "missing_seconds_for_174bit_candidate": 6.56,
      "full_frame_symbols_reference": 79,
      "missing_seconds_for_full_ft8_like_frame": 11.04,
      "soft_bit_count_estimate": 111,
      "missing_soft_bits_estimate": 63,
      "enough_audio_for_174bit_candidate": false,
      "enough_audio_for_full_frame_reference": false,
      "guard_note": "Diagnostic timing candidate. A short WAV can make this look better than real JS8 timing."
    },
    {
      "profile": "js8_near_6400",
      "nsps": 6400,
      "protocol_family": "js8_normal_candidate",
      "symbol_duration_seconds": 0.533333,
      "tone_spacing_hz": 1.875,
      "sync": {
        "start_seconds": 45.466667,
        "base_freq_hz": 1000.0,
        "candidate_score": 40.55,
        "costas_hits": 2,
        "avg_margin_db": 8.4,
        "candidate_count": 12
      },
      "frame": {
        "symbols_available_after_start": 27,
        "data_symbol_count_estimate": 20,
        "expected_data_symbols_candidate": 58
      },
      "fec": {
        "soft_bit_count_estimate": 60,
        "missing_soft_bits_estimate": 114,
        "complete_ldpc_input_candidate_estimate": false
      },
      "rank_score": 95.03181,
      "guard_score": 110.10997,
      "available_after_start_seconds": 14.533333,
      "minimum_symbols_for_174bit_candidate": 65,
      "minimum_seconds_after_start_for_174bit_candidate": 34.666667,
      "missing_seconds_for_174bit_candidate": 20.133334,
      "full_frame_symbols_reference": 79,
      "missing_seconds_for_full_ft8_like_frame": 27.6,
      "soft_bit_count_estimate": 60,
      "missing_soft_bits_estimate": 114,
      "enough_audio_for_174bit_candidate": false,
      "enough_audio_for_full_frame_reference": false,
      "guard_note": "Protocol-realistic JS8 timing candidate."
    },
    {
      "profile": "slow_7680",
      "nsps": 7680,
      "protocol_family": "slow_diagnostic_candidate",
      "symbol_duration_seconds": 0.64,
      "tone_spacing_hz": 1.5625,
      "sync": {
        "start_seconds": 52.0,
        "base_freq_hz": 1017.5,
        "candidate_score": 46.55,
        "costas_hits": 4,
        "avg_margin_db": 1.01,
        "candidate_count": 12
      },
      "frame": {
        "symbols_available_after_start": 12,
        "data_symbol_count_estimate": 5,
        "expected_data_symbols_candidate": 58
      },
      "fec": {
        "soft_bit_count_estimate": 15,
        "missing_soft_bits_estimate": 159,
        "complete_ldpc_input_candidate_estimate": false
      },
      "rank_score": 64.462328,
      "guard_score": -28.151465,
      "available_after_start_seconds": 8.0,
      "minimum_symbols_for_174bit_candidate": 65,
      "minimum_seconds_after_start_for_174bit_candidate": 41.6,
      "missing_seconds_for_174bit_candidate": 33.6,
      "full_frame_symbols_reference": 79,
      "missing_seconds_for_full_ft8_like_frame": 42.56,
      "soft_bit_count_estimate": 15,
      "missing_soft_bits_estimate": 159,
      "enough_audio_for_174bit_candidate": false,
      "enough_audio_for_full_frame_reference": false,
      "guard_note": "Diagnostic timing candidate. A short WAV can make this look better than real JS8 timing."
    }
  ],
  "selected_guard_profile": {
    "profile": "js8_near_6000",
    "nsps": 6000,
    "protocol_family": "js8_normal_candidate",
    "symbol_duration_seconds": 0.5,
    "tone_spacing_hz": 2.0,
    "sync": {
      "start_seconds": 8.25,
      "base_freq_hz": 1010.0,
      "candidate_score": 49.22,
      "costas_hits": 4,
      "avg_margin_db": 3.86,
      "candidate_count": 12
    },
    "frame": {
      "symbols_available_after_start": 103,
      "data_symbol_count_estimate": 58,
      "expected_data_symbols_candidate": 58
    },
    "fec": {
      "soft_bit_count_estimate": 174,
      "missing_soft_bits_estimate": 0,
      "complete_ldpc_input_candidate_estimate": true
    },
    "rank_score": 231.861,
    "guard_score": 306.861,
    "available_after_start_seconds": 51.75,
    "minimum_symbols_for_174bit_candidate": 65,
    "minimum_seconds_after_start_for_174bit_candidate": 32.5,
    "missing_seconds_for_174bit_candidate": 0.0,
    "full_frame_symbols_reference": 79,
    "missing_seconds_for_full_ft8_like_frame": 0.0,
    "soft_bit_count_estimate": 174,
    "missing_soft_bits_estimate": 0,
    "enough_audio_for_174bit_candidate": true,
    "enough_audio_for_full_frame_reference": true,
    "guard_note": "Protocol-realistic JS8 timing candidate."
  },
  "selected_ldpc_probe": {
    "ok": true,
    "sync_candidate": {
      "start_sample": 99000,
      "start_seconds": 8.25,
      "base_freq_hz": 1010.0,
      "tone_spacing_hz": 2.0,
      "nsps": 6000,
      "candidate_score": 49.22,
      "costas_hits": 4,
      "avg_margin_db": 3.86
    },
    "frame_candidate": {
      "input_symbol_count": 96,
      "excluded_costas_symbol_count": 0,
      "detected_costas_blocks": [],
      "data_symbol_count_available": 96,
      "data_symbol_count_used": 58,
      "expected_data_symbols_candidate": 58,
      "costas_policy": "js8_leading_only"
    },
    "fec_input_summary": {
      "soft_bit_count": 174,
      "missing_soft_bits": 0,
      "complete_ldpc_input_candidate": true,
      "llr_convention": "positive=bit0_more_likely, negative=bit1_more_likely, MSB-first candidate"
    },
    "selected_variant": "reverse_full_bitstream",
    "ready_for_real_ldpc_matrix": true
  },
  "decodes": [],
  "warnings": [
    "Step 42 selects the best timing/profile candidate only. It still does not decode final JS8 text.",
    "Step 42 is still RX-only and diagnostic: it guards profile selection and frame length before final LDPC/message work."
  ],
  "next_action": "If selected_guard_profile.enough_audio_for_174bit_candidate is false, make a longer WAV capture. If true, the next lab step can move to real LDPC/FEC matrix integration and JS8 message unpacking."
}
