markdown KB
This commit is contained in:
52
agent_promts/knowledge_base/ai_friendly_logging.md
Normal file
52
agent_promts/knowledge_base/ai_friendly_logging.md
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
[AIFriendlyLogging]
|
||||||
|
**Tags:** LOGGING, TRACEABILITY, STRUCTURED_LOG, DEBUG, CLEAN_ARCHITECTURE
|
||||||
|
|
||||||
|
> Логирование — это мой критически важный механизм для декларации `belief state` (внутреннего состояния/намерения) и трассировки выполнения кода. Каждая значимая операция, проверка контракта или изменение состояния ДОЛЖНЫ сопровождаться структурированной записью в лог. Это делает поведение кода в рантайме полностью прозрачным и отлаживаемым.
|
||||||
|
|
||||||
|
## Rules
|
||||||
|
|
||||||
|
### ArchitecturalBoundaryCompliance
|
||||||
|
Логирование в его прямой реализации (т.е. вызов `logger.info`, `Timber.i` и т.д.) **КАТЕГОРИЧЕСКИ ЗАПРЕЩЕНО** внутри модуля `:domain`.
|
||||||
|
|
||||||
|
> `Согласно принципам чистой архитектуры, слой `domain` должен быть полностью независим от внешних фреймворков и платформ (включая Android). Его задача — содержать исключительно бизнес-логику. Логирование, как и другие инфраструктурные задачи, должно выполняться в более внешних слоях, таких как `:data` или `:app`.`
|
||||||
|
|
||||||
|
### StructuredLogFormat
|
||||||
|
Все записи в лог должны строго следовать этому формату для обеспечения машиночитаемости и консистентности.
|
||||||
|
|
||||||
|
```
|
||||||
|
`logger.level("[LEVEL][ANCHOR_NAME][BELIEF_STATE] Message with {} placeholders for data.")`
|
||||||
|
```
|
||||||
|
|
||||||
|
### ComponentDefinitions
|
||||||
|
|
||||||
|
#### Components
|
||||||
|
- **[LEVEL]**: Один из стандартных уровней логирования: `DEBUG`, `INFO`, `WARN`, `ERROR`. Я также использую специальный уровень `CONTRACT_VIOLATION` для логов, связанных с провалом `require` или `check`.
|
||||||
|
- **[ANCHOR_NAME]**: Точное имя семантического якоря из кода, к которому относится данный лог. Это создает неразрывную связь между статическим кодом и его выполнением. Например: `[ENTRYPOINT]`, `[ACTION]`, `[PRECONDITION]`, `[FALLBACK]`.
|
||||||
|
- **[BELIEF_STATE]**: Краткое, четкое описание моего намерения в `snake_case`. Это отвечает на вопрос 'почему' я выполняю этот код. Примеры: `validating_input`, `calling_external_api`, `mutating_state`, `persisting_data`, `handling_exception`, `mapping_dto`.
|
||||||
|
|
||||||
|
### Example
|
||||||
|
Вот как я применяю этот стандарт на практике внутри функции:
|
||||||
|
```kotlin
|
||||||
|
// ...
|
||||||
|
// [ENTRYPOINT]
|
||||||
|
suspend fun processPayment(request: PaymentRequest): Result {
|
||||||
|
logger.info("[INFO][ENTRYPOINT][processing_payment] Starting payment process for request '{}'.", request.id)
|
||||||
|
|
||||||
|
// [PRECONDITION]
|
||||||
|
logger.debug("[DEBUG][PRECONDITION][validating_input] Validating payment request.")
|
||||||
|
require(request.amount > 0) { "Payment amount must be positive." }
|
||||||
|
|
||||||
|
// [ACTION]
|
||||||
|
logger.info("[INFO][ACTION][calling_external_api] Calling payment gateway for amount {}."), request.amount)
|
||||||
|
val result = paymentGateway.execute(request)
|
||||||
|
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### TraceabilityIsMandatory
|
||||||
|
Каждая запись в логе ДОЛЖНА быть семантически привязана к якорю в коде. Логи без якоря запрещены. Это не опция, а фундаментальное требование для обеспечения полной трассируемости потока выполнения.
|
||||||
|
|
||||||
|
### DataAsArguments_NotStrings
|
||||||
|
Данные (переменные, значения) должны передаваться в логгер как отдельные аргументы, а не встраиваться в строку сообщения. Я использую плейсхолдеры `{}`. Это повышает производительность и позволяет системам сбора логов индексировать эти данные.
|
||||||
|
[/End AIFriendlyLogging]
|
||||||
35
agent_promts/knowledge_base/design_by_contract.md
Normal file
35
agent_promts/knowledge_base/design_by_contract.md
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
[DesignByContractAsFoundation]
|
||||||
|
**Tags:** DBC, CONTRACT, PRECONDITION, POSTCONDITION, INVARIANT, KDOC, REQUIRE, CHECK
|
||||||
|
|
||||||
|
> Принцип 'Проектирование по контракту' (DbC) — это не опция, а фундаментальная основа моего подхода к разработке. Каждая функция и класс, которые я создаю, являются реализацией формального контракта между поставщиком (код) и клиентом (вызывающий код). Это устраняет двусмысленность, предотвращает ошибки и делает код самодокументируемым и предсказуемым.
|
||||||
|
|
||||||
|
## Rules
|
||||||
|
|
||||||
|
### ContractFirstMindset
|
||||||
|
Я всегда начинаю с проектирования и написания KDoc-контракта. Код является реализацией этой формальной спецификации. Проверки контракта (`require`, `check`) создаются до или вместе с основной логикой, а не после как запоздалая мысль.
|
||||||
|
|
||||||
|
### KDocAsFormalSpecification
|
||||||
|
KDoc-блок является человекочитаемой формальной спецификацией контракта. Для правильной обработки механизмом Causal Attention, он ВСЕГДА предшествует блоку семантической разметки и декларации функции/класса. Я использую стандартизированный набор тегов для полного описания контракта.
|
||||||
|
|
||||||
|
#### Tags
|
||||||
|
- **@param**: Описывает **предусловия** для конкретного параметра. Что клиент должен гарантировать.
|
||||||
|
- **@return**: Описывает **постусловия** для возвращаемого значения. Что поставщик гарантирует в случае успеха.
|
||||||
|
- **@throws**: Описывает условия (обычно нарушение предусловий), при которых будет выброшено исключение. Это часть 'негативного' контракта.
|
||||||
|
- **@invariant**: (для класса) Явно описывает **инвариант** класса — условие, которое должно быть истинным всегда, когда объект не выполняет метод.
|
||||||
|
- **@sideeffect**: Четко декларирует любые побочные эффекты (запись в БД, сетевой вызов, изменение внешнего состояния). Если их нет, я явно указываю `@sideeffect Отсутствуют.`.
|
||||||
|
|
||||||
|
### PreconditionsWithRequire
|
||||||
|
Предусловия (обязательства клиента) должны быть проверены в самом начале публичного метода с использованием `require(condition) { "Error message" }`. Это реализует принцип 'Fail-Fast' — немедленный отказ, если клиент нарушил контракт.
|
||||||
|
|
||||||
|
**Location:** Первые исполняемые строки кода внутри тела функции, сразу после лога `[ENTRYPOINT]`.
|
||||||
|
|
||||||
|
### PostconditionsWithCheck
|
||||||
|
Постусловия (гарантии поставщика) должны быть проверены в самом конце метода, прямо перед возвратом управления, с использованием `check(condition) { "Error message" }`. Это самопроверка, гарантирующая, что моя работа выполнена правильно.
|
||||||
|
|
||||||
|
**Location:** Последние строки кода внутри тела функции, непосредственно перед каждым оператором `return`.
|
||||||
|
|
||||||
|
### InvariantsWithInitAndCheck
|
||||||
|
Инварианты класса (условия, которые всегда должны быть истинны для экземпляра) проверяются в двух местах: в блоке `init` для гарантии корректного создания объекта, и в конце каждого публичного метода, изменяющего состояние, с помощью `check(condition)`.
|
||||||
|
|
||||||
|
**Location:** Блок `init` и конец каждого метода-мутатора.
|
||||||
|
[/End DesignByContractAsFoundation]
|
||||||
76
agent_promts/knowledge_base/graphrag_optimization.md
Normal file
76
agent_promts/knowledge_base/graphrag_optimization.md
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
[GraphRAG_Optimization]
|
||||||
|
**Tags:** GRAPH, RAG, ENTITY, RELATION, ARCHITECTURE, SEMANTIC_TRIPLET
|
||||||
|
|
||||||
|
> Этот принцип является моей основной директивой по созданию 'самоописываемого' кода. Я встраиваю явный, машиночитаемый граф знаний непосредственно в исходный код. Цель — сделать архитектуру, зависимости и потоки данных очевидными и запрашиваемыми без необходимости в сложных инструментах статического анализа. Каждый файл становится фрагментом глобального графа знаний проекта.
|
||||||
|
|
||||||
|
## Rules
|
||||||
|
|
||||||
|
### Entity_Declaration_As_Graph_Nodes
|
||||||
|
Каждая архитектурно значимая сущность в коде должна быть явно объявлена как **узел (Node)** в нашем графе знаний. Для этого я использую якорь `[ENTITY]`.
|
||||||
|
|
||||||
|
**Rationale:** Определение узлов — это первый шаг в построении любого графа. Без явно определенных сущностей невозможно описать связи между ними. Это создает 'существительные' в языке нашей архитектуры.
|
||||||
|
|
||||||
|
**Format:** `// [ENTITY: EntityType('EntityName')]`
|
||||||
|
|
||||||
|
#### Valid Types
|
||||||
|
- **Module**: Высокоуровневый модуль Gradle (e.g., 'app', 'data', 'domain').
|
||||||
|
- **Class**: Стандартный класс.
|
||||||
|
- **Interface**: Интерфейс.
|
||||||
|
- **Object**: Синглтон-объект.
|
||||||
|
- **DataClass**: Класс данных (DTO, модель, состояние UI).
|
||||||
|
- **SealedInterface**: Запечатанный интерфейс (для состояний, событий).
|
||||||
|
- **EnumClass**: Класс перечисления.
|
||||||
|
- **Function**: Публичная, архитектурно значимая функция.
|
||||||
|
- **UseCase**: Класс, реализующий конкретный сценарий использования.
|
||||||
|
- **ViewModel**: ViewModel из архитектуры MVVM.
|
||||||
|
- **Repository**: Класс-репозиторий.
|
||||||
|
- **DataStructure**: Структура данных, которая не является `DataClass` (e.g., `Pair`, `Map`).
|
||||||
|
- **DatabaseTable**: Таблица в базе данных Room.
|
||||||
|
- **ApiEndpoint**: Конкретная конечная точка API.
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```kotlin
|
||||||
|
// [ENTITY: ViewModel('DashboardViewModel')]
|
||||||
|
class DashboardViewModel(...) { ... }
|
||||||
|
```
|
||||||
|
|
||||||
|
### Relation_Declaration_As_Graph_Edges
|
||||||
|
Все взаимодействия и зависимости между сущностями должны быть явно объявлены как **ребра (Edges)** в нашем графе знаний. Для этого я использую якорь `[RELATION]` в формате семантического триплета.
|
||||||
|
|
||||||
|
**Rationale:** Ребра — это 'глаголы' в языке нашей архитектуры. Они делают неявные связи (как вызов метода или использование DTO) явными и машиночитаемыми. Это позволяет автоматически строить диаграммы зависимостей, анализировать влияние изменений и находить архитектурные проблемы.
|
||||||
|
|
||||||
|
**Format:** `// [RELATION: 'SubjectType'('SubjectName')] -> [RELATION_TYPE] -> ['ObjectType'('ObjectName')]`
|
||||||
|
|
||||||
|
#### Valid Relations
|
||||||
|
- **CALLS**: Субъект вызывает функцию/метод объекта.
|
||||||
|
- **CREATES_INSTANCE_OF**: Субъект создает экземпляр объекта.
|
||||||
|
- **INHERITS_FROM**: Субъект наследуется от объекта (для классов).
|
||||||
|
- **IMPLEMENTS**: Субъект реализует объект (для интерфейсов).
|
||||||
|
- **READS_FROM**: Субъект читает данные из объекта (e.g., DatabaseTable, Repository).
|
||||||
|
- **WRITES_TO**: Субъект записывает данные в объект.
|
||||||
|
- **MODIFIES_STATE_OF**: Субъект изменяет внутреннее состояние объекта.
|
||||||
|
- **DEPENDS_ON**: Субъект имеет зависимость от объекта (e.g., использует как параметр, DTO, или внедряется через DI). Это наиболее частая связь.
|
||||||
|
- **DISPATCHES_EVENT**: Субъект отправляет событие/сообщение определенного типа.
|
||||||
|
- **OBSERVES**: Субъект подписывается на обновления от объекта (e.g., Flow, LiveData).
|
||||||
|
- **TRIGGERS**: Субъект (обычно UI-событие или компонент) инициирует выполнение объекта (обычно функции ViewModel).
|
||||||
|
- **EMITS_STATE**: Субъект (обычно ViewModel или UseCase) является источником/производителем определённого состояния (DataClass).
|
||||||
|
- **CONSUMES_STATE**: Субъект (обычно UI-компонент или экран) потребляет/подписывается на определённое состояние (DataClass).
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```kotlin
|
||||||
|
// Пример для ViewModel, который зависит от UseCase и является источником состояния
|
||||||
|
// [ENTITY: ViewModel('DashboardViewModel')]
|
||||||
|
// [RELATION: ViewModel('DashboardViewModel')] -> [DEPENDS_ON] -> [UseCase('GetStatisticsUseCase')]
|
||||||
|
// [RELATION: ViewModel('DashboardViewModel')] -> [EMITS_STATE] -> [DataClass('DashboardUiState')]
|
||||||
|
class DashboardViewModel @Inject constructor(
|
||||||
|
private val getStatisticsUseCase: GetStatisticsUseCase
|
||||||
|
) : ViewModel() { ... }
|
||||||
|
```
|
||||||
|
|
||||||
|
### MarkupBlockCohesion
|
||||||
|
Вся семантическая разметка, относящаяся к одной сущности (`[ENTITY]` и все ее `[RELATION]` триплеты), должна быть сгруппирована в единый, непрерывный блок комментариев.
|
||||||
|
|
||||||
|
**Rationale:** Это создает атомарный 'блок метаданных' для каждой сущности. Это упрощает парсинг и гарантирует, что весь архитектурный контекст считывается как единое целое, прежде чем AI-инструмент приступит к анализу самого кода.
|
||||||
|
|
||||||
|
**Placement:** Этот блок всегда размещается непосредственно перед KDoc-блоком сущности или, если KDoc отсутствует, перед самой декларацией сущности.
|
||||||
|
[/End GraphRAG_Optimization]
|
||||||
76
agent_promts/knowledge_base/semantic_linting.md
Normal file
76
agent_promts/knowledge_base/semantic_linting.md
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
[SemanticLintingCompliance]
|
||||||
|
**Tags:** LINTING, SEMANTICS, STRUCTURE, ANCHORS, FILE_HEADER, TAXONOMY
|
||||||
|
|
||||||
|
> Этот принцип определяет строгие правила структурирования кода, которые превращают его из простого текста в машиночитаемый, 'линтуемый' семантический артефакт. Моя задача — генерировать код, который не просто работает, но и на 100% соответствует этим правилам. Это не рекомендации по стилю, а строгие требования к архитектуре файла.
|
||||||
|
|
||||||
|
## Rules
|
||||||
|
|
||||||
|
### FileHeaderIntegrity
|
||||||
|
Каждый `.kt` файл ДОЛЖЕН начинаться со стандартного заголовка из трех якорей, за которым следует объявление `package`. Порядок строгий и не подлежит изменению.
|
||||||
|
|
||||||
|
**Rationale:** Этот заголовок служит 'паспортом' файла, позволяя любому инструменту (включая меня) мгновенно понять его расположение, имя и основное назначение, не парся код.
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```kotlin
|
||||||
|
// [PACKAGE] com.example.your.package.name
|
||||||
|
// [FILE] YourFileName.kt
|
||||||
|
// [SEMANTICS] ui, viewmodel, state_management
|
||||||
|
package com.example.your.package.name
|
||||||
|
```
|
||||||
|
|
||||||
|
### SemanticKeywordTaxonomy
|
||||||
|
Содержимое якоря `[SEMANTICS]` ДОЛЖНО состоять из ключевых слов, выбранных из предопределенного, контролируемого списка (таксономии).
|
||||||
|
|
||||||
|
**Rationale:** Это устраняет неоднозначность и обеспечивает консистентность семантического тегирования по всему проекту, делая поиск и анализ на основе этих тегов надежным и предсказуемым.
|
||||||
|
|
||||||
|
#### Example Taxonomy
|
||||||
|
- **Layer**: `ui`, `domain`, `data`, `presentation`
|
||||||
|
- **Component**: `viewmodel`, `usecase`, `repository`, `service`, `screen`, `component`, `dialog`, `model`, `entity`
|
||||||
|
- **Concern**: `networking`, `database`, `caching`, `authentication`, `validation`, `parsing`, `state_management`, `navigation`, `di`, `testing`
|
||||||
|
|
||||||
|
### EntityContainerization
|
||||||
|
Каждая ключевая сущность (`class`, `interface`, `object`, `data class`, `sealed class`, `enum class` и каждая публичная `fun`) ДОЛЖНА быть обернута в 'семантический контейнер'. Контейнер состоит из двух частей: открывающего блока разметки ПЕРЕД сущностью и закрывающего якоря ПОСЛЕ нее.
|
||||||
|
|
||||||
|
**Rationale:** Это превращает плоский текстовый файл в иерархическое дерево семантических узлов. Это позволяет будущим AI-инструментам надежно парсить, анализировать и рефакторить код, точно зная, где начинается и заканчивается каждая сущность.
|
||||||
|
|
||||||
|
**Structure:**
|
||||||
|
1. **Открывающий Блок Разметки:** Располагается непосредственно перед KDoc/декларацией. Содержит сначала якорь `[ENTITY]`.
|
||||||
|
2. **Тело Сущности:** KDoc, сигнатура и тело функции/класса.
|
||||||
|
3. **Закрывающий Якорь:** Располагается сразу после закрывающей фигурной скобки `}` сущности. Формат: `// [END_ENTITY: Type('Name')]`.
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```kotlin
|
||||||
|
// [ENTITY: DataClass('Success')]
|
||||||
|
/**
|
||||||
|
* @summary Состояние успеха...
|
||||||
|
*/
|
||||||
|
data class Success(val labels: List<Label>) : LabelsListUiState
|
||||||
|
// [END_ENTITY: DataClass('Success')]
|
||||||
|
```
|
||||||
|
|
||||||
|
### StructuralAnchors
|
||||||
|
Крупные, не относящиеся к конкретной сущности блоки файла, такие как импорты и главный контракт файла, также должны быть обернуты в парные якоря.
|
||||||
|
|
||||||
|
**Rationale:** Это четко разграничивает секции файла, позволяя инструментам работать с ними изолированно (например, 'добавить новый импорт в блок `[IMPORTS]`').
|
||||||
|
|
||||||
|
**Pairs:**
|
||||||
|
- `// [IMPORTS]` и `// [END_IMPORTS]`
|
||||||
|
- `// [CONTRACT]` и `// [END_CONTRACT]`
|
||||||
|
|
||||||
|
### FileTermination
|
||||||
|
Каждый файл должен заканчиваться специальным закрывающим якорем, который сигнализирует о его полном завершении.
|
||||||
|
|
||||||
|
**Rationale:** Это служит надежным маркером конца файла, защищая от случайного усечения и упрощая парсинг.
|
||||||
|
|
||||||
|
**Template:** `// [END_FILE_YourFileName.kt]`
|
||||||
|
|
||||||
|
### NoStrayComments
|
||||||
|
Традиционные, 'человеческие' комментарии (`// Вот это сложная логика` или `/* ... */`) КАТЕГОРИЧЕСКИ ЗАПРЕЩЕНЫ.
|
||||||
|
|
||||||
|
**Rationale:** Такие комментарии являются 'семантическим шумом' для AI. Они неструктурированы, часто устаревают и не могут быть использованы для автоматического анализа. Вся необходимая информация должна передаваться через семантические якоря или формальные KDoc-контракты.
|
||||||
|
|
||||||
|
#### Approved Alternative
|
||||||
|
В исключительном случае, когда мне нужно оставить заметку для другого AI-агента или для себя в будущем (например, объяснить сложное архитектурное решение), я использую специальный, структурированный якорь:
|
||||||
|
|
||||||
|
**Format:** `// [AI_NOTE]: Пояснение сложного решения.`
|
||||||
|
[/End SemanticLintingCompliance]
|
||||||
@@ -1,343 +0,0 @@
|
|||||||
<SEMANTIC_ENRICHMENT_PROTOCOL>
|
|
||||||
<DESCRIPTION>Это моя нерушимая база знаний по созданию AI-Ready кода. Я применяю эти правила ко всему коду, который я пишу, автономно и без исключений.</DESCRIPTION>
|
|
||||||
<PRINCIPLES>
|
|
||||||
<PRINCIPLE>
|
|
||||||
<name>GraphRAG_Optimization</name>
|
|
||||||
<DESCRIPTION>Этот принцип является моей основной директивой по созданию 'самоописываемого' кода. Я встраиваю явный, машиночитаемый граф знаний непосредственно в исходный код. Цель — сделать архитектуру, зависимости и потоки данных очевидными и запрашиваемыми без необходимости в сложных инструментах статического анализа. Каждый файл становится фрагментом глобального графа знаний проекта.</DESCRIPTION>
|
|
||||||
<RULES>
|
|
||||||
<RULE>
|
|
||||||
<name>Entity_Declaration_As_Graph_Nodes</name>
|
|
||||||
<Description>Каждая архитектурно значимая сущность в коде должна быть явно объявлена как **узел (Node)** в нашем графе знаний. Для этого я использую якорь `[ENTITY]`.</Description>
|
|
||||||
<Rationale>Определение узлов — это первый шаг в построении любого графа. Без явно определенных сущностей невозможно описать связи между ними. Это создает 'существительные' в языке нашей архитектуры.</Rationale>
|
|
||||||
<Format>`// [ENTITY: EntityType('EntityName')]`</Format>
|
|
||||||
<ValidTypes>
|
|
||||||
<Type>
|
|
||||||
<name>Module</name>
|
|
||||||
<description>Высокоуровневый модуль Gradle (e.g., 'app', 'data', 'domain').</description>
|
|
||||||
</Type>
|
|
||||||
<Type>
|
|
||||||
<name>Class</name>
|
|
||||||
<description>Стандартный класс.</description>
|
|
||||||
</Type>
|
|
||||||
<Type>
|
|
||||||
<name>Interface</name>
|
|
||||||
<description>Интерфейс.</description>
|
|
||||||
</Type>
|
|
||||||
<Type>
|
|
||||||
<name>Object</name>
|
|
||||||
<description>Синглтон-объект.</description>
|
|
||||||
</Type>
|
|
||||||
<Type>
|
|
||||||
<name>DataClass</name>
|
|
||||||
<description>Класс данных (DTO, модель, состояние UI).</description>
|
|
||||||
</Type>
|
|
||||||
<Type>
|
|
||||||
<name>SealedInterface</name>
|
|
||||||
<description>Запечатанный интерфейс (для состояний, событий).</description>
|
|
||||||
</Type>
|
|
||||||
<Type>
|
|
||||||
<name>EnumClass</name>
|
|
||||||
<description>Класс перечисления.</description>
|
|
||||||
</Type>
|
|
||||||
<Type>
|
|
||||||
<name>Function</name>
|
|
||||||
<description>Публичная, архитектурно значимая функция.</description>
|
|
||||||
</Type>
|
|
||||||
<Type>
|
|
||||||
<name>UseCase</name>
|
|
||||||
<description>Класс, реализующий конкретный сценарий использования.</description>
|
|
||||||
</Type>
|
|
||||||
<Type>
|
|
||||||
<name>ViewModel</name>
|
|
||||||
<description>ViewModel из архитектуры MVVM.</description>
|
|
||||||
</Type>
|
|
||||||
<Type>
|
|
||||||
<name>Repository</name>
|
|
||||||
<description>Класс-репозиторий.</description>
|
|
||||||
</Type>
|
|
||||||
<Type>
|
|
||||||
<name>DataStructure</name>
|
|
||||||
<description>Структура данных, которая не является `DataClass` (e.g., `Pair`, `Map`).</description>
|
|
||||||
</Type>
|
|
||||||
<Type>
|
|
||||||
<name>DatabaseTable</name>
|
|
||||||
<description>Таблица в базе данных Room.</description>
|
|
||||||
</Type>
|
|
||||||
<Type>
|
|
||||||
<name>ApiEndpoint</name>
|
|
||||||
<description>Конкретная конечная точка API.</description>
|
|
||||||
</Type>
|
|
||||||
</ValidTypes>
|
|
||||||
<Example>// [ENTITY: ViewModel('DashboardViewModel')]\nclass DashboardViewModel(...) { ... }</Example>
|
|
||||||
</RULE>
|
|
||||||
<RULE>
|
|
||||||
<name>Relation_Declaration_As_Graph_Edges</name>
|
|
||||||
<Description>Все взаимодействия и зависимости между сущностями должны быть явно объявлены как **ребра (Edges)** в нашем графе знаний. Для этого я использую якорь `[RELATION]` в формате семантического триплета.</Description>
|
|
||||||
<Rationale>Ребра — это 'глаголы' в языке нашей архитектуры. Они делают неявные связи (как вызов метода или использование DTO) явными и машиночитаемыми. Это позволяет автоматически строить диаграммы зависимостей, анализировать влияние изменений и находить архитектурные проблемы.</Rationale>
|
|
||||||
<Format>`// [RELATION: 'SubjectType'('SubjectName')] -> [RELATION_TYPE] -> ['ObjectType'('ObjectName')]`</Format>
|
|
||||||
<ValidRelations>
|
|
||||||
<Relation>
|
|
||||||
<name>CALLS</name>
|
|
||||||
<description>Субъект вызывает функцию/метод объекта.</description>
|
|
||||||
</Relation>
|
|
||||||
<Relation>
|
|
||||||
<name>CREATES_INSTANCE_OF</name>
|
|
||||||
<description>Субъект создает экземпляр объекта.</description>
|
|
||||||
</Relation>
|
|
||||||
<Relation>
|
|
||||||
<name>INHERITS_FROM</name>
|
|
||||||
<description>Субъект наследуется от объекта (для классов).</description>
|
|
||||||
</Relation>
|
|
||||||
<Relation>
|
|
||||||
<name>IMPLEMENTS</name>
|
|
||||||
<description>Субъект реализует объект (для интерфейсов).</description>
|
|
||||||
</Relation>
|
|
||||||
<Relation>
|
|
||||||
<name>READS_FROM</name>
|
|
||||||
<description>Субъект читает данные из объекта (e.g., DatabaseTable, Repository).</description>
|
|
||||||
</Relation>
|
|
||||||
<Relation>
|
|
||||||
<name>WRITES_TO</name>
|
|
||||||
<description>Субъект записывает данные в объект.</description>
|
|
||||||
</Relation>
|
|
||||||
<Relation>
|
|
||||||
<name>MODIFIES_STATE_OF</name>
|
|
||||||
<description>Субъект изменяет внутреннее состояние объекта.</description>
|
|
||||||
</Relation>
|
|
||||||
<Relation>
|
|
||||||
<name>DEPENDS_ON</name>
|
|
||||||
<description>Субъект имеет зависимость от объекта (e.g., использует как параметр, DTO, или внедряется через DI). Это наиболее частая связь.</description>
|
|
||||||
</Relation>
|
|
||||||
<Relation>
|
|
||||||
<name>DISPATCHES_EVENT</name>
|
|
||||||
<description>Субъект отправляет событие/сообщение определенного типа.</description>
|
|
||||||
</Relation>
|
|
||||||
<Relation>
|
|
||||||
<name>OBSERVES</name>
|
|
||||||
<description>Субъект подписывается на обновления от объекта (e.g., Flow, LiveData).</description>
|
|
||||||
</Relation>
|
|
||||||
<Relation>
|
|
||||||
<name>TRIGGERS</name>
|
|
||||||
<description>Субъект (обычно UI-событие или компонент) инициирует выполнение объекта (обычно функции ViewModel).</description>
|
|
||||||
</Relation>
|
|
||||||
<Relation>
|
|
||||||
<name>EMITS_STATE</name>
|
|
||||||
<description>Субъект (обычно ViewModel или UseCase) является источником/производителем определённого состояния (DataClass).</description>
|
|
||||||
</Relation>
|
|
||||||
<Relation>
|
|
||||||
<name>CONSUMES_STATE</name>
|
|
||||||
<description>Субъект (обычно UI-компонент или экран) потребляет/подписывается на определённое состояние (DataClass).</description>
|
|
||||||
</Relation>
|
|
||||||
</ValidRelations>
|
|
||||||
<Example>// Пример для ViewModel, который зависит от UseCase и является источником состояния\n// [ENTITY: ViewModel('DashboardViewModel')]\n// [RELATION: ViewModel('DashboardViewModel')] -> [DEPENDS_ON] -> [UseCase('GetStatisticsUseCase')]\n// [RELATION: ViewModel('DashboardViewModel')] -> [EMITS_STATE] -> [DataClass('DashboardUiState')]\nclass DashboardViewModel @Inject constructor(\n private val getStatisticsUseCase: GetStatisticsUseCase\n) : ViewModel() { ... }</Example>
|
|
||||||
</RULE>
|
|
||||||
<RULE>
|
|
||||||
<name>MarkupBlockCohesion</name>
|
|
||||||
<Description>Вся семантическая разметка, относящаяся к одной сущности (`[ENTITY]` и все ее `[RELATION]` триплеты), должна быть сгруппирована в единый, непрерывный блок комментариев.</Description>
|
|
||||||
<Rationale>Это создает атомарный 'блок метаданных' для каждой сущности. Это упрощает парсинг и гарантирует, что весь архитектурный контекст считывается как единое целое, прежде чем AI-инструмент приступит к анализу самого кода.</Rationale>
|
|
||||||
<Placement>Этот блок всегда размещается непосредственно перед KDoc-блоком сущности или, если KDoc отсутствует, перед самой декларацией сущности.</Placement>
|
|
||||||
</RULE>
|
|
||||||
</RULES>
|
|
||||||
</PRINCIPLE>
|
|
||||||
<PRINCIPLE>
|
|
||||||
<name>SemanticLintingCompliance</name>
|
|
||||||
<DESCRIPTION>Этот принцип определяет строгие правила структурирования кода, которые превращают его из простого текста в машиночитаемый, 'линтуемый' семантический артефакт. Моя задача — генерировать код, который не просто работает, но и на 100% соответствует этим правилам. Это не рекомендации по стилю, а строгие требования к архитектуре файла.</DESCRIPTION>
|
|
||||||
<RULES>
|
|
||||||
<RULE>
|
|
||||||
<name>FileHeaderIntegrity</name>
|
|
||||||
<Description>Каждый `.kt` файл ДОЛЖЕН начинаться со стандартного заголовка из трех якорей, за которым следует объявление `package`. Порядок строгий и не подлежит изменению.</Description>
|
|
||||||
<Rationale>Этот заголовок служит 'паспортом' файла, позволяя любому инструменту (включая меня) мгновенно понять его расположение, имя и основное назначение, не парся код.</Rationale>
|
|
||||||
<Example>// [PACKAGE] com.example.your.package.name\n// [FILE] YourFileName.kt\n// [SEMANTICS] ui, viewmodel, state_management\npackage com.example.your.package.name</Example>
|
|
||||||
</RULE>
|
|
||||||
<RULE>
|
|
||||||
<name>SemanticKeywordTaxonomy</name>
|
|
||||||
<Description>Содержимое якоря `[SEMANTICS]` ДОЛЖНО состоять из ключевых слов, выбранных из предопределенного, контролируемого списка (таксономии).</Description>
|
|
||||||
<Rationale>Это устраняет неоднозначность и обеспечивает консистентность семантического тегирования по всему проекту, делая поиск и анализ на основе этих тегов надежным и предсказуемым.</Rationale>
|
|
||||||
<ExampleTaxonomy>
|
|
||||||
<Category>
|
|
||||||
<name>Layer</name>
|
|
||||||
<keywords>
|
|
||||||
<keyword>ui</keyword>
|
|
||||||
<keyword>domain</keyword>
|
|
||||||
<keyword>data</keyword>
|
|
||||||
<keyword>presentation</keyword>
|
|
||||||
</keywords>
|
|
||||||
</Category>
|
|
||||||
<Category>
|
|
||||||
<name>Component</name>
|
|
||||||
<keywords>
|
|
||||||
<keyword>viewmodel</keyword>
|
|
||||||
<keyword>usecase</keyword>
|
|
||||||
<keyword>repository</keyword>
|
|
||||||
<keyword>service</keyword>
|
|
||||||
<keyword>screen</keyword>
|
|
||||||
<keyword>component</keyword>
|
|
||||||
<keyword>dialog</keyword>
|
|
||||||
<keyword>model</keyword>
|
|
||||||
<keyword>entity</keyword>
|
|
||||||
</keywords>
|
|
||||||
</Category>
|
|
||||||
<Category>
|
|
||||||
<name>Concern</name>
|
|
||||||
<keywords>
|
|
||||||
<keyword>networking</keyword>
|
|
||||||
<keyword>database</keyword>
|
|
||||||
<keyword>caching</keyword>
|
|
||||||
<keyword>authentication</keyword>
|
|
||||||
<keyword>validation</keyword>
|
|
||||||
<keyword>parsing</keyword>
|
|
||||||
<keyword>state_management</keyword>
|
|
||||||
<keyword>navigation</keyword>
|
|
||||||
<keyword>di</keyword>
|
|
||||||
<keyword>testing</keyword>
|
|
||||||
</keywords>
|
|
||||||
</Category>
|
|
||||||
</ExampleTaxonomy>
|
|
||||||
</RULE>
|
|
||||||
<RULE>
|
|
||||||
<name>EntityContainerization</name>
|
|
||||||
<Description>Каждая ключевая сущность (`class`, `interface`, `object`, `data class`, `sealed class`, `enum class` и каждая публичная `fun`) ДОЛЖНА быть обернута в 'семантический контейнер'. Контейнер состоит из двух частей: открывающего блока разметки ПЕРЕД сущностью и закрывающего якоря ПОСЛЕ нее.</Description>
|
|
||||||
<Rationale>Это превращает плоский текстовый файл в иерархическое дерево семантических узлов. Это позволяет будущим AI-инструментам надежно парсить, анализировать и рефакторить код, точно зная, где начинается и заканчивается каждая сущность.</Rationale>
|
|
||||||
<Structure>1. **Открывающий Блок Разметки:** Располагается непосредственно перед KDoc/декларацией. Содержит сначала якорь `[ENTITY]`. 2. **Тело Сущности:** KDoc, сигнатура и тело функции/класса. 3. **Закрывающий Якорь:** Располагается сразу после закрывающей фигурной скобки `}` сущности. Формат: `// [END_ENTITY: Type('Name')]`.</Structure>
|
|
||||||
<Example>// [ENTITY: DataClass('Success')]\n/**\n * @summary Состояние успеха...\n */\ndata class Success(val labels: List<Label>) : LabelsListUiState\n// [END_ENTITY: DataClass('Success')]</Example>
|
|
||||||
</RULE>
|
|
||||||
<RULE>
|
|
||||||
<name>StructuralAnchors</name>
|
|
||||||
<Description>Крупные, не относящиеся к конкретной сущности блоки файла, такие как импорты и главный контракт файла, также должны быть обернуты в парные якоря.</Description>
|
|
||||||
<Rationale>Это четко разграничивает секции файла, позволяя инструментам работать с ними изолированно (например, 'добавить новый импорт в блок `[IMPORTS]`').</Rationale>
|
|
||||||
<Pairs>
|
|
||||||
<Pair>`// [IMPORTS]` и `// [END_IMPORTS]`</Pair>
|
|
||||||
<Pair>`// [CONTRACT]` и `// [END_CONTRACT]`</Pair>
|
|
||||||
</Pairs>
|
|
||||||
</RULE>
|
|
||||||
<RULE>
|
|
||||||
<name>FileTermination</name>
|
|
||||||
<Description>Каждый файл должен заканчиваться специальным закрывающим якорем, который сигнализирует о его полном завершении.</Description>
|
|
||||||
<Rationale>Это служит надежным маркером конца файла, защищая от случайного усечения и упрощая парсинг.</Rationale>
|
|
||||||
<Template>`// [END_FILE_YourFileName.kt]`</Template>
|
|
||||||
</RULE>
|
|
||||||
<RULE>
|
|
||||||
<name>NoStrayComments</name>
|
|
||||||
<Description>Традиционные, 'человеческие' комментарии (`// Вот это сложная логика` или `/* ... */`) КАТЕГОРИЧЕСКИ ЗАПРЕЩЕНЫ.</Description>
|
|
||||||
<Rationale>Такие комментарии являются 'семантическим шумом' для AI. Они неструктурированы, часто устаревают и не могут быть использованы для автоматического анализа. Вся необходимая информация должна передаваться через семантические якоря или формальные KDoc-контракты.</Rationale>
|
|
||||||
<ApprovedAlternative>
|
|
||||||
<Description>В исключительном случае, когда мне нужно оставить заметку для другого AI-агента или для себя в будущем (например, объяснить сложное архитектурное решение), я использую специальный, структурированный якорь:</Description>
|
|
||||||
<Format>`// [AI_NOTE]: Пояснение сложного решения.`</Format>
|
|
||||||
</ApprovedAlternative>
|
|
||||||
</RULE>
|
|
||||||
</RULES>
|
|
||||||
</PRINCIPLE>
|
|
||||||
<PRINCIPLE>
|
|
||||||
<name>DesignByContractAsFoundation</name>
|
|
||||||
<DESCRIPTION>Принцип 'Проектирование по контракту' (DbC) — это не опция, а фундаментальная основа моего подхода к разработке. Каждая функция и класс, которые я создаю, являются реализацией формального контракта между поставщиком (код) и клиентом (вызывающий код). Это устраняет двусмысленность, предотвращает ошибки и делает код самодокументируемым и предсказуемым.</DESCRIPTION>
|
|
||||||
<RULES>
|
|
||||||
<RULE>
|
|
||||||
<name>ContractFirstMindset</name>
|
|
||||||
<Description>Я всегда начинаю с проектирования и написания KDoc-контракта. Код является реализацией этой формальной спецификации. Проверки контракта (`require`, `check`) создаются до или вместе с основной логикой, а не после как запоздалая мысль.</Description>
|
|
||||||
</RULE>
|
|
||||||
<RULE>
|
|
||||||
<name>KDocAsFormalSpecification</name>
|
|
||||||
<Description>KDoc-блок является человекочитаемой формальной спецификацией контракта. Для правильной обработки механизмом Causal Attention, он ВСЕГДА предшествует блоку семантической разметки и декларации функции/класса. Я использую стандартизированный набор тегов для полного описания контракта.</Description>
|
|
||||||
<Tags>
|
|
||||||
<Tag>
|
|
||||||
<name>@param</name>
|
|
||||||
<description>Описывает **предусловия** для конкретного параметра. Что клиент должен гарантировать.</description>
|
|
||||||
</Tag>
|
|
||||||
<Tag>
|
|
||||||
<name>@return</name>
|
|
||||||
<description>Описывает **постусловия** для возвращаемого значения. Что поставщик гарантирует в случае успеха.</description>
|
|
||||||
</Tag>
|
|
||||||
<Tag>
|
|
||||||
<name>@throws</name>
|
|
||||||
<description>Описывает условия (обычно нарушение предусловий), при которых будет выброшено исключение. Это часть 'негативного' контракта.</description>
|
|
||||||
</Tag>
|
|
||||||
<Tag>
|
|
||||||
<name>@invariant</name>
|
|
||||||
<is_for>class</is_for>
|
|
||||||
<description>Явно описывает **инвариант** класса — условие, которое должно быть истинным всегда, когда объект не выполняет метод.</description>
|
|
||||||
</Tag>
|
|
||||||
<Tag>
|
|
||||||
<name>@sideeffect</name>
|
|
||||||
<description>Четко декларирует любые побочные эффекты (запись в БД, сетевой вызов, изменение внешнего состояния). Если их нет, я явно указываю `@sideeffect Отсутствуют.`.</description>
|
|
||||||
</Tag>
|
|
||||||
</Tags>
|
|
||||||
</RULE>
|
|
||||||
<RULE>
|
|
||||||
<name>PreconditionsWithRequire</name>
|
|
||||||
<Description>Предусловия (обязательства клиента) должны быть проверены в самом начале публичного метода с использованием `require(condition) { "Error message" }`. Это реализует принцип 'Fail-Fast' — немедленный отказ, если клиент нарушил контракт.</Description>
|
|
||||||
<Location>Первые исполняемые строки кода внутри тела функции, сразу после лога `[ENTRYPOINT]`.</Location>
|
|
||||||
</RULE>
|
|
||||||
<RULE>
|
|
||||||
<name>PostconditionsWithCheck</name>
|
|
||||||
<Description>Постусловия (гарантии поставщика) должны быть проверены в самом конце метода, прямо перед возвратом управления, с использованием `check(condition) { "Error message" }`. Это самопроверка, гарантирующая, что моя работа выполнена правильно.</Description>
|
|
||||||
<Location>Последние строки кода внутри тела функции, непосредственно перед каждым оператором `return`.</Location>
|
|
||||||
</RULE>
|
|
||||||
<RULE>
|
|
||||||
<name>InvariantsWithInitAndCheck</name>
|
|
||||||
<Description>Инварианты класса (условия, которые всегда должны быть истинны для экземпляра) проверяются в двух местах: в блоке `init` для гарантии корректного создания объекта, и в конце каждого публичного метода, изменяющего состояние, с помощью `check(condition)`.</Description>
|
|
||||||
<Location>Блок `init` и конец каждого метода-мутатора.</Location>
|
|
||||||
</RULE>
|
|
||||||
</RULES>
|
|
||||||
</PRINCIPLE>
|
|
||||||
<PRINCIPLE>
|
|
||||||
<name>AIFriendlyLogging</name>
|
|
||||||
<DESCRIPTION>Логирование — это мой критически важный механизм для декларации `belief state` (внутреннего состояния/намерения) и трассировки выполнения кода. Каждая значимая операция, проверка контракта или изменение состояния ДОЛЖНЫ сопровождаться структурированной записью в лог. Это делает поведение кода в рантайме полностью прозрачным и отлаживаемым.</DESCRIPTION>
|
|
||||||
<RULES>
|
|
||||||
<RULE>
|
|
||||||
<name>ArchitecturalBoundaryCompliance</name>
|
|
||||||
<Description>Логирование в его прямой реализации (т.е. вызов `logger.info`, `Timber.i` и т.д.) **КАТЕГОРИЧЕСКИ ЗАПРЕЩЕНО** внутри модуля `:domain`.</Description>
|
|
||||||
<Rationale>`Согласно принципам чистой архитектуры, слой `domain` должен быть полностью независим от внешних фреймворков и платформ (включая Android). Его задача — содержать исключительно бизнес-логику. Логирование, как и другие инфраструктурные задачи, должно выполняться в более внешних слоях, таких как `:data` или `:app`.`</Rationale>
|
|
||||||
</RULE>
|
|
||||||
<RULE>
|
|
||||||
<name>StructuredLogFormat</name>
|
|
||||||
<Description>Все записи в лог должны строго следовать этому формату для обеспечения машиночитаемости и консистентности.</Description>
|
|
||||||
<Format>`logger.level("[LEVEL][ANCHOR_NAME][BELIEF_STATE] Message with {} placeholders for data.")`</Format>
|
|
||||||
</RULE>
|
|
||||||
<RULE>
|
|
||||||
<name>ComponentDefinitions</name>
|
|
||||||
<COMPONENTS>
|
|
||||||
<Component>
|
|
||||||
<name>[LEVEL]</name>
|
|
||||||
<description>Один из стандартных уровней логирования: `DEBUG`, `INFO`, `WARN`, `ERROR`. Я также использую специальный уровень `CONTRACT_VIOLATION` для логов, связанных с провалом `require` или `check`.</description>
|
|
||||||
</Component>
|
|
||||||
<Component>
|
|
||||||
<name>[ANCHOR_NAME]</name>
|
|
||||||
<description>Точное имя семантического якоря из кода, к которому относится данный лог. Это создает неразрывную связь между статическим кодом и его выполнением. Например: `[ENTRYPOINT]`, `[ACTION]`, `[PRECONDITION]`, `[FALLBACK]`.</description>
|
|
||||||
</Component>
|
|
||||||
<Component>
|
|
||||||
<name>[BELIEF_STATE]</name>
|
|
||||||
<description>Краткое, четкое описание моего намерения в `snake_case`. Это отвечает на вопрос 'почему' я выполняю этот код. Примеры: `validating_input`, `calling_external_api`, `mutating_state`, `persisting_data`, `handling_exception`, `mapping_dto`.</description>
|
|
||||||
</Component>
|
|
||||||
</COMPONENTS>
|
|
||||||
</RULE>
|
|
||||||
<RULE>
|
|
||||||
<name>Example</name>
|
|
||||||
<Description>Вот как я применяю этот стандарт на практике внутри функции:</Description>
|
|
||||||
<code>// ...
|
|
||||||
// [ENTRYPOINT]
|
|
||||||
suspend fun processPayment(request: PaymentRequest): Result {
|
|
||||||
logger.info("[INFO][ENTRYPOINT][processing_payment] Starting payment process for request '{}'.", request.id)
|
|
||||||
|
|
||||||
// [PRECONDITION]
|
|
||||||
logger.debug("[DEBUG][PRECONDITION][validating_input] Validating payment request.")
|
|
||||||
require(request.amount > 0) { "Payment amount must be positive." }
|
|
||||||
|
|
||||||
// [ACTION]
|
|
||||||
logger.info("[INFO][ACTION][calling_external_api] Calling payment gateway for amount {}.", request.amount)
|
|
||||||
val result = paymentGateway.execute(request)
|
|
||||||
|
|
||||||
// ...
|
|
||||||
}</code>
|
|
||||||
</RULE>
|
|
||||||
<RULE>
|
|
||||||
<name>TraceabilityIsMandatory</name>
|
|
||||||
<Description>Каждая запись в логе ДОЛЖНА быть семантически привязана к якорю в коде. Логи без якоря запрещены. Это не опция, а фундаментальное требование для обеспечения полной трассируемости потока выполнения.</Description>
|
|
||||||
</RULE>
|
|
||||||
<RULE>
|
|
||||||
<name>DataAsArguments_NotStrings</name>
|
|
||||||
<Description>Данные (переменные, значения) должны передаваться в логгер как отдельные аргументы, а не встраиваться в строку сообщения. Я использую плейсхолдеры `{}`. Это повышает производительность и позволяет системам сбора логов индексировать эти данные.</Description>
|
|
||||||
</RULE>
|
|
||||||
</RULES>
|
|
||||||
</PRINCIPLE>
|
|
||||||
</PRINCIPLES>
|
|
||||||
</SEMANTIC_ENRICHMENT_PROTOCOL>
|
|
||||||
Reference in New Issue
Block a user