Зоря. Частина 1: Вихід на зв'язок
Технічне завдання першого тижня. Результат тижня - ваш клієнт мережі Зоря.нет і реєстрація в просвіт. Далі йдуть жеребкування і частина 2 (правила гри та SDK) . Поруч: легенда, специфікація клієнта, OpenAPI, оцінювання, календар.
1Що ви будуєте
Клієнт мережі Зоря.нет - ваш застосунок на React + TypeScript у вашому приватному репозиторії на GitHub. Через нього ви реєструєтеся, бачите статус доступу до репозиторію, отримуєте новини, особисті листи та наступні частини завдання. З нього ж виросте ігровий штаб у частині 3.
Видається: цей пакет, контракт API в OpenAPI 3.1, живий сервер мережі в режимі ефіру з і навчальний стенд. Не видається: SDK, опис гри, готовий клієнт. Вбудований вебклієнт сервера для учасників закритий.
Обов'язковий мінімум клієнта: реєстрація; отримувач запрошення й статус доступу до репозиторію; опитування сповіщень; читання частин завдання. Реєстрація потрібна в просвіт, решта - до виходу частини 2 (): вона приходить у мережу частиною завдання. Інше в специфікації позначено як рекомендація (специфікація, розділ 1).
Реєстрація будь-яким HTTP-клієнтом зараховується. Запит із curl, Postman чи скрипта сервер не відрізняє від запиту вашого застосунку й не намагається відрізняти. Це не лазівка: сам клієнт у частині 1 не перевіряється, його перевіряє оцінювання штабу пізніше, за документом оцінювання. Клієнт, якого немає, не покаже частину 2 і не стане штабом.
ваш клієнт (браузер або Node) сервер Зоря.нет
+----------------------------+ HTTPS +--------------------------+
| реєстрація, статус, | -------> | /api/v1: ефір, акаунт, |
| новини, листи, частини | <------- | новини, листи, частини |
+----------------------------+ опитув. +------------+-------------+
| бот допуску
ви --- запрошення ---> ваш репозиторій <-- читання --+
(GitHub) + файл .zoria2Тиждень: від публікації до частини 2
Від публікації сервер працює в режимі ефіру. До просвіту він шумить: майже всі відповіді - перешкоди, зрідка проходить справжній кадр із печаткою станції. У легенді це вихід на зв'язок: мережа мовчить під Шумом, і тільки станція пробивається крізь перешкоди. За 6 годин до просвіту в шумі проступає зв'язок: несуча, потім позивні, потім станція на частоті. Технічно це провісник - поле harbinger у кожному справжньому кадрі: opensIn, точна кількість секунд до відкриття, і text, голос станції українською й англійською, без чисел. Якщо клієнт слухав ефір і провісника не було, найближчі 6 годин просвіту не буде.
2026-09-21 початок просвіту: 2026-09-24 05:00 - 2026-09-25 09:00 09-26 09-28
| | | |
v v v v
[ шум ......................| провісник 6 год | ПРОСВІТ, не менше 10 год | після ] жеребкування частина 2
перешкоди, печатка, строк відкриття перешкод немає, реєстрацію
глушіння; реєстрації немає у кадрах реєстрація відкрита закрито| Коли | Сервер | Ви | Що видно в клієнті |
|---|---|---|---|
| Від до провісника | Шум: на маршрутах частини 1 перешкоди або справжні кадри; реєстрація не працює | Пишете клієнт, перевіряєте його на стенді; можна заздалегідь запросити акаунт організаторів і покласти .zoria | Кадри ефіру, уривки листа Доглядача |
| За 6 год до просвіту | Провісник у справжніх кадрах | Плануєте час реєстрації | Відлік до відкриття |
| Просвіт, не менше 10 год | Перешкод немає, реєстрація відкрита; кожна реєстрація - запис у журналі виходу на зв'язок | Реєструєтеся кодом заявки, запрошуєте акаунт організаторів, кладете .zoria | Форма реєстрації, потім статус доступу |
| Після просвіту | Реєстрацію закрито, решта API працює | Доводите доступ до verified | Статус доступу, листи, новини |
| Жеребкування | Перевіряєте своє місце (розділ 7) | Новина | |
| Частина 2 у списку частин завдання | Читаєте частину 2 | Нова частина |
Два проходи очима учасника.
Вручну:
- До просвіту ви відкриваєте клієнт раз на кілька годин, не рідше ніж раз на 10 годин.
- Клієнт показує шум, із провісником - відлік у вашому місцевому часі.
- У просвіт ви вводите логін, відображуване ім'я, пароль, код заявки і свій приватний репозиторій.
- Клієнт показує, кого запросити; ви запрошуєте й кладете
.zoria. - За кілька хвилин статус стає
verified, приходить лист.
Автоматично:
- Клієнт слухає
GET /etherне частіше ніж раз на 15 с і перевіряє печатку. - З провісника він знає момент відкриття:
atкадру плюсopensIn. - На першому справжньому кадрі з
phase: "window"він надсилає заготовлену заявку. - Відповідь
429 authentication-busyозначає, що черга перевірки паролів зайнята: почекатиRetry-Afterсекунд і повторити заявку. Це не відмова і до ліміту адреси не йде. - Якщо відповідь загублено, він входить тими самими логіном і паролем, а не реєструється вдруге.
- Далі він опитує зведення й показує статус доступу.
3Дати й адреси
| Що | Значення |
|---|---|
| Публікація частини 1 і початок ефіру | |
| Початок просвіту | між і ; точний момент заздалегідь не оголошується |
| Тривалість просвіту | не менше 10 год; кінець - поле window.closesAt у кадрі ефіру |
| Провісник | за 6 год до початку просвіту; тільки в ефірі, на сайті не дублюється |
| Час | UTC у текстах і в API; клієнт показує місцевий час |
| Адреса API | https://zoria.net/api/v1 |
| Ефір і журнал виходу на зв'язок | GET /ether, GET /ether/roll |
| Відкритий ключ печатки | GET /ether/key; відбиток (SHA-256 ключа): буде опубліковано 21.09 |
| Навчальний стенд | https://stand.zoria.net/api/v1 |
| Акаунт для запрошення до репозиторію | zoria-net-bot; його ж називає GET /public/config |
| Жеребкування | , час - у календарі |
| Строк підтвердження доступу до репозиторію | у календарі |
| Частина 2 |
Київський час у ці дати - UTC+3.
4Вимоги допуску
Реєстрація в просвіт. Акаунт створюється запитом POST /auth/register у фазі window. До просвіту реєстрація відповідає шумом, після - 403 registration-closed. Перевірка: акаунт існує і є в журналі виходу на зв'язок.
Код заявки і власний репозиторій. Поле invitation - одноразовий код, який організатори надсилають кожному, хто подав заявку, тим каналом, що вказаний у ній. Чужий, використаний або прострочений код - 422 invalid-invitation. Поле repositoryUrl - ваш репозиторій на GitHub: owner/repo або адреса на github.com; списком він більше не обмежений. Репозиторій має бути приватним: у відкритий бот не заходить, бо ваш клієнт не повинен читатися суперниками. Перевірка: акаунт створено кодом заявки, репозиторій прийнято, і далі його підтверджують P1-04 і P1-05.
Оновлено 22.09: порядок і поля - в оголошеннях.
Один учасник - один акаунт, один репозиторій - один учасник. Перевірка: файл .zoria прив'язує репозиторій рівно до одного акаунта; решта заявок на той самий репозиторій отримують needs-attention.
Запрошення акаунта організаторів. Запросіть до репозиторію GitHub-акаунт із розділу 3 (поле repositoryAccess.githubUsername). Репозиторій приватний - цього вимагає P1-02. В особистому репозиторії GitHub немає ролі "тільки читання": запрошений співавтор отримує право запису. У репозиторії організації достатньо ролі Read. Наш акаунт - окремий бот із двофакторною автентифікацією; його токен зберігається тільки на сервері мережі у файлі з правами 0600. Бот у репозиторій не пише: він приймає запрошення й читає .zoria, у наступних частинах - код. Якщо у вашій заявці вказано GitHub-логін, запрошення має прийти від нього. Перевірка: бот приймає запрошення.
Файл .zoria. У корені гілки за замовчуванням лежить файл .zoria. Його перший непорожній рядок - логін вашого акаунта в мережі; регістр і початковий @ значення не мають. Перевірка: бот читає файл після прийняття запрошення, після кожної зміни заявки й кожні 10 хвилин, доки заявку не підтверджено або доки рішення не виніс організатор.
Доступ підтверджено до строку. До строку підтвердження доступу з календаря GET /me/repository віддає accessStatus: "verified". Перевірка: статус на сервері в момент строку.
Доступ тримається до кінця конкурсу. Запрошення не відкликається, репозиторій не видаляється, не перейменовується й не передається, .zoria не видаляється. Перевірка: у наступних частинах код для збирання читається з цього репозиторію.
Клієнт у вашому репозиторії. React + TypeScript; README з командами встановлення й запуску; lockfile; жодних токенів, паролів чи ключів в історії репозиторію. Перевірка: у частині 1 не перевіряється; перевіряється оцінюванням штабу.
Чесна гра в мережі. Заборонено: реєструвати чужий репозиторій; заводити другий акаунт; розподіляти запити між кількома адресами, щоб обійти ліміт ефіру. Дозволено: вийти в мережу з іншої адреси, якщо вашу заглушив сусід за спільною адресою. Перевірка: журнал сервера; санкції - розділ "Чесна гра" документа оцінювання.
5Приймання
Частину 1 приймає машина за двома умовами:
- Реєстрація відбулася в просвіт. Поза просвітом акаунт створити не можна, тож умову виконано, якщо акаунт є.
- До строку підтвердження доступу статус репозиторію -
verified(P1-06).
Де це видно:
GET /me/repository:accessStatus,reason,checkedAt;- лист із
notice.type: "repository"на кожну зміну статусу чи причини; GET /ether/roll: ваш номер під вашим відображуваним ім'ям.
| Статус | Що означає | Що робити |
|---|---|---|
pending | Заявка є, бот ще не вирішив. Поки запрошення немає, reason порожній; запрошення прийнято, а .zoria немає - reason просить покласти файл | Запросити акаунт, покласти .zoria |
verified | Запрошення прийнято, .zoria називає ваш акаунт | Нічого; тримати доступ (P1-07) |
needs-attention | .zoria називає інший акаунт, запрошення прийшло не від логіна із заявки або рішення ухвалив організатор; reason пояснює | Виправити за reason; якщо причина не у файлі й не в запрошенні - до організаторів |
verifiedElsewhere: true означає, що той самий репозиторій уже підтверджено за іншим акаунтом, і ваша заявка підтвердитися не може: перевірте .zoria і зверніться до організаторів.
Після виправлення бот переглядає заявку сам: під час зміни заявки або чергового читання .zoria, не рідше ніж раз на 10 хвилин. Рішення організатора бот не переглядає. Строк виправлення - той самий строк підтвердження доступу.
Балів частина 1 не дає. Її підсумок - місце в жеребкуванні та допуск до наступних частин.
6Вибування і збій на нашому боці
Вибуває учасник:
- який не зареєструвався в просвіт;
- чий доступ не підтверджено до строку з календаря;
- знятий за розділом "Чесна гра" документа оцінювання.
Збій на нашому боці. Якщо за час просвіту за нашим моніторингом сумарно понад 30 хвилин GET /ether не віддавав справжніх кадрів або реєстрація відповідала 5xx, просвіт подовжується на сумарну тривалість збою. Новий кінець приходить у полі window.closesAt кадру ефіру; подовження оголошується на сайті й новиною в мережі. Збій сумарно на 30 хвилин і менше просвіт не подовжує.
Про збій пишіть в офіційний канал із часом в UTC і значенням заголовка X-Request-Id відповіді.
Збоєм на нашому боці не вважаються: мережа чи провайдер учасника; помилка клієнта; глушіння за перевищення ліміту; перешкоди до просвіту; пропущений просвіт.
7Що далі
Жеребкування . Публікується перестановка всіх зареєстрованих, виведена із солі жеребкування. Схема - commit-reveal із публічним маяком випадковості drand: публікується хеш секрету організаторів (буде опубліковано 21.09); сіль - SHA-256 від секрету та значення маяка drand на заздалегідь оголошений раунд після просвіту; на жеребкуванні секрет розкривається, і перестановку може перерахувати кожен. Групи нарізаються з цієї перестановки пізніше. Правило й спосіб перевірити свою групу - оцінювання, дати - календар. Результат жеребкування приходить у клієнт новиною.
Частина 2, . Правила гри, SDK, протокол, шаблон бота і наказ. Частина з'являється в списку частин завдання (GET /stages); клієнт дізнається про неї за лічильником releasedStages у зведенні GET /me/summary.
8Поза частиною 1
- Гра, її правила, SDK, бот, ігрові функції штабу.
- WebSocket і push-сповіщення: обмін тільки опитуванням.
- Готовий клієнт: вбудований вебклієнт сервера закритий.
- Бали.
9Питання учасників
Відповіді на часті питання зібрані окремою сторінкою: часті запитання. Там же - що означають найчастіші відповіді сервера.