Skip to main content

foundry-extension-scenario-authoring

**WORKFLOW SKILL** — Authors and validates cli-interactive-tester scenarios for the azure.ai.agents extension: writes a new scenario YAML (or fixes an existing one) so it follows the tier/tag/hook/fixtures/requires conventions and goals-are-the-contract judging rules, then lint-validates it via list_scenarios (never start_session — no Azure cost). Typically driven through the foundry-extension-scenario-author agent. USE FOR: write a new scenario, add coverage for a command/flag, fix a scenario's tags/hooks/requires, add a fixture, close a coverage gap flagged by a PR regression run. DO NOT USE FOR: RUNNING scenarios or a suite — never drives a scenario or incurs Azure cost (use foundry-extension-scenario-suite-run for a sweep, or foundry-extension-scenario-pr-regression for a PR), driving a single scenario (foundry-extension-scenario-worker), azd core preflight (azd-preflight), changelog (changelog-generation), creating PRs (pull-request), scenarios for other extensions.

Informações da origem

Repositório
Azure/azure-dev
Última atividade na origem
25 de setembro de 2026 às 17:17
Idioma detectado do SKILL.md
inglês
Estrelas
570
Forks
367

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
name
foundry-extension-scenario-authoring
license
MIT
metadata
{"version":"1.4"}
description
**WORKFLOW SKILL** — Authors and validates cli-interactive-tester scenarios for the azure.ai.agents extension: writes a new scenario YAML (or fixes an existing one) so it follows the tier/tag/hook/fixtures/requires conventions and goals-are-the-contract judging rules, then lint-validates it via list_scenarios (never start_session — no Azure cost). Typically driven through the foundry-extension-scenario-author agent. USE FOR: write a new scenario, add coverage for a command/flag, fix a scenario's tags/hooks/requires, add a fixture, close a coverage gap flagged by a PR regression run. DO NOT USE FOR: RUNNING scenarios or a suite — never drives a scenario or incurs Azure cost (use foundry-extension-scenario-suite-run for a sweep, or foundry-extension-scenario-pr-regression for a PR), driving a single scenario (foundry-extension-scenario-worker), azd core preflight (azd-preflight), changelog (changelog-generation), creating PRs (pull-request), scenarios for other extensions.
# foundry-extension-scenario-authoring Authors and validates goal-based **scenarios** for the `azure.ai.agents` [cli-interactive-tester](https://github.com/coreai-microsoft/cli-interactive-tester) suite under `cli/azd/extensions/azure.ai.agents/tests/cli-interactive-tester-scenarios/`. This skill **writes and lints** scenarios; it never **runs** them (running is `foundry-extension-scenario-suite-run` / `foundry-extension-scenario-pr-regression`, driven by the `foundry-extension-scenario-worker` agent, and incurs Azure cost for Tier 1b / Tier 2). **Tools invoked**: the cli-interactive-tester MCP `list_scenarios` tool (for tag/lint validation only — never `start_session`, which would incur Azure cost), read/edit of scenario YAML files, and `ask_user`. ## The authoring contract (read this first) A scenario's `goals:` are its **contract**: a run PASSES only when the product's real behavior matches what the goals literally describe. So the whole point of authoring is to write goals that are a *verifiable spec of correct behavior* — not a loose description the driver has to interpret charitably. The judging rules are single-sourced in the scenarios README: [**How scenarios are judged (authoring contract)**](../../../cli/azd/extensions/azure.ai.agents/tests/cli-interactive-tester-scenarios/README.md#how-scenarios-are-judged-authoring-contract). The consequences for how you write goals: - **Write goals as literal, checkable assertions.** "Confirm the process exits cleanly and prints a version string" is checkable; "make sure version works" is not. A driver will FAIL a scenario whose goals aren't met — it will not rationalize a near-miss into a pass. - **Never encode a workaround in a goal.** If a goal names a flag/command that doesn't exist or expects output that never appears, the scenario FAILS by design. Keep goals current with the product; don't paper over a bug in the goal text. - **Key interactive pickers off stable text labels, not positions.** The driver prefers `choice_text` over `choice_index`, so phrase picker goals around the label (e.g. *select "Use the code in the current directory"*) — indices shift between releases. - **Enumerate expected product prompts.** Goals define every product prompt allowed during the scenario. Name each prompt with stable user-visible text and state the response. Use "if asked" only for a genuinely optional prompt. Never write "follow the prompts" or another catch-all; an unlisted product prompt must fail the scenario. - **Give every executed invoke explicit input.** Write the literal command with a quoted positional message. Use `--input-file` only when file input is what the scenario tests, and define the file contents first. Never leave command construction to the worker with wording such as "run invoke and send a simple message"; bare invoke does not prompt for a message. - **Guard pre-filled prompts.** When a prompt comes pre-populated (e.g. the agent name), the goal must tell the driver to **clear the field first** before typing, or the typed value appends to the default. See the RESOURCE NAMING / AGENT NAME goals in `tier1/1.04-init-from-code.yaml` for the canonical phrasing. - **Gate cost explicitly.** Any goal that reaches `azd provision` / real resource creation belongs in Tier 1b or Tier 2 and must be tagged and tiered accordingly (see below). > The deeper *why* behind the picker / clear-field / no-retry rules is the executor spec > [`driving-mechanics.md`](../../../cli/azd/extensions/azure.ai.agents/tests/cli-interactive-tester-scenarios/driving-mechanics.md). > You don't need to restate it — just author goals that hold under it. ## Scenario anatomy One file targets **one** command or flow. The taxonomy behind each field is single-sourced in the README — this is the annotated skeleton; follow the links for the rules: ```yaml # One-line comment: tier, what it targets, and any cost/prerequisite note. name: "short-kebab-name" # tester run label; keep it short and unique-ish command: "azd ai agent <subcommand> …" # the installed extension entry point cwd: "~/working/azd-agents-<slug>-{instance}" # see cwd + idempotency below; /tmp for read-only tags: ["tier:N", "cmd:<name>", "parallel-safe"] # REQUIRED — see the Tags taxonomy requires: "tier1/1.0X-….yaml" # optional; only when this scenario needs another to PASS first produces: "~/working/azd-agents-…-{instance}/generated-agent" # optional producer output env: # optional; init scenarios disable agent auto-detect AZD_DISABLE_AGENT_DETECT: "1" allocate_ports: [agent] # optional; only for scenarios that bind a port (e.g. 2.12) pre: # optional host-side setup (reset dir, seed fixture, auth guard) - run: "rm -rf {cwd-or-path}" cwd: "~/working" name: "reset working dir" post: # optional host-side cleanup - run: "…" name: "cleanup" goals: # product behavior is the literal, checkable contract - "Wait for … and confirm …." - "Take a screenshot of the final output." # best-effort evidence; capture failure is an observation - "Report a finding if …." ``` Field references (do not restate these — link to them): - **Tiers & placement** — which directory (`tier0/`…`tier2/`) and cost profile: [README § Tiers](../../../cli/azd/extensions/azure.ai.agents/tests/cli-interactive-tester-scenarios/README.md#tiers). - **Tags** — the `tier:N` / `cmd:*` / trait namespaces and rules: [README § Tags](../../../cli/azd/extensions/azure.ai.agents/tests/cli-interactive-tester-scenarios/README.md#tags). - **`requires:`** — cross-scenario prerequisites (Tier 1b → Tier 1): [README § The `requires:` field](../../../cli/azd/extensions/azure.ai.agents/tests/cli-interactive-tester-scenarios/README.md#the-requires-field). - **`produces:`** — the verified Tier 1 scaffold handed to Tier 1b: [README § Producer/consumer scaffold handoff](../../../cli/azd/extensions/azure.ai.agents/tests/cli-interactive-tester-scenarios/README.md#producerconsumer-scaffold-handoff). - **Profile/session placeholders** (`{prefix}`, `{subscription}`, `{region}`, `{model}`, `{model_version}`, `{model_sku}`, `{tenant}`, `{run_id}`, `{shared_agent_name}`, `{foundry_project_name}`, `{fixtures_dir}`, `{instance}`): [README § Profile / overrides](../../../cli/azd/extensions/azure.ai.agents/tests/cli-interactive-tester-scenarios/README.md#profile--overrides). - **Pre/post hooks** — semantics (host-side, sequential, fail-fast), fields, and the reset / fixture-seed / auth-guard patterns: [README § Pre/post hooks](../../../cli/azd/extensions/azure.ai.agents/tests/cli-interactive-tester-scenarios/README.md#prepost-hooks). - **Fixtures** — the `{fixtures_dir}` seed pattern: [README § Fixtures](../../../cli/azd/extensions/azure.ai.agents/tests/cli-interactive-tester-scenarios/README.md#fixtures). - **Idempotency** — how a stateful scenario resets itself so re-runs start clean: [README § Re-running scenarios](../../../cli/azd/extensions/azure.ai.agents/tests/cli-interactive-tester-scenarios/README.md#re-running-scenarios-idempotency). - **Conventions & parallel-readiness** — resource naming, `{instance}` suffixing, port allocation: [README § Conventions](../../../cli/azd/extensions/azure.ai.agents/tests/cli-interactive-tester-scenarios/README.md#conventions) and [§ Parallel-readiness](../../../cli/azd/extensions/azure.ai.agents/tests/cli-interactive-tester-scenarios/README.md#parallel-readiness--port-allocation). ## Authoring procedure 1. **Confirm the target and scope.** Identify the single command / flow under test and whether it is a happy path or a `negative-path` (error / non-zero-exit) assertion. One command per file — if you're tempted to test two, that's two scenarios (or a documented lifecycle scenario, like `2.07-sessions-lifecycle`). If the request is broad or ambiguous, ask via `ask_user` which command and tier are intended. 2. **Pick the tier and file placement.** Choose the lowest tier that can actually exercise the behavior (offline Tier 0 > auth-only Tier 1 > deploy-verify Tier 1b > cloud Tier 2), because cost and flakiness rise with tier. Place the file in the matching `tierN/` directory and name it `<tier-number>.<seq>-<slug>.yaml`, continuing the existing numbering in that directory. 3. **Write `command` and `cwd`.** - `command:` invokes the installed extension (`azd ai agent …`) or `azd …` for provision/deploy/down steps. - Read-only, stateless scenarios (`version`, `--help`, `sample list`) use `cwd: "/tmp"` and declare no hooks. - Stateful scenarios use a dedicated working dir suffixed with `-{instance}` (e.g. `~/working/azd-agents-<slug>-{instance}`) so parallel instances stay isolated. 4. **Make it idempotent with hooks.** For a stateful scenario add a `pre` hook that `rm -rf`s its own `cwd` (and, if it needs source code, a second hook that seeds a fixture from `{fixtures_dir}` — see `tier1/1.04-init-from-code.yaml`). Prefer **pre-wipe only** for local-only scenarios so the scaffold stays on disk for inspection. Tier 1b scenarios that provision paid resources require an always-run `post` hook with a suitable timeout for `azd down --force --purge`. Tier 2 setup additionally downs a project at its current-run path before removing that directory; teardown failure must abort setup and preserve state for recovery. Do not use `continue_on_error` when cleanup failure would orphan resources. 5. **Add a fixture only if required.** If the flow needs pre-existing source (the "use the code in the current directory" path), add the minimal tree under `fixtures/<name>/` and seed it via the hook. Keep fixtures minimal, but make them runnable when a later scenario deploys and invokes the generated scaffold; detection-only placeholders are not sufficient for deploy-verification prerequisites. 6. **Declare producer/consumer handoff when required.** A Tier 1 scenario whose scaffold is deployed by Tier 1b sets `produces:` to the exact generated project directory. Its Tier 1b consumer points `requires:` at that Tier 1 scenario (a **relative path from the scenarios root**) and uses `{prerequisite_scaffold_dir}` for `cwd` and every scaffold hook path. Never duplicate the producer's path in the consumer. Don't use `requires:` to sequence independent scenarios — it is a hard prerequisite, not an ordering hint. 7. **Write the `tags:` list.** At minimum: one `tier:N`, at least one `cmd:*`, and exactly one of `parallel-safe` / `serial-only` (Tier 0/1/1b → `parallel-safe`; Tier 2 → `serial-only`). Add `negative-path`, `picker`, or `verify-deploy` when they apply. Multi-command flows carry multiple `cmd:*` tags. 8. **Write the `goals:` as the contract.** Follow the authoring-contract rules above: literal, checkable product behavior, stable-label picks, clear-field-before-typing, best-effort screenshot evidence, and a final "report a finding if …" goal. Screenshot errors and timeouts are observations and do not block later product goals; all product expectations remain strict. For multi-select prompts, choose one explicit intent: - A **default assertion** lists what must already be selected and unselected, then says to leave that selection unchanged and continue. A mismatch must fail without repair. - A **final-state instruction** lists what should end selected and unselected without asserting the initial state, allowing the worker to change only the differences. An already-correct selection advances without changing any choice. Keep action names, indices, payloads, and keystrokes out of scenario goals; the worker owns those mechanics. For resource-creating flows, include the RESOURCE NAMING and AGENT NAME goals (prefix `{prefix}-`, suffix `-{instance}`) so parallel runs don't collide. Foundry project prompts must use the orchestrator-derived `{foundry_project_name}` because the service limits those names to 32 characters. ## Validation loop (no execution) Validate **statically** — never `start_session`, never drive the scenario, never provision. 1. **Tag lint via `list_scenarios`.** Run `list_scenarios(root="<scenarios-dir>", tags=[<the new scenario's tags>])` and confirm the new file appears under each of its tags. If `list_scenarios` reports `tags: []` for the file, the `tags:` field is missing or malformed — fix it. (`list_scenarios` uses a real YAML parser, so this also catches YAML syntax errors in the file.) 2. **YAML shape.** Re-read the file and confirm required fields (`name`, `command`, `cwd`, `tags`, `goals`) are present and well-formed, that `goals` is a non-empty list of strings, and that any Tier 1 producer declares the exact scaffold directory in `produces:`. 3. **`requires:` resolves.** If `requires:` is set, confirm the referenced path exists relative to the scenarios root and points at the intended prerequisite. 4. **Fixture / hook paths resolve.** If a `pre` hook seeds a fixture, confirm the referenced `fixtures/<name>/` tree exists and the hook uses `{fixtures_dir}` (not a hardcoded path). 5. **Placeholders only reference known variables.** Every `{name}`-shaped token in `command` / `cwd` / hooks / goals is processed as a placeholder and must be a documented profile/session placeholder (including `{model_version}`, `{model_sku}`, and `{foundry_project_name}`) or, for Tier 1b, `{prerequisite_scaffold_dir}`. This includes embedded shell syntax: format an awk action as `{ print }`, not `{print}`, so it cannot be mistaken for an unknown placeholder. Reject every unknown brace-delimited token during static validation. 6. **Invoke input is explicit.** For every goal or `command` that executes `azd ai agent invoke`, confirm the literal command includes a positional message or an intentional `--input-file` whose contents are defined by the scenario. Command-list and help assertions that only mention `invoke` are not executable calls. 7. **Coverage cross-check.** If this scenario closes a coverage gap flagged by a PR regression run, confirm its `cmd:*` tag matches the changed command so future impact-mapping picks it up. Report the validation result to the user. If they then want to *run* the new scenario to confirm it drives cleanly, that's a separate, cost-gated step — hand off to the `foundry-extension-scenario-suite-run` skill / `foundry-extension-scenario-orchestrator` agent (Tier 1b / Tier 2 incur Azure cost and need explicit consent). This skill stops at a validated, unexecuted scenario. ## Exit criteria - A single-command scenario YAML was authored (or corrected) in the correct `tierN/` directory with a compliant `tags:` list, appropriate `cwd` + idempotency hooks, any needed fixture / `requires:`, and `goals:` written as a literal, checkable contract. - The static validation loop passed: `list_scenarios` lists the file under all its tags (not `tags: []`), the YAML parses, and every `requires:` / fixture / placeholder reference resolves. - **No scenario was executed** and no Azure resources were created; any run-to-confirm was handed off to the run skills with a cost note.
Ver no GitHub