ЗОРЯ

Головна/Завдання/Частина 1/ТЗ

Зоря. Частина 1: Вихід на зв'язок

Технічне завдання першого тижня. Результат тижня - ваш клієнт мережі Зоря.нет і реєстрація в просвіт. Далі йдуть жеребкування і частина 2 (правила гри та SDK) . Поруч: легенда, специфікація клієнта, OpenAPI, оцінювання, календар.

оновлено 22.09

1Що ви будуєте

Клієнт мережі Зоря.нет - ваш застосунок на React + TypeScript у вашому приватному репозиторії на GitHub. Через нього ви реєструєтеся, бачите статус доступу до репозиторію, отримуєте новини, особисті листи та наступні частини завдання. З нього ж виросте ігровий штаб у частині 3.

Видається: цей пакет, контракт API в OpenAPI 3.1, живий сервер мережі в режимі ефіру з і навчальний стенд. Не видається: SDK, опис гри, готовий клієнт. Вбудований вебклієнт сервера для учасників закритий.

Обов'язковий мінімум клієнта: реєстрація; отримувач запрошення й статус доступу до репозиторію; опитування сповіщень; читання частин завдання. Реєстрація потрібна в просвіт, решта - до виходу частини 2 (): вона приходить у мережу частиною завдання. Інше в специфікації позначено як рекомендація (специфікація, розділ 1).

Реєстрація будь-яким HTTP-клієнтом зараховується. Запит із curl, Postman чи скрипта сервер не відрізняє від запиту вашого застосунку й не намагається відрізняти. Це не лазівка: сам клієнт у частині 1 не перевіряється, його перевіряє оцінювання штабу пізніше, за документом оцінювання. Клієнт, якого немає, не покаже частину 2 і не стане штабом.

схема
  ваш клієнт (браузер або Node)            сервер Зоря.нет
  +----------------------------+  HTTPS   +--------------------------+
  | реєстрація, статус,        | -------> | /api/v1: ефір, акаунт,   |
  | новини, листи, частини     | <------- | новини, листи, частини   |
  +----------------------------+ опитув.  +------------+-------------+
                                                       | бот допуску
  ви --- запрошення ---> ваш репозиторій <-- читання --+
         (GitHub)        + файл .zoria

2Тиждень: від публікації до частини 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Нова частина

Два проходи очима учасника.

Вручну:

  1. До просвіту ви відкриваєте клієнт раз на кілька годин, не рідше ніж раз на 10 годин.
  2. Клієнт показує шум, із провісником - відлік у вашому місцевому часі.
  3. У просвіт ви вводите логін, відображуване ім'я, пароль, код заявки і свій приватний репозиторій.
  4. Клієнт показує, кого запросити; ви запрошуєте й кладете .zoria.
  5. За кілька хвилин статус стає verified, приходить лист.

Автоматично:

  1. Клієнт слухає GET /ether не частіше ніж раз на 15 с і перевіряє печатку.
  2. З провісника він знає момент відкриття: at кадру плюс opensIn.
  3. На першому справжньому кадрі з phase: "window" він надсилає заготовлену заявку.
  4. Відповідь 429 authentication-busy означає, що черга перевірки паролів зайнята: почекати Retry-After секунд і повторити заявку. Це не відмова і до ліміту адреси не йде.
  5. Якщо відповідь загублено, він входить тими самими логіном і паролем, а не реєструється вдруге.
  6. Далі він опитує зведення й показує статус доступу.

3Дати й адреси

ЩоЗначення
Публікація частини 1 і початок ефіру
Початок просвітуміж і ; точний момент заздалегідь не оголошується
Тривалість просвітуне менше 10 год; кінець - поле window.closesAt у кадрі ефіру
Провісникза 6 год до початку просвіту; тільки в ефірі, на сайті не дублюється
ЧасUTC у текстах і в API; клієнт показує місцевий час
Адреса APIhttps://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Вимоги допуску

P1-01

Реєстрація в просвіт. Акаунт створюється запитом POST /auth/register у фазі window. До просвіту реєстрація відповідає шумом, після - 403 registration-closed. Перевірка: акаунт існує і є в журналі виходу на зв'язок.

P1-02

Код заявки і власний репозиторій. Поле invitation - одноразовий код, який організатори надсилають кожному, хто подав заявку, тим каналом, що вказаний у ній. Чужий, використаний або прострочений код - 422 invalid-invitation. Поле repositoryUrl - ваш репозиторій на GitHub: owner/repo або адреса на github.com; списком він більше не обмежений. Репозиторій має бути приватним: у відкритий бот не заходить, бо ваш клієнт не повинен читатися суперниками. Перевірка: акаунт створено кодом заявки, репозиторій прийнято, і далі його підтверджують P1-04 і P1-05.

Оновлено 22.09: порядок і поля - в оголошеннях.

P1-03

Один учасник - один акаунт, один репозиторій - один учасник. Перевірка: файл .zoria прив'язує репозиторій рівно до одного акаунта; решта заявок на той самий репозиторій отримують needs-attention.

P1-04

Запрошення акаунта організаторів. Запросіть до репозиторію GitHub-акаунт із розділу 3 (поле repositoryAccess.githubUsername). Репозиторій приватний - цього вимагає P1-02. В особистому репозиторії GitHub немає ролі "тільки читання": запрошений співавтор отримує право запису. У репозиторії організації достатньо ролі Read. Наш акаунт - окремий бот із двофакторною автентифікацією; його токен зберігається тільки на сервері мережі у файлі з правами 0600. Бот у репозиторій не пише: він приймає запрошення й читає .zoria, у наступних частинах - код. Якщо у вашій заявці вказано GitHub-логін, запрошення має прийти від нього. Перевірка: бот приймає запрошення.

P1-05

Файл .zoria. У корені гілки за замовчуванням лежить файл .zoria. Його перший непорожній рядок - логін вашого акаунта в мережі; регістр і початковий @ значення не мають. Перевірка: бот читає файл після прийняття запрошення, після кожної зміни заявки й кожні 10 хвилин, доки заявку не підтверджено або доки рішення не виніс організатор.

P1-06

Доступ підтверджено до строку. До строку підтвердження доступу з календаря GET /me/repository віддає accessStatus: "verified". Перевірка: статус на сервері в момент строку.

P1-07

Доступ тримається до кінця конкурсу. Запрошення не відкликається, репозиторій не видаляється, не перейменовується й не передається, .zoria не видаляється. Перевірка: у наступних частинах код для збирання читається з цього репозиторію.

P1-08

Клієнт у вашому репозиторії. React + TypeScript; README з командами встановлення й запуску; lockfile; жодних токенів, паролів чи ключів в історії репозиторію. Перевірка: у частині 1 не перевіряється; перевіряється оцінюванням штабу.

P1-09

Чесна гра в мережі. Заборонено: реєструвати чужий репозиторій; заводити другий акаунт; розподіляти запити між кількома адресами, щоб обійти ліміт ефіру. Дозволено: вийти в мережу з іншої адреси, якщо вашу заглушив сусід за спільною адресою. Перевірка: журнал сервера; санкції - розділ "Чесна гра" документа оцінювання.

5Приймання

Частину 1 приймає машина за двома умовами:

  1. Реєстрація відбулася в просвіт. Поза просвітом акаунт створити не можна, тож умову виконано, якщо акаунт є.
  2. До строку підтвердження доступу статус репозиторію - 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Питання учасників

Відповіді на часті питання зібрані окремою сторінкою: часті запитання. Там же - що означають найчастіші відповіді сервера.