Відомі несподіванки
У цьому файлі зібрано специфічні для репозиторію моменти плутанини, які призводили до помилок агентів.
Критерії для запису
Додавайте запис лише тоді, коли виконано всі умови:
- Це стосується саме цього репозиторію (а не загальна порада).
- Це, найімовірніше, повториться в майбутніх агентів.
- Для цього є конкретний спосіб обійти проблему, якого можна дотримуватися.
Якщо ви не впевнені, запитайте розробника, перш ніж додавати запис.
Шаблон запису
### [Short title]
- **Date:** YYYY-MM-DD
- **Observed by:** agent name or contributor
- **Context:** where/when it happened
- **What was surprising:** concrete unexpected behavior
- **Impact:** what went wrong or could go wrong
- **Mitigation:** exact step future agents should take
- **Status:** confirmed | superseded
Записи
Продакшн-домени застосунків на Vercel можуть відкочуватися до розгортань з гілки master у Git
- Дата: 2026-04-28
- Помітили: Tommaso + Codex
- Контекст: Перевірка дзеркал застосунків Seedit і 5chan у каталозі застосунків Bitsocial Web.
- Що виявилося несподіваним: У проєктах Vercel
seeditі5chanбуло заданоgitProviderOptions.createDeployments = "enabled", тому пуші вmasterна GitHub підвищувалися до продакшн-доменів, хоча політика репозиторію передбачає, що продакшн-дзеркала застосунків обслуговують лише артефакти релізів. - Наслідки: Значки перевірених дзеркал у каталозі застосунків можуть стати хибними, бо продакшн-домени віддають останній комміт розробки замість ZIP-архіву релізу з GitHub, хеш
index.htmlякого записано вabout/src/lib/apps-data.ts. - Як обійти: Перш ніж додавати чи оновлювати метадані перевірки дзеркал, огляньте проєкт Vercel командою
vercel api /v9/projects/<project-id>і переконайтеся, що тамgitProviderOptions.createDeployments = "disabled". Розгортайте вміст ZIP-архіву релізу черезvercel deploy --prebuilt --prod, а для розгортань розробки використовуйтеseedit-omega.vercel.appабо5chan-omega.vercel.app. - Статус: підтверджено
Portless 0.11 повторно використовує застарілий стан проксі, якщо лаунчер не примушує HTTPS
- Дата: 2026-04-28
- Помітили: Tommaso + Codex
- Контекст: Перехід звичайного процесу
yarn startзі старої проксі-адресиhttp://bitsocial.localhost:1355наhttps://bitsocial.localhost. - Що виявилося несподіваним: Навіть із встановленим
portless@0.11.1Portless повторно використовував наявний HTTP-проксі~/.portless/proxy.port = 1355і друкував застарілу адресу з:1355. - Наслідки: Оновити версії пакетів і документацію недостатньо:
yarn startусе одно може оголошувати й використовувати стару адресу, якщо в контриб’ютора запущено застарілий стан Portless. - Як обійти: Нехай стартові скрипти явно запускають HTTPS-проксі Portless на порту
443перед реєстрацією маршрутів застосунку, щоб робочий процес мігрував зі збереженого стану1355, а не успадковував його. - Статус: підтверджено
Portless змінює канонічну локальну адресу застосунку
- Дата: 2026-03-18
- Помітили: Codex
- Контекст: Перевірка в браузері та smoke-прогони
- Що виявилося несподіваним: Локальна адреса за замовчуванням — це не звичний порт Vite. Репозиторій очікує
https://bitsocial.localhostчерез Portless, тож перевіркаlocalhost:3000чиlocalhost:5173може потрапити не на той застосунок або взагалі нікуди. - Наслідки: Перевірки в браузері можуть падати або підтверджувати не ту ціль, навіть коли dev-сервер працює справно.
- Як обійти: Насамперед використовуйте
https://bitsocial.localhostяк цільову адресу. Обходьте її черезPORTLESS=0 corepack yarn startлише тоді, коли вам справді потрібен прямий порт Vite. - Статус: підтверджено
Хуки Commitizen блокують неінтерактивні коміти
- Дата: 2026-03-18
- Помітили: Codex
- Контекст: Робочі процеси створення комітів агентами
- Що виявилося несподіваним:
git commitзапускає Commitizen через Husky і чекає на інтерактивне введення в TTY, через що неінтерактивні оболонки агентів зависають. - Наслідки: Агенти можуть зависати нескінченно на тому, що мало би бути звичайним комітом.
- Як обійти: Для комітів, які створює агент, використовуйте
git commit --no-verify -m "message". Люди й далі можуть користуватисяcorepack yarn commitабоcorepack yarn exec cz. - Статус: підтверджено
Corepack потрібен, щоб не потрапити на Yarn classic
- Дата: 2026-03-19
- Помітили: Codex
- Контекст: Міграція менеджера пакетів на Yarn 4
- Що виявилося несподіваним: На машині досі є глобально встановлений Yarn classic у
PATH, тому звичайний викликyarnможе розв’язатися у v1 замість закріпленої версії Yarn 4. - Наслідки: Розробники можуть випадково обійти закріплення менеджера пакетів у репозиторії й отримати іншу поведінку встановлення або інший вміст lock-файлу.
- Як обійти: Для команд в оболонці використовуйте
corepack yarn ...або спершу виконайтеcorepack enable, щоб звичайнийyarnрозв’язувався у закріплену версію Yarn 4. - Статус: підтверджено
Фіксовані імена застосунків у Portless конфліктують між робочими деревами Bitsocial Web
- Дата: 2026-03-30
- Помітили: Codex
- Контекст: Запуск
yarn startв одному робочому дереві Bitsocial Web, коли інше робоче дерево вже роздавало застосунок через Portless - Що виявилося несподіваним: Використання буквального імені застосунку Portless
bitsocialу кожному робочому дереві призводить до конфлікту самого маршруту навіть тоді, коли базові порти різні, тож другий процес падає, боbitsocial.localhostуже зареєстровано. - Наслідки: Паралельні гілки Bitsocial Web можуть блокувати одна одну, хоча Portless має давати їм безпечно співіснувати.
- Як обійти: Тримайте запуск Portless за
scripts/start-dev.mjs: цей скрипт тепер поза канонічним випадком використовує прив’язаний до гілки маршрут*.bitsocial.localhostі переходить на такий маршрут, коли просте ім’яbitsocial.localhostуже зайняте. - Статус: підтверджено
Раніше попередній перегляд документації жорстко задавав порт 3001
- Дата: 2026-03-30
- Помітили: Codex
- Контекст: Запуск
yarn startпаралельно з іншими локальними репозиторіями та агентами - Що виявилося несподіваним: Коренева dev-команда запускала робочу область документації через
docusaurus start --port 3001, тому вся сесія розробки падала щоразу, коли3001уже займав інший процес, хоча основний застосунок уже працював через Portless. - Наслідки:
yarn startміг убити вебпроцес одразу після його запуску, перериваючи не пов’язану з цим локальну роботу через конфлікт порту документації. - Як обійти: Тримайте запуск документації за
yarn start:docs: тепер він використовує Portless разом зіscripts/start-docs.mjs, щоб врахувати переданий вільний порт або перейти на наступний доступний порт при прямому запуску. - Статус: підтверджено
Фіксоване ім’я хоста документації в Portless було жорстко задане
- Дата: 2026-04-03
- Помітили: Codex
- Контекст: Запуск
yarn startу додатковому робочому дереві Bitsocial Web, коли інше робоче дерево вже роздавало документацію через Portless - Що виявилося несподіваним:
start:docsусе ще реєстрував буквальне ім’я хостаdocs.bitsocial.localhost, томуyarn startміг падати, хоча застосунок about уже вмів уникати конфліктів маршрутів Portless для власного імені хоста. - Наслідки: Паралельні робочі дерева не могли надійно користуватися кореневою dev-командою, бо процес документації завершувався першим, а
concurrentlyпісля цього вбивав решту сесії. - Як обійти: Тримайте запуск документації за
scripts/start-docs.mjs: тепер він виводить те саме прив’язане до гілки ім’я хоста Portless, що й застосунок about, і підставляє цю спільну публічну адресу як ціль dev-проксі для/docs. - Статус: підтверджено
Оболонки в робочих деревах можуть не підхопити закріплену в репозиторії версію Node
- Дата: 2026-04-03
- Помітили: Codex
- Контекст: Запуск
yarn startу робочих деревах Git, як-от.claude/worktrees/*або в сусідніх копіях робочих дерев - Що виявилося несподіваним: Деякі оболонки в робочих деревах розв’язували
nodeіyarn nodeу Homebrew Node25.2.1, хоча репозиторій закріплює22.12.0у.nvmrc, тожyarn startміг непомітно запускати лаунчери розробки на неправильному середовищі виконання. - Наслідки: Поведінка dev-сервера може розходитися між основною копією та робочими деревами, через що баги важко відтворити, а очікуваний для репозиторію інструментарій Node 22 порушується.
- Як обійти: Тримайте лаунчери розробки за
scripts/start-dev.mjsіscripts/start-docs.mjs: тепер вони перезапускаються під бінарником Node із.nvmrc, якщо поточна оболонка має неправильну версію. У налаштуванні оболонки все одно варто віддавати перевагуnvm use. - Статус: підтверджено
Залишки docs-site/ можуть приховувати відсутні вихідні файли документації після рефакторингу
- Дата: 2026-04-01
- Помітили: Codex
- Контекст: Прибирання монорепозиторію після злиття, коли проєкт Docusaurus переїхав із
docs-site/доdocs/ - Що виявилося несподіваним: Стара тека
docs-site/може лишитися на диску зі застарілими, але важливими файлами на кшталтi18n/, навіть після того, як відстежуваний репозиторій переїхав доdocs/. Через це рефакторинг локально виглядає задубльованим і може приховати той факт, що відстежувані переклади документації насправді не перенесли вdocs/. - Наслідки: Агенти можуть видалити стару теку як «сміття» і випадково втратити єдину локальну копію перекладів документації або й далі правити скрипти, які вказують на мертвий шлях
docs-site/. - Як обійти: Вважайте
docs/єдиним канонічним проєктом документації. Перш ніж видаляти будь-які локальні залишкиdocs-site/, відновіть відстежувані вихідні файли, як-отdocs/i18n/, і оновіть скрипти та хуки, щоб вони більше не посилалися наdocs-site. - Статус: підтверджено
Багатомовний попередній перегляд документації може різко з’їдати RAM під час перевірки
- Дата: 2026-04-01
- Помітили: Codex
- Контекст: Виправлення i18n документації, маршрутизації локалей і поведінки Pagefind за допомогою
yarn start:docsразом із Playwright - Що виявилося несподіваним: Типовий режим попереднього перегляду документації тепер робить повну багатомовну збірку документації плюс індексацію Pagefind перед роздачею, і тримати цей процес живим одночасно з кількома сесіями Playwright чи Chrome може з’їдати значно більше RAM, ніж звичайний цикл розробки на Vite або на Docusaurus з однією локаллю.
- Наслідки: Машині може забракнути пам’яті, сесії браузера можуть падати, а перервані прогони можуть залишати по собі застарілі сервери документації чи headless-браузери, які й далі споживають пам’ять.
- Як обійти: Для роботи з документацією, яка не потребує перевірки локалізованих маршрутів чи Pagefind, віддавайте перевагу
DOCS_START_MODE=live yarn start:docs. Використовуйте типовий багатомовний попередній перегляд лише тоді, коли треба перевірити перекладені маршрути або Pagefind. Тримайте одну сесію Playwright, закривайте старі сесії браузера перед відкриттям нових і зупиняйте сервер документації після перевірки, якщо він більше не потрібен. - Статус: підтверджено
translate-docs.py може лишити локалі документації напівперекладеними або з поламаними цілями посилань
- Дата: 2026-04-06
- Помітили: Codex
- Контекст: Виправлення локалізованих маршрутів і вмісту документації після того, як
yarn start:docsвіддавав англійські сторінки з деталями або не міг зібрати вихід для локалі - Що виявилося несподіваним: Конвеєр перекладу документації мав одразу два специфічні для репозиторію режими відмови:
scripts/translate-docs.pyвитягував лише невелику частину повідомленьDocsHome, коли викликиtr(...)мали форму, яку він не розбирав, а перекладений markdown уdocs/i18n/**міг містити машинно перекладені slug-и або артефактиZXQPLACEHOLDERусередині цілей посилань. - Наслідки: Локалізовані головні сторінки можуть непомітно відкочуватися до англійської, локалізовані сторінки з деталями можуть виглядати неперекладеними, а повна збірка
yarn docs:buildможе падати на поламаних посиланнях у локалі, хоча вихідна документація коректна. - Як обійти: Після зміни перекладів документації чи регенерації файлів локалей завжди запускайте
yarn docs:buildз кореня репозиторію, перевіряйте markdown уdocs/i18n/**на наявністьZXQPLACEHOLDERі переконуйтеся, що перекладені посилання й далі ведуть на канонічні slug-и документів, як-от/apps/5chan/, а не на перекладені шляхи URL. Якщо текстDocsHomeзмінився, переконайтеся, щоscripts/translate-docs.pyусе ще витягує всі повідомленняdocs.home.*. - Статус: підтверджено
Перевірки сайту about без JS мають використовувати маршрут Portless, а не окремий SSR-перегляд
- Дата: 2026-04-12
- Помітили: Codex
- Контекст: Перевірка підтримки роботи без JS для сайту
about/з робочого дерева гілки - Що виявилося несподіваним: Окремий SSR-перегляд може виглядати справним, тоді як справжній прив’язаний до гілки маршрут Portless усе ще віддає не ту оболонку застосунку або старіший процес. У цьому репозиторії реальний локальний контракт — це ім’я хоста Portless із
yarn start, а не імпровізований сервер попереднього перегляду. - Наслідки: Агенти можуть помилково стверджувати, що робота без JS підтримується, або пропустити регресії, які виявляються лише на
*.bitsocial.localhost. - Як обійти: Для перевірки
about/у браузері завжди запускайте справжній локальний сервер черезyarn startабоyarn start:aboutі спершу тестуйте прив’язану до гілки адресу Portless. Якщо ім’я хоста Portless виглядає застарілим, огляньте й зупиніть старий процес перед повторним тестуванням. - Статус: підтверджено
chain/ був невидимим для yarn build:verify і yarn doctor
- Дата: 2026-07-05
- Помітили: Codex
- Контекст: Перевірка діфа, що стосувався лише chain/, після того як робочу область
chain/(окремий застосунок на Vite дляchain.bitsocial.net) додали до монорепозиторію. - Що виявилося несподіваним:
scripts/verify-build.mjsрозпізнавав лише префікси шляхівabout/,docs/іstats/, тому діф, що стосувався тільки chain/, друкував "No targeted build checks matched the current diff" і взагалі не запускав збірку, хочаbuild:chainуже існував у кореневомуpackage.json. Окремо від цього,yarn doctorбув жорстко заданий якreact-doctor about -y, тож зміни React уchain/srcне отримували жодного покриття React Doctor. - Наслідки: Агенти, які перевіряли зміни в chain, мусили знати, що треба викликати
yarn build:chainнапряму, замість того щоб довірятиyarn build:verify, а проблеми React уchain/src(ефекти, хуки, мертвий код) лишалися непоміченими дляyarn doctor. - Як обійти:
scripts/verify-build.mjsтепер має гілку дляchain/, дзеркальну до гілки дляabout/, аdoctorіdoctor:verboseтепер виконуютьreact-doctor --project about,chain -yодним викликом.doctor:scoreлишається тільки дляabout, бо--scoreмовчки нічого не друкує в поєднанні з--projectдля більш ніж одного проєкту; якщо потрібна оцінка для chain, використовуйтеyarn react-doctor --project about,chain --verbose -y(або--json). - Статус: підтверджено
Браузерний P2P працює на захищених WebSockets; pkc-js за замовчуванням забороняє WebRTC і WebTransport
- Дата: 2026-08-02
- Помітили: Claude
- Контекст: Написання тексту для лендингу й документації про те, як працює браузерний P2P у Bitsocial
- Що виявилося несподіваним:
@pkcprotocol/pkc-jsпостачається з типовим connection gater, який відхиляє спроби з’єднання через WebRTC і WebTransport у браузері —dist/browser/helia/dial-transport-filter.jsекспортуєDENIED_DIAL_TRANSPORTS_BY_DEFAULT = ["webrtc", "webrtc-direct", "webtransport"]. Коментар у вихідному коді пояснює причину: у браузері ці транспорти додають довгі шляхи встановлення з’єднання, які часто зриваються (STUN/ICE, ротація certhash) і сповільнюють завантаження, тоді як WebSocket працює напряму й надійно. Кожен активний пір на панелі статусу P2P у блозі показує "Secure WebSocket". Цей gater лежить уnode_modules, тому ніщо в самому репозиторії на нього не натякає. - Наслідки: Дуже легко написати технічно правдоподібний, але хибний публічний текст — наприклад, приписати можливість браузерного P2P у Bitsocial тому, що WebTransport досяг статусу Baseline у браузерах у березні 2026 року. Це твердження потрапило на лендинг, у порівняльну таблицю та на дві сторінки документації, перш ніж розробник його помітив. Хибні твердження про архітектуру на публічних сторінках перевіряє саме та аудиторія розробників, на яку націлений сайт.
- Як обійти: Ніколи не робіть висновків про те, які транспорти використовує Bitsocial, з того, що libp2p чи браузерна платформа підтримують у принципі. Дивіться актуальний список заборон у
node_modules/@pkcprotocol/pkc-js/dist/browser/helia/dial-transport-filter.js, переконуйтеся, що підabout/src/немає перевизначенняconnectionGater, і читайте живі підписи транспортів на панелі "P2P status" у блозі, перш ніж робити будь-які публічні заяви. Зміна в апстрімі, яка насправді розблокувала публікацію з браузера, — це виправлення монотонного seqno в gossipsub у@libp2p/gossipsub15.0.21 (травень 2026); pkc-js наразі постачає 16.0.4. - Статус: підтверджено
Відносні посилання ./page.md з неперекладеної сторінки документації ламають кожну локалізовану збірку
- Дата: 2026-08-02
- Помітили: Claude
- Контекст: Додавання нової сторінки лише англійською,
docs/browser-p2p.md, яка посилалася на наявну документацію через./peer-to-peer-protocol.mdі./apps/5chan.md - Що виявилося несподіваним: Кожна локаль у
docs/i18n/<lang>/docusaurus-plugin-content-docs/current/дзеркалить дерево документації. Нова сторінка, якої немає в цих дзеркалах, усе одно рендериться в кожній локалі через відкат до англійської, але її відносні markdown-посилання більше не розв’язуються — Docusaurus видає/ar/browser-p2p/peer-to-peer-protocol.md/і завалює збірку з "Docusaurus found broken links!". Найважливіше:yarn build:verifyіyarn docs:build:verifyзбирають лишеenі проходять чисто; проблему виявляє тільки повна збіркаyarn docs:build, яка обривається на першій за абеткою локалі (ar). - Наслідки: Зміна в документації може пройти всі швидкі локальні перевірки й усе одно зламати продакшн-збірку з усіма локалями. До того ж збій виглядає не пов’язаним зі зміною, бо помилка називає шлях локалі, якого автор ніколи не торкався.
- Як обійти: У будь-якій сторінці документації, яку не дзеркалять у
docs/i18n/**, використовуйте посилання від кореня (/peer-to-peer-protocol/,/apps/5chan/) замість відносних посилань на.md; Docusaurus автоматично додає до них префікс локалі. Наявний приклад —docs/build-your-own-client.md. Перед передаванням будь-якої зміни, яка додає сторінку документації або посилається на неї, запускайте повну збіркуyarn docs:build, а не лишеbuild:verify. - Статус: підтверджено
update-translations.js треба запускати з about/, а паралельні запуски мовчки втрачають ключі
- Дата: 2026-08-02
- Помітили: Claude
- Контекст: Застосування 26 перекладених ключів i18next до всіх 36 локалей через навичку
translate - Що виявилося несподіваним: Дві окремі пастки в одному скрипті. По-перше,
scripts/update-translations.jsвизначає свою ціль якpath.join(process.cwd(), "public", "translations"), але цей репозиторій тримає переклади вabout/public/translations. Запуск задокументованої команди з кореня репозиторію щоразу падає з "Translations directory not found" — уdocs/agent-playbooks/translations.mdпоказаноnode scripts/update-translations.js ..., що читається як команда з кореня репозиторію. По-друге, кожен виклик — це читання-зміна-запис усіх 36 файлів локалей, тож два одночасні виклики затирають один одного, і якийсь ключ зникає без жодної помилки. Навичкаtranslateпрямо вказує запускати до 4 субагентів одночасно, і кожен із них викликав би цей скрипт. - Наслідки: Форма з кореня репозиторію падає гучно й марнує цілий прохід. Проблема паралельності проявляється тихо: ключі зникають з довільних локалей, а діф усе одно виглядає правдоподібно.
- Як обійти: Запускайте його як
cd about && node ../scripts/update-translations.js --key <key> --map <abs-path> --write. Ніколи не дозволяйте субагентам-перекладачам писати файли локалей одночасно — нехай вони лише формують JSON-словники, а потім батьківський агент застосовує кожен ключ послідовно. Після застосування програмно перевірте, що кожен ключ є в усіх 35 неанглійських локалях і що жодне значення не збігається побайтово з англійським джерелом. - Статус: підтверджено