Problem
When agents create GitHub issues, PRs, or comments with Markdown bodies, the body is written via a bash heredoc:
gh issue create --body "$(cat <<'EOF2'
...
EOF2
)"
Agents reflexively backslash-escape backticks inside the heredoc, producing \ + ` pairs. GitHub renders the backslash literally — inline code `foo` becomes \`foo\`, and ```ts code fences become \`\`\`ts. Tickets, PRs, and comments ship with broken Markdown and the developer has to fix each one by hand.
Inside a single-quoted heredoc (<<'EOF'), bash performs no expansion — backticks are already literal and need no escaping. The over-escape is a habit carried from double-quoted strings and command substitution, where backticks do need escaping. Every body routed through bash is at risk.
This happened five times in a single recent session (codeassembly#440, codeassembly#441, devtools.afg#346, devtools.afg#347, devtools.afg#348), each requiring re-fetch, manual fix, and push-back.
Context
Four call sites in the installed skills route Markdown bodies through bash:
create-ticket step 5: gh issue create --body "{body}" — initial ticket body
create-ticket step 7: gh issue comment --body "{plan comment}" — plan attachment
create-gh-pr step 2: gh pr create --body "{body}" — PR body
wrap-up Phase 3 step 3: gh issue comment --body "{insight}" — per-insight post
create-bitbucket-pr is not affected — it uses MCP/REST tooling rather than bash.
The root cause is structural: as long as the body is interpolated into a shell command string, an agent can insert a spurious \ and the bug reappears. Warnings in Constraints sections treat the symptom; only removing the shell interpolation removes the class.
Solution
Adopt a single pattern across all four call sites: write the body to a temp file via the Write tool (no bash involved), then invoke gh ... --body-file {path}. The Write tool operates on raw strings, so there is no shell context in which backtick escaping could feel necessary.
Temp path convention: $TMPDIR/gh-body-{timestamp}.md. Rely on OS-managed scratch; no explicit cleanup.
Shared convention doc: add packages/agents/content/skills/_data/gh-body-file.md describing the pattern and rationale once. Each of the four affected skills replaces its inline gh ... --body "..." invocation with a brief step that references the shared doc.
Rejected alternatives (documented so they are not re-proposed):
- Post-create verification that re-fetches and scans for ``` sequences — redundant once the heredoc is gone; adds latency and prose without catching new classes of bug.
- A "never escape Markdown" note in individual skill Constraints sections — treats the symptom. The heredoc it warns about no longer exists after this change.
- Changes to
create-bitbucket-pr — the skill does not use bash for body content; the escape bug cannot arise there.
Acceptance criteria
Problem
When agents create GitHub issues, PRs, or comments with Markdown bodies, the body is written via a bash heredoc:
Agents reflexively backslash-escape backticks inside the heredoc, producing
\+`pairs. GitHub renders the backslash literally — inline code`foo`becomes\`foo\`, and```tscode fences become\`\`\`ts. Tickets, PRs, and comments ship with broken Markdown and the developer has to fix each one by hand.Inside a single-quoted heredoc (
<<'EOF'), bash performs no expansion — backticks are already literal and need no escaping. The over-escape is a habit carried from double-quoted strings and command substitution, where backticks do need escaping. Every body routed through bash is at risk.This happened five times in a single recent session (codeassembly#440, codeassembly#441, devtools.afg#346, devtools.afg#347, devtools.afg#348), each requiring re-fetch, manual fix, and push-back.
Context
Four call sites in the installed skills route Markdown bodies through bash:
create-ticketstep 5:gh issue create --body "{body}"— initial ticket bodycreate-ticketstep 7:gh issue comment --body "{plan comment}"— plan attachmentcreate-gh-prstep 2:gh pr create --body "{body}"— PR bodywrap-upPhase 3 step 3:gh issue comment --body "{insight}"— per-insight postcreate-bitbucket-pris not affected — it uses MCP/REST tooling rather than bash.The root cause is structural: as long as the body is interpolated into a shell command string, an agent can insert a spurious
\and the bug reappears. Warnings in Constraints sections treat the symptom; only removing the shell interpolation removes the class.Solution
Adopt a single pattern across all four call sites: write the body to a temp file via the
Writetool (no bash involved), then invokegh ... --body-file {path}. The Write tool operates on raw strings, so there is no shell context in which backtick escaping could feel necessary.Temp path convention:
$TMPDIR/gh-body-{timestamp}.md. Rely on OS-managed scratch; no explicit cleanup.Shared convention doc: add
packages/agents/content/skills/_data/gh-body-file.mddescribing the pattern and rationale once. Each of the four affected skills replaces its inlinegh ... --body "..."invocation with a brief step that references the shared doc.Rejected alternatives (documented so they are not re-proposed):
create-bitbucket-pr— the skill does not use bash for body content; the escape bug cannot arise there.Acceptance criteria
packages/agents/content/skills/_data/gh-body-file.mdexists and describes the write-then---body-filepattern, the temp path convention, and the rationale (including why it replaces the heredoc approach).create-ticketstep 5 uses--body-fileforgh issue createand references the shared doc.create-ticketstep 7 uses--body-fileforgh issue comment(plan attachment) and references the shared doc.create-gh-prstep 2 uses--body-fileforgh pr createand references the shared doc.wrap-upPhase 3 step 3 uses--body-fileforgh issue comment(per-insight post) and references the shared doc.gh ... --body "..."invocation for a Markdown body (verifiable viarg '\bgh (issue|pr) (create|comment).*--body "'returning no hits inpackages/agents/content/skills).create-bitbucket-pris unchanged.