-
Nikitos создал
§12.15: «симуляция задержки пакетов» числилась незакрытой — и в C это было написано прямым текстом: `R2D_UNUSED(delay_ms); // задержку пока не откладываем: только потери`. Потери работали, задержки не было. ЧТО СДЕЛАНО: * C: r2d_net_send разделён на обёртку (симуляция) и r2d__net_send_now (реальная отправка). Задержка — ОЧЕРЕДЬ отложенных отправок (64 пакета): пакет кладётся со временем «когда отправить», реально уходит из r2d_net_tick, который зовёт poll() раз в кадр. Спать в кадре нельзя — поэтому именно очередь; * jitter: случайная добавка [0, jitter) к задержке, из того же xorshift, что и потери, поэтому воспроизводимо от сида; * потери применяются ПРИ ПОСТАНОВКЕ, поэтому потерянный пакет очередь не занимает; * очередь переполнена — ОДНО предупреждение в журнал и пакет теряется, кадр не роняется; * engine.netSimulate(loss, delay, seed, jitter), engine.netDelayed(); * $.net.simulate({loss, delay, jitter, seed}), simulation(), delayed(), simulateOff(). ПРОВЕРКА (tests/agent/net_delay_test.py, 14 проверок, ДВА движка на localhost): без задержки пакет доходит быстро; с delay 200 сразу после send пакет В ОЧЕРЕДИ (netDelayed = 1) и до сервера НЕ дошёл, а через ~0.16 с дошёл; simulateOff возвращает быстроту; 100% потерь — не доходит ничего. То есть проверяется не «настройка сохранилась», а что задержка ДЕЙСТВИТЕЛЬНО задерживает. ЧЕСТНОЕ ОГРАНИЧЕНИЕ: симуляция не моделирует переупорядочивание и дубли — пакеты теряются и задерживаются, но не приходят в другом порядке. Записано в net.md §8. ДОКИ: net.md §8 (поля, почему очередь, ограничения), API.md (две функции), TASKS §12.15 (осталось только сглаживание откатов). Полный qjs, агентские тесты, doc_coverage, doc_claims, duplicate_keys, быстрый набор — зелёные.9a5b45c5