Оценка по Jammertest: опубликованный план как заданная истина
kshana jammertest import читает каталог испытаний Jammertest и план передач и превращает слоты одной испытательной зоны в [[events]] доверия к приёмнику. kshana jammertest score пропускает журнал приёмника через мониторы доверия и оценивает его по этому расписанию, испытание за испытанием. Каждый результат — MODELLED: расписание говорит, когда испытание было запланировано, а не когда передатчик был включён.
Программное обеспечение консультативного характера, не навигационное оборудование с утверждённым типом (IEC 61108, IEC 61162): ответственность за судовождение остаётся на операторе. Ничто здесь не одобрено Норвежским управлением общественных дорог, Nkom или организаторами мероприятия; соглашение с ними не заявляется.
План и каталог#
Источник: репозиторий NPRA/jammertest-plan Норвежского управления общественных дорог (https://github.com/NPRA/jammertest-plan), лицензия MIT (авторские права 2024 Норвежское управление общественных дорог; текст лицензии проверяется в xval/jammertest-plan/MANIFEST.tsv). Файлы загружаются, но никогда не включаются в поставку:
xval/jammertest-plan/fetch.sh <dest-dir-outside-the-repo>
Он загружает каталоги и файлы плана 2025 на закреплённом коммите 75c0b2ceea10e470c3799d14a8ef18842d8375a7 и отвергает любой файл, чей SHA-256 отличается от указанного в xval/jammertest-plan/MANIFEST.tsv.
У испытания каталога есть идентификатор из точек, type.group.test (например, 1.2.5: тип 1 — подавление, группа 2, испытание 5). План перечисляет для каждой испытательной зоны и временного слота, какой идентификатор запланирован. Типы 1 (подавление), 2 (спуфинг) и 3 (meaconing) передают; тип 0 (брифинги, льготный период, слоты бронирования и разовые слоты) не передаёт и пропускается. Времена в плане — местное настенное время; --local-offset-h (по умолчанию 2, CEST) задаёт, насколько они отстоят от UTC. Файлы плана содержат поле контактного лица с именем человека: оно никогда не читается, и ничего, полученного из него, не записывается.
Импорт#
kshana jammertest import --catalog testcatalog2025.json \
--plan plan-tuesday-2025-09-16.json --plan plan-wednesday-2025-09-17.json \
--location 1 --log receiver.ubx --format ubx --out events.toml
--log-start <UTC time> заменяет --log/--format, когда журнал не указывает своё начало. На выходе — TOML [[events]] для добавления в сценарий доверия к приёмнику; каждая метка начинается с scheduled truth: и несёт год издания, идентификатор каталога и зону, а заголовок записывает SHA-256 каждого исходного файла. --attack-log <scenario.json> вместо этого читает истину о событиях одной папки набора данных JammerTest 2024 (его attack_log, отметки сдвинуты на --time-shift-h, по умолчанию -2: они указывают Z, но это местное время).
Оценка#
kshana jammertest score session.toml --catalog testcatalog2025.json --plan plan-....json \
--location 1 [--json] [--key signer.key --out pack/]
session.toml — это сценарий доверия к приёмнику ([log] format/path, необязательные [monitors], [compare]). Его собственные [[events]] заменяются импортированным расписанием. По каждому запланированному испытанию:
| поле | значение |
|---|---|
outcome |
detected (тревога в пределах compare.detect_tol_s, по умолчанию 10 с, от запланированного начала), late (позже, внутри слота), missed (нет), not-evaluable |
latency_s |
первая тревога минус запланированное начало |
time_to_recover_s |
от конца слота до начала первого отрезка не менее --recover-hold-s (10 с) без тревоги, перед следующим испытанием |
Испытание поддаётся оценке, только если оно начинается не менее чем через calibration_s + guard_s после начала журнала; журнал с более ранним испытанием помечается baseline_contaminated (базовый уровень мог сформироваться при помехах). Ложные тревоги — это тревожные эпохи после калибровки вне каждого слота, расширенного на --guard-s (60 с) до и после (либо после точки восстановления), которые подсчитываются как эпохи и как прогоны, с числом прогонов на час чистого времени. С --key и --out прогон записывается как подписанный пакет доказательств (docs/EVIDENCE-PACKS.md): оценочная карточка и импортированное расписание лежат внутри config.json, а значит, внутри цепочки хешей и подписи. Пакет — это технический протокол, а не юридическое заключение.
Чего результат не говорит#
- Запланированный слот — это не запись о фактической работе в эфире. Передатчик мог включиться поздно, остановиться рано или вовсе не работать; «пропущенное» испытание может оказаться испытанием, при котором передачи не было, а задержка отсчитывается от запланированного начала.
- «Чистая» эпоха — это «вне запланированных слотов», а не «доказанно свободная от помех».
- Обнаружение мониторами в области измерений ничего не говорит об обнаружении маломощного когерентного спуфера.
- Никакой внешний оракул не указывает истинное время работы в эфире, поэтому здесь ничто не является VALIDATED.
Прогон по набору данных 2024 (предварительно зарегистрирован)#
xval/jammertest-score/PREREGISTRATION.md зафиксировал выборку, определения и пороги до первого оцениваемого прогона; xval/jammertest-score/RESULTS.md записывает этот прогон. Результат: зарегистрированное правило минимума данных не выполнено (4 оцениваемых окон подавления из 4 из 12 папок .ubx: 5 папок отброшено правилом базового уровня, а 3 журналов UBX указывают своё начало только как время недели GPS), поэтому ни один порог нельзя оценить. Ничто не ослаблялось и не перезапускалось. v2 (PREREGISTRATION-v2.md, зафиксирован отдельно до своего прогона; только обработка данных, те же пороги и то же правило минимума данных) привязал журналы только с временем GPS к дате папки, оценил 12 папок только с CSV и использовал сессию подвижной платформы для движущихся роверов. Результат (RESULTS-v2.md): сохранено 14 из 24 папок, но лишь 7 оцениваемых окон подавления, поэтому правило минимума данных снова не выполнено, и ни один порог нельзя оценить. Результат v1 не изменился. Только описательно: 3 из 7 окон подавления дали тревогу в пределах 10 с, 4 — позже, ни одно не пропущено; медианная задержка 18 с; доля ложных тревог на чистых участках 0,089. Определяющим ограничением теперь служит правило базового уровня, которое убирает 10 папок; для дальнейшей регистрации потребовалось бы другое правило для ранних окон. Набор данных (JammerTest 2024, Zenodo 15911589, GPL-3.0-or-later) загружается с помощью xval/oracles/setup.sh и никогда не включается в поставку; тест tests/jammertest_score_2024.rs закрепляет записанный прогон, когда KSHANA_JAMMERTEST_DIR указывает на распакованный набор данных.
Набор данных SimulaMet NMEA 2025#
Набор данных SimulaMet Jammertest 2025, полученный из NMEA (IEEE DataPort, DOI 10.21227/a7v4-xw11), в 0,38 не адаптирован. На его странице не указана лицензия и сказано «This dataset requires an IEEE DataPort Subscription to access»: условия не разрешают явно ни распространение, ни автоматическую загрузку, поэтому ни адаптер, ни скрипт загрузки не писались. Для его использования нужно решение владельца и, желательно, письменное согласие авторов.
Поверхности#
CLI, Rust (kshana::jammertest), Python (jammertest_import, jammertest_score), WebAssembly (те же имена), инструменты MCP с теми же именами, а также команда /kshana-jammertest и навык jammertest. Подписанный пакет доступен только из командной строки (нужен ключ подписи). См. docs/SURFACES.md.