Skip to content

Fix AWF blocked shell expansion patterns in all agentic workflow files#1589

Merged
pethers merged 5 commits intomainfrom
copilot/fix-command-block-error
Apr 7, 2026
Merged

Fix AWF blocked shell expansion patterns in all agentic workflow files#1589
pethers merged 5 commits intomainfrom
copilot/fix-command-block-error

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 7, 2026

  • Analyze workflow run 24085790614 and identify blocked commands
  • Identify 3 blocked commands in agent job
  • Audit all 12 agentic workflow .md files for dangerous shell expansion patterns
  • Add AWF shell safety instructions to all workflow files
  • Fix prose instructions that use ${VAR} and $(cmd) patterns
  • Recompile lock files with gh aw compile
  • Fix remaining prose patterns per code review feedback
  • Obfuscate blocked patterns in AWF safety tables using $+{VAR} format (prevents agents from copying literal blocked patterns)
  • Fix PIPESTATUS guidance to recommend set -o pipefail instead of just $?
  • Fix remaining $(date +%Y-%m-%d) in news-evening-analysis.md prose

@github-actions github-actions bot added documentation Documentation updates workflow GitHub Actions workflows ci-cd CI/CD pipeline changes news News articles and content generation agentic-workflow Agentic workflow changes size-l Large change (250-1000 lines) labels Apr 7, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

🏷️ Automatic Labeling Summary

This 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

  • 🗳️ Content: news, dashboard, visualization, intelligence
  • 💻 Technology: html-css, javascript, workflow, security
  • 📊 Data: cia-data, riksdag-data, data-pipeline, schema
  • 🌍 I18n: i18n, translation, rtl
  • 🔒 ISMS: isms, iso-27001, nist-csf, cis-controls
  • 🏗️ Infrastructure: ci-cd, deployment, performance, monitoring
  • 🔄 Quality: testing, accessibility, documentation, refactor
  • 🤖 AI: agent, skill, agentic-workflow

For more information, see .github/labeler.yml.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

Copilot AI requested a review from pethers April 7, 2026 14:43
@pethers pethers marked this pull request as ready for review April 7, 2026 15:19
Copilot AI review requested due to automatic review settings April 7, 2026 15:19
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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-aw setup 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.

Comment on lines +27 to +38
| `${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
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
| `${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

Copilot uses AI. Check for mistakes.
| `${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 |
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
| `${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 |

Copilot uses AI. Check for mistakes.
Comment on lines +179 to +189
| `${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`
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
| `${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`

Copilot uses AI. Check for mistakes.
| `${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 |
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
| `${PIPESTATUS[0]}` | Check `$?` immediately after the command |
| `${PIPESTATUS[0]}` | Use `set -o pipefail` and check `$?` immediately after the pipeline, or avoid pipelines |

Copilot uses AI. Check for mistakes.
> **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)"`
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
> 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 uses AI. Check for mistakes.
@pethers
Copy link
Copy Markdown
Member

pethers commented Apr 7, 2026

@copilot apply changes based on the comments in this thread

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

…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>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 7, 2026

@copilot apply changes based on the comments in this thread

Applied all 5 review comments in commit 2f13711:

  1. Obfuscated blocked patterns in AWF safety tables across all 13 files — using $+{VAR} format so agents won't copy literal blocked patterns
  2. Fixed PIPESTATUS guidance — now recommends set -o pipefail before the pipeline instead of just $?
  3. Fixed $(date +%Y-%m-%d) in news-evening-analysis.md line 1237 — replaced with $ARTICLE_DATE

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

@pethers pethers merged commit 5f62378 into main Apr 7, 2026
12 checks passed
@pethers pethers deleted the copilot/fix-command-block-error branch April 7, 2026 15:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agentic-workflow Agentic workflow changes ci-cd CI/CD pipeline changes documentation Documentation updates news News articles and content generation size-l Large change (250-1000 lines) workflow GitHub Actions workflows

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants