Завдання/ТЗ частини 1
Зоря. Частина 1: Вихід на зв'язок
Технічне завдання першого тижня. Результат тижня - ваш клієнт мережі Зоря.нет і реєстрація в просвіт. Далі йдуть жеребкування і частина 2 (правила гри та SDK) . Поруч: легенда, специфікація клієнта, OpenAPI, оцінювання, календар.
1Що ви будуєте
Клієнт мережі Зоря.нет - ваш застосунок на React + TypeScript у репозиторії вашої заявки. Через нього ви реєструєтеся, бачите статус доступу до репозиторію, отримуєте новини, особисті листи та наступні частини завдання. З нього ж виросте ігровий штаб у частині 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. Перевірка: акаунт існує і є в журналі виходу на зв'язок.
Репозиторій із заявки. Поле repositoryUrl - репозиторій, який ви вказали в заявці на конкурс: owner/repo або адреса на github.com. Репозиторій не зі списку заявок - 422 repository-not-eligible; якщо в заявці помилка, пишіть на пошту з розділу 3. Перевірка: сервер звіряє адресу зі списком заявок під час реєстрації та зміни репозиторію.
Один учасник - один акаунт, один репозиторій - один учасник. Перевірка: файл .zoria прив'язує репозиторій рівно до одного акаунта; решта заявок на той самий репозиторій отримують needs-attention.
Запрошення акаунта організаторів. Запросіть до репозиторію GitHub-акаунт із розділу 3 (поле repositoryAccess.githubUsername). Репозиторій може бути приватним. В особистому репозиторії 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Питання учасників
Реєструватися вручну чи доручити клієнту? Як зручніше. Зараховується будь-яка реєстрація в просвіт, зокрема через curl.
Просвіт припаде на ніч? Він триває не менше 10 годин: досить заходити в мережу раз на 10 годин. Або клієнт слухає ефір і реєструється сам за кадром відкриття.
Чи дає щось рання реєстрація? Ні. Номер у журналі виходу на зв'язок балів не дає й на жеребкування не впливає.
Чи можна підготувати запрошення і .zoria до просвіту? Так. Запрошення до репозиторію зі списку заявок бот приймає й до реєстрації; заявку буде вирішено на першому проході бота після неї. Логін у .zoria має збігатися з тим, під яким ви зареєструєтеся.
Чи можна змінити репозиторій? Так: PUT /me/repository із сесії входу, тільки на репозиторій зі списку заявок. Статус скидається в pending. Якщо в самій заявці вказано не той репозиторій - пошта.
Хтось зареєстрував мій репозиторій. Заявку вирішує .zoria: підтверджується акаунт, названий у файлі, чужа заявка отримує needs-attention. Покладіть файл зі своїм логіном. Якщо запрошення вже прийнято, а статус не сходиться, - пошта.
Що робити у разі needs-attention? Прочитати reason у GET /me/repository або в листі й виправити назване. Бот перегляне заявку сам.
Чи обов'язковий React? Так, стек конкурсу - React + TypeScript. Решту бібліотек і будову застосунку обираєте ви.
Чи можна клієнту власний бекенд? Так. З Node до API можна звертатися без CORS. Пароль і токен до репозиторію не потрапляють.
Мене заглушили, хоча клієнт опитує рідко. Ліміт рахується за адресою, клієнти за спільною адресою (офіс, NAT) ділять його. Вийдіть у мережу з іншої адреси або домовтеся із сусідами про частоту опитування.
Як перевірити клієнт до просвіту? На навчальному стенді: той самий протокол, коло щогодини за UTC - шум, з :20 провісник, з :30 до :50 просвіт; навчальний список репозиторіїв, база стирається раз на добу (специфікація, розділ 6).
Якою мовою приходять листи сервера? Мовою акаунта: uk за замовчуванням або en. Мову задає поле lang під час реєстрації, змінює PATCH /me. Голос провісника в ефірі приходить одразу обома мовами.