{
  "schema": "webftr-js8-decoder-lab-browser-report-v1",
  "version": "step84-real-wav-status-surface-report-slim",
  "created_utc": "2026-05-28T04:04:08Z",
  "project": "WebFTR JS8 Decoder Lab",
  "root": "/decoders/js8_decoder",
  "expected_root": "/decoders/js8_decoder",
  "logs_dir": "/decoders/js8_decoder/logs",
  "runtime_dir": "/decoders/js8_decoder/runtime",
  "daemon_status": {
    "schema": "webftr-js8lab-daemon-status-v2",
    "version": "step84-real-wav-status-surface-report-slim",
    "created_utc": "2026-05-26T07:46:12Z",
    "updated_utc": "2026-05-28T03:56:11Z",
    "state": "diagnostics_ok",
    "detail": "Diagnose fertig",
    "exit_code": 0,
    "root": "/decoders/js8_decoder",
    "expected_root": "/decoders/js8_decoder",
    "wav": "/decoders/js8_test.wav",
    "mode": "real-wav-status-surface-regression",
    "start_guard": {
      "start_stops_existing_instance": true,
      "stale_pid_cleanup": true,
      "root_orphan_cleanup": true,
      "port_guard": true,
      "foreign_port_owner_not_killed": true
    },
    "server": {
      "host": "0.0.0.0",
      "port": 8000,
      "pid": 82171,
      "running": true,
      "log": "/decoders/js8_decoder/logs/js8_browser_server.log"
    },
    "diagnostics": {
      "pid": 82187,
      "running": false,
      "log": "/decoders/js8_decoder/logs/js8_start_diagnostics_latest.log",
      "last_command": "./run_js8_decoder_lab.sh real-wav-status-surface-regression /decoders/js8_test.wav"
    },
    "latest_chain_summary": {
      "available": true,
      "path": "/decoders/js8_decoder/logs/js8_real_wav_message174_regeneration_latest.json",
      "stat": {
        "exists": true,
        "size": 93483,
        "mtime_utc": "2026-05-28T03:56:08Z"
      },
      "tool_version": "step84-real-wav-status-surface-report-slim",
      "created_utc": "2026-05-28T03:56:08Z",
      "verdict": "step83_wav_to_message174_regeneration_confirmed",
      "input_wav": "/decoders/js8_test.wav",
      "analysis_wav": "/decoders/js8_decoder/runtime/step83_quick_windows/js8_quick_selected_window.wav",
      "wav_was_read": true,
      "wav_duration_seconds": 192.016583,
      "quick_window_selected": true,
      "candidate_export_ok": true,
      "runtime_info87_rows_count": 48,
      "post_ldpc_zero_distance_candidate_count": 0,
      "source_exact_zero_distance_candidate_count": 2,
      "message174_decode_count": 2,
      "frame_probe_count": 2,
      "frame_type_counts": {
        "FrameHeartbeat": 1,
        "FrameDirected": 1
      },
      "control_frame_release_count": 2,
      "webftr_display_count": 2,
      "webftr_rx_rows_preview": [
        {
          "id": "js8-rx67-de15d3110b0d",
          "source_candidate_id": "js8-frame66-bf1ce62fdb4a",
          "source_decode_id": "js8-msg174-44978e4b",
          "mode": "JS8",
          "raw_message174": "001XqOA2iDZ0",
          "valid_message174_crc12": true,
          "crc12_distance": 0,
          "received_crc12": 2920,
          "computed_crc12": 2920,
          "frame_type": "FrameHeartbeat",
          "confidence": "high",
          "confidence_score": 6,
          "confidence_reasons": [
            "valid_heartbeat_callsign",
            "valid_heartbeat_grid"
          ],
          "show_in_rx_list": true,
          "candidate_class": "webftr_control_frame_display_ready",
          "release_guard": "step67_source_confirmed_fixed_control_frame_only",
          "sort_index": 0,
          "source": {
            "source_file": "/decoders/js8_decoder/logs/20260528T035339Z_step83_source_exact_map_probe_output.json",
            "json_path": "$.top_llr_row_exports[0].hard_bits",
            "source_kind": "generic_bit_list",
            "row_index": 165,
            "map_name": "raw",
            "map_source": null
          },
          "status": "HB",
          "from": "004REY/0V4",
          "to": "@HB",
          "grid": "OJ16",
          "message": "HB 004REY/0V4 OJ16",
          "text": "HB 004REY/0V4 OJ16",
          "display_text": "HB 004REY/0V4 OJ16",
          "is_control_frame": true
        },
        {
          "id": "js8-rx67-bd37f68199eb",
          "source_candidate_id": "js8-frame66-66ab29ded46c",
          "source_decode_id": "js8-msg174-8368257f",
          "mode": "JS8",
          "raw_message174": "Q0VsKWqfJ96x",
          "valid_message174_crc12": true,
          "crc12_distance": 0,
          "received_crc12": 980,
          "computed_crc12": 980,
          "frame_type": "FrameDirected",
          "confidence": "high",
          "confidence_score": 10,
          "confidence_reasons": [
            "valid_directed_from",
            "valid_directed_to",
            "directed_command"
          ],
          "show_in_rx_list": true,
          "candidate_class": "webftr_control_frame_display_ready",
          "release_guard": "step67_source_confirmed_fixed_control_frame_only",
          "sort_index": 1,
          "source": {
            "source_file": "/decoders/js8_decoder/logs/20260528T035339Z_step83_source_exact_map_probe_output.json",
            "json_path": "$.top_llr_row_exports[6].hard_bits",
            "source_kind": "generic_bit_list",
            "row_index": 171,
            "map_name": "raw",
            "map_source": null
          },
          "status": "INFO",
          "from": "9I2TZR/P",
          "to": "0Z0PMP",
          "command": "INFO",
          "extra": 59,
          "extra_value": {
            "kind": "number",
            "value": 28
          },
          "message": "INFO 28",
          "text": "9I2TZR/P 0Z0PMP INFO 28",
          "display_text": "9I2TZR/P 0Z0PMP INFO 28",
          "is_control_frame": true
        }
      ],
      "source_chain_ran_from_real_wav_this_step": true,
      "exit_codes": {
        "input_check": 0,
        "quick_window_scan": 0,
        "candidate_export": 0,
        "post_ldpc_info87_runtime_export": 0,
        "source_exact_map_probe": 0,
        "source_confirmed_message174_decode": 0,
        "source_varicode_frame_unpack_probe": 0,
        "source_confirmed_control_frame_rx_release": 0
      },
      "next_action": "If Step84 confirms message174/control-frame regeneration from the real WAV, continue with either a wider real-WAV search for FrameDataCompressed or a real JS8Call/RF comparison fixture."
    },
    "links": {
      "home": "/",
      "api_report": "/api/report",
      "api_status": "/api/status",
      "logs": "/logs/",
      "latest_log": "/logs/latest.log",
      "start_diagnostics_log": "/logs/js8_start_diagnostics_latest.log",
      "server_log": "/logs/js8_browser_server.log"
    },
    "rx_only_guard": {
      "tx": false,
      "ptt": false,
      "tune": false,
      "send": false,
      "js8call_runtime_control": false
    },
    "history": [
      {
        "utc": "2026-05-27T19:39:43Z",
        "state": "diagnostics_running",
        "detail": "Diagnosejob im Hintergrund gestartet",
        "exit_code": null
      },
      {
        "utc": "2026-05-27T19:39:47Z",
        "state": "diagnostics_ok",
        "detail": "Diagnose fertig",
        "exit_code": 0
      },
      {
        "utc": "2026-05-28T02:35:08Z",
        "state": "restarting",
        "detail": "Start-Guard: bestehende JS8Lab-Instanz wird geprüft und beendet",
        "exit_code": null
      },
      {
        "utc": "2026-05-28T02:35:08Z",
        "state": "server_starting",
        "detail": "Browser-Logserver startet auf 0.0.0.0:8000",
        "exit_code": null
      },
      {
        "utc": "2026-05-28T02:35:09Z",
        "state": "server_running",
        "detail": "Browser-Logserver läuft auf 0.0.0.0:8000",
        "exit_code": 0
      },
      {
        "utc": "2026-05-28T02:35:09Z",
        "state": "diagnostics_running",
        "detail": "Diagnose läuft: real-fixture-operator-bundle ",
        "exit_code": null
      },
      {
        "utc": "2026-05-28T02:35:10Z",
        "state": "diagnostics_running",
        "detail": "Diagnosejob im Hintergrund gestartet",
        "exit_code": null
      },
      {
        "utc": "2026-05-28T02:35:14Z",
        "state": "diagnostics_ok",
        "detail": "Diagnose fertig",
        "exit_code": 0
      },
      {
        "utc": "2026-05-28T02:43:27Z",
        "state": "restarting",
        "detail": "Start-Guard: bestehende JS8Lab-Instanz wird geprüft und beendet",
        "exit_code": null
      },
      {
        "utc": "2026-05-28T02:43:27Z",
        "state": "server_starting",
        "detail": "Browser-Logserver startet auf 0.0.0.0:8000",
        "exit_code": null
      },
      {
        "utc": "2026-05-28T02:43:28Z",
        "state": "server_running",
        "detail": "Browser-Logserver läuft auf 0.0.0.0:8000",
        "exit_code": 0
      },
      {
        "utc": "2026-05-28T02:43:28Z",
        "state": "diagnostics_running",
        "detail": "Diagnose läuft: real-fixture-command-export ",
        "exit_code": null
      },
      {
        "utc": "2026-05-28T02:43:30Z",
        "state": "diagnostics_running",
        "detail": "Diagnosejob im Hintergrund gestartet",
        "exit_code": null
      },
      {
        "utc": "2026-05-28T02:43:33Z",
        "state": "diagnostics_ok",
        "detail": "Diagnose fertig",
        "exit_code": 0
      },
      {
        "utc": "2026-05-28T02:48:52Z",
        "state": "restarting",
        "detail": "Start-Guard: bestehende JS8Lab-Instanz wird geprüft und beendet",
        "exit_code": null
      },
      {
        "utc": "2026-05-28T02:48:53Z",
        "state": "server_starting",
        "detail": "Browser-Logserver startet auf 0.0.0.0:8000",
        "exit_code": null
      },
      {
        "utc": "2026-05-28T02:48:54Z",
        "state": "server_running",
        "detail": "Browser-Logserver läuft auf 0.0.0.0:8000",
        "exit_code": 0
      },
      {
        "utc": "2026-05-28T02:48:54Z",
        "state": "diagnostics_running",
        "detail": "Diagnose läuft: real-compressed-text-release-gate ",
        "exit_code": null
      },
      {
        "utc": "2026-05-28T02:48:55Z",
        "state": "diagnostics_running",
        "detail": "Diagnosejob im Hintergrund gestartet",
        "exit_code": null
      },
      {
        "utc": "2026-05-28T02:49:02Z",
        "state": "diagnostics_ok",
        "detail": "Diagnose fertig",
        "exit_code": 0
      },
      {
        "utc": "2026-05-28T02:57:02Z",
        "state": "restarting",
        "detail": "Start-Guard: bestehende JS8Lab-Instanz wird geprüft und beendet",
        "exit_code": null
      },
      {
        "utc": "2026-05-28T02:57:03Z",
        "state": "server_starting",
        "detail": "Browser-Logserver startet auf 0.0.0.0:8000",
        "exit_code": null
      },
      {
        "utc": "2026-05-28T02:57:04Z",
        "state": "server_running",
        "detail": "Browser-Logserver läuft auf 0.0.0.0:8000",
        "exit_code": 0
      },
      {
        "utc": "2026-05-28T02:57:04Z",
        "state": "diagnostics_running",
        "detail": "Diagnose läuft: jsc-cpp-reference-compare-probe ",
        "exit_code": null
      },
      {
        "utc": "2026-05-28T02:57:05Z",
        "state": "diagnostics_running",
        "detail": "Diagnosejob im Hintergrund gestartet",
        "exit_code": null
      },
      {
        "utc": "2026-05-28T02:57:13Z",
        "state": "diagnostics_ok",
        "detail": "Diagnose fertig",
        "exit_code": 0
      },
      {
        "utc": "2026-05-28T03:07:25Z",
        "state": "restarting",
        "detail": "Start-Guard: bestehende JS8Lab-Instanz wird geprüft und beendet",
        "exit_code": null
      },
      {
        "utc": "2026-05-28T03:07:26Z",
        "state": "server_starting",
        "detail": "Browser-Logserver startet auf 0.0.0.0:8000",
        "exit_code": null
      },
      {
        "utc": "2026-05-28T03:07:27Z",
        "state": "server_running",
        "detail": "Browser-Logserver läuft auf 0.0.0.0:8000",
        "exit_code": 0
      },
      {
        "utc": "2026-05-28T03:07:27Z",
        "state": "diagnostics_running",
        "detail": "Diagnose läuft: jsc-cpp-reference-map-transport-fix ",
        "exit_code": null
      },
      {
        "utc": "2026-05-28T03:07:28Z",
        "state": "diagnostics_running",
        "detail": "Diagnosejob im Hintergrund gestartet",
        "exit_code": null
      },
      {
        "utc": "2026-05-28T03:07:40Z",
        "state": "diagnostics_ok",
        "detail": "Diagnose fertig",
        "exit_code": 0
      },
      {
        "utc": "2026-05-28T03:18:38Z",
        "state": "restarting",
        "detail": "Start-Guard: bestehende JS8Lab-Instanz wird geprüft und beendet",
        "exit_code": null
      },
      {
        "utc": "2026-05-28T03:18:38Z",
        "state": "server_starting",
        "detail": "Browser-Logserver startet auf 0.0.0.0:8000",
        "exit_code": null
      },
      {
        "utc": "2026-05-28T03:18:39Z",
        "state": "server_running",
        "detail": "Browser-Logserver läuft auf 0.0.0.0:8000",
        "exit_code": 0
      },
      {
        "utc": "2026-05-28T03:18:39Z",
        "state": "diagnostics_running",
        "detail": "Diagnose läuft: real-wav-full-chain-regression /decoders/js8_test.wav",
        "exit_code": null
      },
      {
        "utc": "2026-05-28T03:18:40Z",
        "state": "diagnostics_running",
        "detail": "Diagnosejob im Hintergrund gestartet",
        "exit_code": null
      },
      {
        "utc": "2026-05-28T03:19:11Z",
        "state": "diagnostics_ok",
        "detail": "Diagnose fertig",
        "exit_code": 0
      },
      {
        "utc": "2026-05-28T03:38:58Z",
        "state": "restarting",
        "detail": "Start-Guard: bestehende JS8Lab-Instanz wird geprüft und beendet",
        "exit_code": null
      },
      {
        "utc": "2026-05-28T03:38:58Z",
        "state": "server_starting",
        "detail": "Browser-Logserver startet auf 0.0.0.0:8000",
        "exit_code": null
      },
      {
        "utc": "2026-05-28T03:38:59Z",
        "state": "server_running",
        "detail": "Browser-Logserver läuft auf 0.0.0.0:8000",
        "exit_code": 0
      },
      {
        "utc": "2026-05-28T03:38:59Z",
        "state": "diagnostics_running",
        "detail": "Diagnose läuft: real-wav-message174-regeneration /decoders/js8_test.wav",
        "exit_code": null
      },
      {
        "utc": "2026-05-28T03:39:01Z",
        "state": "diagnostics_running",
        "detail": "Diagnosejob im Hintergrund gestartet",
        "exit_code": null
      },
      {
        "utc": "2026-05-28T03:41:40Z",
        "state": "diagnostics_ok",
        "detail": "Diagnose fertig",
        "exit_code": 0
      },
      {
        "utc": "2026-05-28T03:53:37Z",
        "state": "restarting",
        "detail": "Start-Guard: bestehende JS8Lab-Instanz wird geprüft und beendet",
        "exit_code": null
      },
      {
        "utc": "2026-05-28T03:53:37Z",
        "state": "server_starting",
        "detail": "Browser-Logserver startet auf 0.0.0.0:8000",
        "exit_code": null
      },
      {
        "utc": "2026-05-28T03:53:39Z",
        "state": "server_running",
        "detail": "Browser-Logserver läuft auf 0.0.0.0:8000",
        "exit_code": 0
      },
      {
        "utc": "2026-05-28T03:53:39Z",
        "state": "diagnostics_running",
        "detail": "Diagnose läuft: real-wav-status-surface-regression /decoders/js8_test.wav",
        "exit_code": null
      },
      {
        "utc": "2026-05-28T03:53:40Z",
        "state": "diagnostics_running",
        "detail": "Diagnosejob im Hintergrund gestartet",
        "exit_code": null
      },
      {
        "utc": "2026-05-28T03:56:11Z",
        "state": "diagnostics_ok",
        "detail": "Diagnose fertig",
        "exit_code": 0
      }
    ],
    "status_file": "/decoders/js8_decoder/runtime/js8lab_status.json"
  },
  "latest_chain_summary": {
    "available": true,
    "path": "/decoders/js8_decoder/logs/js8_real_wav_message174_regeneration_latest.json",
    "stat": {
      "exists": true,
      "is_file": true,
      "is_dir": false,
      "size": 93483,
      "mtime_utc": "2026-05-28T03:56:08Z"
    },
    "tool_version": "step84-real-wav-status-surface-report-slim",
    "created_utc": "2026-05-28T03:56:08Z",
    "verdict": "step83_wav_to_message174_regeneration_confirmed",
    "input_wav": "/decoders/js8_test.wav",
    "analysis_wav": "/decoders/js8_decoder/runtime/step83_quick_windows/js8_quick_selected_window.wav",
    "wav_was_read": true,
    "wav_duration_seconds": 192.016583,
    "quick_window_selected": true,
    "candidate_export_ok": true,
    "runtime_info87_rows_count": 48,
    "post_ldpc_zero_distance_candidate_count": 0,
    "source_exact_zero_distance_candidate_count": 2,
    "message174_decode_count": 2,
    "frame_probe_count": 2,
    "frame_type_counts": {
      "FrameHeartbeat": 1,
      "FrameDirected": 1
    },
    "control_frame_release_count": 2,
    "webftr_display_count": 2,
    "webftr_rx_rows_preview": [
      {
        "id": "js8-rx67-de15d3110b0d",
        "source_candidate_id": "js8-frame66-bf1ce62fdb4a",
        "source_decode_id": "js8-msg174-44978e4b",
        "mode": "JS8",
        "raw_message174": "001XqOA2iDZ0",
        "valid_message174_crc12": true,
        "crc12_distance": 0,
        "received_crc12": 2920,
        "computed_crc12": 2920,
        "frame_type": "FrameHeartbeat",
        "confidence": "high",
        "confidence_score": 6,
        "confidence_reasons": [
          "valid_heartbeat_callsign",
          "valid_heartbeat_grid"
        ],
        "show_in_rx_list": true,
        "candidate_class": "webftr_control_frame_display_ready",
        "release_guard": "step67_source_confirmed_fixed_control_frame_only",
        "sort_index": 0,
        "source": {
          "source_file": "/decoders/js8_decoder/logs/20260528T035339Z_step83_source_exact_map_probe_output.json",
          "json_path": "$.top_llr_row_exports[0].hard_bits",
          "source_kind": "generic_bit_list",
          "row_index": 165,
          "map_name": "raw",
          "map_source": null
        },
        "status": "HB",
        "from": "004REY/0V4",
        "to": "@HB",
        "grid": "OJ16",
        "message": "HB 004REY/0V4 OJ16",
        "text": "HB 004REY/0V4 OJ16",
        "display_text": "HB 004REY/0V4 OJ16",
        "is_control_frame": true
      },
      {
        "id": "js8-rx67-bd37f68199eb",
        "source_candidate_id": "js8-frame66-66ab29ded46c",
        "source_decode_id": "js8-msg174-8368257f",
        "mode": "JS8",
        "raw_message174": "Q0VsKWqfJ96x",
        "valid_message174_crc12": true,
        "crc12_distance": 0,
        "received_crc12": 980,
        "computed_crc12": 980,
        "frame_type": "FrameDirected",
        "confidence": "high",
        "confidence_score": 10,
        "confidence_reasons": [
          "valid_directed_from",
          "valid_directed_to",
          "directed_command"
        ],
        "show_in_rx_list": true,
        "candidate_class": "webftr_control_frame_display_ready",
        "release_guard": "step67_source_confirmed_fixed_control_frame_only",
        "sort_index": 1,
        "source": {
          "source_file": "/decoders/js8_decoder/logs/20260528T035339Z_step83_source_exact_map_probe_output.json",
          "json_path": "$.top_llr_row_exports[6].hard_bits",
          "source_kind": "generic_bit_list",
          "row_index": 171,
          "map_name": "raw",
          "map_source": null
        },
        "status": "INFO",
        "from": "9I2TZR/P",
        "to": "0Z0PMP",
        "command": "INFO",
        "extra": 59,
        "extra_value": {
          "kind": "number",
          "value": 28
        },
        "message": "INFO 28",
        "text": "9I2TZR/P 0Z0PMP INFO 28",
        "display_text": "9I2TZR/P 0Z0PMP INFO 28",
        "is_control_frame": true
      }
    ],
    "source_chain_ran_from_real_wav_this_step": true,
    "exit_codes": {
      "input_check": 0,
      "quick_window_scan": 0,
      "candidate_export": 0,
      "post_ldpc_info87_runtime_export": 0,
      "source_exact_map_probe": 0,
      "source_confirmed_message174_decode": 0,
      "source_varicode_frame_unpack_probe": 0,
      "source_confirmed_control_frame_rx_release": 0
    },
    "next_action": "If Step84 confirms message174/control-frame regeneration from the real WAV, continue with either a wider real-WAV search for FrameDataCompressed or a real JS8Call/RF comparison fixture."
  },
  "wav_candidates": [
    {
      "path": "/decoders/js8_test.wav",
      "exists": true,
      "is_file": true,
      "is_dir": false,
      "size": 4608442,
      "mtime_utc": "2026-05-26T06:05:27Z"
    },
    {
      "path": "/home/webftr/decoders/js8_test.wav",
      "exists": false,
      "error": "[Errno 2] No such file or directory: '/home/webftr/decoders/js8_test.wav'"
    },
    {
      "path": "/decoders/js8_decoder/decoders/js8_test.wav",
      "exists": false,
      "error": "[Errno 2] No such file or directory: '/decoders/js8_decoder/decoders/js8_test.wav'"
    }
  ],
  "selected_wav_hint": {
    "path": "/decoders/js8_test.wav",
    "exists": true,
    "is_file": true,
    "is_dir": false,
    "size": 4608442,
    "mtime_utc": "2026-05-26T06:05:27Z"
  },
  "rx_only_guard": {
    "tx": false,
    "ptt": false,
    "tune": false,
    "send": false,
    "js8call_runtime_control": false,
    "webftr_productive_integration": false
  },
  "latest_manifest": {
    "name": "20260528T035339Z_real-wav-status-surface-regression_manifest.json",
    "url": "/logs/20260528T035339Z_real-wav-status-surface-regression_manifest.json",
    "stat": {
      "exists": true,
      "is_file": true,
      "is_dir": false,
      "size": 2693,
      "mtime_utc": "2026-05-28T03:56:09Z"
    },
    "json": {
      "schema": "webftr-js8-decoder-lab-log-manifest-v2",
      "outputs": {
        "real_wav_message174_regeneration_json": "/decoders/js8_decoder/logs/20260528T035339Z_real_wav_message174_regeneration_output.json",
        "real_wav_message174_regeneration_latest_json": "/decoders/js8_decoder/logs/js8_real_wav_message174_regeneration_latest.json",
        "input_check_json": "/decoders/js8_decoder/logs/20260528T035339Z_step83_input_check_output.json",
        "quick_window_scan_json": "/decoders/js8_decoder/logs/20260528T035339Z_step83_quick_window_scan_output.json",
        "candidate_export_json": "/decoders/js8_decoder/logs/20260528T035339Z_step83_candidate_export_output.json",
        "post_ldpc_json": "/decoders/js8_decoder/logs/20260528T035339Z_step83_post_ldpc_info87_runtime_export_output.json",
        "source_exact_json": "/decoders/js8_decoder/logs/20260528T035339Z_step83_source_exact_map_probe_output.json",
        "message174_json": "/decoders/js8_decoder/logs/20260528T035339Z_step83_source_confirmed_message174_decode_output.json",
        "varicode_json": "/decoders/js8_decoder/logs/20260528T035339Z_step83_source_varicode_frame_unpack_probe_output.json",
        "rx_release_json": "/decoders/js8_decoder/logs/20260528T035339Z_step83_source_confirmed_control_frame_rx_release_output.json"
      }
    }
  },
  "latest_log": {
    "url": "/logs/latest.log",
    "stat": {
      "exists": true,
      "is_file": true,
      "is_dir": false,
      "size": 534781,
      "mtime_utc": "2026-05-28T03:56:11Z"
    },
    "tail": "             \"word\": \"S\",\n              \"separate\": false,\n              \"bits\": \"01100\",\n              \"python_text\": \"S\",\n              \"cpp_text\": \"S\",\n              \"expected_text\": \"S\",\n              \"python_complete\": true,\n              \"cpp_complete\": true,\n              \"passes\": true\n            },\n            {\n              \"index\": 6,\n              \"word\": \"S\",\n              \"separate\": true,\n              \"bits\": \"01101\",\n              \"python_text\": \"S \",\n              \"cpp_text\": \"S \",\n              \"expected_text\": \"S \",\n              \"python_complete\": true,\n              \"cpp_complete\": true,\n              \"passes\": true\n            },\n            {\n              \"index\": 7,\n              \"word\": \"H\",\n              \"separate\": false,\n              \"bits\": \"011100000\",\n              \"python_text\": \"H\",\n              \"cpp_text\": \"H\",\n              \"expected_text\": \"H\",\n              \"python_complete\": true,\n              \"cpp_complete\": true,\n              \"passes\": true\n            },\n            {\n              \"index\": 7,\n              \"word\": \"H\",\n              \"separate\": true,\n              \"bits\": \"011100001\",\n              \"python_text\": \"H \",\n              \"cpp_text\": \"H \",\n              \"expected_text\": \"H \",\n              \"python_complete\": true,\n              \"cpp_complete\": true,\n              \"passes\": true\n            },\n            {\n              \"index\": 8,\n              \"word\": \"R\",\n              \"separate\": false,\n              \"bits\": \"011100010\",\n              \"python_text\": \"R\",\n              \"cpp_text\": \"R\",\n              \"expected_text\": \"R\",\n              \"python_complete\": true,\n              \"cpp_complete\": true,\n              \"passes\": true\n            },\n            {\n              \"index\": 8,\n              \"word\": \"R\",\n              \"separate\": true,\n              \"bits\": \"011100011\",\n              \"python_text\": \"R \",\n              \"cpp_text\": \"R \",\n              \"expected_text\": \"R \",\n              \"python_complete\": true,\n              \"cpp_complete\": true,\n              \"passes\": true\n            },\n            {\n              \"index\": 15,\n              \"word\": \"F\",\n              \"separate\": false,\n              \"bits\": \"100000010\",\n              \"python_text\": \"F\",\n              \"cpp_text\": \"F\",\n              \"expected_text\": \"F\",\n              \"python_complete\": true,\n              \"cpp_complete\": true,\n              \"passes\": true\n            },\n            {\n              \"index\": 15,\n              \"word\": \"F\",\n              \"separate\": true,\n              \"bits\": \"100000011\",\n              \"python_text\": \"F \",\n              \"cpp_text\": \"F \",\n              \"expected_text\": \"F \",\n              \"python_complete\": true,\n              \"cpp_complete\": true,\n              \"passes\": true\n            },\n            {\n              \"index\": 31,\n              \"word\": \")\",\n              \"separate\": false,\n              \"bits\": \"101000110\",\n              \"python_text\": \")\",\n              \"cpp_text\": \")\",\n              \"expected_text\": \")\",\n              \"python_complete\": true,\n              \"cpp_complete\": true,\n              \"passes\": true\n            },\n            {\n              \"index\": 31,\n              \"word\": \")\",\n              \"separate\": true,\n              \"bits\": \"101000111\",\n              \"python_text\": \") \",\n              \"cpp_text\": \") \",\n              \"expected_text\": \") \",\n              \"python_complete\": true,\n              \"cpp_complete\": true,\n              \"passes\": true\n            },\n            {\n              \"index\": 100,\n              \"word\": \"BD\",\n              \"separate\": false,\n              \"bits\": \"0111101100100\",\n              \"python_text\": \"BD\",\n              \"cpp_text\": \"BD\",\n              \"expected_text\": \"BD\",\n              \"python_complete\": true,\n              \"cpp_complete\": true,\n              \"passes\": true\n            },\n            {\n              \"index\": 100,\n              \"word\": \"BD\",\n              \"separate\": true,\n              \"bits\": \"0111101100101\",\n              \"python_text\": \"BD \",\n              \"cpp_text\": \"BD \",\n              \"expected_text\": \"BD \",\n              \"python_complete\": true,\n              \"cpp_complete\": true,\n              \"passes\": true\n            },\n            {\n              \"index\": 1000,\n              \"word\": \"TNU\",\n              \"separate\": false,\n              \"bits\": \"01111100110101100\",\n              \"python_text\": \"TNU\",\n              \"cpp_text\": \"TNU\",\n              \"expected_text\": \"TNU\",\n              \"python_complete\": true,\n              \"cpp_complete\": true,\n              \"passes\": true\n            },\n            {\n              \"index\": 1000,\n              \"word\": \"TNU\",\n              \"separate\": true,\n              \"bits\": \"01111100110101101\",\n              \"python_text\": \"TNU \",\n              \"cpp_text\": \"TNU \",\n              \"expected_text\": \"TNU \",\n              \"python_complete\": true,\n              \"cpp_complete\": true,\n              \"passes\": true\n            },\n            {\n              \"index\": 12345,\n              \"word\": \"EB33\",\n              \"separate\": false,\n              \"bits\": \"100010011100111001000\",\n              \"python_text\": \"EB33\",\n              \"cpp_text\": \"EB33\",\n              \"expected_text\": \"EB33\",\n              \"python_complete\": true,\n              \"cpp_complete\": true,\n              \"passes\": true\n            },\n            {\n              \"index\": 12345,\n              \"word\": \"EB33\",\n              \"separate\": true,\n              \"bits\": \"100010011100111001001\",\n              \"python_text\": \"EB33 \",\n              \"cpp_text\": \"EB33 \",\n              \"expected_text\": \"EB33 \",\n              \"python_complete\": true,\n              \"cpp_complete\": true,\n              \"passes\": true\n            },\n            {\n              \"index\": 199999,\n              \"word\": \"LSYR\",\n              \"separate\": false,\n              \"bits\": \"1010100101111100101100100\",\n              \"python_text\": \"LSYR\",\n              \"cpp_text\": \"LSYR\",\n              \"expected_text\": \"LSYR\",\n              \"python_complete\": true,\n              \"cpp_complete\": true,\n              \"passes\": true\n            },\n            {\n              \"index\": 199999,\n              \"word\": \"LSYR\",\n              \"separate\": true,\n              \"bits\": \"1010100101111100101100101\",\n              \"python_text\": \"LSYR \",\n              \"cpp_text\": \"LSYR \",\n              \"expected_text\": \"LSYR \",\n              \"python_complete\": true,\n              \"cpp_complete\": true,\n              \"passes\": true\n            }\n          ]\n        },\n        \"release_gate_status\": {\n          \"compressed_text_release_allowed\": false,\n          \"productive_webftr_integration_allowed\": false,\n          \"step79_release_gate_still_required\": true,\n          \"external_fixture_still_required\": true,\n          \"multi_frame_assembly_validated\": false\n        },\n        \"webftr_adapter_hint\": {\n          \"safe_to_poll_read_only\": true,\n          \"productive_integration\": false,\n          \"step68_contract_remains_current_stable_ui_source\": true,\n          \"cpp_reference_latest\": \"/logs/js8_jsc_cpp_reference_compare_latest.json\",\n          \"do_not_merge_as_productive_chat_text_yet\": true\n        },\n        \"warnings\": [\n          \"Step81 compares the Python JSC decompressor against an independent C++ harness using the source-extracted JSC map with a hex length-safe map transport.\",\n          \"It still does not prove a real RF/JS8Call FrameDataCompressed text fixture.\",\n          \"Compressed JS8 free-text release remains blocked until Step79 sees an externally confirmed fixture.\",\n          \"RX-only safety remains enforced: no JS8Call runtime control and no TX/PTT/Tune/Send.\"\n        ],\n        \"map_transport_fix\": {\n          \"previous_step80_issue\": \"line-delimited-map-transport-corrupted-words-with-embedded-newlines-or-control-bytes\",\n          \"current_transport\": \"hex-lines-utf8-v1\",\n          \"purpose\": \"keep Python and C++ harness map indices byte-identical\"\n        },\n        \"verdict\": \"step81_cpp_reference_compare_passed_waiting_for_real_external_fixture\",\n        \"next_action\": \"Import one externally confirmed compressed FrameDataCompressed fixture, then rerun Step79/Step81 before any lab text release.\",\n        \"stable_latest_written\": \"/decoders/js8_decoder/logs/js8_jsc_cpp_reference_compare_latest.json\"\n      }\n    }\n  },\n  \"warnings\": [\n    \"Quick-window-scan only selects a likely analysis window; it is not a JS8 text decoder.\",\n    \"Step 54 JS8 Costas guard uses leading-only Costas exclusion by default to preserve 58 data symbols / 174 soft bits on JS8Lab windows; full FT8 middle/trailing exclusion remains diagnostic-only.\",\n    \"Step 54 profile-anchor guard: FEC symbols were extracted from the selected profile sync anchor instead of re-running an independent sync search.\",\n    \"Step 54 prepares LDPC/FEC input candidates and an LDPC probe harness only; it does not yet run final real JS8 LDPC decode or unpack text.\",\n    \"Step 54 does not decode JS8 text yet. It probes FT8-style Gray de-mapping, bit order and 174-bit interleaver candidates for real LDPC/FEC integration.\",\n    \"lab_mask_xor_preview is only a repeatable diagnostic mask, not a confirmed JS8 whitening implementation.\",\n    \"Step 54 locks candidate export to JS8-realistic timing and reuses the selected profile sync anchor for FEC symbol extraction where available.\",\n    \"It still does not perform real LDPC/FEC decode or message unpack.\",\n    \"Next step can tune real JS8/FT8 LDPC matrix/deinterleaver/message unpack against this anchored candidate contract.\",\n    \"This is still a diagnostic runtime export, not a final JS8 text decoder.\",\n    \"Step61 patches the runtime LDPC probes to expose post-LDPC info87 rows and source-index context for the next reorder/whitening alignment step.\",\n    \"Step63 is still a diagnostic/source-extraction step, not a final text decoder.\",\n    \"It starts no JS8Call GUI/Qt process and performs no TX/PTT/Tune/Send actions.\",\n    \"Step64 emits source-confirmed message174 CRC12-zero-distance text candidates; it is not yet a full live JS8 decoder chain from audio to final chat UI.\",\n    \"It starts no JS8Call GUI/Qt process and performs no TX/PTT/Tune/Send actions.\",\n    \"Random-looking 12-character payloads can still be valid message174 candidates until higher JS8 text/Varicode framing is connected.\",\n    \"Step66 is still RX-only diagnostics. It classifies message174 text as JS8 Varicode frame families but does not start JS8Call GUI/Qt.\",\n    \"Rows remain hidden unless callsign/grid/command/text plausibility survives source-style frame unpacking.\",\n    \"Compressed Data frames still require a later JSC::decompress port before real JS8 chat text can be displayed.\",\n    \"Step67 is still RX-only and does not start JS8Call GUI/Qt.\",\n    \"Only source-confirmed fixed control frames such as Heartbeat/Directed/Compound are released to webftr_rx_rows.\",\n    \"Free-text Data/Compressed frames remain blocked until JSC::decompress and multi-frame assembly are source-ported and tested.\"\n  ],\n  \"notes\": [\n    \"Step84 intentionally keeps the default ./start.sh path on the real WAV and adds compact status/report surfaces instead of huge JSON previews.\",\n    \"This remains RX-only and does not start or control JS8Call GUI/Qt runtime.\",\n    \"Compressed/free-text release remains governed by the Step79 fixture gate; Step84 validates the real-WAV-to-message174/control-frame chain and makes the result easy to inspect.\"\n  ],\n  \"next_action\": \"If Step84 confirms message174/control-frame regeneration from the real WAV, continue with either a wider real-WAV search for FrameDataCompressed or a real JS8Call/RF comparison fixture.\"\n}\n[webftr-js8-lab] step83 summary exit_code=0\n\n[webftr-js8-lab] OK\n[webftr-js8-lab] log file: /decoders/js8_decoder/logs/20260528T035339Z_real-wav-status-surface-regression.log\n[webftr-js8-lab] manifest: /decoders/js8_decoder/logs/20260528T035339Z_real-wav-status-surface-regression_manifest.json\n"
  },
  "output_refs": {
    "input_check": {
      "name": "20260528T035339Z_step83_input_check_output.json",
      "path": "/decoders/js8_decoder/logs/20260528T035339Z_step83_input_check_output.json",
      "url": "/logs/20260528T035339Z_step83_input_check_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 698,
        "mtime_utc": "2026-05-28T03:53:39Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-input-check",
        "tool_version": "step63-source-exact-interleaver-whitening-index-extract",
        "rx_only": true,
        "next_action": "Run profile-scan, then auto-ldpc-probe on this WAV.",
        "input_wav": "/decoders/js8_test.wav",
        "warnings": [],
        "decodes": []
      }
    },
    "real_wav_message174_regeneration": {
      "name": "20260528T035339Z_real_wav_message174_regeneration_output.json",
      "path": "/decoders/js8_decoder/logs/20260528T035339Z_real_wav_message174_regeneration_output.json",
      "url": "/logs/20260528T035339Z_real_wav_message174_regeneration_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 93483,
        "mtime_utc": "2026-05-28T03:56:08Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-real-wav-message174-regeneration",
        "tool_version": "step84-real-wav-status-surface-report-slim",
        "schema": "webftr-js8-real-wav-message174-regeneration-v1",
        "created_utc": "2026-05-28T03:56:08Z",
        "rx_only": true,
        "purpose": "Run a visible real-WAV regeneration chain from /decoders/js8_test.wav through candidate export, post-LDPC Info87, source-exact message174 CRC12 probe and guarded control-frame release.",
        "verdict": "step83_wav_to_message174_regeneration_confirmed",
        "next_action": "If Step84 confirms message174/control-frame regeneration from the real WAV, continue with either a wider real-WAV search for FrameDataCompressed or a real JS8Call/RF comparison fixture.",
        "input_wav": "/decoders/js8_test.wav",
        "analysis_wav": "/decoders/js8_decoder/runtime/step83_quick_windows/js8_quick_selected_window.wav",
        "wav_was_read": true,
        "wav_duration_seconds": 192.016583,
        "quick_window_selected": true,
        "selected_window": {
          "start_seconds": 18.0,
          "end_seconds": 78.0,
          "duration_seconds": 60.0,
          "avg_activity_score": -6.286,
          "active_chunks": 10,
          "chunk_count": 10,
          "selection_score": 18.714,
          "window_wav": "/decoders/js8_decoder/runtime/step83_quick_windows/js8_quick_selected_window.wav",
          "tone_candidates": [
            {
              "freq_hz": 1000.0,
              "relative_db": 0.0,
              "power": 15.76347305
            },
            {
              "freq_hz": 1025.0,
              "relative_db": -0.8,
              "power": 13.10923242
            },
            {
              "freq_hz": 2025.0,
              "relative_db": -14.3,
              "power": 0.58516574
            },
            {
              "freq_hz": 975.0,
              "relative_db": -16.4,
              "power": 0.3608126
            },
            {
              "freq_hz": 1050.0,
              "relative_db": -29.42,
              "power": 0.01801849
            },
            {
              "freq_hz": 1525.0,
              "relative_db": -32.35,
              "power": 0.00916685
            },
            {
              "freq_hz": 1825.0,
              "relative_db": -32.46,
              "power": 0.00893784
            },
            {
              "freq_hz": 1925.0,
              "relative_db": -34.06,
              "power": 0.00619164
            },
            {
              "_truncated_list_count": 4
            }
          ]
        },
        "selected_window_wav": "/decoders/js8_decoder/runtime/step83_quick_windows/js8_quick_selected_window.wav",
        "candidate_export_ok": true,
        "runtime_info87_rows_count": 48,
        "post_ldpc_zero_distance_candidate_count": 0,
        "source_exact_zero_distance_candidate_count": 2,
        "message174_decode_count": 2,
        "frame_probe_count": 2,
        "frame_type_counts": {
          "FrameHeartbeat": 1,
          "FrameDirected": 1
        },
        "control_frame_release_count": 2,
        "webftr_display_count": 2,
        "source_chain_ran_from_real_wav_this_step": true,
        "exit_codes": {
          "input_check": 0,
          "quick_window_scan": 0,
          "candidate_export": 0,
          "post_ldpc_info87_runtime_export": 0,
          "source_exact_map_probe": 0,
          "source_confirmed_message174_decode": 0,
          "source_varicode_frame_unpack_probe": 0,
          "source_confirmed_control_frame_rx_release": 0
        },
        "outputs": {
          "input_check_json": "/decoders/js8_decoder/logs/20260528T035339Z_step83_input_check_output.json",
          "quick_window_scan_json": "/decoders/js8_decoder/logs/20260528T035339Z_step83_quick_window_scan_output.json",
          "candidate_export_json": "/decoders/js8_decoder/logs/20260528T035339Z_step83_candidate_export_output.json",
          "post_ldpc_info87_runtime_export_json": "/decoders/js8_decoder/logs/20260528T035339Z_step83_post_ldpc_info87_runtime_export_output.json",
          "source_exact_map_probe_json": "/decoders/js8_decoder/logs/20260528T035339Z_step83_source_exact_map_probe_output.json",
          "source_confirmed_message174_decode_json": "/decoders/js8_decoder/logs/20260528T035339Z_step83_source_confirmed_message174_decode_output.json",
          "source_varicode_frame_unpack_probe_json": "/decoders/js8_decoder/logs/20260528T035339Z_step83_source_varicode_frame_unpack_probe_output.json",
          "source_confirmed_control_frame_rx_release_json": "/decoders/js8_decoder/logs/20260528T035339Z_step83_source_confirmed_control_frame_rx_release_output.json"
        },
        "output_stats": {
          "input_check_json": {
            "path": "/decoders/js8_decoder/logs/20260528T035339Z_step83_input_check_output.json",
            "exists": true,
            "is_file": true,
            "size": 698,
            "mtime_utc": "2026-05-28T03:53:39Z"
          },
          "quick_window_scan_json": {
            "path": "/decoders/js8_decoder/logs/20260528T035339Z_step83_quick_window_scan_output.json",
            "exists": true,
            "is_file": true,
            "size": 8839,
            "mtime_utc": "2026-05-28T03:53:52Z"
          },
          "candidate_export_json": {
            "path": "/decoders/js8_decoder/logs/20260528T035339Z_step83_candidate_export_output.json",
            "exists": true,
            "is_file": true,
            "size": 99951,
            "mtime_utc": "2026-05-28T03:54:51Z"
          },
          "post_ldpc_info87_runtime_export_json": {
            "path": "/decoders/js8_decoder/logs/20260528T035339Z_step83_post_ldpc_info87_runtime_export_output.json",
            "exists": true,
            "is_file": true,
            "size": 106824,
            "mtime_utc": "2026-05-28T03:56:04Z"
          },
          "source_exact_map_probe_json": {
            "path": "/decoders/js8_decoder/logs/20260528T035339Z_step83_source_exact_map_probe_output.json",
            "exists": true,
            "is_file": true,
            "size": 143892,
            "mtime_utc": "2026-05-28T03:56:06Z"
          },
          "source_confirmed_message174_decode_json": {
            "path": "/decoders/js8_decoder/logs/20260528T035339Z_step83_source_confirmed_message174_decode_output.json",
            "exists": true,
            "is_file": true,
            "size": 6617,
            "mtime_utc": "2026-05-28T03:56:07Z"
          },
          "source_varicode_frame_unpack_probe_json": {
            "path": "/decoders/js8_decoder/logs/20260528T035339Z_step83_source_varicode_frame_unpack_probe_output.json",
            "exists": true,
            "is_file": true,
            "size": 60531,
            "mtime_utc": "2026-05-28T03:56:07Z"
          },
          "source_confirmed_control_frame_rx_release_json": {
            "path": "/decoders/js8_decoder/logs/20260528T035339Z_step83_source_confirmed_control_frame_rx_release_output.json",
            "exists": true,
            "is_file": true,
            "size": 9808,
            "mtime_utc": "2026-05-28T03:56:08Z"
          }
        },
        "warnings": [
          "Quick-window-scan only selects a likely analysis window; it is not a JS8 text decoder.",
          "Step 54 JS8 Costas guard uses leading-only Costas exclusion by default to preserve 58 data symbols / 174 soft bits on JS8Lab windows; full FT8 middle/trailing exclusion remains diagnostic-only.",
          "Step 54 profile-anchor guard: FEC symbols were extracted from the selected profile sync anchor instead of re-running an independent sync search.",
          "Step 54 prepares LDPC/FEC input candidates and an LDPC probe harness only; it does not yet run final real JS8 LDPC decode or unpack text.",
          "Step 54 does not decode JS8 text yet. It probes FT8-style Gray de-mapping, bit order and 174-bit interleaver candidates for real LDPC/FEC integration.",
          "lab_mask_xor_preview is only a repeatable diagnostic mask, not a confirmed JS8 whitening implementation.",
          "Step 54 locks candidate export to JS8-realistic timing and reuses the selected profile sync anchor for FEC symbol extraction where available.",
          "It still does not perform real LDPC/FEC decode or message unpack.",
          {
            "_truncated_list_count": 14
          }
        ],
        "notes": [
          "Step84 intentionally keeps the default ./start.sh path on the real WAV and adds compact status/report surfaces instead of huge JSON previews.",
          "This remains RX-only and does not start or control JS8Call GUI/Qt runtime.",
          "Compressed/free-text release remains governed by the Step79 fixture gate; Step84 validates the real-WAV-to-message174/control-frame chain and makes the result easy to inspect."
        ],
        "message174_decodes_preview": [
          {
            "rx_only": true
          },
          {
            "rx_only": true
          }
        ],
        "webftr_rx_rows_preview": [
          {
            "id": "js8-rx67-de15d3110b0d",
            "source_candidate_id": "js8-frame66-bf1ce62fdb4a",
            "source_decode_id": "js8-msg174-44978e4b",
            "mode": "JS8",
            "raw_message174": "001XqOA2iDZ0",
            "valid_message174_crc12": true,
            "crc12_distance": 0,
            "received_crc12": 2920,
            "computed_crc12": 2920,
            "frame_type": "FrameHeartbeat",
            "confidence": "high",
            "confidence_score": 6,
            "confidence_reasons": [
              "valid_heartbeat_callsign",
              "valid_heartbeat_grid"
            ],
            "show_in_rx_list": true,
            "candidate_class": "webftr_control_frame_display_ready",
            "release_guard": "step67_source_confirmed_fixed_control_frame_only",
            "sort_index": 0,
            "source": {
              "source_file": "/decoders/js8_decoder/logs/20260528T035339Z_step83_source_exact_map_probe_output.json",
              "json_path": "$.top_llr_row_exports[0].hard_bits",
              "source_kind": "generic_bit_list",
              "row_index": 165,
              "map_name": "raw",
              "map_source": null
            },
            "status": "HB",
            "from": "004REY/0V4",
            "_truncated_object_key_count": 6
          },
          {
            "id": "js8-rx67-bd37f68199eb",
            "source_candidate_id": "js8-frame66-66ab29ded46c",
            "source_decode_id": "js8-msg174-8368257f",
            "mode": "JS8",
            "raw_message174": "Q0VsKWqfJ96x",
            "valid_message174_crc12": true,
            "crc12_distance": 0,
            "received_crc12": 980,
            "computed_crc12": 980,
            "frame_type": "FrameDirected",
            "confidence": "high",
            "confidence_score": 10,
            "confidence_reasons": [
              "valid_directed_from",
              "valid_directed_to",
              "directed_command"
            ],
            "show_in_rx_list": true,
            "candidate_class": "webftr_control_frame_display_ready",
            "release_guard": "step67_source_confirmed_fixed_control_frame_only",
            "sort_index": 1,
            "source": {
              "source_file": "/decoders/js8_decoder/logs/20260528T035339Z_step83_source_exact_map_probe_output.json",
              "json_path": "$.top_llr_row_exports[6].hard_bits",
              "source_kind": "generic_bit_list",
              "row_index": 171,
              "map_name": "raw",
              "map_source": null
            },
            "status": "INFO",
            "from": "9I2TZR/P",
            "_truncated_object_key_count": 8
          }
        ]
      }
    },
    "step83_input_check": {
      "name": "20260528T035339Z_step83_input_check_output.json",
      "path": "/decoders/js8_decoder/logs/20260528T035339Z_step83_input_check_output.json",
      "url": "/logs/20260528T035339Z_step83_input_check_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 698,
        "mtime_utc": "2026-05-28T03:53:39Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-input-check",
        "tool_version": "step63-source-exact-interleaver-whitening-index-extract",
        "rx_only": true,
        "next_action": "Run profile-scan, then auto-ldpc-probe on this WAV.",
        "input_wav": "/decoders/js8_test.wav",
        "warnings": [],
        "decodes": []
      }
    },
    "step83_quick_window_scan": {
      "name": "20260528T035339Z_step83_quick_window_scan_output.json",
      "path": "/decoders/js8_decoder/logs/20260528T035339Z_step83_quick_window_scan_output.json",
      "url": "/logs/20260528T035339Z_step83_quick_window_scan_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 8839,
        "mtime_utc": "2026-05-28T03:53:52Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-quick-window-scan",
        "tool_version": "step63-source-exact-interleaver-whitening-index-extract",
        "rx_only": true,
        "next_action": "Run sync/soft-symbol/FEC probes on selected_window_wav. Message unpack is not implemented in Step 54.",
        "input_wav": "/decoders/js8_test.wav",
        "selected_window": {
          "start_seconds": 18.0,
          "end_seconds": 78.0,
          "duration_seconds": 60.0,
          "avg_activity_score": -6.286,
          "active_chunks": 10,
          "chunk_count": 10,
          "selection_score": 18.714,
          "window_wav": "/decoders/js8_decoder/runtime/step83_quick_windows/js8_quick_selected_window.wav",
          "tone_candidates": [
            {
              "freq_hz": 1000.0,
              "relative_db": 0.0,
              "power": 15.76347305
            },
            {
              "freq_hz": 1025.0,
              "relative_db": -0.8,
              "power": 13.10923242
            },
            {
              "freq_hz": 2025.0,
              "relative_db": -14.3,
              "power": 0.58516574
            },
            {
              "freq_hz": 975.0,
              "relative_db": -16.4,
              "power": 0.3608126
            },
            {
              "freq_hz": 1050.0,
              "relative_db": -29.42,
              "power": 0.01801849
            },
            {
              "freq_hz": 1525.0,
              "relative_db": -32.35,
              "power": 0.00916685
            },
            {
              "freq_hz": 1825.0,
              "relative_db": -32.46,
              "power": 0.00893784
            },
            {
              "freq_hz": 1925.0,
              "relative_db": -34.06,
              "power": 0.00619164
            },
            {
              "_truncated_list_count": 4
            }
          ]
        },
        "selected_window_wav": "/decoders/js8_decoder/runtime/step83_quick_windows/js8_quick_selected_window.wav",
        "warnings": [
          "Quick-window-scan only selects a likely analysis window; it is not a JS8 text decoder."
        ],
        "decodes": []
      }
    },
    "step83_candidate_export": {
      "name": "20260528T035339Z_step83_candidate_export_output.json",
      "path": "/decoders/js8_decoder/logs/20260528T035339Z_step83_candidate_export_output.json",
      "url": "/logs/20260528T035339Z_step83_candidate_export_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 99951,
        "mtime_utc": "2026-05-28T03:54:51Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-fec-candidate-export",
        "tool_version": "step63-source-exact-interleaver-whitening-index-extract",
        "rx_only": true,
        "next_action": "Run collect-logs and upload the JS8Lab bundle. If selected_variant.complete_174bit_candidate is true, proceed to LDPC/deinterleaver/message-unpack tuning.",
        "input_wav": "/decoders/js8_decoder/runtime/step83_quick_windows/js8_quick_selected_window.wav",
        "outputs": {
          "candidate_json": "/decoders/js8_decoder/runtime/step83_fec_candidates/js8_quick_selected_window_fec_candidate_step17.json",
          "selected_bits_file": "/decoders/js8_decoder/runtime/step83_fec_candidates/js8_quick_selected_window_fec_candidate_step17.bits"
        },
        "warnings": [
          "Step 54 JS8 Costas guard uses leading-only Costas exclusion by default to preserve 58 data symbols / 174 soft bits on JS8Lab windows; full FT8 middle/trailing exclusion remains diagnostic-only.",
          "Step 54 profile-anchor guard: FEC symbols were extracted from the selected profile sync anchor instead of re-running an independent sync search.",
          "Step 54 prepares LDPC/FEC input candidates and an LDPC probe harness only; it does not yet run final real JS8 LDPC decode or unpack text.",
          "Step 54 does not decode JS8 text yet. It probes FT8-style Gray de-mapping, bit order and 174-bit interleaver candidates for real LDPC/FEC integration.",
          "lab_mask_xor_preview is only a repeatable diagnostic mask, not a confirmed JS8 whitening implementation.",
          "Step 54 locks candidate export to JS8-realistic timing and reuses the selected profile sync anchor for FEC symbol extraction where available.",
          "It still does not perform real LDPC/FEC decode or message unpack.",
          "Next step can tune real JS8/FT8 LDPC matrix/deinterleaver/message unpack against this anchored candidate contract."
        ],
        "decodes": []
      }
    },
    "step83_post_ldpc_info87_runtime_export": {
      "name": "20260528T035339Z_step83_post_ldpc_info87_runtime_export_output.json",
      "path": "/decoders/js8_decoder/logs/20260528T035339Z_step83_post_ldpc_info87_runtime_export_output.json",
      "url": "/logs/20260528T035339Z_step83_post_ldpc_info87_runtime_export_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 106824,
        "mtime_utc": "2026-05-28T03:56:04Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-post-ldpc-info87-runtime-export-probe",
        "tool_version": "step63-source-exact-interleaver-whitening-index-extract",
        "next_action": "If best_distance is 0, implement source-confirmed message174 text unpack. If best_distance remains >0, build Step62 to test source-derived deinterleaver/whitening index maps against these exact runtime rows.",
        "input_wav": "/decoders/js8_decoder/runtime/step83_quick_windows/js8_quick_selected_window.wav",
        "runtime_info87_rows_count": 48,
        "outputs": {
          "post_ldpc_info87_runtime_export_json": "/decoders/js8_decoder/runtime/step83_post_ldpc_info87/step61_post_ldpc_info87_runtime_export.json"
        },
        "warnings": [
          "This is still a diagnostic runtime export, not a final JS8 text decoder.",
          "Step61 patches the runtime LDPC probes to expose post-LDPC info87 rows and source-index context for the next reorder/whitening alignment step."
        ]
      }
    },
    "step83_source_exact_map_probe": {
      "name": "20260528T035339Z_step83_source_exact_map_probe_output.json",
      "path": "/decoders/js8_decoder/logs/20260528T035339Z_step83_source_exact_map_probe_output.json",
      "url": "/logs/20260528T035339Z_step83_source_exact_map_probe_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 143892,
        "mtime_utc": "2026-05-28T03:56:06Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-source-exact-map-probe",
        "tool_version": "step64-source-confirmed-message174-decodes-output",
        "next_action": "Zero-distance message174/CRC12 candidate found: build Step64 source-confirmed message174 text unpack and WebFTR-style decodes[] output.",
        "warnings": [
          "Step63 is still a diagnostic/source-extraction step, not a final text decoder.",
          "It starts no JS8Call GUI/Qt process and performs no TX/PTT/Tune/Send actions."
        ],
        "decodes": []
      }
    },
    "step83_source_confirmed_message174_decode": {
      "name": "20260528T035339Z_step83_source_confirmed_message174_decode_output.json",
      "path": "/decoders/js8_decoder/logs/20260528T035339Z_step83_source_confirmed_message174_decode_output.json",
      "url": "/logs/20260528T035339Z_step83_source_confirmed_message174_decode_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 6617,
        "mtime_utc": "2026-05-28T03:56:07Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-source-confirmed-message174-decode",
        "tool_version": "step64-source-confirmed-message174-decodes-output",
        "next_action": "Use Step64 decodes[] as the contract for the next step: connect source-confirmed message174 output into a richer JS8 text/Varicode/framing interpretation and then feed WebFTR RX display fields.",
        "warnings": [
          "Step64 emits source-confirmed message174 CRC12-zero-distance text candidates; it is not yet a full live JS8 decoder chain from audio to final chat UI.",
          "It starts no JS8Call GUI/Qt process and performs no TX/PTT/Tune/Send actions.",
          "Random-looking 12-character payloads can still be valid message174 candidates until higher JS8 text/Varicode framing is connected."
        ],
        "decode_count": 2,
        "decodes": [
          {
            "rx_only": true
          },
          {
            "rx_only": true
          }
        ]
      }
    },
    "step83_source_varicode_frame_unpack_probe": {
      "name": "20260528T035339Z_step83_source_varicode_frame_unpack_probe_output.json",
      "path": "/decoders/js8_decoder/logs/20260528T035339Z_step83_source_varicode_frame_unpack_probe_output.json",
      "url": "/logs/20260528T035339Z_step83_source_varicode_frame_unpack_probe_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 60531,
        "mtime_utc": "2026-05-28T03:56:07Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-source-varicode-frame-unpack-probe",
        "tool_version": "step66-source-varicode-frame-unpack-probe",
        "verdict": "source_varicode_frames_classified_but_not_displayable",
        "next_action": "If frame types look plausible but hidden, port JSC::decompress and multi-frame assembly next; if a display row appears, wire webftr_rx_rows into the JS8 RX UI contract.",
        "frame_probe_count": 2,
        "frame_type_counts": {
          "FrameHeartbeat": 1,
          "FrameDirected": 1
        },
        "webftr_display_count": 0,
        "warnings": [
          "Step66 is still RX-only diagnostics. It classifies message174 text as JS8 Varicode frame families but does not start JS8Call GUI/Qt.",
          "Rows remain hidden unless callsign/grid/command/text plausibility survives source-style frame unpacking.",
          "Compressed Data frames still require a later JSC::decompress port before real JS8 chat text can be displayed."
        ]
      }
    },
    "step83_source_confirmed_control_frame_rx_release": {
      "name": "20260528T035339Z_step83_source_confirmed_control_frame_rx_release_output.json",
      "path": "/decoders/js8_decoder/logs/20260528T035339Z_step83_source_confirmed_control_frame_rx_release_output.json",
      "url": "/logs/20260528T035339Z_step83_source_confirmed_control_frame_rx_release_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 9808,
        "mtime_utc": "2026-05-28T03:56:08Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-source-confirmed-control-frame-rx-release",
        "tool_version": "step67-source-confirmed-control-frame-rx-release",
        "verdict": "source_confirmed_control_frames_ready_for_webftr_rx_rows",
        "next_action": "Wire these guarded webftr_rx_rows into the JS8 RX display contract, then continue with JSC::decompress/multi-frame assembly for real JS8 chat text.",
        "frame_type_counts": {
          "FrameHeartbeat": 1,
          "FrameDirected": 1
        },
        "webftr_display_count": 2,
        "warnings": [
          "Step67 is still RX-only and does not start JS8Call GUI/Qt.",
          "Only source-confirmed fixed control frames such as Heartbeat/Directed/Compound are released to webftr_rx_rows.",
          "Free-text Data/Compressed frames remain blocked until JSC::decompress and multi-frame assembly are source-ported and tested."
        ]
      }
    },
    "real_wav_full_chain_regression": {
      "name": "20260528T031839Z_real_wav_full_chain_regression_output.json",
      "path": "/decoders/js8_decoder/logs/20260528T031839Z_real_wav_full_chain_regression_output.json",
      "url": "/logs/20260528T031839Z_real_wav_full_chain_regression_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 46354,
        "mtime_utc": "2026-05-28T03:19:08Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-real-wav-full-chain-regression",
        "tool_version": "step82-real-wav-full-chain-regression",
        "schema": "webftr-js8-real-wav-full-chain-regression-v1",
        "created_utc": "2026-05-28T03:19:08Z",
        "rx_only": true,
        "purpose": "Make the default Step82 run visibly re-read the real JS8 WAV and perform the fast audio path before later source/JSC logic is considered.",
        "verdict": "step82_real_wav_regression_complete",
        "next_action": "If Step82 confirms the WAV path and sync candidates, continue with a bounded full audio-to-message174 regeneration step before any new Freitext release work.",
        "input_wav": "/decoders/js8_test.wav",
        "analysis_wav": "/decoders/js8_decoder/runtime/step82_quick_windows/js8_quick_selected_window.wav",
        "wav_was_read": true,
        "wav_duration_seconds": 192.016583,
        "quick_window_selected": true,
        "selected_window": {
          "start_seconds": 18.0,
          "end_seconds": 78.0,
          "duration_seconds": 60.0,
          "avg_activity_score": -6.286,
          "active_chunks": 10,
          "chunk_count": 10,
          "selection_score": 18.714,
          "window_wav": "/decoders/js8_decoder/runtime/step82_quick_windows/js8_quick_selected_window.wav",
          "tone_candidates": [
            {
              "freq_hz": 1000.0,
              "relative_db": 0.0,
              "power": 15.76347305
            },
            {
              "freq_hz": 1025.0,
              "relative_db": -0.8,
              "power": 13.10923242
            },
            {
              "freq_hz": 2025.0,
              "relative_db": -14.3,
              "power": 0.58516574
            },
            {
              "freq_hz": 975.0,
              "relative_db": -16.4,
              "power": 0.3608126
            },
            {
              "freq_hz": 1050.0,
              "relative_db": -29.42,
              "power": 0.01801849
            },
            {
              "freq_hz": 1525.0,
              "relative_db": -32.35,
              "power": 0.00916685
            },
            {
              "freq_hz": 1825.0,
              "relative_db": -32.46,
              "power": 0.00893784
            },
            {
              "freq_hz": 1925.0,
              "relative_db": -34.06,
              "power": 0.00619164
            },
            {
              "_truncated_list_count": 4
            }
          ]
        },
        "selected_window_wav": "/decoders/js8_decoder/runtime/step82_quick_windows/js8_quick_selected_window.wav",
        "webftr_display_count": 0,
        "exit_codes": {
          "input_check": 0,
          "quick_window_scan": 0,
          "sync_probe": 0
        },
        "outputs": {
          "input_check_json": "/decoders/js8_decoder/logs/20260528T031839Z_step82_input_check_output.json",
          "quick_window_scan_json": "/decoders/js8_decoder/logs/20260528T031839Z_step82_quick_window_scan_output.json",
          "sync_probe_json": "/decoders/js8_decoder/logs/20260528T031839Z_step82_sync_probe_output.json"
        },
        "output_stats": {
          "selected_window_wav": {
            "path": "/decoders/js8_decoder/runtime/step82_quick_windows/js8_quick_selected_window.wav",
            "exists": true,
            "is_file": true,
            "size": 1440044,
            "mtime_utc": "2026-05-28T03:18:40Z"
          }
        },
        "warnings": [
          "Quick-window-scan only selects a likely analysis window; it is not a JS8 text decoder.",
          "No JS8 text decode is expected in Step 54. Final real LDPC/FEC and Varicode/message unpack are not implemented yet.",
          "Costas7 scoring is a lab candidate extractor; real decoder validation requires actual JS8 WAV samples."
        ],
        "notes": [
          "Step82 is a real-WAV regression gate, not a chat text release.",
          "A fast run is expected because only input-check, quick-window-scan and bounded sync-probe are mandatory by default.",
          "For deeper audio-to-LDPC regeneration use server-deep-run or real-run manually; Step82 keeps the normal ./start.sh cycle lightweight."
        ],
        "decodes": [],
        "sync_candidate_count": 12
      }
    },
    "step82_input_check": {
      "name": "20260528T031839Z_step82_input_check_output.json",
      "path": "/decoders/js8_decoder/logs/20260528T031839Z_step82_input_check_output.json",
      "url": "/logs/20260528T031839Z_step82_input_check_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 698,
        "mtime_utc": "2026-05-28T03:18:39Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-input-check",
        "tool_version": "step63-source-exact-interleaver-whitening-index-extract",
        "rx_only": true,
        "next_action": "Run profile-scan, then auto-ldpc-probe on this WAV.",
        "input_wav": "/decoders/js8_test.wav",
        "warnings": [],
        "decodes": []
      }
    },
    "step82_quick_window_scan": {
      "name": "20260528T031839Z_step82_quick_window_scan_output.json",
      "path": "/decoders/js8_decoder/logs/20260528T031839Z_step82_quick_window_scan_output.json",
      "url": "/logs/20260528T031839Z_step82_quick_window_scan_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 8839,
        "mtime_utc": "2026-05-28T03:18:52Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-quick-window-scan",
        "tool_version": "step63-source-exact-interleaver-whitening-index-extract",
        "rx_only": true,
        "next_action": "Run sync/soft-symbol/FEC probes on selected_window_wav. Message unpack is not implemented in Step 54.",
        "input_wav": "/decoders/js8_test.wav",
        "selected_window": {
          "start_seconds": 18.0,
          "end_seconds": 78.0,
          "duration_seconds": 60.0,
          "avg_activity_score": -6.286,
          "active_chunks": 10,
          "chunk_count": 10,
          "selection_score": 18.714,
          "window_wav": "/decoders/js8_decoder/runtime/step82_quick_windows/js8_quick_selected_window.wav",
          "tone_candidates": [
            {
              "freq_hz": 1000.0,
              "relative_db": 0.0,
              "power": 15.76347305
            },
            {
              "freq_hz": 1025.0,
              "relative_db": -0.8,
              "power": 13.10923242
            },
            {
              "freq_hz": 2025.0,
              "relative_db": -14.3,
              "power": 0.58516574
            },
            {
              "freq_hz": 975.0,
              "relative_db": -16.4,
              "power": 0.3608126
            },
            {
              "freq_hz": 1050.0,
              "relative_db": -29.42,
              "power": 0.01801849
            },
            {
              "freq_hz": 1525.0,
              "relative_db": -32.35,
              "power": 0.00916685
            },
            {
              "freq_hz": 1825.0,
              "relative_db": -32.46,
              "power": 0.00893784
            },
            {
              "freq_hz": 1925.0,
              "relative_db": -34.06,
              "power": 0.00619164
            },
            {
              "_truncated_list_count": 4
            }
          ]
        },
        "selected_window_wav": "/decoders/js8_decoder/runtime/step82_quick_windows/js8_quick_selected_window.wav",
        "warnings": [
          "Quick-window-scan only selects a likely analysis window; it is not a JS8 text decoder."
        ],
        "decodes": []
      }
    },
    "step82_sync_probe": {
      "name": "20260528T031839Z_step82_sync_probe_output.json",
      "path": "/decoders/js8_decoder/logs/20260528T031839Z_step82_sync_probe_output.json",
      "url": "/logs/20260528T031839Z_step82_sync_probe_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 60947,
        "mtime_utc": "2026-05-28T03:19:07Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-sync-probe",
        "tool_version": "step63-source-exact-interleaver-whitening-index-extract",
        "rx_only": true,
        "next_action": "Run sync-probe on real JS8 WAV captures. If stable sync_candidates appear, Step 54 can continue soft-symbol metric extraction for the LDPC/FEC path.",
        "input_wav": "/decoders/js8_decoder/runtime/step82_quick_windows/js8_quick_selected_window.wav",
        "warnings": [
          "No JS8 text decode is expected in Step 54. Final real LDPC/FEC and Varicode/message unpack are not implemented yet.",
          "Costas7 scoring is a lab candidate extractor; real decoder validation requires actual JS8 WAV samples."
        ],
        "decodes": []
      }
    },
    "quick_window_scan": {
      "name": "20260528T035339Z_step83_quick_window_scan_output.json",
      "path": "/decoders/js8_decoder/logs/20260528T035339Z_step83_quick_window_scan_output.json",
      "url": "/logs/20260528T035339Z_step83_quick_window_scan_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 8839,
        "mtime_utc": "2026-05-28T03:53:52Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-quick-window-scan",
        "tool_version": "step63-source-exact-interleaver-whitening-index-extract",
        "rx_only": true,
        "next_action": "Run sync/soft-symbol/FEC probes on selected_window_wav. Message unpack is not implemented in Step 54.",
        "input_wav": "/decoders/js8_test.wav",
        "selected_window": {
          "start_seconds": 18.0,
          "end_seconds": 78.0,
          "duration_seconds": 60.0,
          "avg_activity_score": -6.286,
          "active_chunks": 10,
          "chunk_count": 10,
          "selection_score": 18.714,
          "window_wav": "/decoders/js8_decoder/runtime/step83_quick_windows/js8_quick_selected_window.wav",
          "tone_candidates": [
            {
              "freq_hz": 1000.0,
              "relative_db": 0.0,
              "power": 15.76347305
            },
            {
              "freq_hz": 1025.0,
              "relative_db": -0.8,
              "power": 13.10923242
            },
            {
              "freq_hz": 2025.0,
              "relative_db": -14.3,
              "power": 0.58516574
            },
            {
              "freq_hz": 975.0,
              "relative_db": -16.4,
              "power": 0.3608126
            },
            {
              "freq_hz": 1050.0,
              "relative_db": -29.42,
              "power": 0.01801849
            },
            {
              "freq_hz": 1525.0,
              "relative_db": -32.35,
              "power": 0.00916685
            },
            {
              "freq_hz": 1825.0,
              "relative_db": -32.46,
              "power": 0.00893784
            },
            {
              "freq_hz": 1925.0,
              "relative_db": -34.06,
              "power": 0.00619164
            },
            {
              "_truncated_list_count": 4
            }
          ]
        },
        "selected_window_wav": "/decoders/js8_decoder/runtime/step83_quick_windows/js8_quick_selected_window.wav",
        "warnings": [
          "Quick-window-scan only selects a likely analysis window; it is not a JS8 text decoder."
        ],
        "decodes": []
      }
    },
    "sync_probe": {
      "name": "20260528T031839Z_step82_sync_probe_output.json",
      "path": "/decoders/js8_decoder/logs/20260528T031839Z_step82_sync_probe_output.json",
      "url": "/logs/20260528T031839Z_step82_sync_probe_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 60947,
        "mtime_utc": "2026-05-28T03:19:07Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-sync-probe",
        "tool_version": "step63-source-exact-interleaver-whitening-index-extract",
        "rx_only": true,
        "next_action": "Run sync-probe on real JS8 WAV captures. If stable sync_candidates appear, Step 54 can continue soft-symbol metric extraction for the LDPC/FEC path.",
        "input_wav": "/decoders/js8_decoder/runtime/step82_quick_windows/js8_quick_selected_window.wav",
        "warnings": [
          "No JS8 text decode is expected in Step 54. Final real LDPC/FEC and Varicode/message unpack are not implemented yet.",
          "Costas7 scoring is a lab candidate extractor; real decoder validation requires actual JS8 WAV samples."
        ],
        "decodes": []
      }
    },
    "real_run_quick_prefilter": {
      "name": "20260527T110128Z_real_run_quick_prefilter_output.json",
      "path": "/decoders/js8_decoder/logs/20260527T110128Z_real_run_quick_prefilter_output.json",
      "url": "/logs/20260527T110128Z_real_run_quick_prefilter_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 8815,
        "mtime_utc": "2026-05-27T11:01:42Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-quick-window-scan",
        "tool_version": "step51-source-aligned-tone-offset-cli-fix",
        "rx_only": true,
        "next_action": "Run sync/soft-symbol/FEC probes on selected_window_wav. Message unpack is not implemented in Step 51.",
        "input_wav": "/decoders/js8_test.wav",
        "selected_window": {
          "start_seconds": 24.0,
          "end_seconds": 84.0,
          "duration_seconds": 60.0,
          "avg_activity_score": -6.2272,
          "active_chunks": 5,
          "chunk_count": 5,
          "selection_score": 11.2728,
          "window_wav": "/decoders/js8_decoder/runtime/quick_prefilter_windows/js8_quick_selected_window.wav",
          "tone_candidates": [
            {
              "freq_hz": 1025.0,
              "relative_db": 0.0,
              "power": 7.98385996
            },
            {
              "freq_hz": 1000.0,
              "relative_db": -0.38,
              "power": 7.31762699
            },
            {
              "freq_hz": 2025.0,
              "relative_db": -9.29,
              "power": 0.93974646
            },
            {
              "freq_hz": 975.0,
              "relative_db": -13.3,
              "power": 0.37314359
            },
            {
              "freq_hz": 1050.0,
              "relative_db": -25.6,
              "power": 0.02199227
            },
            {
              "freq_hz": 1775.0,
              "relative_db": -27.4,
              "power": 0.01453049
            },
            {
              "freq_hz": 1150.0,
              "relative_db": -27.44,
              "power": 0.01439727
            },
            {
              "freq_hz": 1425.0,
              "relative_db": -28.11,
              "power": 0.01233556
            },
            {
              "_truncated_list_count": 4
            }
          ]
        },
        "selected_window_wav": "/decoders/js8_decoder/runtime/quick_prefilter_windows/js8_quick_selected_window.wav",
        "warnings": [
          "Quick-window-scan only selects a likely analysis window; it is not a JS8 text decoder."
        ],
        "decodes": []
      }
    },
    "real_run_dirty_window_scan": {
      "name": "20260527T110128Z_real_run_dirty_window_scan_output.json",
      "path": "/decoders/js8_decoder/logs/20260527T110128Z_real_run_dirty_window_scan_output.json",
      "url": "/logs/20260527T110128Z_real_run_dirty_window_scan_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 1269,
        "mtime_utc": "2026-05-27T11:02:43Z"
      },
      "json_preview": {
        "ok": false,
        "rx_only": true,
        "next_action": "Step 51 timeout guard stopped this expensive probe; preserved partial timing JSON when available. The real-run now continues with quick-window fallback when available; otherwise inspect stderr/log bundle."
      }
    },
    "dirty_window_scan": {
      "name": "20260527T110128Z_real_run_dirty_window_scan_output.json",
      "path": "/decoders/js8_decoder/logs/20260527T110128Z_real_run_dirty_window_scan_output.json",
      "url": "/logs/20260527T110128Z_real_run_dirty_window_scan_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 1269,
        "mtime_utc": "2026-05-27T11:02:43Z"
      },
      "json_preview": {
        "ok": false,
        "rx_only": true,
        "next_action": "Step 51 timeout guard stopped this expensive probe; preserved partial timing JSON when available. The real-run now continues with quick-window fallback when available; otherwise inspect stderr/log bundle."
      }
    },
    "ldpc_soft_decode": {
      "name": "20260527T111112Z_ldpc_soft_decode_output.json",
      "path": "/decoders/js8_decoder/logs/20260527T111112Z_ldpc_soft_decode_output.json",
      "url": "/logs/20260527T111112Z_ldpc_soft_decode_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 112544,
        "mtime_utc": "2026-05-27T11:11:21Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-soft-ldpc-minsum-probe",
        "tool_version": "step51-source-aligned-tone-offset-cli-fix",
        "rx_only": true,
        "next_action": "Inspect best_syndrome_closure_repair_probe.top_candidates. Next step should add bounded JS8 91-bit message unpack/CRC validation for the ranked candidate messages while keeping timing best row unchanged.",
        "input_wav": null,
        "outputs": {
          "ldpc_soft_decode_json": "/decoders/js8_decoder/runtime/ldpc_soft_decode/step43_ldpc_soft_decode.json"
        },
        "warnings": [
          "Step 51 keeps the direct timing-sweep primary row first and adds a bounded syndrome-closure repair candidate generator ranked by LLR reliability cost.",
          "Step 51 syndrome-closure repair is diagnostic only: parity repair can force syndrome zero, so candidates still need JS8 message unpack/CRC validation before they count as real decodes.",
          "This still does not unpack JS8 text or validate CRC/message payloads.",
          "If soft success is true or a syndrome-closure candidate passes future JS8 message/CRC validation, the next step can unpack the 91-bit message. Otherwise continue timing/interleaver/LLR tuning."
        ],
        "decodes": []
      }
    },
    "ldpc_matrix_probe": {
      "name": "20260527T111109Z_ldpc_matrix_probe_output.json",
      "path": "/decoders/js8_decoder/logs/20260527T111109Z_ldpc_matrix_probe_output.json",
      "url": "/logs/20260527T111109Z_ldpc_matrix_probe_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 35253,
        "mtime_utc": "2026-05-27T11:11:11Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-real-ldpc-matrix-syndrome-probe",
        "tool_version": "step51-source-aligned-tone-offset-cli-fix",
        "rx_only": true,
        "next_action": "Upload Step35 logs. Inspect best_matrix_probe.mapping_meta and final_syndrome_weight; then either unpack message91 on syndrome 0 or continue bounded LDPC/timing tuning.",
        "input_wav": null,
        "outputs": {
          "ldpc_matrix_probe_json": "/decoders/js8_decoder/runtime/ldpc_matrix_probe/step43_ldpc_matrix_probe.json"
        },
        "warnings": [
          "Step 51 preserves the exact timing-sweep primary row in matrix ranking, then repairs only a bounded subset to avoid Raspberry Pi timeouts.",
          "This is still a diagnostic LDPC/FEC probe and does not unpack JS8 text yet.",
          "If best_matrix_probe reaches syndrome_weight 0, the next step can feed message91 into CRC/message unpack. Otherwise continue timing, symbol boundary, deinterleaver/order or LLR tuning using best mapping_meta."
        ],
        "decodes": []
      }
    },
    "candidate_export": {
      "name": "20260528T035339Z_step83_candidate_export_output.json",
      "path": "/decoders/js8_decoder/logs/20260528T035339Z_step83_candidate_export_output.json",
      "url": "/logs/20260528T035339Z_step83_candidate_export_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 99951,
        "mtime_utc": "2026-05-28T03:54:51Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-fec-candidate-export",
        "tool_version": "step63-source-exact-interleaver-whitening-index-extract",
        "rx_only": true,
        "next_action": "Run collect-logs and upload the JS8Lab bundle. If selected_variant.complete_174bit_candidate is true, proceed to LDPC/deinterleaver/message-unpack tuning.",
        "input_wav": "/decoders/js8_decoder/runtime/step83_quick_windows/js8_quick_selected_window.wav",
        "outputs": {
          "candidate_json": "/decoders/js8_decoder/runtime/step83_fec_candidates/js8_quick_selected_window_fec_candidate_step17.json",
          "selected_bits_file": "/decoders/js8_decoder/runtime/step83_fec_candidates/js8_quick_selected_window_fec_candidate_step17.bits"
        },
        "warnings": [
          "Step 54 JS8 Costas guard uses leading-only Costas exclusion by default to preserve 58 data symbols / 174 soft bits on JS8Lab windows; full FT8 middle/trailing exclusion remains diagnostic-only.",
          "Step 54 profile-anchor guard: FEC symbols were extracted from the selected profile sync anchor instead of re-running an independent sync search.",
          "Step 54 prepares LDPC/FEC input candidates and an LDPC probe harness only; it does not yet run final real JS8 LDPC decode or unpack text.",
          "Step 54 does not decode JS8 text yet. It probes FT8-style Gray de-mapping, bit order and 174-bit interleaver candidates for real LDPC/FEC integration.",
          "lab_mask_xor_preview is only a repeatable diagnostic mask, not a confirmed JS8 whitening implementation.",
          "Step 54 locks candidate export to JS8-realistic timing and reuses the selected profile sync anchor for FEC symbol extraction where available.",
          "It still does not perform real LDPC/FEC decode or message unpack.",
          "Next step can tune real JS8/FT8 LDPC matrix/deinterleaver/message unpack against this anchored candidate contract."
        ],
        "decodes": []
      }
    },
    "timing_boundary_sweep": {
      "name": "20260527T110128Z_real_run_timing_boundary_sweep_output.json",
      "path": "/decoders/js8_decoder/logs/20260527T110128Z_real_run_timing_boundary_sweep_output.json",
      "url": "/logs/20260527T110128Z_real_run_timing_boundary_sweep_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 145265,
        "mtime_utc": "2026-05-27T11:11:09Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-timing-boundary-candidate-sweep",
        "tool_version": "step51-source-aligned-tone-offset-cli-fix",
        "rx_only": true,
        "next_action": "Use outputs.timing_best_candidate_json for LDPC matrix/soft decode. If syndrome is still far from 0, continue interleaver/LLR and symbol-boundary tuning around the best_candidate.",
        "input_wav": "/decoders/js8_decoder/runtime/quick_prefilter_windows/js8_quick_selected_window.wav",
        "outputs": {
          "timing_boundary_sweep_json": "/decoders/js8_decoder/runtime/timing_boundary_sweep/step51_source_aligned_timing_boundary_sweep.json",
          "timing_best_candidate_json": "/decoders/js8_decoder/runtime/timing_boundary_sweep/step51_source_aligned_best_timing_fec_candidate.json",
          "checkpoint_json": "/decoders/js8_decoder/logs/20260527T110128Z_real_run_timing_boundary_sweep_output.json"
        },
        "warnings": [
          "Step 51 expands the Step36 edge hit and exports the best timing candidate for downstream LDPC soft-decode.",
          "No JS8 text unpack or CRC validation is performed yet.",
          "No valid LDPC codeword found is a diagnostic warning, not a hard command failure."
        ],
        "decodes": []
      }
    },
    "real_run_timing_boundary_sweep": {
      "name": "20260527T110128Z_real_run_timing_boundary_sweep_output.json",
      "path": "/decoders/js8_decoder/logs/20260527T110128Z_real_run_timing_boundary_sweep_output.json",
      "url": "/logs/20260527T110128Z_real_run_timing_boundary_sweep_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 145265,
        "mtime_utc": "2026-05-27T11:11:09Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-timing-boundary-candidate-sweep",
        "tool_version": "step51-source-aligned-tone-offset-cli-fix",
        "rx_only": true,
        "next_action": "Use outputs.timing_best_candidate_json for LDPC matrix/soft decode. If syndrome is still far from 0, continue interleaver/LLR and symbol-boundary tuning around the best_candidate.",
        "input_wav": "/decoders/js8_decoder/runtime/quick_prefilter_windows/js8_quick_selected_window.wav",
        "outputs": {
          "timing_boundary_sweep_json": "/decoders/js8_decoder/runtime/timing_boundary_sweep/step51_source_aligned_timing_boundary_sweep.json",
          "timing_best_candidate_json": "/decoders/js8_decoder/runtime/timing_boundary_sweep/step51_source_aligned_best_timing_fec_candidate.json",
          "checkpoint_json": "/decoders/js8_decoder/logs/20260527T110128Z_real_run_timing_boundary_sweep_output.json"
        },
        "warnings": [
          "Step 51 expands the Step36 edge hit and exports the best timing candidate for downstream LDPC soft-decode.",
          "No JS8 text unpack or CRC validation is performed yet.",
          "No valid LDPC codeword found is a diagnostic warning, not a hard command failure."
        ],
        "decodes": []
      }
    },
    "jsc_cpp_reference_compare": {
      "name": "20260528T030727Z_jsc_cpp_reference_compare_output.json",
      "path": "/decoders/js8_decoder/logs/20260528T030727Z_jsc_cpp_reference_compare_output.json",
      "url": "/logs/20260528T030727Z_jsc_cpp_reference_compare_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 14399,
        "mtime_utc": "2026-05-28T03:07:38Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-jsc-cpp-reference-map-transport-fix",
        "tool_version": "step81-jsc-cpp-reference-map-transport-fix",
        "schema": "webftr-js8-jsc-cpp-reference-map-transport-fix-v1",
        "created_utc": "2026-05-28T03:07:38Z",
        "verdict": "step81_cpp_reference_compare_passed_waiting_for_real_external_fixture",
        "next_action": "Import one externally confirmed compressed FrameDataCompressed fixture, then rerun Step79/Step81 before any lab text release.",
        "warnings": [
          "Step81 compares the Python JSC decompressor against an independent C++ harness using the source-extracted JSC map with a hex length-safe map transport.",
          "It still does not prove a real RF/JS8Call FrameDataCompressed text fixture.",
          "Compressed JS8 free-text release remains blocked until Step79 sees an externally confirmed fixture.",
          "RX-only safety remains enforced: no JS8Call runtime control and no TX/PTT/Tune/Send."
        ]
      }
    },
    "compressed_text_release_gate": {
      "name": "20260528T024854Z_compressed_text_release_gate_output.json",
      "path": "/decoders/js8_decoder/logs/20260528T024854Z_compressed_text_release_gate_output.json",
      "url": "/logs/20260528T024854Z_compressed_text_release_gate_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 3100,
        "mtime_utc": "2026-05-28T02:49:00Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-real-compressed-text-release-gate",
        "tool_version": "step79-real-compressed-text-release-gate",
        "schema": "webftr-js8-real-compressed-text-release-gate-v1",
        "created_utc": "2026-05-28T02:49:00Z",
        "verdict": "release_gate_ready_but_waiting_for_external_fixture",
        "next_action": "Import one externally confirmed compressed FrameDataCompressed fixture using the Step78/76 helpers, then rerun Step79.",
        "webftr_display_count": 0,
        "warnings": [
          "Step79 is a release gate, not productive WebFTR integration.",
          "Without a real externally confirmed compressed fixture, no compressed JS8 text is released.",
          "Even with a validated fixture, lab display rows require an explicit flag and multi-frame assembly remains unvalidated.",
          "RX-only safety remains enforced: no JS8Call runtime control and no TX/PTT/Tune/Send."
        ],
        "synthetic_selftest_all_passed": true,
        "external_fixture_count": 0,
        "release_candidate_count": 0,
        "jsc_entry_count": 200000
      }
    },
    "real_fixture_command_export": {
      "name": "20260528T024329Z_real_fixture_command_export_output.json",
      "path": "/decoders/js8_decoder/logs/20260528T024329Z_real_fixture_command_export_output.json",
      "url": "/logs/20260528T024329Z_real_fixture_command_export_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 6092,
        "mtime_utc": "2026-05-28T02:43:32Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-real-fixture-command-export",
        "tool_version": "step78-real-fixture-command-export",
        "schema": "webftr-js8-real-fixture-command-export-v1",
        "created_utc": "2026-05-28T02:43:32Z",
        "next_action": "Use the Step78 command README/helper to import one externally confirmed compressed FrameData fixture.",
        "webftr_display_count": 0,
        "warnings": [
          "Step78 exports operator commands only; it does not release WebFTR chat text.",
          "A real compressed FrameData fixture must be externally confirmed before any free-text release gate.",
          "RX-only safety remains enforced: no JS8Call runtime control and no TX/PTT/Tune/Send."
        ],
        "synthetic_selftest_all_passed": true,
        "external_fixture_count": 0,
        "jsc_entry_count": 200000
      }
    },
    "real_fixture_operator_bundle": {
      "name": "20260528T023509Z_real_fixture_operator_bundle_output.json",
      "path": "/decoders/js8_decoder/logs/20260528T023509Z_real_fixture_operator_bundle_output.json",
      "url": "/logs/20260528T023509Z_real_fixture_operator_bundle_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 5046,
        "mtime_utc": "2026-05-28T02:35:13Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-real-fixture-operator-bundle",
        "tool_version": "step77-real-fixture-operator-bundle",
        "schema": "webftr-js8-real-fixture-operator-bundle-v1",
        "created_utc": "2026-05-28T02:35:13Z",
        "next_action": "Use the generated Step77 bundle/helper or Step76 env variables to add one externally confirmed compressed FrameData fixture.",
        "webftr_display_count": 0,
        "warnings": [
          "Step77 only packages/imports fixture helper material; it does not release WebFTR chat text.",
          "A real compressed FrameData fixture must be externally confirmed before any free-text release gate.",
          "RX-only safety remains enforced: no JS8Call runtime control and no TX/PTT/Tune/Send."
        ],
        "synthetic_selftest_all_passed": true,
        "external_fixture_count": 0,
        "jsc_entry_count": 200000
      }
    },
    "real_fixture_intake_helper": {
      "name": "20260527T193942Z_real_fixture_intake_helper_output.json",
      "path": "/decoders/js8_decoder/logs/20260527T193942Z_real_fixture_intake_helper_output.json",
      "url": "/logs/20260527T193942Z_real_fixture_intake_helper_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 3719,
        "mtime_utc": "2026-05-27T19:39:45Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-real-compressed-fixture-intake-helper",
        "tool_version": "step76-real-compressed-fixture-intake-helper",
        "schema": "webftr-js8-real-compressed-fixture-intake-helper-v1",
        "next_action": "Use runtime/fixtures/add_real_js8_fixture_step76.sh or JS8LAB_FIXTURE_* environment variables to import one real JS8Call/RF comparison frame.",
        "webftr_display_count": 0,
        "warnings": [
          "Step76 only imports and validates a real/reference compressed fixture; it does not release WebFTR chat text.",
          "A fixture must be externally confirmed against JS8Call/JS8Call-Improved or a trusted RF comparison before it can be used for a release gate.",
          "The package remains RX-only and never starts JS8Call GUI/runtime control or TX/PTT/Tune/Send actions."
        ]
      }
    },
    "real_compressed_fixture_request": {
      "name": "20260527T192543Z_real_compressed_fixture_request_output.json",
      "path": "/decoders/js8_decoder/logs/20260527T192543Z_real_compressed_fixture_request_output.json",
      "url": "/logs/20260527T192543Z_real_compressed_fixture_request_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 5067,
        "mtime_utc": "2026-05-27T19:25:46Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-real-compressed-fixture-capture-request",
        "tool_version": "step75-real-compressed-fixture-capture-request",
        "schema": "webftr-js8-real-compressed-fixture-capture-request-v1",
        "next_action": "Fill runtime/fixtures/js8_compressed_frame_fixtures.json from the generated template, then rerun Step75.",
        "webftr_display_count": 0,
        "warnings": [
          "Step75 does not decode new RF data and does not release compressed free text to WebFTR.",
          "Synthetic JSC fixtures are only selftests; a release gate needs a real JS8Call/RF comparison fixture.",
          "The generated template contains placeholder values and must not be counted as evidence until edited with real data."
        ]
      }
    },
    "compressed_frame_fixture_gate": {
      "name": "20260527T191502Z_compressed_frame_fixture_gate_output.json",
      "path": "/decoders/js8_decoder/logs/20260527T191502Z_compressed_frame_fixture_gate_output.json",
      "url": "/logs/20260527T191502Z_compressed_frame_fixture_gate_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 28714,
        "mtime_utc": "2026-05-27T19:15:06Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-compressed-frame-fixture-validation-gate",
        "tool_version": "step74-compressed-frame-fixture-validation-gate",
        "schema": "webftr-js8-compressed-frame-fixture-validation-gate-v1",
        "verdict": "fixture_gate_selftest_ready_waiting_for_real_compressed_frame_fixture",
        "next_action": "Add a real fixture JSON under runtime/fixtures/js8_compressed_frame_fixtures.json or pass it as argument to Step74.",
        "webftr_display_count": 0,
        "warnings": [
          "Step74 validates compressed single-frame fixtures, but still blocks WebFTR chat release.",
          "Synthetic fixtures prove the port harness only; they are not RF/JS8Call comparison evidence.",
          "Multi-frame assembly and final display-release plausibility remain future steps."
        ],
        "synthetic_selftest_all_passed": true,
        "external_fixture_count": 0
      }
    },
    "varicode_compressed_bitslice_jsc_bridge": {
      "name": "20260527T190533Z_varicode_compressed_bitslice_jsc_bridge_output.json",
      "path": "/decoders/js8_decoder/logs/20260527T190533Z_varicode_compressed_bitslice_jsc_bridge_output.json",
      "url": "/logs/20260527T190533Z_varicode_compressed_bitslice_jsc_bridge_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 13508,
        "mtime_utc": "2026-05-27T19:05:36Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-varicode-compressed-bitslice-jsc-bridge-probe",
        "tool_version": "step73-varicode-compressed-bitslice-jsc-bridge-probe",
        "schema": "webftr-js8-varicode-compressed-bitslice-jsc-bridge-probe-v1",
        "verdict": "compressed_bitslice_jsc_bridge_selftest_ready_no_current_compressed_frames",
        "next_action": "Capture or inject a real FrameDataCompressed row; then validate JSC text against JS8Call before any WebFTR chat release.",
        "webftr_display_count": 0,
        "warnings": [
          "Step73 validates the Varicode compressed bit-slice bridge to the JSC decompressor, but keeps chat display blocked.",
          "Synthetic single-frame compressed fixtures are not a substitute for real RF/JS8Call comparison fixtures.",
          "Multi-frame assembly and final display-release plausibility are still future steps."
        ],
        "compressed_candidate_count": 0,
        "selftest_all_passed": true
      }
    },
    "jsc_decompress_port_probe": {
      "name": "20260527T185247Z_jsc_decompress_port_probe_output.json",
      "path": "/decoders/js8_decoder/logs/20260527T185247Z_jsc_decompress_port_probe_output.json",
      "url": "/logs/20260527T185247Z_jsc_decompress_port_probe_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 10108,
        "mtime_utc": "2026-05-27T18:52:55Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-jsc-decompress-guarded-port-probe",
        "tool_version": "step72-jsc-decompress-guarded-port-probe",
        "schema": "webftr-js8-jsc-decompress-guarded-port-probe-v1",
        "verdict": "jsc_decompress_port_roundtrip_ready_no_current_compressed_frames",
        "next_action": "Capture or inject a real FrameDataCompressed fixture and export its post-unpack JSC bitvec; Step73 should connect Varicode bit-slice extraction to this port.",
        "warnings": [
          "Step72 ports the JSC codeword/decompress mechanics and validates map order with local roundtrip fixtures only.",
          "It does not release FrameDataCompressed as JS8 chat text.",
          "A source-faithful Varicode compressed payload bit-slice export is still needed before real compressed frames can be decoded through this port."
        ]
      }
    },
    "jsc_table_extract_probe": {
      "name": "20260527T185247Z_jsc_table_extract_probe_output.json",
      "path": "/decoders/js8_decoder/logs/20260527T185247Z_jsc_table_extract_probe_output.json",
      "url": "/logs/20260527T185247Z_jsc_table_extract_probe_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 23855,
        "mtime_utc": "2026-05-27T18:52:52Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-jsc-table-extract-probe",
        "tool_version": "step71-jsc-table-extract-probe",
        "schema": "webftr-js8-jsc-table-extract-probe-v1",
        "verdict": "jsc_table_payload_extracted_port_ready",
        "next_action": "Implement the guarded JSC bitstream/table decoder against this extracted fingerprint bundle, then validate only with compressed FrameData fixtures.",
        "warnings": [
          "Step71 is a source-table extraction/readiness probe only.",
          "It does not execute JSC::decompress and does not release compressed FrameData as chat text.",
          "Fingerprints/previews are meant to anchor the next guarded source-faithful port step."
        ]
      }
    },
    "data_frame_text_unpack_probe": {
      "name": "20260527T183918Z_data_frame_text_unpack_probe_output.json",
      "path": "/decoders/js8_decoder/logs/20260527T183918Z_data_frame_text_unpack_probe_output.json",
      "url": "/logs/20260527T183918Z_data_frame_text_unpack_probe_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 6092,
        "mtime_utc": "2026-05-27T18:39:20Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-data-frame-text-unpack-probe",
        "tool_version": "step70-data-frame-text-unpack-probe",
        "schema": "webftr-js8-data-frame-text-unpack-probe-v1",
        "verdict": "data_frame_trim_and_huff_harness_ready_no_current_data_frames",
        "next_action": "Wait for or inject a real FrameData/FrameDataCompressed fixture, then run Step70 again; next implementation step is JSC table extraction/port for compressed frames.",
        "webftr_display_count": 0,
        "warnings": [
          "Step70 remains RX-only and does not start JS8Call GUI/Qt.",
          "Step70 does not release decoded data text to WebFTR chat/RX rows.",
          "Compressed FrameData still needs a source-faithful JSC::decompress table port before free text can be considered displayable."
        ],
        "data_frame_candidate_count": 0
      }
    },
    "jsc_decompress_source_audit": {
      "name": "20260527T183331Z_jsc_decompress_source_audit_output.json",
      "path": "/decoders/js8_decoder/logs/20260527T183331Z_jsc_decompress_source_audit_output.json",
      "url": "/logs/20260527T183331Z_jsc_decompress_source_audit_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 111479,
        "mtime_utc": "2026-05-27T18:33:33Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-jsc-decompress-source-audit-probe",
        "tool_version": "step69-jsc-decompress-source-audit-probe",
        "schema": "webftr-js8-jsc-decompress-source-audit-v1",
        "verdict": "jsc_source_ready_no_data_frames_in_current_fixture",
        "next_action": "Port JSC::decompress using the extracted source path, then wait for or inject a FrameData/FrameDataCompressed fixture to validate free text.",
        "warnings": [
          "Step69 is research/audit only and remains RX-only.",
          "No JS8 free-text rows are released by this step.",
          "JSC::decompress must be ported with source fixtures before FrameData/FrameDataCompressed can be shown as chat text."
        ]
      }
    },
    "webftr_rx_ui_contract": {
      "name": "20260527T181644Z_webftr_rx_ui_contract_output.json",
      "path": "/decoders/js8_decoder/logs/20260527T181644Z_webftr_rx_ui_contract_output.json",
      "url": "/logs/20260527T181644Z_webftr_rx_ui_contract_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 6031,
        "mtime_utc": "2026-05-27T18:16:44Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-webftr-rx-ui-contract-export",
        "tool_version": "step69-jsc-decompress-source-audit-probe",
        "schema": "webftr-js8-rx-ui-contract-v1",
        "verdict": "webftr_rx_ui_contract_ready_control_frames_only",
        "next_action": "Use this contract as a read-only WebFTR JS8 RX preview source; next research step is source-porting JSC::decompress/multi-frame assembly for free text.",
        "warnings": [
          "Step68 remains RX-only and does not start JS8Call GUI/Qt.",
          "Only Step67 source-confirmed fixed control frames are exported for UI display.",
          "Normal JS8 free text still needs JSC::decompress and multi-frame assembly before productive display."
        ]
      }
    },
    "source_confirmed_control_frame_rx_release": {
      "name": "20260528T035339Z_step83_source_confirmed_control_frame_rx_release_output.json",
      "path": "/decoders/js8_decoder/logs/20260528T035339Z_step83_source_confirmed_control_frame_rx_release_output.json",
      "url": "/logs/20260528T035339Z_step83_source_confirmed_control_frame_rx_release_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 9808,
        "mtime_utc": "2026-05-28T03:56:08Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-source-confirmed-control-frame-rx-release",
        "tool_version": "step67-source-confirmed-control-frame-rx-release",
        "verdict": "source_confirmed_control_frames_ready_for_webftr_rx_rows",
        "next_action": "Wire these guarded webftr_rx_rows into the JS8 RX display contract, then continue with JSC::decompress/multi-frame assembly for real JS8 chat text.",
        "frame_type_counts": {
          "FrameHeartbeat": 1,
          "FrameDirected": 1
        },
        "webftr_display_count": 2,
        "warnings": [
          "Step67 is still RX-only and does not start JS8Call GUI/Qt.",
          "Only source-confirmed fixed control frames such as Heartbeat/Directed/Compound are released to webftr_rx_rows.",
          "Free-text Data/Compressed frames remain blocked until JSC::decompress and multi-frame assembly are source-ported and tested."
        ]
      }
    },
    "source_varicode_frame_unpack_probe": {
      "name": "20260528T035339Z_step83_source_varicode_frame_unpack_probe_output.json",
      "path": "/decoders/js8_decoder/logs/20260528T035339Z_step83_source_varicode_frame_unpack_probe_output.json",
      "url": "/logs/20260528T035339Z_step83_source_varicode_frame_unpack_probe_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 60531,
        "mtime_utc": "2026-05-28T03:56:07Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-source-varicode-frame-unpack-probe",
        "tool_version": "step66-source-varicode-frame-unpack-probe",
        "verdict": "source_varicode_frames_classified_but_not_displayable",
        "next_action": "If frame types look plausible but hidden, port JSC::decompress and multi-frame assembly next; if a display row appears, wire webftr_rx_rows into the JS8 RX UI contract.",
        "frame_probe_count": 2,
        "frame_type_counts": {
          "FrameHeartbeat": 1,
          "FrameDirected": 1
        },
        "webftr_display_count": 0,
        "warnings": [
          "Step66 is still RX-only diagnostics. It classifies message174 text as JS8 Varicode frame families but does not start JS8Call GUI/Qt.",
          "Rows remain hidden unless callsign/grid/command/text plausibility survives source-style frame unpacking.",
          "Compressed Data frames still require a later JSC::decompress port before real JS8 chat text can be displayed."
        ]
      }
    },
    "rx_display_contract": {
      "name": "20260527T163511Z_rx_display_contract_output.json",
      "path": "/decoders/js8_decoder/logs/20260527T163511Z_rx_display_contract_output.json",
      "url": "/logs/20260527T163511Z_rx_display_contract_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 8654,
        "mtime_utc": "2026-05-27T16:35:12Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-rx-display-contract",
        "tool_version": "step65-rx-display-contract-message174-plausibility-guard",
        "verdict": "message174_candidates_but_no_plausible_js8_text_yet",
        "next_action": "If webftr_display_count is 0, continue with source extraction around JS8 text/framing/callsign packing before WebFTR UI integration; if >0, wire webftr_rx_rows into the JS8 RX table contract.",
        "webftr_display_count": 0,
        "warnings": [
          "Step65 is a safety/display-contract layer: CRC12-zero message174 candidates are not automatically treated as real user-visible JS8 chat lines.",
          "Random-looking compact 12-character payloads remain preserved as diagnostics but are hidden from normal WebFTR RX rows until source text/framing is connected.",
          "No JS8Call GUI/Qt process is started and no TX/PTT/Tune/Send action is performed."
        ]
      }
    },
    "source_confirmed_message174_decode": {
      "name": "20260528T035339Z_step83_source_confirmed_message174_decode_output.json",
      "path": "/decoders/js8_decoder/logs/20260528T035339Z_step83_source_confirmed_message174_decode_output.json",
      "url": "/logs/20260528T035339Z_step83_source_confirmed_message174_decode_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 6617,
        "mtime_utc": "2026-05-28T03:56:07Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-source-confirmed-message174-decode",
        "tool_version": "step64-source-confirmed-message174-decodes-output",
        "next_action": "Use Step64 decodes[] as the contract for the next step: connect source-confirmed message174 output into a richer JS8 text/Varicode/framing interpretation and then feed WebFTR RX display fields.",
        "warnings": [
          "Step64 emits source-confirmed message174 CRC12-zero-distance text candidates; it is not yet a full live JS8 decoder chain from audio to final chat UI.",
          "It starts no JS8Call GUI/Qt process and performs no TX/PTT/Tune/Send actions.",
          "Random-looking 12-character payloads can still be valid message174 candidates until higher JS8 text/Varicode framing is connected."
        ],
        "decode_count": 2,
        "decodes": [
          {
            "rx_only": true
          },
          {
            "rx_only": true
          }
        ]
      }
    },
    "source_exact_map_probe": {
      "name": "20260528T035339Z_step83_source_exact_map_probe_output.json",
      "path": "/decoders/js8_decoder/logs/20260528T035339Z_step83_source_exact_map_probe_output.json",
      "url": "/logs/20260528T035339Z_step83_source_exact_map_probe_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 143892,
        "mtime_utc": "2026-05-28T03:56:06Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-source-exact-map-probe",
        "tool_version": "step64-source-confirmed-message174-decodes-output",
        "next_action": "Zero-distance message174/CRC12 candidate found: build Step64 source-confirmed message174 text unpack and WebFTR-style decodes[] output.",
        "warnings": [
          "Step63 is still a diagnostic/source-extraction step, not a final text decoder.",
          "It starts no JS8Call GUI/Qt process and performs no TX/PTT/Tune/Send actions."
        ],
        "decodes": []
      }
    },
    "info87_source_map_probe": {
      "name": "20260527T145731Z_info87_source_map_probe_output.json",
      "path": "/decoders/js8_decoder/logs/20260527T145731Z_info87_source_map_probe_output.json",
      "url": "/logs/20260527T145731Z_info87_source_map_probe_output.json",
      "stat": {
        "exists": true,
        "is_file": true,
        "is_dir": false,
        "size": 35860,
        "mtime_utc": "2026-05-27T14:57:32Z"
      },
      "json_preview": {
        "ok": true,
        "tool": "webftr-js8-info87-source-map-probe",
        "tool_version": "step62-source-derived-deinterleaver-whitening-map-probe",
        "next_action": "If best_distance reaches 0, implement source-confirmed message174 text unpack. If not, build Step63 to extract exact JS8Call-Improved interleaver/whitening index arrays and apply them before post-LDPC Info87 export.",
        "warnings": [
          "This is a bounded source-map/dewhitening diagnostic against existing runtime rows, not a final text decoder.",
          "If no zero-distance candidate appears, the next step should export source-derived interleaver/whitening indices directly from JS8Call-Improved source snippets and apply them before LDPC/message validation."
        ],
        "decodes": []
      }
    }
  },
  "bundles": [
    {
      "name": "js8_decoder_lab_real_run_20260527T110128Z.zip",
      "url": "/logs/js8_decoder_lab_real_run_20260527T110128Z.zip",
      "size": 5270021,
      "mtime_utc": "2026-05-27T11:12:34Z"
    },
    {
      "name": "js8_decoder_lab_real_run_20260527T104133Z.zip",
      "url": "/logs/js8_decoder_lab_real_run_20260527T104133Z.zip",
      "size": 4699383,
      "mtime_utc": "2026-05-27T10:50:00Z"
    },
    {
      "name": "js8_decoder_lab_full_audit_20260527T100315Z.zip",
      "url": "/logs/js8_decoder_lab_full_audit_20260527T100315Z.zip",
      "size": 4129065,
      "mtime_utc": "2026-05-27T10:03:35Z"
    },
    {
      "name": "js8_decoder_lab_full_audit_20260527T084305Z.zip",
      "url": "/logs/js8_decoder_lab_full_audit_20260527T084305Z.zip",
      "size": 4007964,
      "mtime_utc": "2026-05-27T08:51:47Z"
    },
    {
      "name": "js8_decoder_lab_real_run_20260527T082046Z.zip",
      "url": "/logs/js8_decoder_lab_real_run_20260527T082046Z.zip",
      "size": 4028163,
      "mtime_utc": "2026-05-27T08:31:54Z"
    },
    {
      "name": "js8_decoder_lab_real_run_20260527T080216Z.zip",
      "url": "/logs/js8_decoder_lab_real_run_20260527T080216Z.zip",
      "size": 3541087,
      "mtime_utc": "2026-05-27T08:12:23Z"
    },
    {
      "name": "js8_decoder_lab_real_run_20260527T073615Z.zip",
      "url": "/logs/js8_decoder_lab_real_run_20260527T073615Z.zip",
      "size": 3065595,
      "mtime_utc": "2026-05-27T07:46:16Z"
    },
    {
      "name": "js8_decoder_lab_real_run_20260527T072638Z.zip",
      "url": "/logs/js8_decoder_lab_real_run_20260527T072638Z.zip",
      "size": 2615145,
      "mtime_utc": "2026-05-27T07:36:45Z"
    },
    {
      "name": "js8_decoder_lab_real_run_20260527T070658Z.zip",
      "url": "/logs/js8_decoder_lab_real_run_20260527T070658Z.zip",
      "size": 2232505,
      "mtime_utc": "2026-05-27T07:16:58Z"
    },
    {
      "name": "js8_decoder_lab_real_run_20260527T064500Z.zip",
      "url": "/logs/js8_decoder_lab_real_run_20260527T064500Z.zip",
      "size": 1771764,
      "mtime_utc": "2026-05-27T06:55:08Z"
    },
    {
      "name": "js8_decoder_lab_real_run_20260527T062127Z.zip",
      "url": "/logs/js8_decoder_lab_real_run_20260527T062127Z.zip",
      "size": 1595958,
      "mtime_utc": "2026-05-27T06:31:30Z"
    },
    {
      "name": "js8_decoder_lab_real_run_20260527T055654Z.zip",
      "url": "/logs/js8_decoder_lab_real_run_20260527T055654Z.zip",
      "size": 1408988,
      "mtime_utc": "2026-05-27T06:07:00Z"
    }
  ],
  "stable_latest_links": {
    "browser_report": "/logs/js8_browser_report_latest.json",
    "real_wav_message174_regeneration_latest": "/logs/js8_real_wav_message174_regeneration_latest.json",
    "step83_input_check_latest": "/logs/js8_step83_input_check_latest.json",
    "step83_quick_window_scan_latest": "/logs/js8_step83_quick_window_scan_latest.json",
    "step83_candidate_export_latest": "/logs/js8_step83_candidate_export_latest.json",
    "step83_post_ldpc_info87_runtime_export_latest": "/logs/js8_step83_post_ldpc_info87_runtime_export_latest.json",
    "step83_source_exact_map_probe_latest": "/logs/js8_step83_source_exact_map_probe_latest.json",
    "step83_source_confirmed_message174_decode_latest": "/logs/js8_step83_source_confirmed_message174_decode_latest.json",
    "step83_source_varicode_frame_unpack_probe_latest": "/logs/js8_step83_source_varicode_frame_unpack_probe_latest.json",
    "step83_source_confirmed_control_frame_rx_release_latest": "/logs/js8_step83_source_confirmed_control_frame_rx_release_latest.json",
    "real_wav_full_chain_regression_latest": "/logs/js8_real_wav_full_chain_regression_latest.json",
    "step82_input_check_latest": "/logs/js8_step82_input_check_latest.json",
    "step82_quick_window_scan_latest": "/logs/js8_step82_quick_window_scan_latest.json",
    "step82_sync_probe_latest": "/logs/js8_step82_sync_probe_latest.json",
    "input_check": "/logs/js8_server_input_check_latest.json",
    "quick_window_scan": "/logs/js8_server_quick_window_scan_latest.json",
    "sync_probe": "/logs/js8_server_sync_probe_latest.json",
    "latest_log": "/logs/latest.log",
    "webftr_rx_ui_contract_latest": "/logs/js8_webftr_rx_ui_contract_latest.json",
    "jsc_decompress_source_audit_latest": "/logs/js8_jsc_decompress_source_audit_latest.json",
    "data_frame_text_unpack_probe_latest": "/logs/js8_data_frame_text_unpack_probe_latest.json",
    "jsc_table_extract_probe_latest": "/logs/js8_jsc_table_extract_probe_latest.json",
    "jsc_decompress_port_probe_latest": "/logs/js8_jsc_decompress_port_probe_latest.json",
    "jsc_cpp_reference_compare_latest": "/logs/js8_jsc_cpp_reference_compare_latest.json",
    "compressed_text_release_gate_latest": "/logs/js8_compressed_text_release_gate_latest.json",
    "real_fixture_command_export_latest": "/logs/js8_real_fixture_command_export_latest.json",
    "real_fixture_operator_bundle_latest": "/logs/js8_real_fixture_operator_bundle_latest.json",
    "real_fixture_operator_bundle_zip": "/logs/js8_step77_real_fixture_operator_bundle.zip",
    "real_fixture_intake_helper_latest": "/logs/js8_real_fixture_intake_helper_latest.json",
    "real_compressed_fixture_request_latest": "/logs/js8_real_compressed_fixture_request_latest.json",
    "compressed_frame_fixture_gate_latest": "/logs/js8_compressed_frame_fixture_gate_latest.json",
    "varicode_compressed_bitslice_jsc_bridge_latest": "/logs/js8_varicode_compressed_bitslice_jsc_bridge_latest.json"
  },
  "recent_files": [
    {
      "name": "js8_browser_server.log",
      "size": 435,
      "mtime_utc": "2026-05-28T04:01:56Z",
      "url": "/logs/js8_browser_server.log"
    },
    {
      "name": "js8_browser_report_latest.json",
      "size": 139546,
      "mtime_utc": "2026-05-28T04:01:56Z",
      "url": "/logs/js8_browser_report_latest.json"
    },
    {
      "name": "js8_start_diagnostics_latest.log",
      "size": 535141,
      "mtime_utc": "2026-05-28T03:56:11Z",
      "url": "/logs/js8_start_diagnostics_latest.log"
    },
    {
      "name": "20260528T035339Z_real-wav-status-surface-regression.log",
      "size": 534781,
      "mtime_utc": "2026-05-28T03:56:11Z",
      "url": "/logs/20260528T035339Z_real-wav-status-surface-regression.log"
    },
    {
      "name": "latest.log",
      "size": 534781,
      "mtime_utc": "2026-05-28T03:56:11Z",
      "url": "/logs/latest.log"
    },
    {
      "name": "20260528T035339Z_real-wav-status-surface-regression_manifest.json",
      "size": 2693,
      "mtime_utc": "2026-05-28T03:56:09Z",
      "url": "/logs/20260528T035339Z_real-wav-status-surface-regression_manifest.json"
    },
    {
      "name": "js8_step83_source_confirmed_control_frame_rx_release_latest.json",
      "size": 9808,
      "mtime_utc": "2026-05-28T03:56:08Z",
      "url": "/logs/js8_step83_source_confirmed_control_frame_rx_release_latest.json"
    },
    {
      "name": "js8_step83_source_varicode_frame_unpack_probe_latest.json",
      "size": 60531,
      "mtime_utc": "2026-05-28T03:56:08Z",
      "url": "/logs/js8_step83_source_varicode_frame_unpack_probe_latest.json"
    },
    {
      "name": "js8_step83_source_confirmed_message174_decode_latest.json",
      "size": 6617,
      "mtime_utc": "2026-05-28T03:56:08Z",
      "url": "/logs/js8_step83_source_confirmed_message174_decode_latest.json"
    },
    {
      "name": "js8_step83_source_exact_map_probe_latest.json",
      "size": 143892,
      "mtime_utc": "2026-05-28T03:56:08Z",
      "url": "/logs/js8_step83_source_exact_map_probe_latest.json"
    },
    {
      "name": "js8_step83_post_ldpc_info87_runtime_export_latest.json",
      "size": 106824,
      "mtime_utc": "2026-05-28T03:56:08Z",
      "url": "/logs/js8_step83_post_ldpc_info87_runtime_export_latest.json"
    },
    {
      "name": "js8_step83_candidate_export_latest.json",
      "size": 99951,
      "mtime_utc": "2026-05-28T03:56:08Z",
      "url": "/logs/js8_step83_candidate_export_latest.json"
    },
    {
      "name": "js8_step83_quick_window_scan_latest.json",
      "size": 8839,
      "mtime_utc": "2026-05-28T03:56:08Z",
      "url": "/logs/js8_step83_quick_window_scan_latest.json"
    },
    {
      "name": "js8_step83_input_check_latest.json",
      "size": 698,
      "mtime_utc": "2026-05-28T03:56:08Z",
      "url": "/logs/js8_step83_input_check_latest.json"
    },
    {
      "name": "js8_real_wav_message174_regeneration_latest.json",
      "size": 93483,
      "mtime_utc": "2026-05-28T03:56:08Z",
      "url": "/logs/js8_real_wav_message174_regeneration_latest.json"
    },
    {
      "name": "20260528T035339Z_real_wav_message174_regeneration_output.json",
      "size": 93483,
      "mtime_utc": "2026-05-28T03:56:08Z",
      "url": "/logs/20260528T035339Z_real_wav_message174_regeneration_output.json"
    },
    {
      "name": "20260528T035339Z_real_wav_message174_regeneration_output.stderr.log",
      "size": 0,
      "mtime_utc": "2026-05-28T03:56:08Z",
      "url": "/logs/20260528T035339Z_real_wav_message174_regeneration_output.stderr.log"
    },
    {
      "name": "20260528T035339Z_step83_source_confirmed_control_frame_rx_release_output.json",
      "size": 9808,
      "mtime_utc": "2026-05-28T03:56:08Z",
      "url": "/logs/20260528T035339Z_step83_source_confirmed_control_frame_rx_release_output.json"
    },
    {
      "name": "20260528T035339Z_step83_source_confirmed_control_frame_rx_release_output.stderr.log",
      "size": 0,
      "mtime_utc": "2026-05-28T03:56:07Z",
      "url": "/logs/20260528T035339Z_step83_source_confirmed_control_frame_rx_release_output.stderr.log"
    },
    {
      "name": "20260528T035339Z_step83_source_varicode_frame_unpack_probe_output.json",
      "size": 60531,
      "mtime_utc": "2026-05-28T03:56:07Z",
      "url": "/logs/20260528T035339Z_step83_source_varicode_frame_unpack_probe_output.json"
    },
    {
      "name": "20260528T035339Z_step83_source_varicode_frame_unpack_probe_output.stderr.log",
      "size": 0,
      "mtime_utc": "2026-05-28T03:56:07Z",
      "url": "/logs/20260528T035339Z_step83_source_varicode_frame_unpack_probe_output.stderr.log"
    },
    {
      "name": "20260528T035339Z_step83_source_confirmed_message174_decode_output.json",
      "size": 6617,
      "mtime_utc": "2026-05-28T03:56:07Z",
      "url": "/logs/20260528T035339Z_step83_source_confirmed_message174_decode_output.json"
    },
    {
      "name": "20260528T035339Z_step83_source_confirmed_message174_decode_output.stderr.log",
      "size": 0,
      "mtime_utc": "2026-05-28T03:56:06Z",
      "url": "/logs/20260528T035339Z_step83_source_confirmed_message174_decode_output.stderr.log"
    },
    {
      "name": "20260528T035339Z_step83_source_exact_map_probe_output.json",
      "size": 143892,
      "mtime_utc": "2026-05-28T03:56:06Z",
      "url": "/logs/20260528T035339Z_step83_source_exact_map_probe_output.json"
    },
    {
      "name": "20260528T035339Z_step83_source_exact_map_probe_output.stderr.log",
      "size": 0,
      "mtime_utc": "2026-05-28T03:56:04Z",
      "url": "/logs/20260528T035339Z_step83_source_exact_map_probe_output.stderr.log"
    },
    {
      "name": "20260528T035339Z_step83_post_ldpc_info87_runtime_export_output.json",
      "size": 106824,
      "mtime_utc": "2026-05-28T03:56:04Z",
      "url": "/logs/20260528T035339Z_step83_post_ldpc_info87_runtime_export_output.json"
    },
    {
      "name": "20260528T035339Z_step83_post_ldpc_info87_runtime_export_output.stderr.log",
      "size": 0,
      "mtime_utc": "2026-05-28T03:54:51Z",
      "url": "/logs/20260528T035339Z_step83_post_ldpc_info87_runtime_export_output.stderr.log"
    },
    {
      "name": "20260528T035339Z_step83_candidate_export_output.json",
      "size": 99951,
      "mtime_utc": "2026-05-28T03:54:51Z",
      "url": "/logs/20260528T035339Z_step83_candidate_export_output.json"
    },
    {
      "name": "20260528T035339Z_step83_candidate_export_output.stderr.log",
      "size": 0,
      "mtime_utc": "2026-05-28T03:53:52Z",
      "url": "/logs/20260528T035339Z_step83_candidate_export_output.stderr.log"
    },
    {
      "name": "20260528T035339Z_step83_quick_window_scan_output.json",
      "size": 8839,
      "mtime_utc": "2026-05-28T03:53:52Z",
      "url": "/logs/20260528T035339Z_step83_quick_window_scan_output.json"
    },
    {
      "name": "20260528T035339Z_step83_quick_window_scan_output.stderr.log",
      "size": 168,
      "mtime_utc": "2026-05-28T03:53:39Z",
      "url": "/logs/20260528T035339Z_step83_quick_window_scan_output.stderr.log"
    },
    {
      "name": "20260528T035339Z_step83_input_check_output.json",
      "size": 698,
      "mtime_utc": "2026-05-28T03:53:39Z",
      "url": "/logs/20260528T035339Z_step83_input_check_output.json"
    },
    {
      "name": "20260528T035339Z_step83_input_check_output.stderr.log",
      "size": 0,
      "mtime_utc": "2026-05-28T03:53:39Z",
      "url": "/logs/20260528T035339Z_step83_input_check_output.stderr.log"
    },
    {
      "name": "20260528T033900Z_real-wav-message174-regeneration.log",
      "size": 533206,
      "mtime_utc": "2026-05-28T03:41:40Z",
      "url": "/logs/20260528T033900Z_real-wav-message174-regeneration.log"
    },
    {
      "name": "20260528T033900Z_real-wav-message174-regeneration_manifest.json",
      "size": 2655,
      "mtime_utc": "2026-05-28T03:41:38Z",
      "url": "/logs/20260528T033900Z_real-wav-message174-regeneration_manifest.json"
    },
    {
      "name": "20260528T033900Z_real_wav_message174_regeneration_output.json",
      "size": 93456,
      "mtime_utc": "2026-05-28T03:41:36Z",
      "url": "/logs/20260528T033900Z_real_wav_message174_regeneration_output.json"
    },
    {
      "name": "20260528T033900Z_real_wav_message174_regeneration_output.stderr.log",
      "size": 0,
      "mtime_utc": "2026-05-28T03:41:36Z",
      "url": "/logs/20260528T033900Z_real_wav_message174_regeneration_output.stderr.log"
    },
    {
      "name": "20260528T033900Z_step83_source_confirmed_control_frame_rx_release_output.json",
      "size": 9808,
      "mtime_utc": "2026-05-28T03:41:36Z",
      "url": "/logs/20260528T033900Z_step83_source_confirmed_control_frame_rx_release_output.json"
    },
    {
      "name": "20260528T033900Z_step83_source_confirmed_control_frame_rx_release_output.stderr.log",
      "size": 0,
      "mtime_utc": "2026-05-28T03:41:36Z",
      "url": "/logs/20260528T033900Z_step83_source_confirmed_control_frame_rx_release_output.stderr.log"
    },
    {
      "name": "20260528T033900Z_step83_source_varicode_frame_unpack_probe_output.json",
      "size": 60531,
      "mtime_utc": "2026-05-28T03:41:36Z",
      "url": "/logs/20260528T033900Z_step83_source_varicode_frame_unpack_probe_output.json"
    },
    {
      "name": "20260528T033900Z_step83_source_varicode_frame_unpack_probe_output.stderr.log",
      "size": 0,
      "mtime_utc": "2026-05-28T03:41:35Z",
      "url": "/logs/20260528T033900Z_step83_source_varicode_frame_unpack_probe_output.stderr.log"
    },
    {
      "name": "20260528T033900Z_step83_source_confirmed_message174_decode_output.json",
      "size": 6357,
      "mtime_utc": "2026-05-28T03:41:35Z",
      "url": "/logs/20260528T033900Z_step83_source_confirmed_message174_decode_output.json"
    },
    {
      "name": "20260528T033900Z_step83_source_confirmed_message174_decode_output.stderr.log",
      "size": 0,
      "mtime_utc": "2026-05-28T03:41:35Z",
      "url": "/logs/20260528T033900Z_step83_source_confirmed_message174_decode_output.stderr.log"
    },
    {
      "name": "20260528T033900Z_step83_source_exact_map_probe_output.json",
      "size": 142707,
      "mtime_utc": "2026-05-28T03:41:35Z",
      "url": "/logs/20260528T033900Z_step83_source_exact_map_probe_output.json"
    },
    {
      "name": "20260528T033900Z_step83_source_exact_map_probe_output.stderr.log",
      "size": 0,
      "mtime_utc": "2026-05-28T03:41:32Z",
      "url": "/logs/20260528T033900Z_step83_source_exact_map_probe_output.stderr.log"
    },
    {
      "name": "20260528T033900Z_step83_post_ldpc_info87_runtime_export_output.json",
      "size": 106824,
      "mtime_utc": "2026-05-28T03:41:32Z",
      "url": "/logs/20260528T033900Z_step83_post_ldpc_info87_runtime_export_output.json"
    },
    {
      "name": "20260528T033900Z_step83_post_ldpc_info87_runtime_export_output.stderr.log",
      "size": 0,
      "mtime_utc": "2026-05-28T03:40:17Z",
      "url": "/logs/20260528T033900Z_step83_post_ldpc_info87_runtime_export_output.stderr.log"
    },
    {
      "name": "20260528T033900Z_step83_candidate_export_output.json",
      "size": 99951,
      "mtime_utc": "2026-05-28T03:40:17Z",
      "url": "/logs/20260528T033900Z_step83_candidate_export_output.json"
    },
    {
      "name": "20260528T033900Z_step83_candidate_export_output.stderr.log",
      "size": 0,
      "mtime_utc": "2026-05-28T03:39:15Z",
      "url": "/logs/20260528T033900Z_step83_candidate_export_output.stderr.log"
    },
    {
      "name": "20260528T033900Z_step83_quick_window_scan_output.json",
      "size": 8839,
      "mtime_utc": "2026-05-28T03:39:15Z",
      "url": "/logs/20260528T033900Z_step83_quick_window_scan_output.json"
    },
    {
      "name": "20260528T033900Z_step83_quick_window_scan_output.stderr.log",
      "size": 168,
      "mtime_utc": "2026-05-28T03:39:00Z",
      "url": "/logs/20260528T033900Z_step83_quick_window_scan_output.stderr.log"
    },
    {
      "name": "20260528T033900Z_step83_input_check_output.json",
      "size": 698,
      "mtime_utc": "2026-05-28T03:39:00Z",
      "url": "/logs/20260528T033900Z_step83_input_check_output.json"
    },
    {
      "name": "20260528T033900Z_step83_input_check_output.stderr.log",
      "size": 0,
      "mtime_utc": "2026-05-28T03:39:00Z",
      "url": "/logs/20260528T033900Z_step83_input_check_output.stderr.log"
    },
    {
      "name": "20260528T031839Z_real-wav-full-chain-regression.log",
      "size": 119355,
      "mtime_utc": "2026-05-28T03:19:11Z",
      "url": "/logs/20260528T031839Z_real-wav-full-chain-regression.log"
    },
    {
      "name": "20260528T031839Z_real-wav-full-chain-regression_manifest.json",
      "size": 1825,
      "mtime_utc": "2026-05-28T03:19:09Z",
      "url": "/logs/20260528T031839Z_real-wav-full-chain-regression_manifest.json"
    },
    {
      "name": "js8_step82_sync_probe_latest.json",
      "size": 60947,
      "mtime_utc": "2026-05-28T03:19:08Z",
      "url": "/logs/js8_step82_sync_probe_latest.json"
    },
    {
      "name": "js8_step82_input_check_latest.json",
      "size": 698,
      "mtime_utc": "2026-05-28T03:19:08Z",
      "url": "/logs/js8_step82_input_check_latest.json"
    },
    {
      "name": "js8_step82_quick_window_scan_latest.json",
      "size": 8839,
      "mtime_utc": "2026-05-28T03:19:08Z",
      "url": "/logs/js8_step82_quick_window_scan_latest.json"
    },
    {
      "name": "js8_real_wav_full_chain_regression_latest.json",
      "size": 46354,
      "mtime_utc": "2026-05-28T03:19:08Z",
      "url": "/logs/js8_real_wav_full_chain_regression_latest.json"
    },
    {
      "name": "20260528T031839Z_real_wav_full_chain_regression_output.json",
      "size": 46354,
      "mtime_utc": "2026-05-28T03:19:08Z",
      "url": "/logs/20260528T031839Z_real_wav_full_chain_regression_output.json"
    },
    {
      "name": "20260528T031839Z_real_wav_full_chain_regression_output.stderr.log",
      "size": 0,
      "mtime_utc": "2026-05-28T03:19:07Z",
      "url": "/logs/20260528T031839Z_real_wav_full_chain_regression_output.stderr.log"
    },
    {
      "name": "20260528T031839Z_step82_sync_probe_output.json",
      "size": 60947,
      "mtime_utc": "2026-05-28T03:19:07Z",
      "url": "/logs/20260528T031839Z_step82_sync_probe_output.json"
    },
    {
      "name": "20260528T031839Z_step82_sync_probe_output.stderr.log",
      "size": 0,
      "mtime_utc": "2026-05-28T03:18:52Z",
      "url": "/logs/20260528T031839Z_step82_sync_probe_output.stderr.log"
    },
    {
      "name": "20260528T031839Z_step82_quick_window_scan_output.json",
      "size": 8839,
      "mtime_utc": "2026-05-28T03:18:52Z",
      "url": "/logs/20260528T031839Z_step82_quick_window_scan_output.json"
    },
    {
      "name": "20260528T031839Z_step82_quick_window_scan_output.stderr.log",
      "size": 168,
      "mtime_utc": "2026-05-28T03:18:40Z",
      "url": "/logs/20260528T031839Z_step82_quick_window_scan_output.stderr.log"
    },
    {
      "name": "20260528T031839Z_step82_input_check_output.json",
      "size": 698,
      "mtime_utc": "2026-05-28T03:18:39Z",
      "url": "/logs/20260528T031839Z_step82_input_check_output.json"
    },
    {
      "name": "20260528T031839Z_step82_input_check_output.stderr.log",
      "size": 0,
      "mtime_utc": "2026-05-28T03:18:39Z",
      "url": "/logs/20260528T031839Z_step82_input_check_output.stderr.log"
    },
    {
      "name": "20260528T030727Z_jsc-cpp-reference-map-transport-fix.log",
      "size": 15375,
      "mtime_utc": "2026-05-28T03:07:39Z",
      "url": "/logs/20260528T030727Z_jsc-cpp-reference-map-transport-fix.log"
    },
    {
      "name": "20260528T030727Z_jsc-cpp-reference-map-transport-fix_manifest.json",
      "size": 1376,
      "mtime_utc": "2026-05-28T03:07:38Z",
      "url": "/logs/20260528T030727Z_jsc-cpp-reference-map-transport-fix_manifest.json"
    },
    {
      "name": "js8_jsc_cpp_reference_compare_latest.json",
      "size": 14399,
      "mtime_utc": "2026-05-28T03:07:38Z",
      "url": "/logs/js8_jsc_cpp_reference_compare_latest.json"
    },
    {
      "name": "20260528T030727Z_jsc_cpp_reference_compare_output.json",
      "size": 14399,
      "mtime_utc": "2026-05-28T03:07:38Z",
      "url": "/logs/20260528T030727Z_jsc_cpp_reference_compare_output.json"
    },
    {
      "name": "20260528T030727Z_jsc_cpp_reference_compare_output.stderr.log",
      "size": 0,
      "mtime_utc": "2026-05-28T03:07:27Z",
      "url": "/logs/20260528T030727Z_jsc_cpp_reference_compare_output.stderr.log"
    },
    {
      "name": "20260528T025704Z_jsc-cpp-reference-compare-probe.log",
      "size": 14919,
      "mtime_utc": "2026-05-28T02:57:13Z",
      "url": "/logs/20260528T025704Z_jsc-cpp-reference-compare-probe.log"
    },
    {
      "name": "20260528T025704Z_jsc-cpp-reference-compare-probe_manifest.json",
      "size": 1364,
      "mtime_utc": "2026-05-28T02:57:11Z",
      "url": "/logs/20260528T025704Z_jsc-cpp-reference-compare-probe_manifest.json"
    },
    {
      "name": "20260528T025704Z_jsc_cpp_reference_compare_output.json",
      "size": 13963,
      "mtime_utc": "2026-05-28T02:57:11Z",
      "url": "/logs/20260528T025704Z_jsc_cpp_reference_compare_output.json"
    },
    {
      "name": "20260528T025704Z_jsc_cpp_reference_compare_output.stderr.log",
      "size": 0,
      "mtime_utc": "2026-05-28T02:57:04Z",
      "url": "/logs/20260528T025704Z_jsc_cpp_reference_compare_output.stderr.log"
    },
    {
      "name": "20260528T024854Z_real-compressed-text-release-gate.log",
      "size": 4150,
      "mtime_utc": "2026-05-28T02:49:02Z",
      "url": "/logs/20260528T024854Z_real-compressed-text-release-gate.log"
    },
    {
      "name": "20260528T024854Z_real-compressed-text-release-gate_manifest.json",
      "size": 1726,
      "mtime_utc": "2026-05-28T02:49:01Z",
      "url": "/logs/20260528T024854Z_real-compressed-text-release-gate_manifest.json"
    },
    {
      "name": "js8_compressed_text_release_gate_latest.json",
      "size": 3100,
      "mtime_utc": "2026-05-28T02:49:01Z",
      "url": "/logs/js8_compressed_text_release_gate_latest.json"
    },
    {
      "name": "20260528T024854Z_compressed_text_release_gate_output.json",
      "size": 3100,
      "mtime_utc": "2026-05-28T02:49:00Z",
      "url": "/logs/20260528T024854Z_compressed_text_release_gate_output.json"
    }
  ],
  "browser_links": {
    "home": "/",
    "api_report": "/api/report",
    "logs": "/logs/"
  },
  "note": "Read-only browser report for JS8 Decoder Lab logs. It does not start TX/PTT/Tune/Send or control JS8Call runtime."
}