Назад к обновлениям
UpdatedJul 28, 2026

distributed-system-testing — Updated!

Навыки ИИ-агентов для тестирования распределённых систем

Поделиться

Навыки тестирования распределённых систем

Два навыка для ИИ-агентов, которые пишут код и занимаются тестированием распределённых и stateful-систем, управляемым утверждениями продукта (claim-driven). Вместе они создают структурированный Markdown-план тестов и отчёт о результатах с вердиктами из 10 состояний и явной классификацией вины SUT / harness / checker / environment. Ревьюер читает два артефакта и решает, можно ли выпускать; ничего больше перезапускать не нужно.

Работает с Claude Code, Codex, Copilot CLI, Cursor, Gemini или любым агентом, который читает Markdown и выполняет команды shell. Навыки представляют собой обычные файлы SKILL.md. Агент выполняет их; результатом являются план и отчёт о результатах.

Один навык проектирует план. Другой — выполняет его. План начинается с утверждений, которые делает продукт, генерирует гипотезы, привязанные к этим утверждениям, и описывает сценарии, названные по утверждению, которое каждый из них пытается опровергнуть. Для критичных к согласованности сценариев каждый сценарий также привязывает абстрактную модель (register | queue | log | lock | lease | ledger | …) к схеме истории операций, именованному checker-у и немезису с наблюдаемыми доказательствами срабатывания. План завершается обоснованием достаточности покрытия и консервативной оценкой уверенности.

Зачем

Подход по умолчанию к тестированию распределённых и stateful-систем — написать несколько интеграционных тестов и считать задачу выполненной — находит лишь малую долю багов, которые реально ломают такие системы в проде: частичные сетевые разделения, недетерминированная конкурентность, восстановление после сбоя, апгрейд/откат, идемпотентность при повторном воспроизведении, чувствительная к таймингам упорядоченность.

Эти навыки навязывают осознанный (opinionated) процесс, опирающийся на нелёгкий опыт индустрии:

  • Управляемость утверждениями, а не тестами. Исходите из того, что обещает продукт. Каждый сценарий опровергает одно утверждение при одном сбое. Тест, названный по своему утверждению, труднее ослабить, чем тест, названный по своему окружению.
  • Достаточность покрытия — это измеримый результат. План завершается обоснованием того, что выбранных сценариев достаточно для выпуска, плюс честным списком того, что остаётся непроверенным.
  • Используйте собственный инструментарий SUT. Навык выполнения сначала находит существующие тесты, runbook-и и каркасы для инъекции сбоев, прежде чем изобретать что-то новое.
  • Модель + история + checker, а не просто хаос. Для утверждений о безопасности, долговечности, идемпотентности, изоляции, упорядоченности или членстве каждый сценарий объявляет абстрактную модель, схему истории операций, именованный checker (линеаризуемость, сериализуемость, session-consistency, no-lost-ack, exactly-once, …) и то, как трактуются неоднозначные исходы (таймауты, неизвестные коммиты, ретраи). Хаос плюс модель и checker, а не только хаос.
  • Никаких молчаливых PASS. Каждый PASS ссылается на доказательства выполнения оракула и на сигнал, подтверждающий, что сбой действительно сработал. Вердикты берутся из набора из 10 состояний, так что «скрипт хаоса отработал чисто» нельзя прочитать как «утверждение пережило сбой». Каждый FAIL несёт метку вины SUT / harness / checker / environment, чтобы воспроизводители попадали в нужную очередь.

Что вы получаете

End-to-end два навыка создают:

docs/testing-plans/<slug>.md        ← plan with §0–§9 (see below)
test-sessions/<slug>/<UTC>/
  ├── session-log.md                 ← timeline + toolbox + env probe
  ├── logs/                          ← per-scenario stdout/stderr
  ├── metrics/                       ← metric snapshots
  ├── artifacts/                     ← ephemeral harnesses, dumps
  └── findings/
      ├── <scenario>.md              ← per-scenario verdict (written as run proceeds)
      └── report.md                  ← summary + adequacy + confidence delta

Структура плана (ревьюер может прочитать это и решить, выпускать ли продукт, не перезапуская тесты):

0. Architectural summary       — system as it actually exists
1. Scope
1b. Claims under test          — the spine
1c. Missing claims discovered  — docs ↔ code drift
2. SUT model
3. Existing test inventory     — what's already covered
4. Failure-mode hypotheses     — tied to claim IDs
5. Coverage matrix             — claim × hypothesis
6. Technique selection         — from the catalog
6b. Environment requirements
7. Scenarios                   — each named after the claim, with
                                  Target test file + Skeleton
   7.M Model / history /       — mandatory when the scenario falsifies
       checker discipline        a claim in {safety, durability,
                                  idempotency, isolation, ordering,
                                  membership}: model under test,
                                  operation-history schema, named
                                  checker, nemesis + landing evidence,
                                  ambiguous-outcome handling, reduction
                                  plan (SUT/harness/checker/env blame)
7b. Coverage adequacy argument — why these tests are enough
7c. Residual uncertainty       — what stays unverified, and why ok
7d. Confidence statement       — the reviewer's verdict
8. What this plan does NOT cover
9. Open questions / followups

Пример блока §7.M (фрагмент плана)

### Scenario S3: linearizable_append_under_partition
- Falsifies if it FAILs: C1 (every acknowledged append is durable
  and linearisable), C5 (leader election completes within 5s)
- Workload: 8 clients, 70% append / 30% read, 5min, key-skew zipf
- Faults: asymmetric partition isolating current leader at T+60s
  for 30s
- Oracle: linearizability via Porcupine over per-key histories

§7.M (model / history / checker discipline)
- Model under test:    log
- Operation history:   default 11-field schema (op id, process id,
                       invoke/complete ts, op type, key, input,
                       output, error, timeout marker, node seen,
                       fault epoch). Recorded in-process + server-
                       side audit.
- Checker:             linearizability (Porcupine) per-key, then
                       no-lost-ack against final state
- Nemesis + landing:   asymmetric-partition (iptables drop one
                       direction). Landing evidence = iptables drop
                       counter goes 0 → 14,712 over the 30s window
                       AND raft log emits "leader-lost; starting
                       election" within 2s of injection.
- Ambiguous outcomes:  timeouts → timeout_marker=true, complete_ts
                       =null, treated as could-have-succeeded;
                       retries are separate ops sharing input
- Reduction plan:      if FAIL, bisect fault window + fix seed, then
                       classify SUT / harness / checker / environment
                       per references/test-case-reduction.md

Пример строки отчёта о результатах

IDВердиктДоказательства срабатывания немезисаКласс редукции
S3PASS-hardeningiptables ctr 0→14,712; raft re-election at T+1.8sn/a
S4FAIL-reproduciblepartition landed; Elle: G2-item anomaly on key K17SUT
S7INCONCLUSIVE-fault-not-proveniptables rule installed but counter stayed 0 — wrong chainharness
S9PARTIAL-modellanding ok; checker covered per-key, not cross-keyn/a

(Полный шаблон отчёта о результатах содержит Oracle, доказательства выполнения оракула, ссылки на артефакты, раздел «достаточность vs план» и дельту уверенности — см. skills/executing-distributed-system-tests/assets/findings-report-template.md.)

Категории