|
| 1 | +# `ado-aw-debug:` — Debug-only front-matter section |
| 2 | + |
| 3 | +_Part of the [ado-aw documentation](../AGENTS.md)._ |
| 4 | + |
| 5 | +> ⚠️ **This section is for dogfood pipelines only.** |
| 6 | +> Anything declared under `ado-aw-debug:` is **not** part of the regular |
| 7 | +> agent surface and is not recommended for general use. Knobs here exist so |
| 8 | +> the team can validate `githubnext/ado-aw` changes against real Azure |
| 9 | +> DevOps pipelines and file failures back to GitHub for triage. Each knob |
| 10 | +> bypasses or weakens a normal safety control. |
| 11 | +
|
| 12 | +The compiler accepts a top-level `ado-aw-debug:` block in agent front |
| 13 | +matter. Currently exposed knobs: |
| 14 | + |
| 15 | +| Knob | Purpose | Default | |
| 16 | +| --- | --- | --- | |
| 17 | +| `skip-integrity` | Omit the "Verify pipeline integrity" step from the generated YAML. OR-ed with the `--skip-integrity` CLI flag. | `false` | |
| 18 | +| `create-issue` | Enable the [debug-only `create-issue`](#create-issue) safe output. | absent (disabled) | |
| 19 | + |
| 20 | +Unrecognised keys under `ado-aw-debug:` cause a compile-time error |
| 21 | +(`#[serde(deny_unknown_fields)]`). |
| 22 | + |
| 23 | +## `create-issue` |
| 24 | + |
| 25 | +Files a GitHub issue against an operator-configured target repository. |
| 26 | +Used to surface failures from ADO-hosted dogfood pipelines back to |
| 27 | +`githubnext/ado-aw` for triage. |
| 28 | + |
| 29 | +### Why it's gated |
| 30 | + |
| 31 | +`create-issue` is **default-deny** at three layers: |
| 32 | + |
| 33 | +1. **MCP layer.** The SafeOutputs MCP server lists `create-issue` in |
| 34 | + [`DEBUG_ONLY_TOOLS`][debug-only-tools], so the route is removed from |
| 35 | + the tool router unless the compiler explicitly opts in via |
| 36 | + `--enabled-tools`. |
| 37 | +2. **Compiler layer.** `--enabled-tools create-issue` is only emitted |
| 38 | + when `ado-aw-debug.create-issue:` is present in front matter. The |
| 39 | + compiler also rejects `safe-outputs.create-issue:` outright, so the |
| 40 | + tool can't be smuggled in via the regular safe-outputs surface. |
| 41 | +3. **Executor layer.** Stage 3 maintains a separate |
| 42 | + `ExecutionContext.debug_enabled_tools` set populated only from |
| 43 | + `ado-aw-debug:`. The executor refuses any NDJSON `create-issue` |
| 44 | + entry that isn't in that set, so a forged or smuggled NDJSON entry |
| 45 | + fails closed before any token is read. |
| 46 | + |
| 47 | +[debug-only-tools]: ../src/safeoutputs/mod.rs |
| 48 | + |
| 49 | +### Front-matter schema |
| 50 | + |
| 51 | +```yaml |
| 52 | +ado-aw-debug: |
| 53 | + create-issue: |
| 54 | + target-repo: githubnext/ado-aw # REQUIRED. Operator-only; agent has no override. |
| 55 | + title-prefix: "[pipeline-failure] " # Optional; prepended to every agent title. |
| 56 | + labels: # Optional; static labels always applied. |
| 57 | + - pipeline-failure |
| 58 | + - automated |
| 59 | + allowed-labels: # Optional; default-deny — see below. |
| 60 | + - "agent-*" |
| 61 | + - "pipeline-failure" |
| 62 | + assignees: # Optional; static assignees always applied. |
| 63 | + - "jamesdevine" |
| 64 | + max: 3 # Optional; per-run budget. Default 1. |
| 65 | +``` |
| 66 | +
|
| 67 | +* **`target-repo`** is required. Format `owner/repo`. The agent has no |
| 68 | + parameter to override it; you cannot redirect issues to a different |
| 69 | + repository at runtime. |
| 70 | +* **`title-prefix`** is appended at execution time. The final title length |
| 71 | + (prefix + agent title) must be ≤ 256 characters; longer titles fail at |
| 72 | + Stage 3. |
| 73 | +* **`labels`** are applied unconditionally to every issue, on top of any |
| 74 | + agent-supplied labels that pass `allowed-labels`. |
| 75 | +* **`allowed-labels`** is **default-deny**: an empty or absent list means |
| 76 | + **no agent-supplied labels are accepted**. To accept any agent label, |
| 77 | + set `allowed-labels: ["*"]` explicitly. Patterns may include `*` |
| 78 | + wildcards (e.g. `"agent-*"`). |
| 79 | +* **Allowed-label matching is case-insensitive.** It uses the same |
| 80 | + `tag_matches_pattern` helper as ADO tag allow-lists. GitHub labels are |
| 81 | + case-sensitive, so `allowed-labels: ["safe"]` will also admit |
| 82 | + `SAFE` and `Safe` — keep that in mind when modelling policy. |
| 83 | +* **`assignees`** are merged with agent-supplied assignees. There is |
| 84 | + intentionally no `allowed-assignees` allowlist in v1; if you need |
| 85 | + one, configure assignees only via the static `assignees:` list and |
| 86 | + skip the agent parameter. |
| 87 | +* **`max`** controls per-run budget the same way it does for other |
| 88 | + safe-output tools. |
| 89 | + |
| 90 | +### Agent-supplied parameters |
| 91 | + |
| 92 | +The agent calls the `create-issue` MCP tool with: |
| 93 | + |
| 94 | +```jsonc |
| 95 | +{ |
| 96 | + "title": "Pipeline failure on main", |
| 97 | + "body": "<markdown body, ≥ 30 chars>", |
| 98 | + "labels": ["pipeline-failure"], // optional |
| 99 | + "assignees": ["copilot"] // optional |
| 100 | +} |
| 101 | +``` |
| 102 | + |
| 103 | +The MCP-side `Validate` impl rejects ADO pipeline-command sequences in |
| 104 | +labels and assignees (see [src/safeoutputs/create_issue.rs](../src/safeoutputs/create_issue.rs)). |
| 105 | +Stage 3 also neutralises `##vso[…]` in any error messages it produces, so |
| 106 | +agent-supplied content cannot escape the executor's stdout. |
| 107 | + |
| 108 | +### Pipeline variable: `ADO_AW_DEBUG_GITHUB_TOKEN` |
| 109 | + |
| 110 | +Stage 3 authenticates against GitHub using the |
| 111 | +**`ADO_AW_DEBUG_GITHUB_TOKEN`** ADO pipeline variable. The compiler emits |
| 112 | + |
| 113 | +```yaml |
| 114 | +env: |
| 115 | + SYSTEM_ACCESSTOKEN: $(SC_WRITE_TOKEN) # if write permissions: are set |
| 116 | + ADO_AW_DEBUG_GITHUB_TOKEN: $(ADO_AW_DEBUG_GITHUB_TOKEN) # only when ado-aw-debug.create-issue is set |
| 117 | +``` |
| 118 | + |
| 119 | +into the executor step's `env:` block. The token is **not** exposed to |
| 120 | +the agent in Stage 1 — the read-only `GITHUB_TOKEN` the agent sees is a |
| 121 | +separate variable wired through `engine.env` and used only for GitHub |
| 122 | +MCP read access. |
| 123 | + |
| 124 | +### Setting up the PAT |
| 125 | + |
| 126 | +1. **Generate a fine-grained PAT** scoped to **only** `target-repo` (e.g. |
| 127 | + `githubnext/ado-aw`). Required permissions: |
| 128 | + * Repository access: only the target repo. |
| 129 | + * Permissions: **Issues** = Read and write. Nothing else. |
| 130 | +2. **Store as a secret pipeline variable** named exactly |
| 131 | + `ADO_AW_DEBUG_GITHUB_TOKEN`. Mark it secret. Do **not** copy it into |
| 132 | + `engine.env` or any non-secret variable. |
| 133 | +3. **Confirm the operator-configured target-repo matches the PAT scope.** |
| 134 | + The compiler validator only checks shape (`owner/repo`); it cannot |
| 135 | + verify the PAT has access. If the PAT lacks Issues:write, the Stage 3 |
| 136 | + call fails with the GitHub API error and Stage 3 reports |
| 137 | + `succeeded with issues`. |
| 138 | +4. `ado-aw configure` does **not** automate this variable today — set it |
| 139 | + manually in the ADO pipeline definition. |
| 140 | + |
| 141 | +### Auto-footer |
| 142 | + |
| 143 | +Every issue gets an auto-appended traceability footer that looks like: |
| 144 | + |
| 145 | +```markdown |
| 146 | +<!-- ado-aw --> |
| 147 | +--- |
| 148 | +Pipeline: `dogfood-failure-reporter` |
| 149 | +Run: <https://dev.azure.com/myorg/MyProject/_build/results?buildId=42> |
| 150 | +Trigger: `Manual` |
| 151 | +``` |
| 152 | +
|
| 153 | +The `<!-- ado-aw -->` marker is stable so that future tooling can locate |
| 154 | +the generated content without parsing prose. The footer is built from |
| 155 | +`BUILD_BUILDID`, `BUILD_DEFINITIONNAME`, `BUILD_REASON`, |
| 156 | +`SYSTEM_TEAMFOUNDATIONCOLLECTIONURI` and `SYSTEM_TEAMPROJECT` — these are |
| 157 | +present whenever Stage 3 runs inside an ADO pipeline. |
| 158 | + |
| 159 | +If your pipeline / org / project names are sensitive, do not enable |
| 160 | +`create-issue` against a public repo. |
| 161 | + |
| 162 | +### Security checklist |
| 163 | + |
| 164 | +- [ ] Target repo's GitHub PAT is scoped to that repo only and only has |
| 165 | + Issues:write. |
| 166 | +- [ ] `ADO_AW_DEBUG_GITHUB_TOKEN` is stored as a secret pipeline |
| 167 | + variable, never hard-coded or printed. |
| 168 | +- [ ] `allowed-labels` is set explicitly. Empty means default-deny; |
| 169 | + `["*"]` accepts any agent label — pick deliberately. |
| 170 | +- [ ] `target-repo` is private if the agent's prompts or pipeline |
| 171 | + metadata are sensitive (the auto-footer publishes ADO run URLs and |
| 172 | + pipeline names). |
| 173 | +- [ ] `skip-integrity` is **not** enabled in pipelines triggered by |
| 174 | + untrusted PRs. |
| 175 | + |
| 176 | +## `skip-integrity` |
| 177 | + |
| 178 | +Equivalent to passing `--skip-integrity` on the `ado-aw compile` CLI. |
| 179 | +Setting either OR setting both omits the `Verify pipeline integrity` |
| 180 | +step from the generated YAML. |
| 181 | + |
| 182 | +The integrity step downloads the same `ado-aw` binary the pipeline was |
| 183 | +compiled with and runs `ado-aw check` against the committed pipeline |
| 184 | +file. Without it, a tampered `*.yml` won't be caught at run time. |
| 185 | + |
| 186 | +Use this only for short-lived dogfood pipelines where you're iterating |
| 187 | +on the compiler and re-compiling frequently. |
| 188 | + |
| 189 | +## See also |
| 190 | + |
| 191 | +- [`docs/safe-outputs.md`](safe-outputs.md) — regular safe-outputs |
| 192 | + surface (`create-issue` is **not** in it). |
| 193 | +- [`docs/cli.md`](cli.md) — `--skip-integrity` CLI flag. |
| 194 | +- [`docs/template-markers.md`](template-markers.md) — `{{ executor_ado_env }}` |
| 195 | + and `{{ integrity_check }}` markers and their conditional behaviour. |
0 commit comments