Читать книгу: «Слепое пятно»
ЭПИГРАФ
Подпись живёт дольше
человека.
Чернила не меняются.
Меняется только то, что
однажды написанное начинает
работать само.
Глава 1
Ветер был сырым и упрямым. Он шёл с залива, не делая разницы между бетоном полосы, сеткой периметра и людьми у КПП. Марков остановился на жёлтой линии, на секунду потерял баланс – поток толкнул в бок – и перехватил рюкзак, чтобы лямка не соскользнула с плеча. Пластик пропуска в ладони был холодным, как только что вынутый из морозилки металлический калибр. Он приложил карточку к считывателю. Турникет подумал дольше, чем следовало.
Дежурный посмотрел поверх стекла. Лицо у него было красное от ветра, глаза – внимательные, без желания разговаривать.
– Марков? – спросил он, будто сверял не имя, а интонацию.
– Да.
Зелёный огонёк щёлкнул, турникет поддался. Плечом – чуть мягче, чем нужно – он вошёл внутрь, и шум стал другим: вместо открытого ветра – ровный гул вентиляции, шуршание шин на мокром асфальте далеко за стеной.
Внутри пахло краской и пылью от коробок, которые кто-то вскрывал совсем недавно. Аэродром Береговое был почти новым, или так старательно делали вид. На стене, прямо напротив поста, висел щит с планом эвакуации: зелёные стрелки шли так ровно, будто им никогда не придётся работать.
Он отметил время, не глядя на часы – привычка считать такты в голове. Если турникет держал его на полторы секунды дольше нормы, это ничего не значило. Если считать, что это было «ничего», легче жить. Но привычка всё равно записала задержку в ту же тихую полку, где лежали другие мелочи, не стоившие разговора. Щелчок реле где-то в нутре турникета отозвался короткой памятью: старый цех, облупленная краска, стенд, который «повис» в тишине, и тот самый раз – когда тишина оказалась громче любого аварийного зуммера.
Рабочее место нашлось без блужданий. Ему выдали ключ от ящика, временную наклейку на ноутбук и бумагу со словами «подпись здесь и здесь». Бумага шуршала сухо, как линейка по хрусткому ватману. Он расписался – не вчитываясь в формулировки, которые и так помнил: ответственность, конфиденциальность, допуск. Потом – коридор, два пролёта вверх, стеклянная дверь без опознавательных знаков, и за ней – их комната.
Четыре стола, по два монитора на каждом. Короткие бирки на кромках столешниц с фамилиями и четырёхзначными кодами. У окна – место, где по плану сидеть ему. Из окна – серый прямоугольник полосы и тёмная линия леса за ней. Солнца не было, но яркость отсвечивала от клина облаков, делая всё нарочито чистым, как в буклете.
Он включил станцию. Вентилятор коротко взвыл, как будто брал высоту, потом выровнялся. Экран загорелся – сначала серым, потом белым, потом пошли знакомые прямоугольники. Он ввёл логин, пароль, подождал. Система проверила сертификат, пожевала что-то на своей стороне, выдала десктоп.
Пока грузились инструменты, он пошёл за кофе. Автомат у стены работал яростно, как будто спорил с кем-то. Кофе вышел водянистым и горячим, зато сработало главное: пальцы оттаяли. Вернувшись, он подвёл стул. Стул был новый и тугой, пружина щёлкнула – чуть громче, чем следует в пустой комнате.
Синхронизация времени шла в фоновом окне. Он смотрел на цифры и ловил привычное спокойствие, которое приходит, когда цифры подчиняются. NTP-серверы дали метку, локальная станция подстроилась. Разница была маленькой. Слишком маленькой.
Он наклонился ближе. Разница прыгнула, потом встала на «0.027 с» и замерла. Система приняла это как норму и отметила зелёным. Он сделал скрин, не зная ещё, пригодится ли. Скорее всего – нет. Но если пригодится, потом будет поздно вспоминать. Он сохранил и на внешний диск, небольшой серый прямоугольник с тёплым корпусом. Щёлк – и файл лёг туда, где лежали другие «мелочи».
Расписание испытаний открылось отдельным окном. Утро – калибровка по эталонной цели. Днём – короткий вылет с минимальной РЭБ. Вечером – резерв. «АРЕС: режим помощника» – приписка мелким шрифтом, та, что всегда вызывала раздражение. Он не любил слово «помощник» в софте. Софт не помогает. Софт делает, что ему велят. Или то, на что настроили.
В соседнем окне мигнул статус подсистем. Диагнозов нет. Жёлтых зон нет. Подсистема предикции молчала. Дверь открылась бесшумно. Вошёл Петров, снял с шеи шарф, кинул на спинку стула.
– Добрался? – спросил он без приветствия.
– Добрался.
– Через полчаса – ангар. Громов уже там. Зайцев подтянется к разбору.
Марков кивнул. Петров не спросил ни про дорогу, ни про кофе, ни про вечер. И это было правильным.
Пока шли по коридору к лифту, Петров говорил про график и про «окно».
– Окно узкое, – сказал он. – Без самодеятельности. Режим помощника – и по листу.
Это звучало как бытовая инструкция, не как предупреждение. Так и должно быть.
Лифт остановился ниже, чем ожидалось – пол провалился сантиметров на пять и встал мягко. Они прошли к двери в ангар, показали пропуска и вошли внутрь. Воздух там был другой – плотный, с тонким металлическим послевкусием. Генератор работал, отдавая басом через бетон. Где-то под крышей летучая мышь чертила невидимые круги; на секунду показалось, что эта тень – отметка на экране, ускользнувшая от фильтра.
Дрон висел под потолком на стропах, как рыбина, которую ещё не решили – пустить в дело или повесить на стену. Техники, не поднимая глаз, проверяли разъёмы. Громов стоял чуть в стороне, опираясь ладонью о край стола с планшетом. Перед тем как надеть гарнитуру, он прикоснулся к её амбушюру и дважды коротко стукнул по пластику ногтем – как тест микрофона без звука. Не ритуал – привычка. На экране рядом с ним был открыт не общий «красивый» вид, а сырые числа: скорости, углы, время. Он смотрел туда, где картинка ещё не соединена в историю.
– По плану маршрут без фокусов, – сказал Петров. – Проверяем коридор, закрепляем параметры. Всё по листу.
– Принял, – Громов кивнул, усмехаться не стал. Лицо спокойное, взгляд чистый, как у человека, который всегда слышит метку времени раньше, чем голос.
Марков разложил бумаги на металлической поверхности стола. Пальцы чуть прилипли к холодной стали. Открыл ноутбук, поднял интерфейс наблюдения. АРЕС отображался отдельным блоком – статус «готов», зелёный свет, активные каналы подсветились тонкими пиктограммами. Перечень алгоритмов подал короткий список: фильтрация – в норме, классификация – в норме, предикция – пусто.
Первый прогон делали на стенде. Эталонная цель прошла по экрану ровно так, как должна: вход в сектор, удержание курса, выход. Марков переводил взгляд с одной панели на другую, ловя минимальные провалы в частоте кадров, миллисекундные дрожания. Всё было в пределах. Он отметил едва заметную сдвижку подписей по времени на соседних окнах – на двадцать с чем-то миллисекунд – и отметил же: то, что уже видел утром.
– Переходим в коридор, – сказал Петров.
Зал, где шёл прогон, был шире, звук – с эхо. На стене – карта сектора, линии изолиний, подписи, которые никто не читает, потому что все помнят. Оператор у пульта поднял глаза, коротко кивнул. Громов надел гарнитуру, на секунду прикрыл левое ухо ладонью – отсёк всё лишнее – и посмотрел на экран сырых данных ещё раз, как на исходный документ.
Когда цель вошла в сектор, зелёная точка появилась там, где должна. Ещё одна – на долю градуса правее. Марков едва заметил – отсюда не увидишь, если не знаешь, что искать. Вторая отметка мигнула и пропала, как пузырёк воздуха под плёнкой. На панели АРЕС вспыхнула строка: «объединение треков», и погасла. Предупреждения не было. Вообще не было – даже мягкого серого намёка, который разрабатывали, чтобы не пугать никого лишнего.
– Видел? – спросил он тихо, не отвлекаясь от монитора.
– Что? – Петров не отводил взгляд от общей картины.
– Ничего, – сказал Марков. Он уже знал, что вернётся к этому в серверной.
Остальной прогон прошёл без сюрпризов. Имитация порыва ветра, короткий провал канала на ровно одну секунду – «как в паспорте», сказал кто-то у стены – и снова всё в пределах. Голос Громова в гарнитуре был ровным, без усилий, как если бы он разговаривал с комнатой. Он не любил заполнять тишину – говорил только отмеренное.
На выходе из ангара влажный воздух тянулся следом, как запах, который не сразу отстаёт. Петров говорил что-то про график, про визит на следующей неделе. Марков слушал половиной уха. В голове шёл другой процесс: как именно алгоритм принял решение, что два трека – это один? Где стоял порог? И на основании какой истории данных? Документация говорила об одном. Экран – о другом.
В комнате он сел и открыл логи. Ленты побежали ровно, будто кто-то разметил их линейкой. Он прокрутил до нужного момента. Там, где появлялась вторая отметка, запись о «слиянии» стояла на кадр раньше. Предиктор сообщил о действии прежде, чем во входном потоке «родилась» вторая отметка. Разница – двадцать семь миллисекунд. Та же цифра. Она повторилась с таким спокойствием, как будто её так и задумали.
Он остановил ленту, отмотал на пять секунд вверх, запустил снова. То же. Ещё раз. Та же последовательность. Он сделал снимки экрана, сохранил копию лога на внешний диск. В углу монитора на миг вспыхнуло «Доступ ограничен». Он кликнул – сообщение исчезло, будто не включалось. Он не стал спорить с интерфейсом. Он просто записал это – сначала в файл, потом в голову.
Папка легла на стол без слов. Тот же плотный картон с привычным запахом типографской краски.
– На подпись, – сказал голос у двери и ушёл.
Он не открыл. Сначала – логи. Потом – бумага.
Он пробежал глазами через блок самодиагностики. Подписи были аккуратные, как будто их ставила одна невидимая рука. «NOFAULT». «NOFAULT». «NOFAULT». Он сверил время самодиагностики с временами завершения тестов. И увидел, что в одном месте подпись пришла раньше. На один такт. Мелочь, если не привык считать такты. Если привык – это другой порядок вещей.
Он вынул листок из кармана – клочок с цифрами, куда отметил утренние 0.027. Положил рядом с монитором. Сравнил. Слишком хорошо совпадало, чтобы быть совпадением. Или, наоборот, слишком ровно, чтобы пытаться докопаться до «почему» прямо сейчас.
Вентиляция в потолке на секунду остановилась и снова пошла. Эти паузы были ничем. Если считать, что они – ничто.
Он закрыл логи, открыл ещё раз, уже через другой инструмент – без графики, чистый текст. Когда он читал голые строки, ему было легче. Из текста исчезало всё, что пытается быть умнее, чем есть. Метки времени снова выстроились, как шпалы: ровно, повторяясь. И одна из них – «NOFAULT» – приходила на миг раньше последней команды теста. Как если бы кто-то решил, что конец уже известен, и не стал ждать.
Снаружи ветер гонял по плитам воды узкие тени. Серый свет не менялся. Здесь время было другим: оно мерилось циклами, кадрами, кадрами в кадрах. Он смотрел на экран и поймал себя на том, что улыбается. Неправильно. Он это знал. Но улыбка всё равно осталась на лице – как отметка на экране, которая не должна была появиться. Он коснулся пальцем угла монитора, убрал руку, записал ещё одну строчку в файл с сегодняшними мелочами. Потом взял папку. Бумага поддалась с сухим шорохом. Он подписал там, где нужно было подписать, и ещё раз взглянул на время в углу: 0.027 с.
Эта цифра, казалось, уже жила здесь. В этой комнате, в этом утре. В этих системах, которые любили тишину чуть больше, чем положено.
Глава 2
Утро началось с холода, который держался внутри, как будто здание не успело прогреться за ночь. В ангаре пол отдавал вибрацией от генератора, через подошвы в кости – низкий, равномерный бас. Пахло сыростью, металлом и чем-то резиновым – то ли от шлангов, то ли от изоляции. Кофе из автомата оставлял сухой привкус, не столько вкус, сколько функцию.
Гул усиливался, когда открывали ворота. Щели в резиновых уплотнителях свистели, и в этот свист на секунду врезался другой – память принесла обрывок цеха: фонарь качается, стенд молчит, а где-то под потолком тот самый тонкий звук, который был первым признаком, что всё уже не по плану. Он отогнал картинку, как отгоняют блик на мониторе: невелика помеха, но мешает смотреть.
Перед началом он прошёл короткий лист настройки. На экране – утилита калибровки сектора. Маркеры по азимуту, по углу места, шаг, задержка отклика при переходе через границы. Всё спокойное, без сюрпризов. Уловимые расхождения по времени между окнами он отметил, но не удивился: утро только начиналось, а цифры редко двадцать четыре часа вели себя идеально одинаково.
Петров стоял с блокнотом, что-то помечал, не отрываясь. Когда Громов подошёл к столу, бросил короткий взгляд на сырые данные, коснулся амбушюра гарнитуры и дважды постучал по пластиковой чашке ногтем – проверка без участия системы. Жест не был адресом. Это была его собственная точка входа в работу.
– По дорожке идём так же, – сказал Петров. – Начнём с короткой. Дальше – по факту. Без импровизации.
Они встали каждый на своё место. Оператор у пульта поднял ладонь и опустил – как флажок, который никто не видит. По внутренней связи прошла сухая последовательность команд – готовность, питание, канал связи. В динамике шуршал воздух, как если бы микрофон задели рукавом.
Эталонную цель подняли без зрелища. На экране она появилась как точка, за ней – подпись скорости и курса, всё в пределах ГОСТа, который здесь никто вслух не называл. Первые минуты были ровные. Марков отслеживал кадры, выискивая в них не предательскую ошибку, а те самые «мелочи», из которых потом складывается вывод. Колебание частоты выводов – в пределах. Плавность фильтра – та, что заявлена. АРЕС молчал там, где должен, и докладывал там, где положено.
Громов говорил мало. Короткие фразы, без прилагательных, без «кажется» и «наверное». Когда он брал голосом на себя что-то, это слышалось и по воздуху, и по тому, как менялся рисунок тишины между словами.
– Заходим в коридор, – сказал Петров.
На стене светился сектор, выверенный по линиям, как учебная картинка, которую ставят первому курсу. Марков переводил взгляд с общей проекции на сырые числа. Не книжные «скорость» и «угол», а те, что были выгружены в диагностический поток: дельты между кадрами, джиттер в миллисекундах, метки «стабильно/нет». Он не искал ничего конкретного. Он давал глазам привыкнуть.
Когда цель вошла в сектор, точка появилась там, где должна. Почти одновременно – в правом нижнем углу – лёгкая вспышка вторичной, на долю градуса правее. Если бы не знать, что смотреть, можно было бы не увидеть. Вторая отметка мигнула и исчезла так тихо, что не оставила следа в общей картине. На панели АРЕС на долю секунды вспыхнула строка «слияние треков» – и погасла. Никакого предупреждения. Даже серой плашки, которую они обсуждали ещё в институте: «не пугать, но запомнить».
– Есть, – сказал Громов в гарнитуру, не меняя тона. – Держу.
Он чуть поправил курс, словно выравнивал линейку на столе.
Марков отметил момент. Пальцы сами нашли сочетание клавиш, которое разворачивало дополнительный лог. В динамике пошёл треск – канал напомнил, что воздух влажный и что сегодня любой провод может сказать своё слово. Свист в воротах усилился. Секунда – и пропал канал телеметрии. Ровно секунда. Петров поднял ладонь и провёл по воздуху вниз – «не тормозим». В таких местах можно сбить ритм и переписать себе память на потом, где будет казаться, что всё было сложно. А сейчас всё было просто: минус одна секунда, минус один канал, всё остальное – по плану.
Канал вернулся так же сухо, как ушёл. В этот момент на экране снова на миг треснула картинка – маленькое двойное эхо. АРЕС объединил отметки до того, как второй пик полностью сформировался. «Слияние» вспыхнуло и исчезло. Громов молчал. Его ладонь двинулась на долю сантиметра – как если бы он положил невидимую тяжесть на правую сторону шкалы.
– Фиксируем, – сказал Петров негромко.
Эта фраза значила «идём дальше».
Остальная часть прогона прошла чисто. Порыв – отмечен, компенсация – штатная. По диаграмме заметно, что фильтр предпочитает сгладить редкий выброс, а не удержать «остроту» сигнала – согласно настройкам. Марков поймал взгляд Зайцева через стекло: тот стоял у двери и слушал в пол-уха. Кивка не было. Лицо – как у человека, который пришёл не мешать.
После остановки Марков первым делом выгрузил логи. Независимо от того, что показывала «красивая» панель, ему нужно было видеть тесный текст. Он взял флешку, проверил пустое имя, смонтировал, сохранил. На всякий случай – резервная копия в сетевую папку, которая жила своей жизнью и редко выдавала сюрпризы.
Они вернулись в комнату. В коридоре пахло мокрой одеждой и чем-то сладким из столовой, что забивалось в вентиляцию и до полудня не уходило. Петров остался у переговорной, кому-то звонил, стоя лицом к стене. Марков прошёл к своему столу. Пружина в стуле снова щёлкнула. Когда она щёлкала чуть громче, чем нужно, это почему-то помогало собраться.
Он открыл файл лога. Строки шли ровно. Метки времени были как надо: аккуратно увеличивались, не пропуская тактов. В нужном месте – заметный «впад» канала. Так и записано: «telemetry: drop 1000 ms». Ровно, без лишних слов. Ещё через пару десятков строк – «trk: merge». Параметры в скобках. Он остановил ленту, вернулся на десять секунд, включил построчный просмотр.
Запись называлась не так, как в документации. Не «fuse_simple», не «fuse_weighted». Внутри стояло: «policy=17c». Он прочитал дважды. Для верности – ещё раз.
Ни в одной из презентаций, которые он помнил, такой метки не было. В утверждённом перечне политик слияния числились другие: базовая, расширенная, участок для «грязной погоды». Они были пронумерованы по-своему, но буквы там не стояло. И уж точно не «c».
Он покрутил колесо мыши. Рядом со строкой висели параметры. «theta=0.61». «window=2». «early_ok=true». Этих слов не должно быть в тестовой сборке. В документации для полигона это место выглядело иначе: «слияние при условии достаточной близости по азимуту, скорости и одной дополнительной метрике уверенности». Без чисел. Без флажка «раньше можно».
Он сделал снимок экрана, сохранил отдельным файлом. Потом открыл рабочую вики. Поиском пробежался по словам «17c», «theta», «early_ok». Ничего. Поисковик предложил «имеете в виду 17?». Он не имел в виду «17». Он имел в виду букву рядом с номером, которой не должно быть.
Зайцев заглянул в комнату, постучал по косяку фалангой пальца – сухо, как по дереву. Этот звук занял своё место среди сегодняшних. Марков не поднял головы – не из упрямства, просто строка ещё шла и было рано отвлекаться.
Он вернулся к моменту, где точка «двоится». До «слияния» предиктор вывел внутреннюю оценку – короткий числовой хвост без подписи. Раньше он эти хвосты проскакивал глазами. Сейчас задержал взгляд. Там был ритм, уже знакомый по другим записям: значения шли не как живой сигнал, а как будто по нотам. Два кадра – нарастание, один – спад, дальше – ровная линия и резкое «слияние». «window=2». Ровно два кадра. Он даже не записал – просто отметил этой строчке место в голове.
В коридоре скрипнули двери. Ворвался тонкий свист – кто-то снова открыл одну из створок в ангар. Этот свист был как курсив: выделял мысль, но не менял смысл.
– Как? – Петров стоял у двери, не заходя.
– По данным – чисто, – сказал Марков. – Кроме одного.
– Что?
– «merge» с политикой, которой нет в документации. «17c».
Петров не изменился в лице.
– Разберёмся на разборе. Сейчас не ломаем темп.
Марков кивнул. Это был не отказ. Это был способ не превращать наблюдение в событие раньше времени. Он снова посмотрел на строку с «17c» и положил рядом с клавиатурой листок с короткими пометками: время, «drop 1000 ms», «двойная отметка, правее на долю», «слияние до появления полной формы», «policy=17c», «theta=0.61, window=2, early_ok=true».
Он вернулся к общей картинке на «красивом» экране. Ничего подозрительного. Если взять эту панель как единственный источник истины, сегодняшний день прошёл штатно. В этом и была её задача: пройти штатно. Работа Маркова была другой.
Он поднялся, чтобы размяться, прошёлся до окна и обратно. За стеклом по плитам тянулись узкие ленты воды – ветер толкал их боком, и они ломались на стыках. Вентиляция в потолке поменяла тон, как это иногда случается к полудню: будто система вспомнила о другой скорости.
Вернувшись к столу, он открыл последний файл – внутреннюю справку, которую ему прислали перед приездом. Там была короткая таблица с политиками слияния: пять штук, каждая с картинками, которые понравились бы «высоким». Ни одной буквы рядом с цифрами. Он закрыл справку. Открыл ещё один инструмент – монитор потоков. Поставил метку времени на тот кадр, где «слияние» случилось раньше, чем появилось второе эхо. И поймал себя на том, что ищет не «кто включил», а «когда решено, что включится».
Он не нашёл там подписи человека. Он нашёл там подпись решения. Короткая строка, которая гласила, что если оценка уверенности «выше порога» и «окно предсказания равно двум», то система имеет право объединить треки, не дожидаясь полного формирования второго. Такие правила пишут люди. Но не всегда эти люди потом вспоминают, что именно написали, и где это лежит.
Папка на краю стола снова напомнила о себе – он подвинул её локтем. Бумага не любила ждать. Логи – любили.
Он сделал ещё одну вещь, которую делал редко. Скопировал из лога несколько строк и положил их в отдельный файл – тот, где он хранил «паттерны». Не потому, что это было доказательством. Потому что через неделю, когда текстов станет слишком много, глаз может перестать видеть повторяющееся. А память – всегда пытается быть добрее, чем надо.
Гул в ангаре просел на тон. Где-то закрыли один из источников. Свист в воротах стих. В комнате стало слышно, как вентилятор в системном блоке набирает обороты – коротко и сдержанно, как вздох.
Он посмотрел на экран ещё раз. Строка с «policy=17c» стояла посреди ровного поля обычных событий. Она не выглядела особенной. Ни один цвет не выделял её среди других. Но цифры рядом были не теми, что должны быть «для полигона». И в оглавлении, которое знали все, этой политики не существовало. Он искал её название в голове – как ищут знакомое лицо в толпе – и не находил.
Значит, её не должно быть.
Но она была.
Глава 3
Переговорная была как коробка для звука: матовые стёкла, мягкий потолочный свет, стол, который не отражал, а поглощал. Маркер писал сухо, без жира, и всё равно пахло спиртом – отголосок лабораторий, где на столах стояли не ноутбуки, а катушки и осциллографы. Проектор гудел ровно и серебрил доску – как тонкий иней.
На шапке распечатанного протокола висела аккуратная строка: АО «ЗАСЛОН». Под ней – дата, время, список присутствующих. Чужие голоса были здесь уместны: в комнате, где обычно говорили «свои», они звучали как другой акцент, не мешая делу, но напоминая, что снаружи есть правила, не написанные их почерком.
– Коротко по утру, – сказал Петров, щёлкнул колпачком, провёл на доске линию по времени. – Эталон – штатно. Коридор – как в плане. Порыв – отработан.
Марков сидел ближе к проектору. На его экране был не «красивый» вид, а лента чисел. Сырые. Без подписи цвета. Он включил нужный отрезок. Строки побежали в такт дыханию.
– Здесь, – он коснулся тачпада, – перед сливанием. Вторая отметка на долю градуса правее. Появляется, не успевает сформироваться полностью, АРЕС объединяет.
Петров кивнул. Он держал маркер как указку, не как оружие.
– Без предупреждения?
– Без.
Громов был у стены, прислонившись плечом к матовому стеклу. Гарнитуры на нём не было, ладонь – свободна. Когда Марков показал «двойник», Громов чуть наклонился и прищурился не на яркую точку, а на цифры справа – те, что в соседней панели, с меньшим шрифтом. Он всегда смотрел туда, где картинка ещё не стала картинкой.
Дверь открылась, вошёл Зайцев. Без папок. Застегнул куртку на один ход выше, чем было нужно в помещении, сел в торце и положил ладони на стол – не переплетая пальцев, а параллельно. Помолчал. Потом спросил:
– Всё по регламенту?
Петров не посмотрел на него. Он посмотрел на Маркова.
– По факту – да, – сказал Марков. – По форме – есть вопросы к политике слияния.
– К форме – позже, – тихо сказал Петров. – Сейчас – матчасть.
Он подвинулся к доске. Нарисовал две кривые – первичный и вторичный трек. Подписал «азимут», «скорость», «дельта t». Повернулся:
– Гони без АРЕС.
Марков выключил блок предиктора и повторил отрезок на стенде, который сохранял сырые измерения. Сразу стало заметно, как линия скорости «дышит» – три–четыре процента гуляния в допуске. Картинка перестала быть гладкой. Это не было плохо. Это было честно.
– С АРЕСом, – сказал Петров.
Он вернул алгоритм в цепочку. Линия стала ровной, как транспортир. Идеальной ровности на полигоне не бывает. Но здесь была.
– Слишком красиво, – сказал кто-то у окна вполголоса.
– Красота нас не волнует, – отрезал Петров, не грубо. – Волнует соответствие.
Зайцев не двинулся. Его лицо ничем не выдало отношение. Он спросил ещё один короткий вопрос:
– Документально?
– Документально – режим помощника, – ответил Петров. – По плану. По листу. – И, словно отметив для «внешних», добавил: – В рамках регламента АО «ЗАСЛОН».
Маркер прошуршал по доске. Петров нарисовал окно слияния – «окно-2» – и заштриховал два ранних кадра.
– Если у нас ранняя уверенность падает выше порога, – сказал он, – мы имеем право склеить, не дожидаясь полной формы. Но порог – фиксированный. И название – фиксированное. В документации это «расширенная». Без букв.
– А у нас, – сказал тихо Марков, – в логе «полиси семнадцать-цэ». Порог – шестьдесят одна сотая. И допуск на раннее – «истина».
Он не спорил. Он называл то, что видел.
Петров кивнул. Повернулся к Громову:
– В полёте – что-то чувствовалось?
– Ровнее, чем бывает в такую влажность, – сказал Громов. – Секундный провал канал отработал без ощутимого хвоста. Руки – не понадобились.
Он сказал «ровнее», не «лучше». И это слово попало куда надо.
– Давай ещё по ADS-B, – сказал Петров.
Они прогнали симулятор – вторичный канал, «самолётный» ответчик. Синхронизировали метки. Без АРЕС кривые «шили» друг с другом, иногда расшивались, потом снова сходились – как это и бывает. С АРЕС – совпали до последнего знака после запятой в удобном интерфейсе, где дробные части прятались за красивой плашкой.
– Так не бывает, – сказал Марков больше себе, чем вслух. – На полигоне так не бывает. Петров сдержанно кивнул. Он не любил фразы «так не бывает» – они растягивают обсуждение до философии. Он любил факты.
– Фиксируем: с АРЕС совпадение избыточно стабильное. Без АРЕС – гуляние в допуске. Предупреждения – нет. – Он поставил точку. – Дальше – аудит.
Он снял колпачок, положил маркер на край стола рядом с протоколом, где в шапке всё так же стояло «АО “ЗАСЛОН”». Колпачок покатился и тихо упёрся в край бумаги.
Разговор свернули быстро. Зайцев поднялся, пожал плечами, как будто накинул на них что-то невидимое, и вышел первым. Громов задержался у двери. На секунду встретился взглядом с Марковым. Взгляд был без вопроса. Скорее – знак, что видел то же место, но со своей стороны.
Когда комната опустела, Марков выключил проектор и остался при своём экране. Он не любил смотреть на картинку, где всё идеально. Ему нужен был текст.
Он открыл цепочку сборок. Ночной прогон, триггер от расписания. Артефакты – чек-суммы, подписи. В колонке «комментарий» – нейтральное «минор апдейт параметров». Автор – сервисная учётка. Время – вполне нормальное. Никаких «минут вперёд» – это было бы слишком ярко для утра третьего дня.
Он провалился глубже – в состав пакета. Политики слияния лежали в отдельном каталоге. Их имена были знакомы, как фамилии в пропускном листе. И одно – нет. «policy_17c.bundle». Не файл настроек. Пакет. В этот момент взгляд поставил вокруг слова скобки, как на доске.
Он щёлкнул по нему. Содержимое не раскрылось – «нет прав». Он не удивился. Правильно, что нет. Неправильно – что файл здесь.
Он пошёл другим путём. Отпечатки. Контрольные суммы. Нашёл «хэш» в журнале сборки. Тот повторялся – раз, другой – за последнюю неделю. С неизменной подписью. Как повторяющаяся мелодия, которую слышишь сквозь шум.
Вики молчала. Поиск по «17c» дал ноль. Поиск по «окно» и «раньше» – выдал документ, где слово «раньше» стояло в контекстах, которые к ним не относились. В справочнике для полигона про ранний допуск не было и намёка.
Он открыл протокол испытаний. Перелистнул к разделу «алгоритмические конфигурации». Там были таблички, графики, подписи. И рядом – пустота, где хотелось бы увидеть ещё один столбец: номер политики, контрольная сумма, путь. Этого столбца не существовало. Его как будто и не задумывали.
Пружина стула отщёлкнула и замерла. Вентиляция сменила тон на полтона ниже. В такие моменты казалось, что ещё чуть-чуть – и цифры сами скажут, что в них не так. Они не скажут. Их надо спрашивать правильно.
Он вернулся к логу. Строка с «merge» и «policy=17c» стояла, как заголовок, который притворился текстом. Рядом – «theta=0.61», «window=2», «early_ok=true». Ничего лишнего. Ничего, за что можно зацепить зубами прямо сейчас и не сломать.
Пальцы нашли сочетание клавиш на автопилоте – выгрузка подпроцесса слияния. В вытяжке текстов мелькнула короткая фраза из внутренней диагностики: «policy loaded: 17c». Без даты, без автора, без ветки. Только факт.
Он потянулся к полке, где стояла тонкая серо-зелёная папка «Интеграция – общий». Достал вложенную записку с маршрутом CI. На схеме было аккуратно нарисовано, где политики подхватываются из «утверждённого перечня». Стрелка шла в обход каталога, где лежал «bundle». На схеме путь был один. В жизни – два.
Он уже знал, что покажет Петрову вечером: не обсуждение «почему так нельзя», а два скриншота, две стрелки и одну подпись: «отклонение от утверждённого маршрута». Без прилагательных.
Дверь скрипнула. Вошёл Петров.
– Как?
– Нашёл артефакт, – сказал Марков. – «policy_17c.bundle». В пакете сборки. Не в перечне. Права – закрыты.
Петров кивнул медленно.
– Утверждённых – пять, – сказал он и улыбнулся краем губ. – Буквы у нас не водятся.
– Здесь – водится, – сказал Марков.
Петров провёл пальцем по кромке стола – жест, который у него заменял «я думаю». Потом сказал:
– На вечер – короткий аудит с безопасниками. Зайцев будет. Подготовь так, чтобы без споров. Факты. И… – он бросил взгляд на шапку протокола с «АО “ЗАСЛОН”» – …без лишних слов.
– Понял.
Когда Петров ушёл, Марков ещё раз посмотрел на экран. На синей полосе времени маленькая «клякса» – секунда выпадения канала – казалась естественной неровностью. На серых строках рядом слова были ровные. И среди них – одно слово, которого не должно было быть. Оно не делало текст красивее. Оно делало его другим.
