# Feature Request: Handle `[EXT:*]` targets in Axiom validator ## Проблема Сейчас Axiom-валидатор проверяет `@RELATION PREDICATE -> [Target]` на существование контракта с ID `Target`. Для кастомных контрактов это верно. Но для `[EXT:*]` (external references) это generates false `unresolved_relation`. **Пример бага:** ```python # @RELATION DEPENDS_ON -> [EXT:Python:json] # @RELATION DEPENDS_ON -> [EXT:Library:pydantic] # @RELATION DEPENDS_ON -> [EXT:frontend:authStore] ``` Валидатор: «ищу контракт `EXT:Python:json` — не нашёл → unresolved_relation». ## Временный костыль Агент создал `backend/src/schemas/_external_stubs.py` — **~250 пустышек-контрактов**: ```python # #region EXT:Library:pydantic [C:1] [TYPE External] # @BRIEF External library stub — no code # #endregion EXT:Library:pydantic ``` **Проблемы костыля:** 1. 250 мусорных контрактов в индексе (шум в графе, раздувает DuckDB) 2. Нужно поддерживать вручную — каждый новый EXT требует новой пустышки 3. Ломает семантику: `EXT:` означает «external, контракт не нужен» ## Правильный фикс (Rust-код) В валидаторе `unresolved_relation` нужно добавить проверку: **если target начинается с `EXT:` — пропустить unresolved check**. ### Suggestion ```rust // Сейчас: fn check_resolved(target_id: &str, contracts: &ContractIndex) -> bool { contracts.contains(target_id) // требует контракт для любого ID } // Должно быть: fn check_resolved(target_id: &str, contracts: &ContractIndex) -> bool { if target_id.starts_with("EXT:") { return true; // external reference — контракт не нужен } contracts.contains(target_id) } ``` ### Ожидаемый эффект - `@RELATION CALLS -> [EXT:Python:json]` → not checked → **0 warnings** - `@RELATION DEPENDS_ON -> [EXT:Library:pydantic]` → not checked → **0 warnings** - `@RELATION BINDS_TO -> [EXT:frontend:authStore]` → not checked → **0 warnings** - Можно полностью удалить `_external_stubs.py` → -250 шумовых контрактов ### Альтернатива: registry approach Если нужна валидация формата EXT, можно сделать registry разрешённых неймспейсов: ```yaml # axiom_config.yaml external_namespaces: - EXT:Python # Python stdlib - EXT:Library # External PyPI/npm libraries - EXT:frontend # Frontend stores/components - EXT:path # File system paths - EXT:code # Code expressions - EXT:method # Method references - EXT:docker # Docker/shell scripts - EXT:internal # Internal module references ``` Тогда валидатор проверяет не наличие контракта, а формат: `^EXT:\w+:\S+$`. ## Что делать с существующим stubs-файлом После фикса в Rust: ```bash # 1. Удалить файл пустышек rm backend/src/schemas/_external_stubs.py # 2. Перестроить индекс axiom_semantic_index rebuild rebuild_mode="full" use_duckdb=true # 3. Аудит должен показать 0 axiom_semantic_validation audit_contracts ```