39 KiB
CLAUDE.md (Русский)
🌐 Languages: 🇺🇸 English · 🇸🇦 ar · 🇦🇿 az · 🇧🇬 bg · 🇧🇩 bn · 🇨🇿 cs · 🇩🇰 da · 🇩🇪 de · 🇪🇸 es · 🇮🇷 fa · 🇫🇮 fi · 🇫🇷 fr · 🇮🇳 gu · 🇮🇱 he · 🇮🇳 hi · 🇭🇺 hu · 🇮🇩 id · 🇮🇩 in · 🇮🇹 it · 🇯🇵 ja · 🇰🇷 ko · 🇮🇳 mr · 🇲🇾 ms · 🇳🇱 nl · 🇳🇴 no · 🇵🇭 phi · 🇵🇱 pl · 🇵🇹 pt · 🇧🇷 pt-BR · 🇷🇴 ro · 🇸🇰 sk · 🇸🇪 sv · 🇰🇪 sw · 🇮🇳 ta · 🇮🇳 te · 🇹🇭 th · 🇹🇷 tr · 🇺🇦 uk-UA · 🇵🇰 ur · 🇻🇳 vi · 🇨🇳 zh-CN
Этот файл предоставляет руководство для Claude Code (claude.ai/code) при работе с кодом в этом репозитории.
Быстрый старт
npm install # Установка зависимостей (автоматически генерирует .env из .env.example)
npm run dev # Сервер разработки на http://localhost:20128
npm run build # Продакшн сборка (Next.js 16 standalone)
npm run lint # ESLint (ожидается 0 ошибок; предупреждения уже существуют)
npm run typecheck:core # Проверка TypeScript (должна быть чистой)
npm run typecheck:noimplicit:core # Строгая проверка (без неявного any)
npm run test:coverage # Модульные тесты + контроль покрытия (75/75/75/70 — операторы/строки/функции/ветви)
npm run check # линт + тесты в одном
npm run check:cycles # Обнаружение циклических зависимостей
Запуск тестов
# Один файл теста (родной тестовый запускатель Node.js — большинство тестов)
node --import tsx/esm --test tests/unit/your-file.test.ts
# Vitest (MCP сервер, autoCombo, кэш)
npm run test:vitest
# Все наборы
npm run test:all
Для полной матрицы тестов смотрите CONTRIBUTING.md → "Запуск тестов". Для глубокой архитектуры смотрите AGENTS.md.
Проект в общем
OmniRoute — унифицированный AI прокси/маршрутизатор. Один конечный пункт, более 160 поставщиков LLM, автоматическое резервирование.
| Уровень | Местоположение | Цель |
|---|---|---|
| API маршруты | src/app/api/v1/ |
Next.js App Router — точки входа |
| Обработчики | open-sse/handlers/ |
Обработка запросов (чат, встраивания и т.д.) |
| Исполнители | open-sse/executors/ |
HTTP-диспетчер, специфичный для поставщика |
| Переводчики | open-sse/translator/ |
Конверсия форматов (OpenAI↔Claude↔Gemini) |
| Трансформер | open-sse/transformer/ |
API ответов ↔ Завершения чата |
| Сервисы | open-sse/services/ |
Комбинированная маршрутизация, ограничения по скорости, кэширование и т.д. |
| База данных | src/lib/db/ |
Модули домена SQLite (более 45 файлов, 55 миграций) |
| Домен/Политика | src/domain/ |
Движок политик, правила затрат, логика резервирования |
| MCP сервер | open-sse/mcp-server/ |
37 инструментов (30 базовых + 3 памяти + 4 навыка), 3 транспорта, ~13 областей |
| A2A сервер | src/lib/a2a/ |
Протокол агента JSON-RPC 2.0 |
| Навыки | src/lib/skills/ |
Расширяемая структура навыков |
| Память | src/lib/memory/ |
Постоянная разговорная память |
Монорепозиторий: src/ (приложение Next.js 16), open-sse/ (рабочее пространство стримингового движка), electron/ (десктопное приложение), tests/, bin/ (точка входа CLI).
Запросный Пайплайн
Клиент → /v1/chat/completions (маршрут Next.js)
→ CORS → валидация Zod → аутентификация? → проверка политики → защита от инъекций в запрос
→ handleChatCore() [open-sse/handlers/chatCore.ts]
→ проверка кэша → ограничение по частоте → комбинированная маршрутизация?
→ resolveComboTargets() → handleSingleModel() для каждой цели
→ translateRequest() → getExecutor() → executor.execute()
→ fetch() вверх по потоку → повторная попытка с задержкой
→ перевод ответа → SSE поток или JSON
→ Если Responses API: responsesTransformer.ts TransformStream
API маршруты следуют последовательному шаблону: Маршрут → предварительная проверка CORS → валидация тела Zod → необязательная аутентификация (extractApiKey/isValidApiKey) → соблюдение политики API ключа → делегирование обработчикам (open-sse). Нет глобального промежуточного ПО Next.js — перехват специфичен для маршрута.
Комбинированная маршрутизация (open-sse/services/combo.ts): 14 стратегий (приоритет, взвешенный, заполнение в первую очередь, круговая, P2C, случайный, наименее используемый, оптимизированный по стоимости, учитывающий сброс, строгий случайный, авто, lkgp, оптимизированный по контексту, контекстный реле). Каждая цель вызывает handleSingleModel(), который оборачивает handleChatCore() с обработкой ошибок для каждой цели и проверками автоматического отключения. См. docs/routing/AUTO-COMBO.md для 9-факторного оценивания Auto-Combo и docs/architecture/RESILIENCE_GUIDE.md для 3 слоев устойчивости.
Состояние времени выполнения устойчивости
OmniRoute имеет три связанных, но различных механизма временных сбоев. Держите их область применения отдельно при отладке поведения маршрутизации. См. диаграмму устойчивости в 3 слоя (источник: docs/diagrams/resilience-3layers.mmd) для быстрого обзора.
Прерывание цепи поставщика
Область применения: весь поставщик, например, glm, openai, anthropic.
Цель: прекратить отправку трафика к поставщику, который постоянно терпит неудачу на уровне upstream/service, чтобы один нездоровый поставщик не замедлял каждый запрос.
Реализация:
- Основной класс:
src/shared/utils/circuitBreaker.ts - Провода ворот/выполнения чата:
src/sse/handlers/chatHelpers.ts,src/sse/handlers/chat.ts - API состояния времени выполнения:
src/app/api/monitoring/health/route.ts - Общие обертки:
open-sse/services/accountFallback.ts - Таблица сохраненного состояния:
domain_circuit_breakers
Состояния:
CLOSED: нормальный трафик разрешен.OPEN: поставщик временно заблокирован; вызывающие получают ответ о том, что цепь поставщика открыта или комбинированная маршрутизация пропускает к другой цели.HALF_OPEN: время сброса истекло; разрешить пробный запрос. Успех закрывает прерывание, неудача снова открывает его.
По умолчанию (open-sse/config/constants.ts):
- OAuth поставщики: порог
3, время сброса60s. - Поставщики API-ключей: порог
5, время сброса30s. - Локальные поставщики: порог
2, время сброса15s.
Только статусы сбоев на уровне поставщика должны срабатывать на прерывание цепи поставщика:
(408, 500, 502, 503, 504);
Не срабатывайте на прерывание всей цепи поставщика для нормальных ошибок аккаунта/ключа/модели, таких как большинство
401, 403 или 429. Обычно они относятся к охлаждению соединения или блокировке модели. Общий ответ API-ключа 403 должен быть восстанавливаемым, если он не классифицируется как терминальная ошибка поставщика/аккаунта.
Прерывание использует ленивое восстановление, а не фоновый таймер. Когда OPEN истекает, такие
чтения, как getStatus(), canExecute(), и getRetryAfterMs() обновляют состояние на
HALF_OPEN, чтобы панели мониторинга и сборщики кандидатов на комбинирование не продолжали исключать
истекший поставщик навсегда.
Охлаждение соединения
Область применения: одно соединение/аккаунт/ключ поставщика.
Цель: временно пропустить один плохой ключ/аккаунт, позволяя другим соединениям для того же поставщика продолжать обслуживать запросы.
Реализация:
- Путь записи/обновления:
src/sse/services/auth.ts::markAccountUnavailable() - Выбор/фильтрация аккаунта:
src/sse/services/auth.ts::getProviderCredentials... - Расчет охлаждения:
open-sse/services/accountFallback.ts::checkFallbackError() - Настройки:
src/lib/resilience/settings.ts
Важные поля на соединениях поставщика:
rateLimitedUntil;
testStatus: "unavailable";
lastError;
lastErrorType;
errorCode;
backoffLevel;
Во время выбора аккаунта соединение пропускается, пока:
new Date(rateLimitedUntil).getTime() > Date.now();
Охлаждения также ленивые: когда rateLimitedUntil в прошлом, соединение снова становится
доступным. При успешном использовании clearAccountError() очищает testStatus,
rateLimitedUntil, поля ошибок и backoffLevel.
Поведение охлаждения соединения по умолчанию:
- Базовое охлаждение OAuth:
5s. - Базовое охлаждение API-ключа:
3s. - API-ключ
429должен предпочитать подсказки повторной попытки вверх по потоку (Retry-After, заголовки сброса или парсируемый текст сброса), когда это возможно. - Повторяющиеся восстанавливаемые сбои используют экспоненциальное увеличение задержки:
baseCooldownMs * 2 ** failureIndex;
Защита от эффекта "громадного стада" предотвращает одновременные сбои на одном соединении от
повторного продления охлаждения или двойного увеличения backoffLevel.
Терминальные состояния не являются охлаждениями. banned, expired, и credits_exhausted должны оставаться недоступными до тех пор, пока учетные данные/настройки не изменятся или оператор не сбросит их. Не перезаписывайте терминальные состояния временным состоянием охлаждения.
Блокировка модели
Область применения: поставщик + соединение + модель.
Цель: избежать отключения целого соединения, когда только одна модель недоступна или ограничена по квоте для этого соединения.
Примеры:
- Поставщики с квотой на модель, возвращающие
429. - Локальные поставщики, возвращающие
404для одной отсутствующей модели. - Ошибки разрешения режима/модели, специфичные для поставщика, такие как выбранные режимы Grok.
Блокировка модели находится в open-sse/services/accountFallback.ts и позволяет тому же
соединению продолжать обслуживать другие модели.
Рекомендации по отладке
- Если все ключи для поставщика пропущены, проверьте как состояние прерывания поставщика, так и
rateLimitedUntil/testStatusкаждого соединения. - Если поставщик кажется постоянно исключенным после окна сброса, проверьте, читает ли код
необработанное
state, а не используетgetStatus()/canExecute(). - Если один ключ поставщика терпит неудачу, но другие должны работать, предпочтите охлаждение соединения перед прерыванием поставщика.
- Если только одна модель терпит неудачу, предпочтите блокировку модели перед охлаждением соединения.
- Если состояние должно восстанавливаться самостоятельно, оно должно иметь будущую метку времени/время сброса и путь чтения, который обновляет истекшее состояние. Постоянные статусы требуют ручных изменений учетных данных или конфигурации.
Ключевые Конвенции
Стиль Кода
- 2 пробела, точки с запятой, двойные кавычки, ширина 100 символов, запятые в конце для es5 (обеспечивается lint-staged через Prettier)
- Импорты: внешние → внутренние (
@/,@omniroute/open-sse) → относительные - Именование: файлы=camelCase/kebab, компоненты=PascalCase, константы=UPPER_SNAKE
- ESLint:
no-eval,no-implied-eval,no-new-func= ошибка везде;no-explicit-any= предупреждение вopen-sse/иtests/ - TypeScript:
strict: false, целевая версия ES2022, модуль esnext, разрешение bundler. Предпочитайте явные типы.
База Данных
- Всегда используйте модули домена из
src/lib/db/— никогда не пишите сырой SQL в маршрутах или обработчиках - Никогда не добавляйте логику в
src/lib/localDb.ts(только слой повторного экспорта) - Никогда не используйте barrel-import из
localDb.ts— вместо этого импортируйте конкретные модулиdb/ - Синглтон БД:
getDbInstance()изsrc/lib/db/core.ts(журналирование WAL) - Миграции:
src/lib/db/migrations/— версионированные SQL файлы, идемпотентные, выполняются в транзакциях
Обработка Ошибок
- try/catch с конкретными типами ошибок, логирование с контекстом pino
- Никогда не игнорируйте ошибки в потоках SSE — используйте сигналы прерывания для очистки
- Возвращайте правильные коды состояния HTTP (4xx/5xx)
Безопасность
- Никогда не используйте
eval(),new Function(), или подразумеваемый eval - Проверяйте все входные данные с помощью схем Zod
- Шифруйте учетные данные в состоянии покоя (AES-256-GCM)
- Список заголовков для отказа:
src/shared/constants/upstreamHeaders.ts— поддерживайте согласованность между очисткой, схемами Zod и юнит-тестами при редактировании - Публичные учетные данные для upstream (OAuth client_id/secret в стиле Gemini/Antigravity/Windsurf + ключи Firebase Web, извлеченные из публичных CLI): ДОЛЖНЫ быть встроены через
resolvePublicCred()изopen-sse/utils/publicCreds.ts— никогда как строковые литералы. См.docs/security/PUBLIC_CREDS.mdдля обязательного шаблона. - Ответы на ошибки (HTTP / SSE / обработчик executor / MCP): ДОЛЖНЫ проходить через
buildErrorBody()илиsanitizeErrorMessage()изopen-sse/utils/error.ts— никогда не помещайте сырыеerr.stackилиerr.messageв тело ответа. См.docs/security/ERROR_SANITIZATION.md. - Команды оболочки, построенные из переменных: при вызове
exec()/spawn()со скриптом, который требует значения времени выполнения, передавайте их через опциюenv(автоматически экранируется для оболочки) — никогда не интерполируйте ненадежные/внешние пути в тело скрипта. Ссылка:src/mitm/cert/install.ts::updateNssDatabases. - Библиотеки с безопасными настройками по умолчанию (tldrsec/awesome-secure-defaults): предпочитайте Helmet.js, DOMPurify, ssrf-req-filter, safe-regex, Google Tink перед пользовательскими реализациями при добавлении новых поверхностей, чувствительных к безопасности.
Общие Сценарии Модификации
Добавление Нового Провайдера
- Зарегистрируйте в
src/shared/constants/providers.ts(проверка Zod при загрузке) - Добавьте executor в
open-sse/executors/, если нужна пользовательская логика (расширьтеBaseExecutor) - Добавьте переводчик в
open-sse/translator/, если формат не OpenAI - Добавьте конфигурацию OAuth в
src/lib/oauth/constants/oauth.ts, если на основе OAuth — если upstream CLI поставляет публичный client_id/secret, встроите черезresolvePublicCred()(см.docs/security/PUBLIC_CREDS.md), никогда как литерал - Зарегистрируйте модели в
open-sse/config/providerRegistry.ts - Напишите тесты в
tests/unit/(включите проверку формы publicCreds, если вы добавили новый встроенный по умолчанию)
Добавление Нового API Маршрута
- Создайте директорию в
src/app/api/v1/your-route/ - Создайте
route.tsс обработчикамиGET/POST - Следуйте шаблону: CORS → проверка тела Zod → необязательная аутентификация → делегирование обработчика
- Обработчик помещается в
open-sse/handlers/(импортируйте оттуда, а не инлайн) - Ответы на ошибки используют
buildErrorBody()/errorResponse()изopen-sse/utils/error.ts(автоматически очищены — никогда не помещайтеerr.stackилиerr.messageсырыми в тело). См.docs/security/ERROR_SANITIZATION.md. - Добавьте тесты — включая как минимум одно утверждение, что ответы на ошибки не раскрывают трассировки стека (
!body.error.message.includes("at /"))
Добавление Нового Модуля БД
- Создайте
src/lib/db/yourModule.ts— импортируйтеgetDbInstanceиз./core.ts - Экспортируйте функции CRUD для вашей таблицы(ц)
- Добавьте миграцию в
src/lib/db/migrations/, если нужны новые таблицы - Повторно экспортируйте из
src/lib/localDb.ts(добавьте только в список повторного экспорта) - Напишите тесты
Добавление Нового Инструмента MCP
- Добавьте определение инструмента в
open-sse/mcp-server/tools/с схемой ввода Zod + асинхронным обработчиком - Зарегистрируйте в наборе инструментов (подключено через
createMcpServer()) - Назначьте соответствующим областям
- Напишите тесты (вызов инструмента записывается в таблицу
mcp_audit)
Добавление Нового A2A Навыка
- Создайте навык в
src/lib/a2a/skills/(уже существует 5: smart-routing, quota-management, provider-discovery, cost-analysis, health-report) - Навык получает контекст задачи (сообщения, метаданные) → возвращает структурированный результат
- Зарегистрируйте в
A2A_SKILL_HANDLERSвsrc/lib/a2a/taskExecution.ts - Экспонируйте в
src/app/.well-known/agent.json/route.ts(Agent Card) - Напишите тесты в
tests/unit/ - Документируйте в
docs/frameworks/A2A-SERVER.mdтаблицу навыков
Добавление Нового Облачного Агента
- Создайте класс агента в
src/lib/cloudAgent/agents/, расширяющийCloudAgentBase(уже существует 3: codex-cloud, devin, jules) - Реализуйте
createTask,getStatus,approvePlan,sendMessage,listSources - Зарегистрируйте в
src/lib/cloudAgent/registry.ts - Добавьте обработку OAuth/учетных данных, если необходимо (
src/lib/oauth/providers/) - Тесты + документируйте в
docs/frameworks/CLOUD_AGENT.md
Добавление Нового Ограничителя / Eval / Навыка / События Webhook
- Ограничитель:
src/lib/guardrails/→ документация:docs/security/GUARDRAILS.md - Eval suite:
src/lib/evals/→ документация:docs/frameworks/EVALS.md - Навык (песочница):
src/lib/skills/→ документация:docs/frameworks/SKILLS.md - Событие Webhook:
src/lib/webhookDispatcher.ts→ документация:docs/frameworks/WEBHOOKS.md
Справочная документация
Для любых нетривиальных изменений сначала прочитайте соответствующий углубленный материал:
| Область | Документ |
|---|---|
| Навигация по репозиторию | docs/architecture/REPOSITORY_MAP.md |
| Архитектура | docs/architecture/ARCHITECTURE.md |
| Справочник по инженерии | docs/architecture/CODEBASE_DOCUMENTATION.md |
| Авто-комбо (9-факторная оценка, 14 стратегий) | docs/routing/AUTO-COMBO.md |
| Устойчивость (3 механизма) | docs/architecture/RESILIENCE_GUIDE.md |
| Воспроизведение рассуждений | docs/routing/REASONING_REPLAY.md |
| Каркас навыков | docs/frameworks/SKILLS.md |
| Система памяти (FTS5 + Qdrant) | docs/frameworks/MEMORY.md |
| Облачные агенты | docs/frameworks/CLOUD_AGENT.md |
| Ограничения (PII / инъекция / видение) | docs/security/GUARDRAILS.md |
| Публичные учетные данные (Gemini и др.) | docs/security/PUBLIC_CREDS.md |
| Санитизация сообщений об ошибках | docs/security/ERROR_SANITIZATION.md |
| Оценки | docs/frameworks/EVALS.md |
| Соответствие / аудит | docs/security/COMPLIANCE.md |
| Вебхуки | docs/frameworks/WEBHOOKS.md |
| Пайплайн авторизации | docs/architecture/AUTHZ_GUIDE.md |
| Скрытность (TLS / отпечаток) | docs/security/STEALTH_GUIDE.md |
| Протоколы агентов (A2A / ACP / Cloud) | docs/frameworks/AGENT_PROTOCOLS_GUIDE.md |
| MCP сервер | docs/frameworks/MCP-SERVER.md |
| A2A сервер | docs/frameworks/A2A-SERVER.md |
| Справочник API + OpenAPI | docs/reference/API_REFERENCE.md + docs/reference/openapi.yaml |
| Каталог провайдеров (автоматически сгенерированный) | docs/reference/PROVIDER_REFERENCE.md |
| Процесс выпуска | docs/ops/RELEASE_CHECKLIST.md |
Тестирование
| Что | Команда |
|---|---|
| Модульные тесты | npm run test:unit |
| Один файл | node --import tsx/esm --test tests/unit/file.test.ts |
| Vitest (MCP, autoCombo) | npm run test:vitest |
| E2E (Playwright) | npm run test:e2e |
| Протокол E2E (MCP+A2A) | npm run test:protocols:e2e |
| Экосистема | npm run test:ecosystem |
| Порог покрытия | npm run test:coverage (75/75/75/70 — операторы/строки/функции/ветви) |
| Отчет о покрытии | npm run coverage:report |
Правило PR: Если вы изменяете производственный код в src/, open-sse/, electron/ или bin/, вы должны включить или обновить тесты в том же PR.
Предпочтение уровня тестирования: сначала модульные → интеграционные (мульти-модульные или состояние БД) → e2e (только UI/рабочий процесс). Кодируйте воспроизведения ошибок как автоматизированные тесты до или вместе с исправлением.
Политика покрытия Copilot: Когда PR изменяет производственный код и покрытие ниже 75% (операторы/строки/функции) или 70% (ветви), не просто сообщайте — добавьте или обновите тесты, повторно запустите порог покрытия, затем запросите подтверждение. Включите выполненные команды, измененные тестовые файлы и окончательный результат покрытия в отчет PR.
Git Workflow
# Никогда не коммитьте напрямую в main
git checkout -b feat/your-feature
git commit -m "feat: опишите ваше изменение"
git push -u origin feat/your-feature
Префиксы веток: feat/, fix/, refactor/, docs/, test/, chore/
Формат коммита (Conventional Commits): feat(db): добавить circuit breaker — области: db, sse, oauth, dashboard, api, cli, docker, ci, mcp, a2a, memory, skills
Хуки Husky:
- pre-commit: lint-staged +
check-docs-sync+check:any-budget:t11 - pre-push:
npm run test:unit
Среда
- Время выполнения: Node.js ≥20.20.2 <21 || ≥22.22.2 <23 || ≥24 <25, ES Модули
- TypeScript: 5.9+, целевой ES2022, модуль esnext, разрешение bundler
- Псевдонимы путей:
@/*→src/,@omniroute/open-sse→open-sse/,@omniroute/open-sse/*→open-sse/* - Порт по умолчанию: 20128 (API + панель управления на одном порту)
- Директория данных: переменная окружения
DATA_DIR, по умолчанию~/.omniroute/ - Ключевые переменные окружения:
PORT,JWT_SECRET,API_KEY_SECRET,INITIAL_PASSWORD,REQUIRE_API_KEY,APP_LOG_LEVEL - Настройка:
cp .env.example .env, затем сгенерируйтеJWT_SECRET(openssl rand -base64 48) иAPI_KEY_SECRET(openssl rand -hex 32)
Жесткие правила
- Никогда не коммитьте секреты или учетные данные
- Никогда не добавляйте логику в
localDb.ts - Никогда не используйте
eval()/new Function()/ подразумеваемый eval - Никогда не коммитьте напрямую в
main - Никогда не пишите сырой SQL в маршрутах — используйте модули
src/lib/db/ - Никогда не игнорируйте ошибки в потоках SSE
- Всегда проверяйте входные данные с помощью схем Zod
- Всегда включайте тесты при изменении производственного кода
- Покрытие должно оставаться ≥75% (операторы, строки, функции) / ≥70% (ветви). Текущая измеренная: ~82%.
- Никогда не обходите хуки Husky (
--no-verify,--no-gpg-sign) без явного одобрения оператора. - Никогда не встраивайте публичные upstream OAuth client_id/secret или ключи Firebase Web в виде строковых литералов — всегда используйте
resolvePublicCred()(open-sse/utils/publicCreds.ts). См.docs/security/PUBLIC_CREDS.md. - Никогда не возвращайте сырой
err.stack/err.messageв HTTP / SSE / ответах исполнителя — всегда обрабатывайте черезbuildErrorBody()илиsanitizeErrorMessage()(open-sse/utils/error.ts). См.docs/security/ERROR_SANITIZATION.md. - Никогда не интерполируйте внешние пути или значения времени выполнения в shell-скрипты, передаваемые в
exec()/spawn()— передавайте через опциюenv. Ссылка:src/mitm/cert/install.ts::updateNssDatabases. - Никогда не игнорируйте предупреждение CodeQL / Secret-Scanning без (a) предварительной проверки документации по шаблонам выше, чтобы увидеть, применим ли помощник, и (b) записи технического обоснования в комментарии об отклонении. Прецедент:
js/stack-trace-exposure, поднятый на вызовах, которые уже обрабатываются черезsanitizeErrorMessage(), является известным ограничением CodeQL (пользовательские санитайзеры не распознаются) — отклоняйте какfalse positive, ссылаясь наdocs/security/ERROR_SANITIZATION.md. - Никогда не открывайте маршруты, которые запускают дочерние процессы (
/api/mcp/,/api/cli-tools/runtime/), без классификацииisLocalOnlyPath()вsrc/server/authz/routeGuard.ts. Принуждение к петле происходит без условий перед любой проверкой аутентификации — утечка JWT через туннель не может вызвать запуск процесса. См.docs/security/ROUTE_GUARD_TIERS.md. - Никогда не включайте трейлеры
Co-Authored-By, которые приписывают авторство AI-ассистенту, LLM или автоматизированному аккаунту (например, имена, содержащие "Claude", "GPT", "Copilot", "Bot"; письма наanthropic.com/openai.com/ адресахnoreply.github.com, принадлежащих ботам). Такие трейлеры направляют атрибуцию коммитов к аккаунту бота на GitHub, скрывая реального автора (diegosouzapw) в истории PR. Человеческие соавторы — включая авторов upstream PR и репортёров issues, портируемых в OmniRoute — МОГУТ и ДОЛЖНЫ быть отмечены стандартными трейлерамиCo-authored-by: Name <email>; рабочие процессы upstream-port (/port-upstream-features,/port-upstream-issues) зависят от этого.