# Authoring and validation reference

## Contents

- [Choose the correct workflow](#choose-the-correct-workflow)
- [Create a new scenario](#create-a-new-scenario)
- [Minimal YAML contract](#minimal-yaml-contract)
- [Static validation](#static-validation)
- [Go compile validation](#go-compile-validation)
- [Full local replay](#full-local-replay)
- [GitHub Actions validation](#github-actions-validation)
- [Completion checklist](#completion-checklist)

## Choose the correct workflow

- Explicitly load `skills/write-scenario-yaml/SKILL.md` for any new or modified `scenario_testcases/*.yaml` file. It requires explicit evidence for each HTTP API and CLI call.
- Explicitly load `skills/review-scenario-yaml/SKILL.md` after authoring and repair every evidence-backed finding.
- Use this skill directly for framework explanation, code location, execution tracing, local validation, and GHA troubleshooting.

Do not create a new authoring path inside this skill. The narrower skills contain the current evidence ledger and review contracts.

## Create a new scenario

1. Read `README.md` completely.
2. Identify API tier, provider, auth mode, host/base path, lifecycle, requested success/failure behavior, and cleanup requirements.
3. Select the closest existing `scenario_testcases/*.yaml` with the same tier, provider, auth mode, and resource lifecycle.
4. Verify every interface call from current primary evidence:
   - Dedicated v1beta1: [`api/spec/tidb_cloud_open_api/dedicated/v1beta1/`](https://github.com/tidbcloud/tidb-management-service/tree/main/api/spec/tidb_cloud_open_api/dedicated/v1beta1)
   - Premium/BYOC/Essential V2 v1beta2: [`api/spec/tidb_cloud_open_api/nextgen/v1beta2/`](https://github.com/tidbcloud/tidb-management-service/tree/main/api/spec/tidb_cloud_open_api/nextgen/v1beta2)
   - Serverless v1beta1: [`api/spec/tidb_cloud_open_api/serverless/v1beta1/`](https://github.com/tidbcloud/tidb-management-service/tree/main/api/spec/tidb_cloud_open_api/serverless/v1beta1)
5. Build the lifecycle in executable order: prepare, execute, poll readiness/terminal state, assert behavior, delete child resources, and delete parents.
6. Keep YAML sequence and strictly increasing unique `order` values aligned.
7. Use placeholders for environment values, IDs, and secrets. Bind them through `path_params`, `body_params`, and `args_params`.
8. Save actual cluster IDs as `cluster_1`, `cluster_2`, and so on. Do not use the `cluster` prefix for endpoints, ports, usernames, or unrelated values.
9. Give asynchronous polling a bounded non-zero retry interval and calculate the total delay budget.
10. Run static validation and the mandatory review skill before live execution.

Treat an existing YAML as a structural example, not as proof of a method, path, field, response shape, status, or cloud command.

## Minimal YAML contract

```yaml
scenario:
  id: <stable-uuid>
  context:
    base_path: /v1beta2
    host: null
  description: <scenario-purpose>
  name: <scenario-name>
steps:
  - operation_id: <operation-or-command-label>
    request_type: http
    request: |-
      {"auth":{"auth_type":"digest","content":{"public_key":"placeholder","private_key":"placeholder"}},"method":"GET","path":"/tidbs","path_params":{},"query_params":{},"headers":{},"body":{},"body_params":{}}
    expect: |-
      {"status_code":200,"cel":"true"}
    save: null
    max_retries: 0
    delay_after: 0
    continue_on_unexpected: false
    order: 1
```

Use the compact example only to understand nesting. Copy formatting and realistic fields from a matching existing case, and replace `cel: "true"` with an assertion that proves the requested behavior.

Supported executable request types are:

| Type | Executable |
|---|---|
| `http` | HTTP request |
| `cmd_aws` | `aws` |
| `cmd_gcp` | `gcloud` |
| `cmd_azure` | `az` |
| `cmd_mysqlsh` | `mysqlsh` |
| `cmd_aliyun` | `aliyun` |

Keep `request`, `expect`, and non-null `save` as valid JSON strings embedded in YAML. Use `status_code` for HTTP and `exit_code` for new command expectations.

## Static validation

Static validation is the default safe local check. It needs no TiDB Cloud credentials and makes no API or cloud calls.

From the APITestGen repository root:

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

Repeat `--file` for multiple explicit targets, or omit it to inspect changed scenario YAML. The checker covers YAML/embedded JSON objects, supported request types, order, placeholder bindings, retries, selected auth/lifecycle structural defects, and exact patterns for AWS access-key IDs, GitHub tokens, and private-key PEM blocks. It is not a general secret scanner.

Findings produce a nonzero exit code; no changed files and a completed check
with zero findings exit zero. Run the stdlib-only regression harness after
changing the gate:

```sh
ruby --disable-gems skills/review-scenario-yaml/scripts/check_changed_scenarios_test.rb
```

Then explicitly load `skills/review-scenario-yaml/SKILL.md` for semantic review against the current API contract, runner, comparable variants, and lifecycle.

Static success does not prove CEL against a live response, cloud permissions, asynchronous timing, cleanup completion, or end-to-end behavior.

## Go compile validation

Use compile validation only when runner compatibility or build health is relevant. Obtain `tidb-management-service` from its GitHub repository in any directory; do not require it to be a sibling of APITestGen.

```sh
TIDB_MANAGEMENT_SERVICE_DIR=/path/to/tidb-management-service
cd "${TIDB_MANAGEMENT_SERVICE_DIR}/functional-test"
go test -run '^$' ./cases/openapidedicated/autogencase
```

This compiles the package without selecting `TestScenario`. It may download Go modules and may require access to private dependencies. It does not load, parse, or execute the target YAML.

## Full local replay

Use full replay only with explicit authority for live test resources. It executes HTTP and command steps and may create, mutate, or delete TiDB Cloud and provider resources.

Read [runtime-configuration.md](runtime-configuration.md) for the complete parameter matrix, non-secret config-file pattern, protected environment-variable template, and account/provider-specific optional inputs.

Check out both repositories from GitHub into any locations, then copy the target YAML before compilation:

```sh
APITESTGEN_DIR=/path/to/APITestGen
TIDB_MANAGEMENT_SERVICE_DIR=/path/to/tidb-management-service
YAML_FILE=example.yaml

cp "${APITESTGEN_DIR}/scenario_testcases/${YAML_FILE}" \
  "${TIDB_MANAGEMENT_SERVICE_DIR}/functional-test/cases/openapidedicated/autogencase/testdata/${YAML_FILE}"
cd "${TIDB_MANAGEMENT_SERVICE_DIR}/functional-test"
```

Load the protected environment described in the runtime configuration reference. The current `TestScenario` attempts browser token acquisition whenever `ACCOUNT_TOKEN` is empty. The current `SetupSuite` also opens both databases even when reading YAML from the embedded filesystem and not saving results. Plan local prerequisites accordingly.

Run the same target as GHA:

```sh
make GO_TEST_RUN_ARGS='TestScenario' GO_TEST_TESTIFY_METHOD='.*' \
  test-openapidedicated-autogencase
```

Read `e2e-tests.xml` and the runner logs. Do not leave copied testdata, generated resources, or credentials in a commit. Inspect teardown logs and verify explicit non-cluster cleanup.

## GitHub Actions validation

Read [runtime-configuration.md](runtime-configuration.md) before dispatching. It documents the inspected incompatible contracts and provides non-secret GitHub UI, `gh workflow run`, and REST templates only for a repaired workflow that reads credentials from GitHub repository or environment secrets.

Choose the workflow matching the scenario family and provider. Common workflow sources include:

- Dedicated: [`e2e-openapi-dedicated-scenario.yaml`](https://github.com/tidbcloud/tidb-management-service/blob/main/.github/workflows/e2e-openapi-dedicated-scenario.yaml)
- BYOC: [`e2e-openapi-byoc-scenario.yaml`](https://github.com/tidbcloud/tidb-management-service/blob/main/.github/workflows/e2e-openapi-byoc-scenario.yaml)
- Essential: [`e2e-openapi-essential-scenario.yaml`](https://github.com/tidbcloud/tidb-management-service/blob/main/.github/workflows/e2e-openapi-essential-scenario.yaml)
- Essential V2: [`e2e-openapi-essential-v2-scenario.yaml`](https://github.com/tidbcloud/tidb-management-service/blob/main/.github/workflows/e2e-openapi-essential-v2-scenario.yaml)
- NextGen global: [`e2e-openapi-nextgen-scenario.yaml`](https://github.com/tidbcloud/tidb-management-service/blob/main/.github/workflows/e2e-openapi-nextgen-scenario.yaml)
- NextGen regional: [`e2e-regionalapi-nextgen-scenario.yaml`](https://github.com/tidbcloud/tidb-management-service/blob/main/.github/workflows/e2e-regionalapi-nextgen-scenario.yaml)

Pass the exact YAML filename through the provider-specific scenario input. Confirm the resolved matrix and fetched file before trusting the test result.

Branch behavior matters:

- Dedicated, BYOC, Essential, NextGen global, and NextGen regional currently fetch APITestGen `main`; merge the YAML or change the workflow in an explicitly reviewed test branch before expecting those workflows to see unmerged content.
- Essential V2 exposes `apitestgen_branch` and checks out that branch, so use the scenario PR branch for pre-merge validation.

A valid GHA result requires the fetch/copy step, `Run scenario cases`, and non-zero JUnit test totals to succeed. A missing JUnit file usually means installation, checkout, fetch, setup, or compilation failed before the scenario completed.

## Completion checklist

- The scenario file lives under `scenario_testcases/` and has no credentials or fixed environment resources.
- Every HTTP/CLI call has explicit current evidence.
- YAML sequence and unique increasing `order` values express the same lifecycle.
- Every producer placeholder is saved before use; failed continued steps do not feed dependencies.
- Expectations prove behavior, not only transport success.
- Retry budgets are bounded and use non-zero delay for polling.
- Every created child and parent resource has a safe cleanup path.
- The deterministic checker passes.
- The review performed from `skills/review-scenario-yaml/SKILL.md` reports no unresolved evidence-backed findings.
- The report states whether compile, local replay, or GHA validation was actually run.
