---
name: write-scenario-yaml
description: Create or update APITestGen TiDB Cloud E2E scenario YAML test cases from user requirements with an explicit evidence basis for every HTTP API and CLI call. Use when asked to design, add, or modify files under scenario_testcases/*.yaml for Dedicated, BYOC, Essential V2, regional, provider-specific, RBAC, lifecycle, or failure scenarios. Exhaust repository, runner, primary-documentation, history, and supplied-artifact evidence without guessing or waiting for user input; edit only calls with a uniquely proven safe contract, then invoke review-scenario-yaml and repair every evidence-backed finding.
---

# Write APITestGen Scenario YAML

Produce a review-clean scenario file whose API and command behavior is traceable to explicit evidence. Never invent an endpoint, method, parameter, response field, status code, auth mode, CLI argument, or asynchronous state.

## 1. Establish the task boundary

1. Work from the APITestGen repository root.
2. Run `git status --short`, `git log -1 --oneline`, `git show -1 --stat`, and `git diff --stat`. Preserve unrelated and pre-existing changes.
3. Read `README.md` completely before editing scenario YAML.
4. Resolve runner evidence in this order: `$TIDB_MANAGEMENT_SERVICE_DIR` when it names a checkout, `../tidb-management-service` when that sibling exists, then the pinned official source at [`tidb-management-service@ff5c78ac9`](https://github.com/tidbcloud/tidb-management-service/tree/ff5c78ac952849735b14a93ecabcceec4933ea33). The inspected baseline is revision `ff5c78ac952849735b14a93ecabcceec4933ea33` on 2026-07-15; re-check a later requested revision when available. Never require the repositories to share a parent directory.
5. Verify material runner behavior in `Scenario_suite_test.go`, `model/generationsteps.go`, `actionbuilder.go`, and `action.go` from the resolved source.
6. Identify the target API tier, provider, auth mode, host/base path, requested behavior, expected failures, resource lifecycle, and target YAML files. Choose a descriptive filename only when the user leaves it open.
7. Find the closest existing YAML with the same tier, provider, auth mode, base path, and resource lifecycle. Use it for runner-compatible structure, not as sole proof of an API contract.

## 2. Prove every interface call

Read [evidence-policy.md](references/evidence-policy.md). Build an evidence ledger before writing. Include one row for every HTTP step and command step, including setup, polling, verification, and cleanup calls.

For HTTP calls, establish all of these facts:

- API version, operation ID, method, base path, and relative path;
- auth mode, required headers, path/query/body fields, types, and allowed values used by the test;
- success or error status being asserted;
- response fields and values used by CEL or `save`;
- asynchronous states, dependency order, and cleanup operation.

For command calls, establish the executable, subcommand, arguments, provider context, exit code, output format, and output fields used by CEL or `save`.

Treat current OpenAPI/proto definitions, precise user-provided contracts or examples, official command documentation/help, and observed response artifacts as contract evidence. Treat runner code as evidence for YAML execution semantics. Treat existing scenario files as supporting evidence and templates; do not blindly copy their API assumptions.

## 3. Exhaust evidence and block unsafe gaps

Before declaring a gap, search every available evidence class: repository files and history; the resolved runner checkout; pinned official runner/API sources; official command documentation or local help; supplied logs, responses, specifications, and other artifacts. Route external documentation lookup through the appropriate research surface when available.

If the exhausted sources do not select one unique safe contract, do not write or repair the affected call. Do not ask or wait. Record a blocked evidence gap containing:

- the affected operation or command;
- every source and revision checked;
- the exact method/path, parameter, response, status, auth, state, or output fact still missing or conflicting;
- why the uncertainty changes execution or cleanup;
- the smallest additional artifact that would resolve the gap.

Never replace missing evidence with a conventional value, a similar endpoint, an old case, or an assumption. Supplied artifacts become evidence only when their environment and version apply to the requested scenario.

## 4. Design the lifecycle

Before editing, define the executable sequence:

1. Prepare the smallest practical prerequisite resources.
2. Execute the requested operation.
3. Poll the exact readiness or terminal signal when the API is asynchronous.
4. Assert meaningful behavior, not only transport success.
5. Clean up every created resource, including child resources that block parent deletion.

Keep steps in actual execution order. The filesystem runner executes YAML sequence and does not sort by `order`; assign strictly increasing, unique `order` values that match the sequence.

## 5. Write the scenario

- Create or update only the target files under `scenario_testcases/`.
- Generate a stable unique scenario ID for a new file and use scenario-specific resource names.
- Keep `request`, `expect`, and non-null `save` values as valid JSON strings in YAML block scalars.
- Use only supported request types: `http`, `cmd_aws`, `cmd_gcp`, `cmd_azure`, `cmd_mysqlsh`, and `cmd_aliyun`.
- Bind dynamic path, body, and command values through `path_params`, `body_params`, and `args_params`.
- Use typed body placeholders only when the entire string is `{name:integer}` or `{name:number}`.
- Put command flags and placeholder-expanded values in separate args because args beginning with `--` are not expanded.
- Use `status_code` for HTTP expectations and `exit_code` for command expectations. Make CEL expressions prove the requested behavior.
- Save response/output fields only after a successful expectation. Trace every saved placeholder to all consumers.
- Name real cluster ID placeholders `cluster_1`, `cluster_2`, and so on. Never use the `cluster` prefix for unrelated values because teardown treats every such key as a cluster ID.
- Give polling a bounded non-zero retry interval. Calculate the delay budget as `max_retries * delay_after`.
- Do not let later steps depend on placeholders from a step that can fail under `continue_on_unexpected: true`.
- Never commit secrets, credentials, tokens, DSNs, passwords, environment-specific resource IDs, or real storage access data.
- Do not make live API or cloud calls while authoring unless the user explicitly requests execution and supplies the required authority.

## 6. Run deterministic checks

Run the repository-local checker for each target file:

```sh
ruby --disable-gems skills/review-scenario-yaml/scripts/check_changed_scenarios.rb \
  --base HEAD \
  --file scenario_testcases/example.yaml
```

Repeat `--file` for multiple files. Fix parse, embedded JSON, request type, order, placeholder, retry, secret, and runner-compatibility defects when the evidence uniquely determines the correction.

## 7. Invoke mandatory review and repair

After authoring, explicitly load and follow `skills/review-scenario-yaml/SKILL.md`. Pass the explicit target file list and request a full semantic review using the evidence ledger and current runner/API sources.

Handle every review finding:

- Apply the smallest repair immediately when current evidence uniquely determines it.
- If a repair needs an unproven API, parameter, response, status, auth, state, timing, CLI, or product decision, exhaust the evidence sources above. If no unique safe contract emerges, do not edit; record a blocked evidence gap with the proposed repair and remaining uncertainty.
- Re-run the deterministic checker and the full review after each repair pass.
- Continue until the reviewer reports `未发现需要修改的问题`, or stop explicitly blocked on an exhausted evidence gap. Never claim completion while a finding remains unresolved.

## 8. Report the result

List the changed scenario files, tested lifecycle, condensed evidence ledger with source paths or user-provided facts, deterministic check result, review result, repairs applied, and validation gaps. State clearly when no live workflow was run.
