Skip to content

Render workflow prompts with JavaScript instead of shell heredocs - #51850

Merged
pelikhan merged 10 commits into
mainfrom
copilot/update-compiler-to-actions-javascript
Aug 11, 2026
Merged

Render workflow prompts with JavaScript instead of shell heredocs#51850
pelikhan merged 10 commits into
mainfrom
copilot/update-compiler-to-actions-javascript

Conversation

Copilot AI commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Shell heredocs assembled prompts from user-controlled expressions, exposing the generated workflow to injection. Prompt rendering now treats every expression and prompt fragment as opaque data.

  • Rendering

    • Add create_prompt.cjs and invoke it through pinned actions/github-script.
    • Remove the heredoc shell renderer.
  • Input isolation

    • Pass content, conditions, and module paths through environment variables.
    • Validate renderer configuration and restrict file reads to the prompt directory.
env:
  GH_AW_PROMPT_CONTENT_0000: ${{ user_controlled_expression }}
with:
  script: |
    const { main } = require(process.env.GH_AW_ACTIONS_DIR + '/create_prompt.cjs');
    await main();
  • Regression coverage
    • Add compiler and renderer cases for shell, heredoc, JavaScript, YAML, Unicode, traversal, multiline, and conditional injection payloads.
    • Refresh generated workflows and WASM golden outputs.

Copilot AI and others added 3 commits August 10, 2026 18:02
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title Render prompts with JavaScript instead of shell heredocs Render workflow prompts with JavaScript instead of shell heredocs Aug 10, 2026
Copilot AI requested a review from pelikhan August 10, 2026 18:17
@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot pass core object for logging like other scripts

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Aug 10, 2026

Copy link
Copy Markdown
Contributor Author

@copilot pass core object for logging like other scripts

Updated the renderer to accept core explicitly and changed generated callers/tests to use main(core) in a0fac6a.

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot run pr-finisher skill

Copilot AI commented Aug 10, 2026

Copy link
Copy Markdown
Contributor Author

@copilot run pr-finisher skill

Completed the PR-finisher pass. Formatting, lint, impacted unit tests, full tests, and all 284 workflow recompilations pass locally; review and security scans found no issues, and no additional code changes were needed. The PR remains draft and its Actions runs are approval-gated with zero jobs executed.

@pelikhan
pelikhan marked this pull request as ready for review August 10, 2026 20:30
Copilot AI balanced review requested due to automatic review settings August 10, 2026 20:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot resolve the merge conflicts on this branch.

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Aug 10, 2026

Copy link
Copy Markdown
Contributor Author

@copilot resolve the merge conflicts on this branch.

Resolved the conflicts with main in merge commit 409a595. The four affected workflows were recompiled with the JavaScript prompt renderer preserved.

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot fix lint go

@pelikhan

Copy link
Copy Markdown
Collaborator

/matt

@pelikhan

Copy link
Copy Markdown
Collaborator

/review

@pelikhan

Copy link
Copy Markdown
Collaborator

/matt

@pelikhan

Copy link
Copy Markdown
Collaborator

/ponytail

@github-actions

github-actions Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer

@github-actions

github-actions Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Ponytail Reviewer completed successfully!

pr-diff.patch is empty (0 bytes) — no diff content available to review for over-engineering.

Generated by Ponytail Reviewer

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Skills-Based Review 🧠

Applied /diagnosing-bugs, /tdd, and /codebase-design — requesting changes on two correctness issues (symlink escape, file-permission race) and three maintainability issues (stale test assertions, ESM/CJS mismatch, global.core).

✅ The core architectural move — replacing shell heredocs with a JavaScript renderer that isolates user-controlled content in environment variables — is the right fix and is cleanly executed. The injection test matrix in create_prompt.test.cjs is comprehensive.

📋 Key Findings

Security / Correctness

  • Symlink escape (create_prompt.cjs line 52): resolvePromptFile uses path.resolve() but not fs.realpathSync(), so a symlink inside promptsDir pointing outside the sandbox passes the check.
  • File-permission race (create_prompt.cjs line 131): writeFileSync with mode: 0o600 does not chmod an already-existing file on POSIX, leaving a previously world-readable file world-readable.
  • Prompt path inconsistency (unified_prompt_step.go line 409): GH_AW_PROMPT is hardcoded to /tmp/gh-aw/... while the JS renderer roots its sandbox under RUNNER_TEMP. Misaligned roots make path reasoning harder and fail on runners where /tmp is restricted.

Test Quality

  • Stale assertions (heredoc_interpolation_test.go line 82): Checks for __GH_AW_ placeholders that belonged to the old heredoc design rather than the new env-variable approach.
  • ESM/CJS mismatch (create_prompt.test.cjs line 8): Top-level import with a require() call in the same file is fragile.
  • Missing global.core (create_prompt.test.cjs line 6): Other test files set global.core = mockCore; omitting it here may silently hide transitive failures.

Positive Highlights

  • ✅ Injection payload matrix covers shell, backtick, YAML, Unicode, heredoc-escape, and multiline cases
  • condition_env must equal the exact string "true" — good defence against truthy-value confusion
  • writeYAMLEnv uses %q quoting — prevents YAML structure injection from config values
  • GH_AW_ACTIONS_DIR passed through env keeps Actions expressions out of JavaScript source

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · sonnet46 · 133.5 AIC · ⌖ 10.2 AIC · ⊞ 7.1K
Comment /matt to run again

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot quick triage: this PR still has a fresh blocking Matt review requesting changes. Please fix the symlink-escape and existing-file permission issues in the JavaScript prompt renderer, align the prompt temp-path handling with the runner temp sandbox, clean up the stale test assertions/module setup noted in review, then run the pr-finisher skill and hand back a short maintainer-facing summary.

Branch refresh was requested. Run: https://github.com/github/gh-aw/actions/runs/31454952282

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 15.9 AIC · ⌖ 5.21 AIC · ⊞ 8.5K ·
Comment /souschef to run again

@pelikhan

Copy link
Copy Markdown
Collaborator

/ponytail

@github-actions

github-actions Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Ponytail Reviewer completed successfully!

pr-diff.patch is empty (0 bytes), so there are no changed lines to review for over-engineering. Skipping review.

Generated by Ponytail Reviewer

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot run pr-finisher skill

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot create an integration test that compares the current rendering scheme with the new JavaScript based rendering.

Copilot AI and others added 2 commits August 11, 2026 03:59
…er-to-actions-javascript

Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>

Copilot AI commented Aug 11, 2026

Copy link
Copy Markdown
Contributor Author

@copilot quick triage: this PR still has a fresh blocking Matt review requesting changes. Please fix the symlink-escape and existing-file permission issues in the JavaScript prompt renderer, align the...

Fixed in 26218ca: canonical path checks now block symlink escapes, prompt writes tighten existing-file permissions before content, activation prompt processing uses the runner temp sandbox, and stale renderer tests/module setup are updated. The branch was refreshed through merge commit 9931709; PR-finisher validation, all 284 recompilations, renderer checks, and the full Go suite pass.

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot review rendered prompt.txt from existing agentic workflow runs and compare with JavaScript version.

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Aug 11, 2026

Copy link
Copy Markdown
Contributor Author

@copilot run pr-finisher skill

Completed the PR-finisher pass in a3a959c. The final change-scoped gate, full Go suite, renderer integration tests, all 284 recompilations, review, secret scan, and CodeQL assessment pass. CI on this agent-pushed HEAD still needs a maintainer re-trigger.

@copilot create an integration test that compares the current rendering scheme with the new JavaScript based rendering.

Added create_prompt.integration.test.cjs in a3a959c. It executes the legacy shell and JavaScript renderers with identical inline, file-backed, Unicode, and conditional inputs, then compares output bytes for both conditional branches.

Copilot AI commented Aug 11, 2026

Copy link
Copy Markdown
Contributor Author

@copilot review rendered prompt.txt from existing agentic workflow runs and compare with JavaScript version.

Reviewed real artifacts and replayed the JavaScript renderer with each run’s exact configuration/context. Step Name Alignment run 31458023382 matched byte-for-byte (25,032 bytes, SHA-256 f83a8b84321f…), and AI Moderator run 31405519731 matched byte-for-byte (16,302 bytes, SHA-256 2dd581c0e3ee…). Their pre-interpolation templates also matched exactly. The existing renderer integration test passes; no additional code changes are needed.

@pelikhan
pelikhan merged commit bf74326 into main Aug 11, 2026
37 checks passed
@pelikhan
pelikhan deleted the copilot/update-compiler-to-actions-javascript branch August 11, 2026 05:04
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in a new release.

Release: v0.86.2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants