new test contracts

This commit is contained in:
2026-02-26 19:29:07 +03:00
parent a8f7147500
commit 81d62c1345
10 changed files with 143 additions and 135 deletions

View File

@@ -6,7 +6,7 @@ description: Audit AI-generated unit tests. Your goal is to aggressively search
**OBJECTIVE:** Audit AI-generated unit tests. Your goal is to aggressively search for "Test Tautologies", "Logic Echoing", and "Contract Negligence". You are the final gatekeeper. If a test is meaningless, you MUST reject it. **OBJECTIVE:** Audit AI-generated unit tests. Your goal is to aggressively search for "Test Tautologies", "Logic Echoing", and "Contract Negligence". You are the final gatekeeper. If a test is meaningless, you MUST reject it.
**INPUT:** **INPUT:**
1. SOURCE CODE (with GRACE-Poly `[DEF]` Contract: `@PRE`, `@POST`, `@TEST_DATA`). 1. SOURCE CODE (with GRACE-Poly `[DEF]` Contract: `@PRE`, `@POST`, `@TEST_`).
2. GENERATED TEST CODE. 2. GENERATED TEST CODE.
### I. CRITICAL ANTI-PATTERNS (REJECT IMMEDIATELY IF FOUND): ### I. CRITICAL ANTI-PATTERNS (REJECT IMMEDIATELY IF FOUND):
@@ -17,7 +17,7 @@ description: Audit AI-generated unit tests. Your goal is to aggressively search
2. **The Logic Mirror (Echoing):** 2. **The Logic Mirror (Echoing):**
- *Definition:* The test re-implements the exact same algorithmic logic found in the source code to calculate the `expected_result`. If the original logic is flawed, the test will falsely pass. - *Definition:* The test re-implements the exact same algorithmic logic found in the source code to calculate the `expected_result`. If the original logic is flawed, the test will falsely pass.
- *Rule:* Tests must assert against **static, predefined outcomes** (from `@TEST_DATA` or explicit constants), NOT dynamically calculated outcomes using the same logic as the source. - *Rule:* Tests must assert against **static, predefined outcomes** (from `@TEST_` or explicit constants), NOT dynamically calculated outcomes using the same logic as the source.
3. **The "Happy Path" Illusion:** 3. **The "Happy Path" Illusion:**
- *Definition:* The test suite only checks successful executions but ignores the `@PRE` conditions (Negative Testing). - *Definition:* The test suite only checks successful executions but ignores the `@PRE` conditions (Negative Testing).
@@ -31,7 +31,7 @@ description: Audit AI-generated unit tests. Your goal is to aggressively search
Evaluate the test code against these criteria: Evaluate the test code against these criteria:
1. **Target Invocation:** Does the test actually import and call the function/component declared in the `@RELATION: VERIFIES` tag? 1. **Target Invocation:** Does the test actually import and call the function/component declared in the `@RELATION: VERIFIES` tag?
2. **Contract Alignment:** Does the test suite cover 100% of the `@PRE` (negative tests) and `@POST` (assertions) conditions from the source contract? 2. **Contract Alignment:** Does the test suite cover 100% of the `@PRE` (negative tests) and `@POST` (assertions) conditions from the source contract?
3. **Data Usage:** Does the test use the exact scenarios defined in `@TEST_DATA`? 3. **Data Usage:** Does the test use the exact scenarios defined in `@TEST_`?
4. **Mocking Sanity:** Are external dependencies mocked correctly WITHOUT mocking the system under test itself? 4. **Mocking Sanity:** Are external dependencies mocked correctly WITHOUT mocking the system under test itself?
### III. OUTPUT FORMAT ### III. OUTPUT FORMAT

View File

@@ -26,7 +26,7 @@
4. **ТЕСТИРОВАНИЕ И КАЧЕСТВО:** 4. **ТЕСТИРОВАНИЕ И КАЧЕСТВО:**
- Я презираю "Test Tautologies" (тесты ради покрытия, зеркалящие логику). - Я презираю "Test Tautologies" (тесты ради покрытия, зеркалящие логику).
- Тесты должны быть Contract-Driven. Если есть `@PRE`, я ожидаю тест на его нарушение. - Тесты должны быть Contract-Driven. Если есть `@PRE`, я ожидаю тест на его нарушение.
- Тесты обязаны использовать `@TEST_DATA` из контрактов. - Тесты обязаны использовать `@TEST_` из контрактов.
5. **ГЛОБАЛЬНАЯ НАВИГАЦИЯ (GraphRAG):** 5. **ГЛОБАЛЬНАЯ НАВИГАЦИЯ (GraphRAG):**
- Понимай, что мы работаем в среде Sparse Attention. - Понимай, что мы работаем в среде Sparse Attention.

View File

@@ -5,12 +5,75 @@
# @LAYER: Domain (Core) # @LAYER: Domain (Core)
# @RELATION: DEPENDS_ON -> [DEF:Infra:PostgresDB] # @RELATION: DEPENDS_ON -> [DEF:Infra:PostgresDB]
# @RELATION: DEPENDS_ON -> [DEF:Infra:AuditLog] # @RELATION: DEPENDS_ON -> [DEF:Infra:AuditLog]
#
# @INVARIANT: Total system balance must remain constant (Double-Entry Bookkeeping). # @INVARIANT: Total system balance must remain constant (Double-Entry Bookkeeping).
# @INVARIANT: Negative transfers are strictly forbidden. # @INVARIANT: Negative transfers are strictly forbidden.
# @INVARIANT: No partial commit must occur under failure (ACID Atomicity).
# @TEST_CONTRACT: TransferInput ->
# {
# required_fields: {
# sender_id: str,
# receiver_id: str,
# amount: Decimal
# },
# invariants: [
# "amount > 0",
# "sender_id != receiver_id"
# ],
# constraints: [
# "sender must exist",
# "receiver must exist"
# ]
# }
# @TEST_CONTRACT: TransferResult ->
# {
# required_fields: {
# tx_id: str,
# status: str,
# new_balance: Decimal
# },
# invariants: [
# "status == COMPLETED implies balance mutation occurred"
# ]
# }
# @TEST_FIXTURE: sufficient_funds ->
# {
# sender_balance: 500.00,
# receiver_balance: 100.00,
# amount: 100.00
# }
# @TEST_EDGE: insufficient_funds ->
# {
# sender_balance: 50.00,
# receiver_balance: 100.00,
# amount: 100.00
# }
#
# @TEST_EDGE: negative_amount ->
# {
# sender_balance: 500.00,
# receiver_balance: 100.00,
# amount: -10.00
# }
#
# @TEST_EDGE: self_transfer ->
# {
# sender_id: "acc_A",
# receiver_id: "acc_A",
# amount: 10.00
# }
# @TEST_EDGE: audit_failure -> raises Exception
# @TEST_EDGE: concurrency_conflict -> special: concurrent_execution
# @TEST_INVARIANT: total_balance_constant -> verifies: [sufficient_funds, concurrency_conflict]
# @TEST_INVARIANT: no_partial_commit -> verifies: [audit_failure]
# @TEST_INVARIANT: negative_transfer_forbidden -> verifies: [negative_amount]
# @TEST_DATA: sufficient_funds -> {"from": "acc_A", "to": "acc_B", "amt": 100.00}
# @TEST_DATA: insufficient_funds -> {"from": "acc_empty", "to": "acc_B", "amt": 1000.00}
# @TEST_DATA: concurrency_lock -> {./fixtures/transactions.json#race_condition}
from decimal import Decimal from decimal import Decimal
from typing import NamedTuple from typing import NamedTuple

View File

@@ -1,24 +1,67 @@
<!-- [DEF:FrontendComponentShot:Component] --> <!-- [DEF:FrontendComponentShot:Component] -->
<!-- /** <!--
/**
* @TIER: CRITICAL * @TIER: CRITICAL
* @SEMANTICS: Task, Button, Action, UX * @SEMANTICS: Task, Button, Action, UX
* @PURPOSE: Action button to spawn a new task with full UX feedback cycle. * @PURPOSE: Action button to spawn a new task with full UX feedback cycle.
* @LAYER: UI (Presentation) * @LAYER: UI (Presentation)
* @RELATION: CALLS -> postApi * @RELATION: CALLS -> postApi
*
* @INVARIANT: Must prevent double-submission while loading. * @INVARIANT: Must prevent double-submission while loading.
* @INVARIANT: Loading state must always terminate (no infinite spinner).
* @INVARIANT: User must receive feedback on both success and failure.
* *
* @TEST_DATA: idle_state -> {"isLoading": false} * @TEST_CONTRACT: ComponentState ->
* @TEST_DATA: loading_state -> {"isLoading": true} * {
* required_fields: {
* isLoading: bool
* },
* invariants: [
* "isLoading=true implies button.disabled=true",
* "isLoading=true implies aria-busy=true",
* "isLoading=true implies spinner visible"
* ]
* }
* *
* @UX_STATE: Idle -> Button enabled, primary color. * @TEST_CONTRACT: ApiResponse ->
* @UX_STATE: Loading -> Button disabled, spinner visible. * {
* @UX_STATE: Error -> Toast notification triggers. * required_fields: {},
* optional_fields: {
* task_id: str
* }
* }
* @TEST_FIXTURE: idle_state ->
* {
* isLoading: false
* }
*
* @TEST_FIXTURE: successful_response ->
* {
* task_id: "task_123"
* }
* @TEST_EDGE: api_failure -> raises Error("Network")
* @TEST_EDGE: empty_response -> {}
* @TEST_EDGE: rapid_double_click -> special: concurrent_click
* @TEST_EDGE: unresolved_promise -> special: pending_state
* @TEST_INVARIANT: prevent_double_submission -> verifies: [rapid_double_click]
* @TEST_INVARIANT: loading_state_consistency -> verifies: [idle_state, pending_state]
* @TEST_INVARIANT: feedback_always_emitted -> verifies: [successful_response, api_failure]
* @UX_STATE: Idle -> Button enabled, primary color, no spinner.
* @UX_STATE: Loading -> Button disabled, spinner visible, aria-busy=true.
* @UX_STATE: Success -> Toast success displayed.
* @UX_STATE: Error -> Toast error displayed.
*
* @UX_FEEDBACK: toast.success, toast.error
* *
* @UX_FEEDBACK: Toast success/error.
* @UX_TEST: Idle -> {click: spawnTask, expected: isLoading=true} * @UX_TEST: Idle -> {click: spawnTask, expected: isLoading=true}
* @UX_TEST: Success -> {api_resolve: 200, expected: toast.success called} * @UX_TEST: Loading -> {double_click: ignored, expected: single_api_call}
*/ * @UX_TEST: Success -> {api_resolve: task_id, expected: toast.success called}
--> * @UX_TEST: Error -> {api_reject: error, expected: toast.error called}
-->
<script> <script>
import { postApi } from "$lib/api.js"; import { postApi } from "$lib/api.js";
import { t } from "$lib/i18n"; import { t } from "$lib/i18n";

View File

@@ -95,7 +95,7 @@
- Tester Agent **ОБЯЗАН** использовать @TEST_CONTRACT, @TEST_FIXTURE и @TEST_EDGE при написании тестов для CRITICAL модулей. - Tester Agent **ОБЯЗАН** использовать @TEST_CONTRACT, @TEST_FIXTURE и @TEST_EDGE при написании тестов для CRITICAL модулей.
2. **STANDARD** (BizLogic/**Forms**): 2. **STANDARD** (BizLogic/**Forms**):
- Требование: Базовый контракт (@PURPOSE, @UX_STATE), Логи, @RELATION. - Требование: Базовый контракт (@PURPOSE, @UX_STATE), Логи, @RELATION.
- @TEST_DATA: Рекомендуется для Complex Forms. - @TEST_INVARIANT, @TEST_CONTRACT: Рекомендуется для Complex Forms.
3. **TRIVIAL** (DTO/**Atoms**): 3. **TRIVIAL** (DTO/**Atoms**):
- Требование: Только Якоря [DEF] и @PURPOSE. - Требование: Только Якоря [DEF] и @PURPOSE.

View File

@@ -6,7 +6,7 @@ description: Audit AI-generated unit tests. Your goal is to aggressively search
**OBJECTIVE:** Audit AI-generated unit tests. Your goal is to aggressively search for "Test Tautologies", "Logic Echoing", and "Contract Negligence". You are the final gatekeeper. If a test is meaningless, you MUST reject it. **OBJECTIVE:** Audit AI-generated unit tests. Your goal is to aggressively search for "Test Tautologies", "Logic Echoing", and "Contract Negligence". You are the final gatekeeper. If a test is meaningless, you MUST reject it.
**INPUT:** **INPUT:**
1. SOURCE CODE (with GRACE-Poly `[DEF]` Contract: `@PRE`, `@POST`, `@TEST_DATA`). 1. SOURCE CODE (with GRACE-Poly `[DEF]` Contract: `@PRE`, `@POST`, `@TEST_`).
2. GENERATED TEST CODE. 2. GENERATED TEST CODE.
### I. CRITICAL ANTI-PATTERNS (REJECT IMMEDIATELY IF FOUND): ### I. CRITICAL ANTI-PATTERNS (REJECT IMMEDIATELY IF FOUND):
@@ -17,7 +17,7 @@ description: Audit AI-generated unit tests. Your goal is to aggressively search
2. **The Logic Mirror (Echoing):** 2. **The Logic Mirror (Echoing):**
- *Definition:* The test re-implements the exact same algorithmic logic found in the source code to calculate the `expected_result`. If the original logic is flawed, the test will falsely pass. - *Definition:* The test re-implements the exact same algorithmic logic found in the source code to calculate the `expected_result`. If the original logic is flawed, the test will falsely pass.
- *Rule:* Tests must assert against **static, predefined outcomes** (from `@TEST_DATA` or explicit constants), NOT dynamically calculated outcomes using the same logic as the source. - *Rule:* Tests must assert against **static, predefined outcomes** (from `@TEST_` or explicit constants), NOT dynamically calculated outcomes using the same logic as the source.
3. **The "Happy Path" Illusion:** 3. **The "Happy Path" Illusion:**
- *Definition:* The test suite only checks successful executions but ignores the `@PRE` conditions (Negative Testing). - *Definition:* The test suite only checks successful executions but ignores the `@PRE` conditions (Negative Testing).
@@ -31,7 +31,7 @@ description: Audit AI-generated unit tests. Your goal is to aggressively search
Evaluate the test code against these criteria: Evaluate the test code against these criteria:
1. **Target Invocation:** Does the test actually import and call the function/component declared in the `@RELATION: VERIFIES` tag? 1. **Target Invocation:** Does the test actually import and call the function/component declared in the `@RELATION: VERIFIES` tag?
2. **Contract Alignment:** Does the test suite cover 100% of the `@PRE` (negative tests) and `@POST` (assertions) conditions from the source contract? 2. **Contract Alignment:** Does the test suite cover 100% of the `@PRE` (negative tests) and `@POST` (assertions) conditions from the source contract?
3. **Data Usage:** Does the test use the exact scenarios defined in `@TEST_DATA`? 3. **Data Usage:** Does the test use the exact scenarios defined in `@TEST_`?
4. **Mocking Sanity:** Are external dependencies mocked correctly WITHOUT mocking the system under test itself? 4. **Mocking Sanity:** Are external dependencies mocked correctly WITHOUT mocking the system under test itself?
### III. OUTPUT FORMAT ### III. OUTPUT FORMAT

View File

@@ -20,7 +20,7 @@ Execute full testing cycle: analyze code for testable modules, write tests with
1. **NEVER delete existing tests** - Only update if they fail due to bugs in the test or implementation 1. **NEVER delete existing tests** - Only update if they fail due to bugs in the test or implementation
2. **NEVER duplicate tests** - Check existing tests first before creating new ones 2. **NEVER duplicate tests** - Check existing tests first before creating new ones
3. **Use TEST_DATA fixtures** - For CRITICAL tier modules, read @TEST_DATA from .specify/memory/semantics.md 3. **Use TEST_DATA fixtures** - For CRITICAL tier modules, read @TEST_ from semantics header
4. **Co-location required** - Write tests in `__tests__` directories relative to the code being tested 4. **Co-location required** - Write tests in `__tests__` directories relative to the code being tested
## Execution Steps ## Execution Steps
@@ -42,7 +42,7 @@ Determine:
**From .specify/memory/semantics.md:** **From .specify/memory/semantics.md:**
- Read @TIER annotations for modules - Read @TIER annotations for modules
- For CRITICAL modules: Read @TEST_DATA fixtures - For CRITICAL modules: Read @TEST_ fixtures
**From existing tests:** **From existing tests:**
- Scan `__tests__` directories for existing tests - Scan `__tests__` directories for existing tests
@@ -61,7 +61,7 @@ Create coverage matrix:
For each module requiring tests: For each module requiring tests:
1. **Check existing tests**: Scan `__tests__/` for duplicates 1. **Check existing tests**: Scan `__tests__/` for duplicates
2. **Read TEST_DATA**: If CRITICAL tier, read @TEST_DATA from .specify/memory/semantics.md 2. **Read TEST_DATA**: If CRITICAL tier, read @TEST_ from semantic header
3. **Write test**: Follow co-location strategy 3. **Write test**: Follow co-location strategy
- Python: `src/module/__tests__/test_module.py` - Python: `src/module/__tests__/test_module.py`
- Svelte: `src/lib/components/__tests__/test_component.test.js` - Svelte: `src/lib/components/__tests__/test_component.test.js`

View File

@@ -20,7 +20,7 @@ Analyze test failure reports, identify root causes, and fix implementation issue
1. **USE CODER MODE**: Always switch to `coder` mode for code fixes 1. **USE CODER MODE**: Always switch to `coder` mode for code fixes
2. **SEMANTIC PROTOCOL**: Never remove semantic annotations ([DEF], @TAGS). Only update code logic. 2. **SEMANTIC PROTOCOL**: Never remove semantic annotations ([DEF], @TAGS). Only update code logic.
3. **TEST DATA**: If tests use @TEST_DATA fixtures, preserve them when fixing 3. **TEST DATA**: If tests use @TEST_ fixtures, preserve them when fixing
4. **NO DELETION**: Never delete existing tests or semantic annotations 4. **NO DELETION**: Never delete existing tests or semantic annotations
5. **REPORT FIRST**: Always write a fix report before making changes 5. **REPORT FIRST**: Always write a fix report before making changes

View File

@@ -42,7 +42,7 @@ Determine:
**From .ai/standards/semantics.md:** **From .ai/standards/semantics.md:**
- Read @TIER annotations for modules - Read @TIER annotations for modules
- For CRITICAL modules: Read @TEST_DATA fixtures - For CRITICAL modules: Read @TEST_ fixtures
**From existing tests:** **From existing tests:**
- Scan `__tests__` directories for existing tests - Scan `__tests__` directories for existing tests
@@ -61,7 +61,7 @@ Create coverage matrix:
For each module requiring tests: For each module requiring tests:
1. **Check existing tests**: Scan `__tests__/` for duplicates 1. **Check existing tests**: Scan `__tests__/` for duplicates
2. **Read TEST_DATA**: If CRITICAL tier, read @TEST_DATA from .ai/standards/semantics.md 2. **Read TEST_DATA**: If CRITICAL tier, read @TEST_ from semantics header
3. **Write test**: Follow co-location strategy 3. **Write test**: Follow co-location strategy
- Python: `src/module/__tests__/test_module.py` - Python: `src/module/__tests__/test_module.py`
- Svelte: `src/lib/components/__tests__/test_component.test.js` - Svelte: `src/lib/components/__tests__/test_component.test.js`

View File

@@ -1,98 +0,0 @@
### **SYSTEM STANDARD: GRACE-Poly (UX Edition)**
РОЛЬ: Архитектор Семантической Когерентности.
ЗАДАЧА: Генерация кода (Python/Svelte).
РЕЖИМ: Строгий. Детерминированный. Без болтовни.
#### I. ЗАКОН (АКСИОМЫ)
1. Смысл первичен. Код вторичен.
2. Контракт (@PRE/@POST) — источник истины.
**3. UX — это логика, а не декор. Состояния интерфейса — часть контракта.**
4. Структура `[DEF]...[/DEF]` — нерушима.
5. Архитектура в Header — неизменяема.
6. Сложность фрактала ограничена: модуль < 300 строк.
#### II. СИНТАКСИС (ЖЕСТКИЙ ФОРМАТ)
ЯКОРЬ (Контейнер):
Начало: `# [DEF:id:Type]` (Python) | `<!-- [DEF:id:Type] -->` (Svelte)
Конец: `# [/DEF:id:Type]` (Python) | `<!-- [/DEF:id:Type] -->` (Svelte) (ОБЯЗАТЕЛЬНО для аккумуляции)
Типы: Module, Class, Function, Component, Store.
ТЕГ (Метаданные):
Вид: `# @KEY: Value` (внутри DEF, до кода).
ГРАФ (Связи):
Вид: `# @RELATION: PREDICATE -> TARGET_ID`
Предикаты: DEPENDS_ON, CALLS, INHERITS, IMPLEMENTS, DISPATCHES, **BINDS_TO**.
#### III. СТРУКТУРА ФАЙЛА
1. HEADER (Всегда первый):
[DEF:filename:Module]
@TIER: [CRITICAL|STANDARD|TRIVIAL] (Дефолт: STANDARD)
@SEMANTICS: [keywords]
@PURPOSE: [Главная цель]
@LAYER: [Domain/UI/Infra]
@RELATION: [Зависимости]
@INVARIANT: [Незыблемое правило]
2. BODY: Импорты -> Реализация.
3. FOOTER: [/DEF:filename]
#### IV. КОНТРАКТ (DBC & UX)
Расположение: Внутри [DEF], ПЕРЕД кодом.
Стиль Python: Комментарии `# @TAG`.
Стиль Svelte: JSDoc `/** @tag */` внутри `<script>`.
**Базовые Теги:**
@PURPOSE: Суть (High Entropy).
@PRE: Входные условия.
@POST: Гарантии выхода.
@SIDE_EFFECT: Мутации, IO.
**UX Теги (Svelte/Frontend):**
**@UX_STATE:** `[StateName] -> Визуальное поведение` (Idle, Loading, Error).
**@UX_FEEDBACK:** Реакция системы (Toast, Shake, Red Border).
**@UX_RECOVERY:** Механизм исправления ошибки пользователем (Retry, Clear Input).
**UX Testing Tags (для Tester Agent):**
**@UX_TEST:** Спецификация теста для UX состояния.
Формат: `@UX_TEST: [state] -> {action, expected}`
Пример: `@UX_TEST: Idle -> {click: toggle, expected: isExpanded=true}`
Правило: Не используй `assert` в коде, используй `if/raise` или `guards`.
#### V. АДАПТАЦИЯ (TIERS)
Определяется тегом `@TIER` в Header.
1. **CRITICAL** (Core/Security/**Complex UI**):
- Требование: Полный контракт (включая **все @UX теги**), Граф, Инварианты, Строгие Логи.
- **@TEST_DATA**: Обязательные эталонные данные для тестирования. Формат:
```
@TEST_DATA: fixture_name -> {JSON_PATH} | {INLINE_DATA}
```
Примеры:
- `@TEST_DATA: valid_user -> {./fixtures/users.json#valid}`
- `@TEST_DATA: empty_state -> {"dashboards": [], "total": 0}`
- Tester Agent **ОБЯЗАН** использовать @TEST_DATA при написании тестов для CRITICAL модулей.
2. **STANDARD** (BizLogic/**Forms**):
- Требование: Базовый контракт (@PURPOSE, @UX_STATE), Логи, @RELATION.
- @TEST_DATA: Рекомендуется для Complex Forms.
3. **TRIVIAL** (DTO/**Atoms**):
- Требование: Только Якоря [DEF] и @PURPOSE.
#### VI. ЛОГИРОВАНИЕ (BELIEF STATE & TASK LOGS)
Цель: Трассировка для самокоррекции и пользовательский мониторинг.
Python:
- Системные логи: Context Manager `with belief_scope("ID"):`.
- Логи задач: `context.logger.info("msg", source="component")`.
Svelte: `console.log("[ID][STATE] Msg")`.
Состояния: Entry -> Action -> Coherence:OK / Failed -> Exit.
Инвариант: Каждый лог задачи должен иметь атрибут `source` для фильтрации.
#### VII. АЛГОРИТМ ГЕНЕРАЦИИ
1. АНАЛИЗ. Оцени TIER, слой и UX-требования.
2. КАРКАС. Создай `[DEF]`, Header и Контракты.
3. РЕАЛИЗАЦИЯ. Напиши логику, удовлетворяющую Контракту (и UX-состояниям).
4. ЗАМЫКАНИЕ. Закрой все `[/DEF]`.
ЕСЛИ ошибка или противоречие -> СТОП. Выведи `[COHERENCE_CHECK_FAILED]`.