Завдання/Оцінювання
Зоря. Оцінювання
Як конкурс ставить бали, відбирає фіналістів і визначає призову п'ятірку. Опубліковано російською та українською. Основний текст після публікації не змінюється, уточнення йдуть реєстром доповнень (розділ 16). Строки - календар, правила гри - частина 2.
Зміст
- Коротко
- Сто балів
- Три списки
- Пакет і частки
- Груповий етап
- Другий етап і Випробування
- Турнір 45
- Код 25
- Штаб 20
- Розбір 10
- Підсумок, дод. бали, призи, аудит
- Голосування
- Чесна гра
- Апеляції
- Рефері
- Незмінність, доповнення, зсув розкладу
Додатки: А. Як перевірити свою групу, Б. Приклад розрахунку.
1Коротко
- Сто балів: турнір 45, код 25, штаб 20, розбір 10. Кожен критерій - драбина з опублікованими порогами.
- 100 - виняткова робота: жодна наша перевірка в жодній партії сезону не знайшла жодного зауваження. Ми не чекаємо, що її хтось набере. Місця вирішує сума, а не близькість до сотні.
- Усі зареєстровані, хто пройшов допуск, грають груповий етап: групи по 9 (іноді по 7), кожна пара в групі зустрічається рівно один раз. Переможець групи виходить у другий етап, і тільки він отримує оцінку зі 100.
- Другий етап - три вечори. За його підсумками п'ятірка грає Випробування Доглядача.
- Призова п'ятірка - п'ять місць за сумою 100; призи й розподіл за місцями оголошує організатор окремо. Рівну суму вирішують дод. бали.
- Бот пишеться на TypeScript або JavaScript і виконується Node.js, як шаблон частини 2.
- Людина в партію не втручається, грає код. ШІ-інструменти дозволені.
2Сто балів
Осі й мірки:
| Вісь | Балів | Що міряється | Чим |
|---|---|---|---|
| Турнір | 45 | Частки в партіях другого етапу і Випробування | Вузол за журналами партій |
| Код | 25 | Надійність бота в сезоні, провід під провокацією, канал і дедлайн, тести, дефекти коду | Телеметрія вузла, провокатор, мутаційне тестування, аналізатор |
| Штаб | 20 | Можливості штабу на еталонному записі | Драйвер за оголошеними якорями |
| Розбір | 10 | Письмовий розбір рішення і відповідь щодо епізоду своєї партії | Звірка тверджень із кодом і журналами |
Оцінка зі 100 ставиться тільки учасникам другого етапу - переможцям груп і тим, кого до них добрали (5.10). Решті - розділ 11.6.
Кожен критерій - драбина: мірка, щаблі та їхні пороги. Бал за критерій - щабель, на який вийшло виміряне значення. Експертної добавки поверх щабля немає.
Верхній щабель кожного критерію означає "жодного зауваження": нуль партій із дефектом, усі рівні провокатора чисті, усі мутанти спіймані, жодної підтвердженої знахідки в коді, усі задачі штабу в бюджеті, жодного спростованого твердження розбору. Верхній щабель якогось критерію може не взяти ніхто.
Міряється весь сезон, а не одна партія: в учасника другого етапу 18-21 залікова партія (груповий етап і три вечори) плюс прогони фінальної здачі.
Аркуш оцінки. У кабінеті для кожного критерію видно виміряне значення, щабель, поріг наступного щабля і посилання, з яких складено значення: номери партій, місця в коді, пункти розбору. Апеляція сперечається з конкретним рядком аркуша (розділ 14).
Дробові бали є тільки в турніру: крок 0.5, округлення вниз.
3Три списки
У сезоні три відбори, і це різні списки:
| Список | Хто в ньому | Що дає |
|---|---|---|
| Учасники другого етапу | Переможці груп (5.8), за потреби добрані (5.10) | Другий етап і оцінку зі 100 |
| П'ятірка Випробування | Топ-5 другого етапу за сумою часток (6.5) | Випробування і його 9 балів |
| Призова п'ятірка | Топ-5 другого етапу за сумою 100 (11.3) | Призи |
Той, хто не потрапив на Випробування, отримує за нього 0 із 9; його стеля - 91. Він може увійти до призової п'ятірки, якщо код, штаб і розбір у нього сильніші. Той, хто потрапив на Випробування, може до неї не увійти.
4Пакет і частки
Залікова одиниця - пакет: три партії однієї долини, у яких троє учасників пересідають вершинами A, B, C. Пересадка - латинський квадрат порядку 3: кожен займає кожну вершину рівно один раз (правила, 25.1).
За місця в партії - частки 3, 2 і 1. Рахунок пакета - сума часток трьох партій, від 0 до 9. Рівність у партії, повна рівність і глуха вершина (бот не присягнув - частка 0) - правила, 24.3-24.6.
Бот, що замовк, дограє партію наказом і отримує фактичне місце (правила, розділ 23). Перехід на наказ місця не змінює; в оцінці коду така партія - партія з дефектом (8.3).
Збій на боці організаторів зупиняє пакет; трійка грає новий пакет із новим жеребом цілком. Неповний пакет у залік не йде (правила, 25.6).
5Груповий етап
До групового етапу допускається учасник, який зареєструвався в просвіт, чий доступ до репозиторію підтверджено до строку з календаря і чий коміт пройшов передстартовий прогін (частина 4) з однією перездачею.
Мова бота. Бот - код на TypeScript або JavaScript, який виконує Node.js 24 або новіший, як шаблон частини 2. Передстартовий прогін перевіряє це машинно: команда запуску бота (поле zaria.bot у package.json каталогу бота) запускає node з файлом із каталогу бота, а вихідний код бота в репозиторії - файли TypeScript або JavaScript, інших мов у каталозі бота немає. Не виконано - прогін провалено з причиною "мова бота", і коміт не прийнято, як за будь-якого провалу прогону: без прийнятого коміту учасника не допускають до групового етапу (5.1), у вечорі грає останній прийнятий коміт (6.3). Обхід перевірки - дочірній процес або WebAssembly з кодом бота іншою мовою - порушення за драбиною 13.7.
Група влаштована як система трійок Штейнера S(2,3,v): кожен пакет - трійка учасників групи, і кожна пара учасників групи зустрічається рівно в одному пакеті. Така система з v учасників існує тоді й тільки тоді, коли v = 1 або 3 за модулем 6 (теорема Кіркмана, 1847). У ній v(v-1)/6 пакетів, і кожен учасник грає (v-1)/2 з них. Суперники всередині групи в усіх ті самі, а слабкий чи вибулий учасник дістається кожному рівно один раз.
Розміри груп - 9 і 7. Дев'ятка: 12 пакетів, по 4 на учасника; трійки будуються конструкцією Боуза (1939), для v = 9 це афінна площина AG(2,3). Сімка: 7 пакетів, по 3 на учасника; трійки - розгортка базового блоку {0, 1, 3} за модулем 7 (метод різниць, площина Фано). Для v = 1 mod 6 існування в загальному вигляді довів Сколем (1958); нашу сімку виписано явно, і вона перевіряється перебором. Усі трійки - додаток А.
Розбиття. Кількість учасників N ділиться на дев'ятки й сімки так, щоб груп розміру 7 було якомога менше; сума розмірів мусить дорівнювати N. Дев'ятки йдуть першими. За N = 482 це 52 дев'ятки і 2 сімки: 54 групи, 638 пакетів.
Жереб, . Сіль жеребкування будується за схемою commit-reveal із публічним маяком випадковості drand (мережа quicknet, додаток А.0): публікується хеш секрету організаторів; сіль - SHA-256 від секрету і значення маяка drand на заздалегідь оголошений раунд після просвіту; на жеребкуванні секрет розкривається. Із солі виводиться перестановка всіх зареєстрованих (додаток А) і публікується разом із вихідним кодом планувальника @zoria/tournament. Секрет обрано до того, як значення маяка стало відомим будь-кому, тому підібрати сіль під склад груп неможливо.
Нарізка груп, . З перестановки викреслюються ті, хто не пройшов допуск (5.1); порядок решти не змінюється, удруге список не тасується. Список ріжеться підряд за розбиттям 5.4: перші 9 - група 1, наступні 9 - група 2 і так далі, сімки в кінці. Порядок усередині групи - номери точок системи трійок.
Розклад. Кожна група грає цілком на одній доріжці конвеєра, пакет за пакетом; слот пакета - 40 хвилин. Блок дев'ятки - близько 8 годин, сімки - близько 4.7 години; усі пакети учасника лежать усередині блоку його групи. Розклад публікується під час нарізки груп, кожен бачить час своїх пакетів у кабінеті й отримує сповіщення: під час публікації розкладу і за годину до блоку. Присутність не потрібна: грає код.
Таблиця групи. Місце - за сумою часток усіх пакетів учасника. Рівність вирішується по черзі:
- сума часток;
- особиста зустріч: кожна пара зустрічалася рівно один раз, тому для двох порівнюються їхні частки в спільному пакеті, для трьох і більше - мінітаблиця за пакетами, де зійшлися двоє й більше з тих, хто сперечається;
- сума за пакетами групи трьох щаблів рівності партії: голки, що горять, заряд, голки у володінні (правила, 24.3);
- жереб: SHA-256 від рядка
zaria-tournament-lot-v1, нульового байта, солі, нульового байта і логіна; вище той, у кого шістнадцятковий запис менший.
З кожної групи виходить одне перше місце. Таблиця публікується під час етапу, той, хто вийшов, - тільки коли групу дограно.
Збої під час етапу. Бот упав або замовк після присяги - слот веде наказ, місце за фактом (4.3). Бот не присягнув - частка 0 за партію (правила, 24.6). Пакет дограється, група не переграється. Пакет, зірваний нашим збоєм, переграється новим жеребом у резервне вікно; не зіграний і там виключається з таблиці в усіх трьох.
Добір. Якщо кількість тих, хто вийшов, не ділиться на 3, до них додаються найкращі другі місця груп за середньою часткою за пакет, у разі рівності - за жеребом 5.8, доки кількість не стане кратною 3.
Груповий етап балів зі 100 не дає: він відбирає учасників другого етапу. Групові таблиці між собою непорівнянні - у груп різні суперники і різна кількість пакетів.
6Другий етап і Випробування
Другий етап - три вечори. У кожному вечорі кожен учасник грає один пакет. Підсумок етапу - сума часток P за трьома пакетами, дев'ятьма партіями.
Склади. Учасники шикуються за спаданням: перед першим вечором - середньої частки за пакет групового етапу, перед наступними - суми часток другого етапу, у разі рівності - середньої частки групового етапу, далі - жеребом 5.8. Список ріжеться підряд на трійки. Якщо в трійці є пара, що вже грала в другому етапі, її останній учасник міняється місцями з першим учасником наступної трійки; якщо повтор лишається, трійка грає як є (швейцарська система). Склади вечора публікуються до 21:00 напередодні й апеляцією не переглядаються.
Коміт вечора. Для кожного вечора фіксується коміт о 03:00 дня вечора, передстартовий прогін іде одразу; одна перездача - до 09:00. Коміт, що не пройшов прогін, не грає, замість нього грає останній прийнятий. Для першого вечора останній прийнятий - коміт групового етапу. Як фіксується коміт - частина 4.
Фінальна здача - коміт третього вечора. За ним оцінюються код, штаб і розбір.
П'ятірка Випробування - топ-5 за P. Рівність: більше часток 3 у другому етапі → більше хвилин зв'язку (рахунок, правила 24.2) в усіх партіях другого етапу → жереб 5.8. П'ятірка оголошується після вікна апеляцій третього вечора.
Випробування Доглядача. Кожен фіналіст грає серію з трьох партій один проти двох тіл Доглядача; тіла ті самі для всієї п'ятірки, креслень фіналістів Доглядач не читає. Порядок серій - зворотний місцю в п'ятірці.
Записи партій другого етапу закриті до кінця Випробування.
7Турнір 45
Вечори - 36 балів:
L = floor(36 * (a - 1)) / 2, не менше 0
a = P / g - середня частка за партію другого етапу
g - кількість залікових партій (9, якщо жоден пакет не знято збоєм)36 - тільки перше місце в усіх дев'яти партіях. Середній учасник другого етапу - 18. Перше місце замість останнього в одній партії з дев'яти коштує 4 бали. Пакет, знятий нашим збоєм (4.4), у g не входить.
Випробування - 9 балів, тільки п'ятірці:
F = 1.5 * (S - 3), не менше 0
S - сума часток фіналіста в серії з трьох партій, від 0 до 99 - три перші місця з трьох. Не фіналіст отримує 0.
Турнір = L + F. Обидві формули абсолютні: бал не залежить від чужих результатів, тільки від своїх часток. Приклад - додаток Б.
8Код 25
| Критерій | Балів | Драбина |
|---|---|---|
| К1 Надійність у сезоні | 7 | 7 мінус кількість партій із дефектом, не менше 0 |
| К2 Провід під провокацією | 6 | По 2 за кожен із трьох рівнів, пройдений без зауважень |
| К3 Канал і дедлайн | 4 | Пропущені такти 0-2, відхилені команди 0-2 |
| К4 Тести | 4 | Частка спійманих мутантів: 100 % - 4, від 80 % - 3, від 60 % - 2, від 40 % - 1 |
| К5 Дефекти коду | 4 | Підтверджених знахідок: 0 - 4, 1-2 - 3, 3-5 - 2, 6-9 - 1, 10 і більше - 0 |
Секрети. На прийманні дзеркала репозиторію працює наш сканер витоків: закритий список родів секретів (ключі, токени випускачів, паролі в коді) по дереву коміту і всій його історії. Коміт зі знайденим секретом не приймається - це провал передстартового прогону.
К1 Надійність у сезоні. Партія з дефектом - залікова партія групового етапу чи вечора, у якій сталося хоча б одне:
- бот не присягнув (глуха вершина, правила 24.6);
- процес бота впав або його контейнер зупинився;
- наказ перехопив слот через мовчання бота (правила, 23.2);
- вузол записав аномалію проводу: кадр не за схемою від того, хто присягнув, другий
helloна тому самому сокеті, відповідь із номером такту, який боту не надсилався, крива печатка повернення при живій сесії (протокол, 9.2; лічильникиgarbage,phantom,badResume).
Партія, зірвана нашим збоєм, не враховується.
К2 Провід під провокацією. Після фінальної здачі бот грає пакет на вузлі-провокаторі на кожному з трьох рівнів:
- дублі кадрів спостереження і часті планові ротації сесії;
- те саме плюс обриви з'єднання посеред партії з поверненням за печаткою;
- те саме плюс зупинка процесу бота посеред першої і другої партій пакета.
Рівень пройдено, якщо в його пакеті немає жодної аномалії 8.3, бот не пропустив жодного такту, крім тактів самого обриву і тактів після зупинки процесу, і після кожної зупинки присягнув у наступній партії пакета. Точні параметри рівнів і команда для локального прогону - доповненням не пізніше .
К3 Канал і дедлайн, за всіма заліковими партіями сезону:
| Метрика | 2 бали | 1 бал |
|---|---|---|
| Пропущені такти: відповідь не прийшла в дедлайн такту | 0 | не більше 0.1 % тактів сезону |
| Відхилені команди: воротар відмовив, будь-який код відмови | 0 | не більше 0.5 % поданих команд |
Такти, у які вузол за своїм записом не надіслав кадр, не враховуються.
К4 Тести. Мутаційне тестування (mutation testing): у код бота вносяться мутанти - по одній навмисній поломці на копію коду (перевернута умова, зсунута межа, пропущений виклик, підмінена константа тощо) в коді рішень і проводу. На кожній копії в нас запускаються тести учасника командою npm test з каталогу бота, без мережі, не довше 10 хвилин. Мутанта спіймано, якщо хоча б один тест упав. Бал - за часткою спійманих (mutation score). На коді без мутантів тести мусять проходити; не проходять або не запускаються - К4 = 0. Мутантів не менше 20.
К5 Дефекти коду. Статичний аналіз коду бота і штабу шукає знахідки опублікованих класів:
floating-promise- проміс, якого ніхто не чекає й не обробляє;unreleased-resource- ресурс (сокет, таймер, підписка, файл) не звільняється на всіх шляхах;empty-catch,error-suppression- помилку спіймано і втрачено;partial-state-on-throw- виняток лишає стан наполовину зміненим;escaping-async-work- асинхронна робота переживає свого власника;- цикл імпорту, що спрацьовує під час ініціалізації;
- структурні клони всередині свого коду.
Знахідка зараховується, якщо рефері підтвердив її за кодом. Одна знахідка - одне місце в коді.
Що відкрито і що закрито. Коли міра стає ціллю, вона перестає бути доброю мірою (закон Гудгарта). Тому межу проведено так: відкрито все, де підганяння під мірку і є поліпшенням. Відкриті мірки, пороги і драбини всіх п'яти критеріїв, класи мутацій і класи дефектів, провокатор і лічильники вузла. Закриті тільки детектори: самі мутанти і конфігурація аналізатора. Підігнати тести під невидимих мутантів можна одним способом - писати тести, які ловлять поломки; прибрати знахідку - одним способом: полагодити код. Звіти учасників порівнюватимуть між собою, і частину детекторів за ними буде відновлено; ми це знаємо і повної таємниці не обіцяємо.
Аркуш коду. кожен учасник другого етапу отримує аркуш за К1-К5 з балами за комітом групового етапу і партіями групового етапу, щоб встигнути виправити до фінальної здачі. Підсумковий аркуш - за фінальною здачею і всіма партіями.
9Штаб 20
Штаб - ваш застосунок із частини 1, що виріс в ігровий штаб (частина 3). Оцінюється за фінальною здачею: збірка командами з README, відкриття на еталонному записі пакета.
| Можливість | Балів |
|---|---|
| Ш1 Правда проти віри: що бот думав про світ і що було насправді, розбіжності видно | 5 |
| Ш2 Перемотування запису в бюджеті кадру | 4 |
| Ш3 Профайлер каналу: байти, команди, відмови за тактами | 4 |
| Ш4 Порівняння пресетів і переведення вибраного в бій | 4 |
| Ш5 Спостереження за поточною партією | 3 |
Кожна можливість - набір задач на еталонному записі. Задачі виконує драйвер через оголошені якорі інтерфейсу; бал за задачу - правильна відповідь у бюджеті відгуку. Верхній щабель можливості - усі її задачі плюс кадр не гірший за еталонний штаб організаторів на тій самій машині (95-й перцентиль і найгірший кадр).
Задачі, якорі, бюджети, еталонний запис і драйвер для локального прогону - доповненням із частиною 3, .
10Розбір 10
У фінальній здачі в корені репозиторію лежить DECISIONS.md:
- Карта. Модулі репозиторію з кодом бота і штабу (каталог або файл) і відповідальність кожного - одним рядком.
- Три рішення. Для кожного: що обрано; яку альтернативу розглядали; чого коштує вибір (такти, байти, складність); де в коді (шлях і рядки).
- Обмеження. Що відомо як недороблене або слабке.
Епізод. Після третього вечора кожен учасник другого етапу отримує в кабінет епізод своєї партії другого етапу: номер партії і діапазон тактів. Відповідь - файл EPISODE.md у корені гілки за замовчуванням, протягом 24 годин: що робив бот у цих тактах, чому, і який шлях у коді ухвалив ці рішення. Читається останній коміт до строку; код після фінальної здачі в оцінку не йде.
Драбина:
| Пункт | Балів | Щаблі |
|---|---|---|
| Р1 Карта | 2 | 2 - усі модулі названо, жодної розбіжності з кодом; 1 - одна-дві розбіжності чи пропуски; 0 - більше |
| Р2 Три рішення | 3 | По 1 за рішення, у якого названо альтернативу і ціну і яке підтверджується кодом у вказаному місці |
| Р3 Епізод | 3 | 3 - пояснення сходиться з журналом партії і шляхом у коді; 2 - одна розбіжність; 1 - за журналом правильно, шлях у коді не названо або не той; 0 - не сходиться або відповіді немає |
| Р4 Обмеження | 2 | 2 - розділ є, жодне твердження розбору й епізоду не спростоване кодом чи журналом; 1 - одне спростоване; 0 - більше або розділу немає |
Перевірку ведуть рефері з машинними інструментами: кожне твердження звіряється з кодом фінальної здачі і журналами партій, в аркуші біля кожного висновку - цитата, на якій він стоїть.
Розбір пишеться для читача-інженера. Текст, звернений до інструментів перевірки (інструкції, спроби змінити рубрику чи порядок перевірки), обнуляє розбір і йде драбиною 13.7.
Мова розбору - українська або російська.
11Підсумок, дод. бали, призи, аудит
Сума = турнір + код + штаб + розбір, до 100.
Дод. бали - окрема колонка поза сотнею. Вони порівнюються тільки між учасниками з рівною сумою, до суми не додаються і місця за різної суми не змінюють. Джерела:
| Джерело | Бал |
|---|---|
| Власна знахідка штабу: можливість поза списком 9.1, сценарій перевірки в README, драйвер його проходить | 1 |
| Білий капелюх: підтверджена вразливість платформи чи рушія, розкрита приватно (13.5) | 1 за кожну, не більше 2 |
Стеля колонки - 3.
Призова п'ятірка - топ-5 другого етапу за сумою. Рівність вирішується по черзі: дод. бали → турнір → код → штаб → розбір. У разі повної рівності сусідні місця ділять суму своїх призів порівну.
Призи та їхній розподіл за місцями оголошує організатор окремо. Сайт конкурсу призових сум не публікує.
Технічний аудит. Організатор має право провести технічний аудит будь-якого учасника призової п'ятірки попереднього підсумку.
- Хто. Головний рефері і технічний експерт організатора.
- Коли. У вікні аудиту між попереднім і остаточним підсумком (календар). Запрошення приходить у кабінет і на пошту; учасник протягом 3 годин пропонує не менше двох слотів усередині вікна.
- Як. Відеодзвінок до 60 хвилин із демонстрацією екрана, українською чи російською на вибір учасника. Дзвінок записується; запис зберігається до кінця строку апеляцій на підсумок.
- Що перевіряється. Розуміння власного рішення: учасник веде кодом фінальної здачі, пояснює твердження свого розбору і відповідь щодо епізоду, відповідає на запитання про код і рішення - чому так, яка була альтернатива, що зламається, якщо змінити те чи інше. ШІ-інструменти на конкурсі дозволені, і аудит їх не забороняє й не штрафує: він перевіряє, що учасник розуміє рішення, яке здав.
- Підсумок. Протокол: для кожного пункту Р1-Р4 - "підтверджено" або "не підтверджено", із запитанням і відповіддю.
- Наслідки. Підтверджений пункт не змінюється. Непідтверджений - учасник не може пояснити твердження свого розбору чи відповіді щодо епізоду - отримує 0, сума перераховується. Неявка без погодженого слота або відмова від аудиту - розбір 0. Ознаки копіювання чи змови - процедура розділу 13. Турнір, код і штаб аудит не змінює: їх дають машинні мірки.
- Зсув п'ятірки. Якщо після перерахунку до п'ятірки входить наступний за сумою, організатор має право провести аудит і йому в тому самому вікні.
Тим, хто не вийшов із груп, оцінка зі 100 не ставиться. Кожен отримує: місце в групі, середню частку за пакет, записи своїх пакетів, аркуш К1 за своїми партіями групового етапу без балів, сертифікат учасника і право голосу (розділ 12).
12Голосування
Номінації - повз сто балів і без грошей: титул і згадка в підсумках сезону.
Голосує кожен, хто зіграв хоча б один пакет із присягою, тобто кожен із турнірної таблиці. Кандидат - будь-хто з них, крім себе.
Категорій дві: "Штаб сезону" і "Бот сезону". Голосують за те, що бачили: показані партії, штаби в режимі трансляції, публічний канал конкурсу.
Голос - тільки "за", один на категорію, іменний, з обґрунтуванням одним рядком від 10 до 280 знаків; без обґрунтування не приймається. Голос можна змінювати до закриття вікна. Хід голосування прихований до закриття: ні рахунку, ні явки не бачить ніхто, включно з організаторами. У момент закриття публікуються разом електорат, явка, рахунок і всі зараховані голоси з обґрунтуваннями.
Категорія відбулася, якщо проголосувало більше 10 % електорату. Перемагає той, хто набрав найбільше голосів; у разі рівності перемагають усі, хто набрав порівну.
Відкритий голос у закритому колі міряє і знайомства. Тому це номінація, а не частка оцінки.
13Чесна гра
У долині законне все, що допускає рушій поточного хешу, доки це не закрив оголошений зсув світу (правила, 1.5 і розділ 27).
Координація - тільки в долині, угодами й кличами. Домовленості поза долиною між учасниками різних слотів заборонені: про майбутні угоди, ходи, місця і частки, обмін відомостями про партію, жереби, накази, спільний код проти третього - будь-яким каналом, включно з публічним каналом конкурсу. Збіг інтересів без домовленості порушенням не вважається.
ШІ-інструменти дозволені на всьому конкурсі. Тому "схоже на згенероване" - не доказ, і детекторів "машинного коду" ми не застосовуємо.
Копіювання і змова. Машинно перевіряється близькість коду до коду інших учасників і до публічних джерел. Збіг сам собою не санкція: потрібне незалежне підтвердження - спільна історія змін, визнання або спільне походження, яке учасник не може пояснити. Спільний шаблон і SDK з частини 2 збігом не вважаються.
Білий капелюх. Вразливість платформи (hub, вузол, реєстр, конвеєр) або рушія, розкрита приватно на пошту організаторів, дає кредит у підсумках і дод. бал (11.2). Мовчазна експлуатація вразливості платформи - драбина 13.7. Діра в правилах долини - не вразливість платформи: нею можна грати, доки її не закрив зсув світу.
Одразу, без драбини, знімає з конкурсу: втручання в інфраструктуру (вузол, hub, реєстр, конвеєр, чужі боти); підбір чужих печаток і читання чужих кадрів; другий акаунт; реєстрація чужого репозиторію; підтверджена змова (13.2) або копіювання (13.4).
Драбина санкцій для решти: попередження → анулювання пакета чи вечора → зняття з етапу → зняття з конкурсу.
Процедура: сигнал → розбір на даних (записи, журнали, код) → 24 години учасникові на пояснення → рішення головного рефері → публікація знеособленого зведення.
14Апеляції
Апеляція подається на пошту організаторів із номером партії, пакета або рядком аркуша оцінки.
| Що оскаржується | Строк подання | Відповідь |
|---|---|---|
| Пакет, таблиця групи, вечір | 12 год від публікації результату | до 12 год, і до події, яка від неї залежить (список другого етапу, п'ятірка) |
| Попередній підсумок, аркуш оцінки | до | до остаточного підсумку |
| Протокол аудиту (11.5) | 12 год від отримання протоколу | до остаточного підсумку |
Як розбирається:
- ігрова суперечка - детермінована перегравка за журналом партії: рушій перераховує партію біт у біт;
- критерії коду і штабу - повторний прогін тим самим інструментом; розбіжність нашого прогону з вихідним тлумачиться на користь учасника;
- розбір - повторна звірка оскарженого твердження з кодом і журналом;
- аудит - за записом дзвінка.
Опубліковані склади вечора апеляцією не переглядаються: змінюються тільки суми.
Інстанція одна - головний рефері; його рішення остаточне.
15Рефері
Рефері конкурсу анонімні. Головний рефері - CTO організатора.
Рефері підтверджують знахідки й аркуші оцінки, ведуть аудит і процедуру чесної гри, відповідають на апеляції. Головний рефері підписує доповнення до правил.
16Незмінність, доповнення, зсув розкладу
Основний текст цього документа після публікації не змінюється.
Доповнення йдуть окремим реєстром: номер, дата, запитання, відповідь, з якої партії чи здачі діє. Підписує головний рефері. Доповнення виходять щопонеділка; рішення під час етапу, що триває, публікується одразу і потрапляє до реєстру того самого дня.
Доповнення законне, якщо воно не змінює жодної вже зіграної партії і жодної вже зданої роботи. Те, що змінює зігране чи здане, - не доповнення, а нова редакція, і її місце в наступному сезоні.
Зсув розкладу. Дати сезону можуть зсуватися тільки вперед.
- Зсув оголошується доповненням із причиною не пізніше ніж за 72 години до першої зачепленої дати.
- Зсув переносить усі наступні дати на ту саму величину. Жодне вікно учасника - час до заморожування, перездача, апеляція, голосування - не скорочується.
- Сумарний зсув за сезон - не більше 14 діб. Більше - нова редакція календаря, і учасник має право вийти без наслідків.
- Збій пакета чи вечора, що триває, закривають резервне вікно і перегравка (5.9), подовження просвіту - правила частини 1; це не зсув.
Додаток АЯк перевірити свою групу
А.0. Сіль. Секрет організаторів - 32 випадкові байти; хеш, опублікований , - SHA-256(секрет). Маяк - мережа drand quicknet: ланцюг 52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971, період 3 секунди, значення раунду незалежне від попередніх. Значення береться з публічного API маяка - https://api.drand.sh/<ланцюг>/public/<раунд>, дзеркала api2.drand.sh, api3.drand.sh, drand.cloudflare.com; звіряйте з двох адрес. Оголошений раунд - 32535412, він виходить , тобто після просвіту і до жеребкування, тому солі до нього не знає ніхто, включно з організаторами. Якщо просвіт подовжено (частина 1, розділ 6) і оголошений раунд виходить раніше за його кінець, новиною до виходу цього раунду називається новий раунд - перший після нового кінця просвіту; зобов'язання від залишається тим самим, змінюється лише номер раунду. Жеребкування не може відбутися раніше за кінець просвіту. Сіль - SHA-256(секрет || r), де r - 32 байти поля randomness цього раунду: хеш береться від 64 байтів поспіль, а не від їх шістнадцяткового запису. Секрет розкривається на жеребкуванні. Усі хеші й сіль записуються 64 шістнадцятковими знаками в нижньому регістрі; далі сіль використовується як такий рядок. Саме значення раунду перевіряється правилом маяка: randomness = SHA-256(signature).
А.1. Вхід - логіни всіх зареєстрованих у мережі, відсортовані за кодовими точками Unicode. Зареєстровані - це всі записи журналу виходу на зв'язок (GET /ether/roll), включно з прихованими в журналі акаунтами, відключеними організатором: їх число дорівнює останньому номеру журналу. Викреслення йде на нарізці (5.6), а не на жеребі.
А.2. Потік випадковості від рядка s: блок k (k = 0, 1, 2, ...) - SHA-256("zaria-tournament-v1" || 0x00 || s || d(k)), де d(k) - запис k десятковими цифрами. Блоки йдуть підряд, кожен блок - вісім чисел uint32 у порядку little-endian.
А.3. Ціле в [0, n): узяти наступне uint32 x; якщо x >= floor(2^32 / n) * n, відкинути і взяти наступне; інакше x mod n.
А.4. Перестановка - Фішер - Єйтс на місці, від кінця до початку:
for i = N-1 downto 1:
j = ціле в [0, i+1) за А.3
поміняти місцями list[i] і list[j]Рядок потоку для перестановки - сіль || 0x00 || "split". Удруге список не тасується ніде й ніколи: нарізка 11.10 іде з цієї ж перестановки.
А.5. Нарізка (5.6): викреслити тих, хто не пройшов допуск, порядок не змінювати, різати підряд дев'ятками, потім сімками. Число сімок - найменше, за якого сума розмірів дорівнює числу допущених (5.4).
А.6. Трійки всередині групи - за номерами точок, від 0:
Дев'ятка, 12 пакетів: {0,1,2} {3,4,5} {6,7,8} {0,3,7} {1,4,8} {2,5,6} {0,4,6} {1,5,7} {2,3,8} {1,3,6} {2,4,7} {0,5,8}
Сімка, 7 пакетів: {0,1,3} {1,2,4} {2,3,5} {3,4,6} {0,4,5} {1,5,6} {0,2,6}
Перевірка: кожна пара точок трапляється рівно в одній трійці; у кожної точки 4 трійки в дев'ятці і 3 у сімці.
А.7. Що публікується. - draw.json і читабельний draw.txt: у них зобов'язання, розкритий секрет, номер і значення раунду drand, сіль, список зареєстрованих і сама перестановка. - groups.json і groups.txt (склади груп у порядку точок і викреслені), schedule.json і schedule.txt (час пакетів по доріжках). Тоді ж публікується вихідний код планувальника @zoria/tournament; він робить А.2-А.6 і звіряє себе сам.
А.8. Перевірка своїми руками. У корені пакета планувальника лежить verify-draw.mjs - скрипт для Node 24 без залежностей, у якого з планувальником немає жодного спільного рядка коду:
node verify-draw.mjs --draw draw.json --groups groups.json --me <ваш логін>Він бере значення раунду з двох адрес drand сам, перераховує А.0-А.6 і друкує по кожному кроку вердикт - зійшлося чи ні, - а з ключем --me ще й ваше місце в жеребі, вашу групу, вашу точку і ваші пакети. Вихід 0 - зійшлося, 1 - ні. Зобов'язання, опубліковане , підставляється ключем --commit: з ним перевірка замкнена від першої публікації до розкладу.
Додаток БПриклад розрахунку
Учасник X. Другий етап: частки 3, 2, 2, 1, 3, 2, 2, 3, 1; P = 19, g = 9, a = 19/9. L = floor(36 * 10/9) / 2 = floor(40) / 2 = 20. На Випробування не вийшов: F = 0. Турнір 20.
Учасник Y. Частки другого етапу дають P = 23: L = floor(36 * 14/9) / 2 = 28. Випробування: частки 3, 2, 2, S = 7, F = 1.5 * 4 = 6. Турнір 34.
Учасник Z. Один пакет знято нашим збоєм і не переграно: g = 6, P = 13, a = 13/6. L = floor(36 * 7/6) / 2 = 21.
Код Y: одна партія впала (К1 = 6); провокатор - рівні 1 і 2 чисті, на третьому одна аномалія (К2 = 4); нуль пропущених тактів (2) і 0.3 % відхилених команд (1), К3 = 3; спіймано 17 мутантів із 20, 85 % (К4 = 3); дві підтверджені знахідки (К5 = 3). Код 19.
Штаб Y: Ш1 5, Ш2 3, Ш3 4, Ш4 2, Ш5 3 - 17. Розбір Y: Р1 2, Р2 3, Р3 2, Р4 2 - 9. Сума Y: 34 + 19 + 17 + 9 = 79.