-
Source-of-truth is Python, not TS or JSON. One Python file drives both mock and DB —
so they NEVER diverge. See references/02-source-of-truth.md.
-
re.sub replacement strings interpret \\n as newline. This will silently break
your generated TypeScript with «Unterminated string constant». Always wrap repl in
lambda m: repl_str. See references/06-pitfalls.md Pitfall #1.
-
Stale /tmp/lessonN_steps.py on Thrall. patch_db.py does
sys.path.insert(0, '/tmp'). If an old version sits in /tmp (from a previous session),
it will load that one instead of yours and silently patch the WRONG content. Always
cp /root/lessonN_steps.py /tmp/lessonN_steps.py before running patch_db. See
Pitfall #2.
-
Bonus pages don't show video or timecodes. bonusN !== null in
apps/web/app/intensive/lesson/[id]/page.tsx controls this. Don't accidentally
re-enable them.
-
No ID buttons on any block. Earlier ID copy was visual noise — removed from
step / code / prompt / mcp_config / agent_config. Only main «Копировать» (content)
button remains.
-
Production deploy goes to prod server (), NOT Thrall. DNS for
<your-agentos-domain> points at prod server. There IS a shadow PM2 <your-pm2-name>
on Thrall :3020 — deploying there looks green on internal curl but prince sees old
code. Always dig +short <your-agentos-domain> before deploy.
-
Service-role-key NEVER in chat output. bot/.env on Thrall contains
SUPABASE_SERVICE_ROLE_KEY which bypasses RLS. Never cat bot/.env, never
tr "\0" "\n" < /proc/PID/environ without | grep -v ROLE_KEY. See Pitfall #5.
-
Visual verify after deploy is MANDATORY (HARD RULE). После любого
UI-deploy НЕЛЬЗЯ рапортовать «Готово» только на основе HTTP 200 + grep
на ключевые строки. grep ловит наличие нужного, но не отсутствие
лишних элементов от прошлой версии. Обязательный шаг:
- открыть страницу через
agent-browser (CDP, headless Chrome)
- mobile viewport (375px width)
- screenshot full-page (проскроллить полностью включая footer)
- глазами сверить с ожиданием: positive (новое есть) + negative (старого нет)
- только потом «Готово»
Если visual verify не сделана (agent-browser недоступен) — явно сказать
user: «визуально не проверила, могут быть остаточные UI-элементы».
См. Pitfall #9 в references/06-pitfalls.md. Применяется ко ВСЕМ
UI-задачам: EdgeLab, AgentOS Intensive, workshop, любая страница на
*.<your-domain>.
-
READ README перед build/deploy (HARD RULE, 2026-05-13). Перед npm run build
либо правкой env / deploy скриптов / infra — обязательно Read README.md репо
целиком (или Grep по «deploy», «env», «host», «prod», «production»). Не доверяй
.env.example (часто staging-значения) и устаревшим skill-файлам. README на HEAD —
canonical. Эту ошибку уже один раз получили (NEXT_PUBLIC_API_BASE_URL из staging
значения сломал prod). См. Pitfall #11 + core/rules.md главное правило.
-
«Материалы» эфира = поле materials, не blocks (HARD RULE). На странице эфира
вкладка-счётчик «Материалы · N» считает из intensive_eth_details.materials (массив
{name, desc, url, filename}), НЕ из link-блоков внутри blocks. После добавления
link-блоков в описание шага обязательно параллельно PATCH materials тем же набором.
См. Pitfall #15.
-
Cabinet счётчики материалов — хардкод-мок (HARD RULE). apps/web/app/intensive/cabinet/page.tsx
имеет массив BROADCASTS с полями materials/lessons/open зашитыми статикой.
Ничего не читает из БД. При добавлении материалов к эфиру N — параллельно
править BROADCASTS[N-1].materials и делать полный rebuild + redeploy. См. Pitfall #16.
-
Hot-patch скомпилированных chunks с тем же hash — антипаттерн (HARD RULE).
Браузер кеширует chunk по hash в имени файла как immutable. Правка содержимого
без смены hash → у существующих посетителей старый код, у новых — новый. Всегда
полный npm run build (получит новый hash) → tarball → scp → pm2 restart.
См. Pitfall #12.
-
Статика только вне /intensive/* префикса. Next.js app router имеет роуты
/intensive/cabinet, /intensive/eth/[id], /intensive/lesson/[id] и т.д. Файлы
в public/intensive/<anything>/... → HTTP 404 из-за конфликта. Паттерн в проекте:
public/efir-N/... → /efir-N/.... После добавления статики в public/ —
обязательный pm2 restart (Next.js standalone кеширует listing при старте,
см. Pitfall #14).
-
Контент урока живёт в 4 местах, не в одном (HARD RULE). После любого
изменения контента урока обязательно обновить ВСЕ 4 источника, иначе
listing-страницы покажут старое:
- DB
intensive_lessons.blocks — детальная страница
BONUS_LESSONS / ONBOARDING_LESSONS mock в app/intensive/lesson/[id]/page.tsx — SSR fallback
LESSONS[] hardcoded в app/intensive/cabinet/onboarding/page.tsx — список предобучения
FEED_ITEMS[] hardcoded в app/intensive/materials/page.tsx — агрегация материалов
Обязательный grep-чеклист после изменения:
grep -rn "ONBOARDING_LESSONS\|BONUS_LESSONS\|FEED_ITEMS\|LESSONS\[" apps/web/app/
Visual verify (#8) ловит автоматически — если делать скриншот
listing-страниц, а не только детальной. См. Pitfall #10.
Для уроков с видео-эфиром нужны три связанные сущности — все три в скилле автоматизированы.
См. полный пайплайн в references/07-video-pipeline.md.