Skip to content

feat(test): expose stable JUnit and Allure artifacts - #52

Open
korolevpavel wants to merge 19 commits into
alkoleft:masterfrom
korolevpavel:feat/issue-26-test-artifacts
Open

feat(test): expose stable JUnit and Allure artifacts#52
korolevpavel wants to merge 19 commits into
alkoleft:masterfrom
korolevpavel:feat/issue-26-test-artifacts

Conversation

@korolevpavel

@korolevpavel korolevpavel commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Summary

  • expose one stable typed artifact contract for YaXUnit and Vanessa Automation
  • generate JUnit and Allure results together, aggregate every native JUnit report, and use the report summary as the test-result source of truth
  • retain unique per-run directories on success, test failure, cancellation, and infrastructure failure, with existing-only deterministic artifact inventory
  • publish platform/runner logs plus optional error details and screenshots
  • preserve the upstream --no-build contract: file-infobase preflight runs before artifact allocation, while MCP remains build-first
  • harden artifact traversal and Vanessa log materialization against symlink/reparse races, including atomic replacement on Unix and Windows
  • document the external JSON and artifact workflow in the repository skill

Closes #26

Verification

  • cargo fmt --all -- --check
  • cargo check --locked
  • cargo test --locked --test cli_test — 30 passed
  • cargo test --locked --bin v8-runner use_cases::run_tests — 30 passed
  • cargo test --locked --test architecture_guardrails — 5 passed
  • cargo test --locked --bin v8-runner mcp::service::tests — 36 passed
  • cargo test --locked --test mcp_stdio mcp_stdio_run_ — 2 passed
  • cargo test --locked --all-targets — 718 passed; the same 48 known macOS/sandbox-sensitive baseline failures remain (/private/var canonicalization, denied local binds, EDT/interactive timing, and launch temp-log races); no issue test: возвращать JUnit/Allure/log как стабильные artifacts #26 test failed

Review notes

  • independent general review and a separate Rust expert review found no blocking issues
  • Windows-specific filesystem code was statically checked against windows-sys 0.61.2 and covered by architecture guards; this macOS host could not execute the Windows path, so the repository Windows CI job is the runtime gate
  • strict repository-wide Clippy remains red on existing upstream lint debt; no issue-specific defect was identified from that output

Summary by CodeRabbit

  • Новые возможности
    • Добавлена поддержка выгрузки результатов в формат Allure наряду с JUnit XML.
    • Артефакты теперь сохраняются и для успешных, и для неуспешных запусков; диагностики упорядочены и публикуются внутри run-каталога.
    • Для отсутствующих/пустых JUnit или Allure применяется классификация invalid_output; добавлены структурированные типы и пути артефактов в результатах.
    • Ограничен объём optional-диагностик (до 100 файлов) с предсказуемым усечением.
  • Документация
    • Обновлены требования к структуре артефактов и поведению при ошибках (CLI/MCP JSON, layout run-directory).

- specify native JUnit and Allure contracts
- define report-authoritative terminal classification
- define TDD implementation tasks
- require independent verification and Rust review
- distinguish JUnit and Allure outputs
- retain supported test artifacts on success
- configure simultaneous native reports
- inventory only materialized run outputs
- materialize JUnit and Allure fixture outputs\n- expose only existing retained artifact paths
- aggregate deterministic JUnit summaries
- preserve test failures across nonzero exits
- attach existing run artifacts to post-setup interruptions
- make test completion policies exhaustive
- cover CLI and MCP artifact contracts
- document retained test diagnostics
- restore legacy artifact compatibility and retain build failures
- secure runner log materialization and iterative artifact discovery
- inventory optional diagnostics with deterministic typed paths
- reject source reparse points through verified no-follow handles
- atomically replace logs with write-through MoveFileExW
- preserve extended-length paths and add Windows guard coverage
- preserve no-build preflight before artifact allocation
- retain build-first artifacts across infrastructure failures
- align typed test errors and external artifact documentation
@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@korolevpavel, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 36 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f2fa1db6-be94-4b8d-94e5-649320d16310

📥 Commits

Reviewing files that changed from the base of the PR and between 5c3fb7c and 3b3745a.

📒 Files selected for processing (3)
  • SKILL/references/testing.md
  • tests/cli_test.rs
  • tests/mcp_stdio.rs

Walkthrough

Изменён контракт результатов тестов для YaXUnit и Vanessa: добавлены одновременные JUnit и Allure, стабильная инвентаризация артефактов, report-first классификация исходов, сохранение run-директорий и расширенные CLI/MCP-тесты.

Changes

Контракт и статусы

Layer / File(s) Summary
Контракты артефактов и статусов
src/domain/*.rs, src/use_cases/request.rs, docs/superpowers/specs/..., docs/superpowers/plans/...
Добавлены типы JUnit/Allure, коды ошибок Allure, опциональные retained paths и правила классификации native report ошибок.
Генерация JUnit и Allure
src/use_cases/run_tests.rs, src/use_cases/vanessa.rs, src/cli/execute.rs, src/mcp/service.rs, Cargo.toml
YaXUnit и Vanessa создают оба формата отчётов, используют отдельные каталоги и сохраняют успешные артефакты.
Обнаружение и инвентаризация отчетов
src/use_cases/run_tests.rs, docs/superpowers/*
Добавлены multi-JUnit discovery и aggregation, Allure validation, стабильная сортировка артефактов, бюджетирование диагностик и исключение symlink-выходов.
Классификация завершения и сохранение
src/use_cases/run_tests/coordinator.rs, src/use_cases/run_tests/helpers.rs, src/use_cases/run_tests.rs
Изменены build/run-последовательность, обработка отмены, report-first classification и сохранение run-директорий при ошибках.
CLI, MCP и документация
tests/cli_test.rs, tests/mcp_stdio.rs, tests/architecture_guardrails.rs, SKILL/*, docs/CAPABILITIES.md, scripts/test/*
Добавлены сценарии для missing/empty reports, test failures при nonzero exit, повторных запусков, JSON-контрактов и Windows atomic replacement.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

  • alkoleft/v8-runner-rust#36: затрагивает режимы --no-build и skip в координаторе запусков.

Poem

Я, кролик, несу JUnit и Allure в нору,
Логи укладываю в точную структуру.
Красный тест — не потерян, отчёт говорит,
Каждый новый запуск свой след сохранит.
Прыг-скок — и JSON всё честно хранит!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.68% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Название кратко и точно описывает основной результат PR: стабильные JUnit и Allure artifacts для тестов.
Linked Issues check ✅ Passed Изменения соответствуют #26: JUnit+Allure, стабильные per-run пути, summary, логи и классификация invalid_output реализованы.
Out of Scope Changes check ✅ Passed Явных изменений вне цели PR не видно; все доработки относятся к артефактам, контрактам, тестам и документации.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (8)
src/use_cases/run_tests/helpers.rs (1)

173-182: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Тест не проверяет сам инвентарь, только root_dir.

artifacts.push(...) добавляет ArtifactRef с ролью ARTIFACT_ROLE_RUN_DIR, но ассерты его не касаются — реализация, теряющая items, всё равно прошла бы тест, хотя имя теста обещает «retains existing inventory».

💚 Предлагаемое усиление
-        assert_eq!(
-            result.execution.artifacts.and_then(|set| set.root_dir),
-            Some(run_dir.path().to_path_buf())
-        );
+        let retained = result.execution.artifacts.expect("retained artifacts");
+        assert_eq!(retained.root_dir, Some(run_dir.path().to_path_buf()));
+        assert_eq!(retained.items.len(), 1);
+        assert_eq!(retained.items[0].kind, ArtifactKind::RunDirectory);
+        assert_eq!(
+            retained.items[0].role.as_deref(),
+            Some(ARTIFACT_ROLE_RUN_DIR)
+        );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/use_cases/run_tests/helpers.rs` around lines 173 - 182, Усильте проверки
в тесте, сохраняющем инвентарь, рядом с ассертом `result.execution.artifacts`:
проверьте, что коллекция `items` содержит добавленный `ArtifactRef` с ролью
`ARTIFACT_ROLE_RUN_DIR`. Сохраните существующую проверку `root_dir` и убедитесь,
что тест завершится ошибкой при потере или изменении записи инвентаря.
tests/cli_test.rs (3)

311-321: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Обёртка setup_project_with_additional_launch_keys стала пустым делегатом.

Она передаёт аргументы в setup_project_with_native_reports один в один. Можно оставить одну функцию (или сделать обёртку #[inline]-алиасом), чтобы не плодить два имени с одинаковой сигнатурой.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/cli_test.rs` around lines 311 - 321, Remove the redundant
setup_project_with_additional_launch_keys wrapper, since it delegates unchanged
to setup_project_with_native_reports; update its callers to use
setup_project_with_native_reports directly while preserving the existing
arguments and behavior.

468-484: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Пять почти идентичных блоков скраба.

Можно свернуть в цикл по парам (key, placeholder).

♻️ Вариант
-    if value["data"]["retained_paths"]["config_json"].is_string() {
-        value["data"]["retained_paths"]["config_json"] = Value::String("<config_json>".to_owned());
-    }
-    if value["data"]["retained_paths"]["junit_xml"].is_string() {
-        value["data"]["retained_paths"]["junit_xml"] = Value::String("<junit_xml>".to_owned());
-    }
-    if value["data"]["retained_paths"]["allure_results"].is_string() {
-        value["data"]["retained_paths"]["allure_results"] =
-            Value::String("<allure_results>".to_owned());
-    }
-    if value["data"]["retained_paths"]["yaxunit_log"].is_string() {
-        value["data"]["retained_paths"]["yaxunit_log"] = Value::String("<yaxunit_log>".to_owned());
-    }
-    if value["data"]["retained_paths"]["platform_log"].is_string() {
-        value["data"]["retained_paths"]["platform_log"] =
-            Value::String("<platform_log>".to_owned());
-    }
+    for key in [
+        "config_json",
+        "junit_xml",
+        "allure_results",
+        "yaxunit_log",
+        "platform_log",
+    ] {
+        if value["data"]["retained_paths"][key].is_string() {
+            value["data"]["retained_paths"][key] = Value::String(format!("<{key}>"));
+        }
+    }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/cli_test.rs` around lines 468 - 484, Сократите повторяющиеся блоки
нормализации в обработке retained_paths, объединив ключи и соответствующие
плейсхолдеры в цикл по парам. Сохраните текущую проверку is_string и те же
значения для config_json, junit_xml, allure_results, yaxunit_log и platform_log.

191-224: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Молчаливые String::replace в write_va_test_script могут дать ложно-зелёные тесты.

Скрипт собирается серией текстовых замен: если хотя бы один шаблон (junit_output, allure_output, mkdir -p "$report_dir" "$allure_dir") перестанет совпадать после правки базового body, replace тихо ничего не заменит и фикстура MissingJunit/EmptyAllure фактически превратится в Complete — тест перестанет проверять то, что заявлено. Для YaXUnit рядом уже используется более надёжный подход (NativeReportFixture::materialization собирает фрагменты сразу). Как минимум стоит проверять, что замена состоялась.

♻️ Минимальная страховка
+    fn replace_once(body: &str, from: &str, to: &str) -> String {
+        let replaced = body.replace(from, to);
+        assert_ne!(replaced, body, "VA script fixture pattern not found: {from}");
+        replaced
+    }

Далее использовать replace_once вместо body.replace(...) во всех ветках match native_reports и в подготовительных заменах.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/cli_test.rs` around lines 191 - 224, Update write_va_test_script so
every fixture-specific replacement, including the preparatory body replacements
and all NativeReportFixture match branches, uses a checked single-replacement
operation such as replace_once instead of silent String::replace. Ensure each
expected template match is validated and fails if absent, preserving the
intended MissingJunit, EmptyJunit, MissingAllure, and EmptyAllure fixture
behavior.
tests/mcp_stdio.rs (1)

346-346: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Выбирайте отчеты по format, а не по позиции в reports.

Mock парсит reports[0] как JUnit и reports[1] как Allure, хотя текущий YaXUnit-генератор хранит отчеты только в одном порядке. Этот подход делает фикстуру хрупкой: изменение/перестановка порядка отчетов в конфиге может закомить XML-файл в Allure-каталог или наоборот. Выбирайте запись по значению format/type в обеих мок-фикстурах — tests/mcp_stdio.rs#L346 и аналогичные места в tests/cli_test.rs.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/mcp_stdio.rs` at line 346, Update the mock report-selection logic in
the embedded script and analogous fixtures in tests/cli_test.rs to identify
JUnit and Allure reports by their format/type fields instead of reports array
positions. Use the matching report paths for XML and Allure output, preserving
the existing fixture generation behavior.
src/domain/artifact.rs (1)

97-102: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Развязать лайфтайм role и &self в get_all_by_role.

Сейчас role: &'a str привязан к тому же лайфтайму, что и &'a self, поэтому временная String в качестве роли не скомпилируется, хотя итератор ссылки на неё не хранит.

♻️ Предлагаемая сигнатура
-    pub fn get_all_by_role<'a>(&'a self, role: &'a str) -> impl Iterator<Item = &'a Path> + 'a {
+    pub fn get_all_by_role<'a, 'r: 'a>(
+        &'a self,
+        role: &'r str,
+    ) -> impl Iterator<Item = &'a Path> + 'a {
         self.items
             .iter()
             .filter(move |item| item.role.as_deref() == Some(role))
             .map(|item| item.path.as_path())
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/domain/artifact.rs` around lines 97 - 102, Update get_all_by_role so the
role parameter has an independent lifetime from the borrow of self, while
retaining the iterator’s lifetime tied to self and preserving the existing role
comparison and path mapping.
src/cli/execute.rs (1)

1877-1898: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Добавьте allure_results в текстовый перечень артефактов.

RetainedPaths теперь содержит каталог Allure, но текстовый вывод перечисляет только run_dir, report, runner_log и platform_log, поэтому пользователю CLI путь к Allure не виден (он доступен лишь в JSON).

♻️ Предлагаемое дополнение
     if let Some(junit_xml) = paths.junit_xml {
         push_unique_detail(
             details,
             format!("[artifact] report -> {}", junit_xml.display()),
         );
     }
+    if let Some(allure_results) = paths.allure_results {
+        push_unique_detail(
+            details,
+            format!("[artifact] allure_results -> {}", allure_results.display()),
+        );
+    }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/cli/execute.rs` around lines 1877 - 1898, Добавьте в текстовый перечень
артефактов в соответствующем блоке обработки RetainedPaths запись для каталога
allure_results, используя push_unique_detail и формат, аналогичный
run_dir/report, чтобы путь к Allure отображался в CLI наряду с остальными
артефактами.
src/use_cases/run_tests.rs (1)

796-807: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Инвентарь необязательных диагностик не ограничен по количеству.

push_optional_diagnostics добавляет в публичный ArtifactSet каждый файл из error-details/ и screenshots/ рекурсивно. Прогон Vanessa со скриншотом на каждый шаг может дать тысячи элементов и раздуть JSON-конверт CLI/MCP. Рассмотрите верхний предел с усечением и отдельным элементом-каталогом.

Also applies to: 853-860

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/use_cases/run_tests.rs` around lines 796 - 807, Ограничьте количество
необязательных диагностик, добавляемых через push_optional_diagnostics для
error_details_dir и screenshots_dir, единым верхним пределом. При превышении
лимита сохраняйте усечение и добавляйте отдельный элемент-каталог, указывающий
на оставшиеся файлы, чтобы ArtifactSet и CLI/MCP JSON не разрастались.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/use_cases/run_tests.rs`:
- Around line 232-416: Добавьте Windows-тестовое покрытие для
materialize_vanessa_runner_log и связанных функций open_file_no_follow,
ensure_windows_handle_is_not_reparse_point и replace_file, поскольку текущий
windows-latest Rust CI выполняет только cargo check. Обеспечьте тесты для
успешной материализации, обработки symlink/reparse-point источника и замены
существующего файла через Windows-реализацию MoveFileExW, используя
Windows-совместимые временные пути и настройки тестового запуска.

---

Nitpick comments:
In `@src/cli/execute.rs`:
- Around line 1877-1898: Добавьте в текстовый перечень артефактов в
соответствующем блоке обработки RetainedPaths запись для каталога
allure_results, используя push_unique_detail и формат, аналогичный
run_dir/report, чтобы путь к Allure отображался в CLI наряду с остальными
артефактами.

In `@src/domain/artifact.rs`:
- Around line 97-102: Update get_all_by_role so the role parameter has an
independent lifetime from the borrow of self, while retaining the iterator’s
lifetime tied to self and preserving the existing role comparison and path
mapping.

In `@src/use_cases/run_tests.rs`:
- Around line 796-807: Ограничьте количество необязательных диагностик,
добавляемых через push_optional_diagnostics для error_details_dir и
screenshots_dir, единым верхним пределом. При превышении лимита сохраняйте
усечение и добавляйте отдельный элемент-каталог, указывающий на оставшиеся
файлы, чтобы ArtifactSet и CLI/MCP JSON не разрастались.

In `@src/use_cases/run_tests/helpers.rs`:
- Around line 173-182: Усильте проверки в тесте, сохраняющем инвентарь, рядом с
ассертом `result.execution.artifacts`: проверьте, что коллекция `items` содержит
добавленный `ArtifactRef` с ролью `ARTIFACT_ROLE_RUN_DIR`. Сохраните
существующую проверку `root_dir` и убедитесь, что тест завершится ошибкой при
потере или изменении записи инвентаря.

In `@tests/cli_test.rs`:
- Around line 311-321: Remove the redundant
setup_project_with_additional_launch_keys wrapper, since it delegates unchanged
to setup_project_with_native_reports; update its callers to use
setup_project_with_native_reports directly while preserving the existing
arguments and behavior.
- Around line 468-484: Сократите повторяющиеся блоки нормализации в обработке
retained_paths, объединив ключи и соответствующие плейсхолдеры в цикл по парам.
Сохраните текущую проверку is_string и те же значения для config_json,
junit_xml, allure_results, yaxunit_log и platform_log.
- Around line 191-224: Update write_va_test_script so every fixture-specific
replacement, including the preparatory body replacements and all
NativeReportFixture match branches, uses a checked single-replacement operation
such as replace_once instead of silent String::replace. Ensure each expected
template match is validated and fails if absent, preserving the intended
MissingJunit, EmptyJunit, MissingAllure, and EmptyAllure fixture behavior.

In `@tests/mcp_stdio.rs`:
- Line 346: Update the mock report-selection logic in the embedded script and
analogous fixtures in tests/cli_test.rs to identify JUnit and Allure reports by
their format/type fields instead of reports array positions. Use the matching
report paths for XML and Allure output, preserving the existing fixture
generation behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 85d9ed81-f097-4da9-933e-fdbf56ead8b6

📥 Commits

Reviewing files that changed from the base of the PR and between 325cccb and 96584cc.

⛔ Files ignored due to path filters (3)
  • Cargo.lock is excluded by !**/*.lock
  • tests/snapshots/cli_test__test_module_compact_json.snap is excluded by !**/*.snap
  • tests/snapshots/cli_test__test_module_full_json.snap is excluded by !**/*.snap
📒 Files selected for processing (19)
  • Cargo.toml
  • SKILL/SKILL.md
  • SKILL/references/testing.md
  • docs/CAPABILITIES.md
  • docs/superpowers/plans/2026-07-26-test-result-artifacts.md
  • docs/superpowers/specs/2026-07-26-test-result-artifacts-design.md
  • src/cli/execute.rs
  • src/domain/artifact.rs
  • src/domain/runner.rs
  • src/domain/test.rs
  • src/mcp/service.rs
  • src/use_cases/request.rs
  • src/use_cases/run_tests.rs
  • src/use_cases/run_tests/coordinator.rs
  • src/use_cases/run_tests/helpers.rs
  • src/use_cases/vanessa.rs
  • tests/architecture_guardrails.rs
  • tests/cli_test.rs
  • tests/mcp_stdio.rs

Comment thread src/use_cases/run_tests.rs
- publish timeout logs only when the regular file exists
- validate exact text and JSON artifact paths across platforms
- expose Allure artifacts in text output and strengthen inventory assertions
- run targeted Windows materialization and atomic replacement tests
- document the expanded Windows contract coverage
- bound optional diagnostic inventory with directory fallbacks
- document fixture hardening and lifetime waiver
- define TDD steps for bounded diagnostics
- cover fixture hardening and verification gates
- cap diagnostic files across error details and screenshots
- retain truncated category directories and document the contract
- remove positional assumptions from CLI and MCP fixtures
- fail fast when Vanessa fixture templates drift
- remove duplicated setup and snapshot normalization
@korolevpavel

Copy link
Copy Markdown
Contributor Author

Дополнительные review nitpicks исправлены в a146e76, 3617256 и 5c3fb7c:

  • optional diagnostics ограничены общим бюджетом 100 файлов; при усечении сохраняется ссылка на корневой каталог категории, контракт отражён в docs/CAPABILITIES.md и SKILL/SKILL.md;
  • CLI/MCP YaXUnit fixtures выбирают JUnit и Allure по format, а не по позиции;
  • Vanessa fixture replacements теперь проверяются через replace_once;
  • удалён пустой setup delegate и свёрнута повторяющаяся snapshot normalization.

Замечание по lifetime ArtifactSet::get_all_by_role оставлено без изменения: iterator захватывает ссылку role, поэтому она обязана жить всё время использования iterator. Текущая сигнатура уже компилирует временную String, если iterator потребляется в том же statement; предложенный bound этого не расширяет.

Targeted verification: artifact collector 5/5, CLI suite 30/30, затронутые MCP contracts 3/3. Полный результат Linux/Windows подтвердит CI ветки.

- propagate selector failures before artifact writes
- cover reordered and missing report formats
- document shared diagnostic inventory bounds
@korolevpavel

Copy link
Copy Markdown
Contributor Author

Финальный review выявил и исправил ещё один fixture-safety edge case в 3b3745a: ошибки Python selector теперь явно останавливают shell mock, пустые пути отклоняются до записи, а regression-тесты проверяют reordered reports и отсутствие обязательного format без записи вне temp workspace. Также синхронизирован SKILL/references/testing.md.

Свежая локальная проверка HEAD: artifact collector 5/5, CLI suite 32/32, затронутые MCP contracts 3/3, cargo fmt --check и git diff --check — успешно. Scoped re-review: findings addressed, новых Critical/Important нет.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

test: возвращать JUnit/Allure/log как стабильные artifacts

1 participant