You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
**No merge safe-output exists.** If the workflow needs to merge PRs, use `post-steps:` with a fresh App token. See `references/production-gotchas.md` for the pattern.
117
+
116
118
Refer to `references/safe-outputs.md` for the full catalog of safe-output types and parameters.
117
119
118
120
### Phase 5: Security & Permissions
119
121
120
-
Derive minimal permissions from the selected tools and safe-outputs:
122
+
Derive minimal **read-only** permissions from the selected tools and safe-outputs. **Write permissions are NOT allowed in frontmatter** — the compiler rejects them. All write operations go through safe-outputs.
Write operations (labels, comments, PRs, etc.) are handled entirely by safe-outputs using the App token — no `write` permissions needed in `permissions:`.
133
+
135
134
Ask about security posture:
136
135
137
136
```
@@ -177,6 +176,8 @@ Use expression syntax for dynamic values:
177
176
-`${{ secrets.NAME }}` — secret references
178
177
-`${{ vars.NAME }}` — variable references
179
178
179
+
**Code block interpolation warning:**`${{ }}` expressions in plain text ARE interpolated, but expressions inside fenced code blocks (` ```bash `, etc.) are NOT interpolated — the agent receives them as literal strings. If bash code blocks need event data, declare env vars in plain text (e.g., `ISSUE_NUMBER` from `${{ github.event.issue.number }}`) and use `$ISSUE_NUMBER` in code blocks. See `references/production-gotchas.md` for details.
180
+
180
181
### Phase 8: Assembly & Compilation
181
182
182
183
1. Assemble the complete workflow file combining frontmatter + prose body
@@ -327,13 +328,18 @@ If compilation succeeds (or the user reports a runtime/behavioral issue):
327
328
- Check network access if external calls needed
328
329
- Check safe-output constraints aren't too restrictive
329
330
- Check MCP server configuration (env vars, args, container image)
331
+
-**Check `tools.github.app` permission inheritance** — App token requests ALL workflow permissions, not just what MCP needs
332
+
-**Check `tools.github` vs `gh` CLI conflict** — MCP server takes ownership of GITHUB_TOKEN, blocking `gh` CLI auth
333
+
-**Check `add-comment` discussions default** — requests `discussions:write` even if unused; add `discussions: false`
334
+
-**Check `.lock.yml` vs `.yml` push restriction** — standard `.yml` files block App token pushes
330
335
331
336
2.**Behavioral error** — the workflow runs but produces wrong results:
332
337
- Review prose instructions for ambiguity
333
338
- Check if the agent has sufficient context
334
339
- Check tool selection matches the task
335
340
- Review safe-output allowlists for missing values
336
341
- Check for `event.json` fallback if event context is missing
342
+
-**Check code block interpolation** — `${{ }}` in fenced code blocks are NOT interpolated; agent gets literal strings
337
343
338
344
### Step 3: Gather Context
339
345
@@ -342,7 +348,7 @@ Ask the user to provide:
342
348
- Error messages or logs (from GitHub Actions)
343
349
- Expected vs actual behavior
344
350
345
-
Use `references/validation.md` for the error catalog and common fixes.
351
+
Use `references/validation.md` for the error catalog and `references/production-gotchas.md` for runtime gotchas verified through production debugging.
346
352
347
353
---
348
354
@@ -358,6 +364,7 @@ For questions about:
358
364
-**Body writing** → refer to `references/markdown-body.md`
359
365
-**Errors and debugging** → refer to `references/validation.md`
360
366
-**Examples** → refer to `references/examples.md`
367
+
-**Runtime gotchas, App tokens, MCP pitfalls** → refer to `references/production-gotchas.md`
361
368
362
369
For questions not covered by embedded references, fetch the latest spec:
363
370
- Full spec: `https://github.github.com/gh-aw/llms-full.txt`
@@ -374,7 +381,7 @@ These rules apply across ALL modes:
374
381
1.**Trigger field is `issues` (plural), not `issue`** — this is the most common mistake
375
382
2.**Event-triggered workflows need `reaction: eyes`** in the `on:` block for pre_activation permissions
376
383
3.**Safe-outputs are the ONLY way to write** — the agent itself is read-only
377
-
4.**Permissions must match** — every safe-output type requires specific permission scopes
384
+
4.**Write permissions are NOT allowed in frontmatter** — the compiler rejects `write` in `permissions:`; all writes go through safe-outputs using the App token
378
385
5.**`strict: false` is required** when processing untrusted/external input (public repo issues)
379
386
6.**Bash defaults are safe** — only `echo`, `ls`, `pwd`, `cat`, `head`, `tail`, `grep`, `wc`, `sort`, `uniq`, `date`
380
387
7.**GitHub toolsets default** to `[context, repos, issues, pull_requests]` in Actions
@@ -387,3 +394,15 @@ These rules apply across ALL modes:
387
394
14.**`strict: false` is also required for custom API domains** — ecosystem identifiers (`defaults`, `github`, `containers`, `node`, `python`) work in strict mode, but custom domains like `*.datadoghq.com` require `strict: false`
388
395
15.**Add `node` and `python` ecosystems** when MCP servers use `npx` or `uvx` — these ecosystems allow package registry access (npm, PyPI) needed for process-based MCP servers
389
396
16.**MCP gateway logs are the primary debug source** — when MCP tool calls return vague errors (e.g., "no data found"), download `agent-artifacts/mcp-logs/{server}.log` from the workflow run to see the real error (TLS failures, auth errors, timeouts)
397
+
17.**`${{ }}` expressions in fenced code blocks are NOT interpolated** — they are passed as literal strings to the agent; use env vars in code blocks instead (see `references/production-gotchas.md`)
398
+
18.**`tools.github.app` requests ALL workflow permissions** — if the App lacks any permission in the `permissions:` block (e.g., `packages: read`), the App token creation fails with HTTP 422; omit `app:` for read-only MCP access
399
+
19.**`tools.github` conflicts with `gh` CLI** — the MCP server takes ownership of GITHUB_TOKEN; if workflow only uses `gh` CLI via bash, remove `tools.github` entirely
400
+
20.**`add-comment` defaults to `discussions:write`** — always add `discussions: false` under `add-comment:` unless discussions are explicitly needed, or the App token fails with HTTP 422
401
+
21.**No `merge-pull-request` safe-output exists** — use `post-steps:` with a fresh App token to merge PRs
402
+
22.**`.lock.yml` files are exempt from workflow push restrictions** — standard `.yml`/`.yaml` files block App token pushes in `.github/workflows/`; never mix standard GH Actions `.yml` files with gh-aw workflows if using App tokens for safe-outputs
403
+
23.**Frontmatter `if:` guard** prevents workflow runs from starting entirely — evaluated before any jobs run, saves compute vs job-level guards
404
+
24.**`post-steps:` runs after AI execution** — has access to job context (`${{ github.event.* }}`, secrets, vars); use for merging PRs, closing issues, cleanup requiring App tokens
405
+
25.**`gh aw compile` does NOT escape `"` in entrypointArgs** — never use double quotes in MCP server command strings; use `grep` instead of `jq` if the expression would contain quotes
406
+
26.**MCP server stdout breaks initialization** — any stdout before the JSON-RPC handshake breaks the MCP gateway; redirect all `apk add`, `pip install`, `curl` output to `/dev/null`
407
+
27.**`gh aw mcp inspect/list` does NOT follow `imports:`** — only sees servers in direct frontmatter; check compiled `.lock.yml` to verify imported servers
408
+
28.**`pull_request` trigger uses the merge commit workflow** — if you push a new lock.yml to main and immediately re-trigger a PR, the merge ref may use the old main; wait briefly between pushes and PR events
0 commit comments