Fix AWF blocked shell expansion patterns in all agentic workflow files#1589
Fix AWF blocked shell expansion patterns in all agentic workflow files#1589
Conversation
…terns in all agentic workflow files Agent-Logs-Url: https://github.com/Hack23/riksdagsmonitor/sessions/a35252cf-ce26-41dc-ad66-886f9e2b1bec Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
Agent-Logs-Url: https://github.com/Hack23/riksdagsmonitor/sessions/a35252cf-ce26-41dc-ad66-886f9e2b1bec Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
Agent-Logs-Url: https://github.com/Hack23/riksdagsmonitor/sessions/a35252cf-ce26-41dc-ad66-886f9e2b1bec Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
🏷️ Automatic Labeling SummaryThis PR has been automatically labeled based on the files changed and PR metadata. Applied Labels: documentation,workflow,ci-cd,size-l,news,agentic-workflow Label Categories
For more information, see |
🔍 Lighthouse Performance Audit
📥 Download full Lighthouse report Budget Compliance: Performance budgets enforced via |
There was a problem hiding this comment.
Pull request overview
This PR updates the agentic workflow markdown prompts and related tooling pins to prevent the Agent Workflow Firewall (AWF) from blocking agent-generated bash commands that contain unsafe shell expansion patterns.
Changes:
- Added an “AWF Shell Safety” guidance section to agentic workflow prompt files to steer agents away from
${...}and$(...)patterns. - Replaced unsafe shell-expansion patterns in workflow prose/instructions (e.g.,
${ARTICLE_DATE:-...}→$ARTICLE_DATE,realtime-${HHMM}→realtime-$HHMM). - Bumped
gh-awsetup actions and lock entries to v0.67.1.
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| .github/workflows/SHARED_PROMPT_PATTERNS.md | Adds centralized AWF shell safety guidance intended to be reused across workflows. |
| .github/workflows/news-weekly-review.md | Adds AWF safety section + adjusts prose examples to use $ARTICLE_DATE. |
| .github/workflows/news-week-ahead.md | Adds AWF safety section + adjusts prose examples to use $ARTICLE_DATE. |
| .github/workflows/news-translate.md | Adds AWF safety section for translation workflow agent instructions. |
| .github/workflows/news-realtime-monitor.md | Adds AWF safety section + updates realtime path prose to realtime-$HHMM. |
| .github/workflows/news-propositions.md | Adds AWF safety section + updates analysis reference paths to $ARTICLE_DATE. |
| .github/workflows/news-motions.md | Adds AWF safety section + updates analysis paths to $ARTICLE_DATE. |
| .github/workflows/news-monthly-review.md | Adds AWF safety section + updates commit/paths prose to $ARTICLE_DATE. |
| .github/workflows/news-month-ahead.md | Adds AWF safety section + updates commit/paths prose to $ARTICLE_DATE. |
| .github/workflows/news-interpellations.md | Adds AWF safety section + updates analysis paths to $ARTICLE_DATE. |
| .github/workflows/news-evening-analysis.md | Adds AWF safety section + updates several analysis path references to $ARTICLE_DATE. |
| .github/workflows/news-committee-reports.md | Adds AWF safety section + updates analysis paths to $ARTICLE_DATE. |
| .github/workflows/news-article-generator.md | Adds AWF safety section + updates prose to use $REQUESTED_TYPE/$ARTICLE_DATE. |
| .github/workflows/agentics-maintenance.yml | Updates pinned gh-aw-actions setup/setup-cli usage to v0.67.1 (auto-generated). |
| .github/aw/actions-lock.json | Adds lock entries for gh-aw-actions v0.67.1 SHAs. |
| | `${VAR}` | `$VAR` | Brace-enclosed expansion is blocked | | ||
| | `${VAR:-default}` | `if [ -z "$VAR" ]; then VAR=default; fi` then use `$VAR` | Default-value expansion is blocked | | ||
| | `$(command)` | Pipe the result or use `find -exec` | Command substitution is blocked | | ||
| | `$(basename $f)` | `find ... -exec basename {} \;` or `ls` with path stripping | Nested command substitution blocked | | ||
| | `${PIPESTATUS[0]}` | Check `$?` immediately after the command | Array expansion is blocked | | ||
| | `for f in "$DIR/"*.json; do echo "$(basename $f)"; done` | `find "$DIR" -name "*.json" -exec basename {} \;` | Loop + substitution blocked | | ||
| | `realtime-${HHMM}` | `realtime-$HHMM` | Even simple brace expansion is blocked | | ||
|
|
||
| **Rules for agent-generated bash:** | ||
| 1. **NEVER** use `${...}` (curly braces around variable names) — always use `$VAR` instead | ||
| 2. **NEVER** use `$(...)` (command substitution) — use pipes, `find -exec`, or separate commands | ||
| 3. **NEVER** use `${VAR:-default}` or `${VAR:=default}` — set defaults with `if/then` first |
There was a problem hiding this comment.
This AWF safety table includes the literal blocked patterns (${VAR}, $(command), etc.). Since this document is directly read by agents, it risks being copy/pasted into agent-generated bash commands (reintroducing AWF blocks). Consider obfuscating/escaping the blocked patterns (e.g., insert spaces or use $+{VAR}) and updating nearby examples to only show AWF-safe syntax.
| | `${VAR}` | `$VAR` | Brace-enclosed expansion is blocked | | |
| | `${VAR:-default}` | `if [ -z "$VAR" ]; then VAR=default; fi` then use `$VAR` | Default-value expansion is blocked | | |
| | `$(command)` | Pipe the result or use `find -exec` | Command substitution is blocked | | |
| | `$(basename $f)` | `find ... -exec basename {} \;` or `ls` with path stripping | Nested command substitution blocked | | |
| | `${PIPESTATUS[0]}` | Check `$?` immediately after the command | Array expansion is blocked | | |
| | `for f in "$DIR/"*.json; do echo "$(basename $f)"; done` | `find "$DIR" -name "*.json" -exec basename {} \;` | Loop + substitution blocked | | |
| | `realtime-${HHMM}` | `realtime-$HHMM` | Even simple brace expansion is blocked | | |
| **Rules for agent-generated bash:** | |
| 1. **NEVER** use `${...}` (curly braces around variable names) — always use `$VAR` instead | |
| 2. **NEVER** use `$(...)` (command substitution) — use pipes, `find -exec`, or separate commands | |
| 3. **NEVER** use `${VAR:-default}` or `${VAR:=default}` — set defaults with `if/then` first | |
| | `$`+`{VAR}` | `$VAR` | Brace-enclosed expansion is blocked | | |
| | `$`+`{VAR:-default}` | `if [ -z "$VAR" ]; then VAR=default; fi` then use `$VAR` | Default-value expansion is blocked | | |
| | `$`+`(command)` | Pipe the result or use `find -exec` | Command substitution is blocked | | |
| | `$`+`(basename $f)` | `find ... -exec basename {} \;` or `ls` with path stripping | Nested command substitution blocked | | |
| | `$`+`{PIPESTATUS[0]}` | Check `$?` immediately after the command | Array expansion is blocked | | |
| | `for f in "$DIR/"*.json; do echo "$`+`(basename $f)"; done` | `find "$DIR" -name "*.json" -exec basename {} \;` | Loop + substitution blocked | | |
| | `realtime-$`+`{HHMM}` | `realtime-$HHMM` | Even simple brace expansion is blocked | | |
| **Rules for agent-generated bash:** | |
| 1. **NEVER** use `$`+`{...}` (curly braces around variable names) — always use `$VAR` instead | |
| 2. **NEVER** use `$`+`(...)` (command substitution) — use pipes, `find -exec`, or separate commands | |
| 3. **NEVER** use `$`+`{VAR:-default}` or `$`+`{VAR:=default}` — set defaults with `if/then` first |
| | `${VAR:-default}` | `if [ -z "$VAR" ]; then VAR=default; fi` then use `$VAR` | Default-value expansion is blocked | | ||
| | `$(command)` | Pipe the result or use `find -exec` | Command substitution is blocked | | ||
| | `$(basename $f)` | `find ... -exec basename {} \;` or `ls` with path stripping | Nested command substitution blocked | | ||
| | `${PIPESTATUS[0]}` | Check `$?` immediately after the command | Array expansion is blocked | |
There was a problem hiding this comment.
The guidance "${PIPESTATUS[0]}" → "check $?" is not behaviorally equivalent when the original use is a pipeline (e.g., cmd | tee ...). $? only reports the last command’s status unless pipefail is set. Recommend updating the safe alternative to use set -o pipefail (and check $?), or restructure to avoid pipelines so the correct failure is detected without PIPESTATUS.
| | `${PIPESTATUS[0]}` | Check `$?` immediately after the command | Array expansion is blocked | | |
| | `${PIPESTATUS[0]}` | Use `set -o pipefail` before the pipeline, then check `$?`; or restructure to avoid the pipeline | `$?` only matches the pipeline failure you care about when `pipefail` is set | |
| | `${VAR}` | `$VAR` (no curly braces) | | ||
| | `${VAR:-default}` | Set default first: `if [ -z "$VAR" ]; then VAR=default; fi` then use `$VAR` | | ||
| | `$(command)` | Run as separate command, or use `find -exec` | | ||
| | `$(basename $f)` | Use `find -exec basename {} \;` or `ls` | | ||
| | `${PIPESTATUS[0]}` | Check `$?` immediately after the command | | ||
| | `realtime-${HHMM}` | `realtime-$HHMM` (no braces) | | ||
| | `for f in "$DIR/"*.json; do echo "$(basename $f)"; done` | `find "$DIR" -name "*.json" -exec basename {} \;` | | ||
|
|
||
| **Key rules:** | ||
| 1. **NEVER** use `${...}` — always use `$VAR` (no curly braces) | ||
| 2. **NEVER** use `$(...)` command substitution — use pipes or `find -exec` |
There was a problem hiding this comment.
This AWF safety table includes literal blocked patterns (${VAR}, $(command), ${PIPESTATUS[0]}, etc.). Since this section is meant to be used as a template for agent-generated bash, consider escaping/obfuscating the blocked patterns to reduce the chance they get pasted into a bash tool command and blocked by AWF.
| | `${VAR}` | `$VAR` (no curly braces) | | |
| | `${VAR:-default}` | Set default first: `if [ -z "$VAR" ]; then VAR=default; fi` then use `$VAR` | | |
| | `$(command)` | Run as separate command, or use `find -exec` | | |
| | `$(basename $f)` | Use `find -exec basename {} \;` or `ls` | | |
| | `${PIPESTATUS[0]}` | Check `$?` immediately after the command | | |
| | `realtime-${HHMM}` | `realtime-$HHMM` (no braces) | | |
| | `for f in "$DIR/"*.json; do echo "$(basename $f)"; done` | `find "$DIR" -name "*.json" -exec basename {} \;` | | |
| **Key rules:** | |
| 1. **NEVER** use `${...}` — always use `$VAR` (no curly braces) | |
| 2. **NEVER** use `$(...)` command substitution — use pipes or `find -exec` | |
| | ``$`` + ``{VAR}`` | `$VAR` (no curly braces) | | |
| | ``$`` + ``{VAR:-default}`` | Set default first: `if [ -z "$VAR" ]; then VAR=default; fi` then use `$VAR` | | |
| | ``$`` + ``(command)`` | Run as separate command, or use `find -exec` | | |
| | ``$`` + ``(basename $f)`` | Use `find -exec basename {} \;` or `ls` | | |
| | ``$`` + ``{PIPESTATUS[0]}`` | Check `$?` immediately after the command | | |
| | `realtime-` + ``$`` + ``{HHMM}`` | `realtime-$HHMM` (no braces) | | |
| | `for f in "$DIR/"*.json; do echo "` + ``$`` + ``(basename $f)`` + `"; done` | `find "$DIR" -name "*.json" -exec basename {} \;` | | |
| **Key rules:** | |
| 1. **NEVER** use ``$`` + ``{...}`` — always use `$VAR` (no curly braces) | |
| 2. **NEVER** use ``$`` + ``(...)`` command substitution — use pipes or `find -exec` |
| | `${VAR:-default}` | Set default first: `if [ -z "$VAR" ]; then VAR=default; fi` then use `$VAR` | | ||
| | `$(command)` | Run as separate command, or use `find -exec` | | ||
| | `$(basename $f)` | Use `find -exec basename {} \;` or `ls` | | ||
| | `${PIPESTATUS[0]}` | Check `$?` immediately after the command | |
There was a problem hiding this comment.
The AWF-safe alternative for ${PIPESTATUS[0]} currently says to check $?, but $? won’t capture the failing command in a pipeline unless set -o pipefail is enabled. Update this row to recommend pipefail (or avoiding pipelines) so the guidance doesn’t accidentally hide failures.
| | `${PIPESTATUS[0]}` | Check `$?` immediately after the command | | |
| | `${PIPESTATUS[0]}` | Use `set -o pipefail` and check `$?` immediately after the pipeline, or avoid pipelines | |
| > **Exact steps:** | ||
| > 1. Write article files to `news/` using `bash` or `edit` tools | ||
| > 2. Stage and commit locally (scoped to evening-analysis subfolder): `git add news/ "analysis/daily/${ARTICLE_DATE:-$(date -u +%Y-%m-%d)}/evening-analysis/" analysis/weekly/ && git commit -m "🌆 Evening Analysis - $(date +%Y-%m-%d)"` | ||
| > 2. Stage and commit locally (scoped to evening-analysis subfolder): `git add news/ "analysis/daily/$ARTICLE_DATE/evening-analysis/" analysis/weekly/ && git commit -m "🌆 Evening Analysis - $(date +%Y-%m-%d)"` |
There was a problem hiding this comment.
This inline commit command still uses command substitution $(date +%Y-%m-%d), which is one of the AWF-blocked patterns described in this PR. Replace it with an AWF-safe value (e.g., $ARTICLE_DATE or a {date} placeholder) to avoid agents copying it into a bash tool command and getting blocked.
| > 2. Stage and commit locally (scoped to evening-analysis subfolder): `git add news/ "analysis/daily/$ARTICLE_DATE/evening-analysis/" analysis/weekly/ && git commit -m "🌆 Evening Analysis - $(date +%Y-%m-%d)"` | |
| > 2. Stage and commit locally (scoped to evening-analysis subfolder): `git add news/ "analysis/daily/$ARTICLE_DATE/evening-analysis/" analysis/weekly/ && git commit -m "🌆 Evening Analysis - $ARTICLE_DATE"` |
|
@copilot apply changes based on the comments in this thread |
🔍 Lighthouse Performance Audit
📥 Download full Lighthouse report Budget Compliance: Performance budgets enforced via |
…nce, fix evening-analysis $(date) pattern Agent-Logs-Url: https://github.com/Hack23/riksdagsmonitor/sessions/8470f6d8-6056-4e17-9c1b-ed4c6c113a47 Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
Applied all 5 review comments in commit
|
🔍 Lighthouse Performance Audit
📥 Download full Lighthouse report Budget Compliance: Performance budgets enforced via |
${VAR}and$(cmd)patternsgh aw compile$+{VAR}format (prevents agents from copying literal blocked patterns)set -o pipefailinstead of just$?$(date +%Y-%m-%d)in news-evening-analysis.md prose