From 3018612f2f64b66ccf6f0fee00f6f96e2bcfb6e1 Mon Sep 17 00:00:00 2001 From: Toni Bergholm Date: Mon, 9 Nov 2026 16:52:26 +0200 Subject: [PATCH 1/2] docs(agents): keep prose out of shell commands An apostrophe in a bash -c heredoc ended the quoting and ran review text as shell code in a main checkout. --- CLAUDE.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CLAUDE.md b/CLAUDE.md index 080bcd2..a700aef 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -298,6 +298,7 @@ Test-suite platform facts (the part worth knowing, not the count): commander-15 `requiredOption` interaction (ADR-0032). - CLI-child e2e tests must use async `execFile`, never `execFileSync`, or the in-process proxy deadlocks. +- Put PR bodies, reviews, comments and commit messages in a file written with a file-writing tool and pass its path (`gh ... -F `, `git commit -F `). Never inline prose in a shell command, heredoc or `bash -c` string: an apostrophe ends the quoting and backticks run as commands in the current checkout. ## Definition of done for a change From 51918080ba1403067c667708d873c354c0a85bcf Mon Sep 17 00:00:00 2001 From: Toni Bergholm Date: Mon, 9 Nov 2026 16:56:32 +0200 Subject: [PATCH 2/2] docs(agents): name --body-file and keep body files outside the checkout Review follow-up: covers gh api and $(...), exempts titles, and removes inline-body and heredoc examples from agent docs and skills. --- CLAUDE.md | 3 ++- docs/agents/issue-tracker.md | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index a700aef..d83b224 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -298,7 +298,6 @@ Test-suite platform facts (the part worth knowing, not the count): commander-15 `requiredOption` interaction (ADR-0032). - CLI-child e2e tests must use async `execFile`, never `execFileSync`, or the in-process proxy deadlocks. -- Put PR bodies, reviews, comments and commit messages in a file written with a file-writing tool and pass its path (`gh ... -F `, `git commit -F `). Never inline prose in a shell command, heredoc or `bash -c` string: an apostrophe ends the quoting and backticks run as commands in the current checkout. ## Definition of done for a change @@ -314,6 +313,8 @@ Accepted one to reverse it; supersede it). Issues are tracked as **GitHub Issues** in `git-agentic/pkg-registry` via the `gh` CLI. External PRs are **not** a triage surface. See `docs/agents/issue-tracker.md`. +Write PR, issue and review bodies, comments and commit messages to a file outside the checkout with a file-writing tool, and pass its path (`gh ... --body-file `, `gh api ... -F body=@`, `git commit -F `). Never inline them in a shell command, heredoc or `bash -c` string: quotes break, and backticks or `$(...)` then run as commands in the current checkout. Titles may stay inline without backticks. + ### Triage labels Default vocabulary — `needs-triage`, `needs-info`, `ready-for-agent`, `ready-for-human`, `wontfix`. See `docs/agents/triage-labels.md`. diff --git a/docs/agents/issue-tracker.md b/docs/agents/issue-tracker.md index bf595e2..3db7b42 100644 --- a/docs/agents/issue-tracker.md +++ b/docs/agents/issue-tracker.md @@ -4,12 +4,12 @@ Issues and specs for this repo live as GitHub issues. Use the `gh` CLI for all o ## Conventions -- **Create an issue**: `gh issue create --title "..." --body "..."`. Use a heredoc for multi-line bodies. +- **Create an issue**: `gh issue create --title "..." --body-file `. - **Read an issue**: `gh issue view --comments`, filtering comments by `jq` and also fetching labels. - **List issues**: `gh issue list --state open --json number,title,body,labels,comments --jq '[.[] | {number, title, body, labels: [.labels[].name], comments: [.comments[].body]}]'` with appropriate `--label` and `--state` filters. -- **Comment on an issue**: `gh issue comment --body "..."` +- **Comment on an issue**: `gh issue comment --body-file ` - **Apply / remove labels**: `gh issue edit --add-label "..."` / `--remove-label "..."` -- **Close**: `gh issue close --comment "..."` +- **Close**: `gh issue comment --body-file `, then `gh issue close ` Infer the repo from `git remote -v` — `gh` does this automatically when run inside a clone. @@ -42,4 +42,4 @@ Used by `/wayfinder`. The **map** is a single issue with **child** issues as tic - **Blocking**: GitHub's **native issue dependencies** — the canonical, UI-visible representation. Add an edge with `gh api --method POST repos///issues//dependencies/blocked_by -F issue_id=`, where `` is the blocker's numeric **database id** (`gh api repos///issues/ --jq .id`, _not_ the `#number` or `node_id`). GitHub reports `issue_dependencies_summary.blocked_by` (open blockers only — the live gate). Where dependencies aren't available, fall back to a `Blocked by: #, #` line at the top of the child body. A ticket is unblocked when every blocker is closed. - **Frontier query**: list the map's open children (`gh issue list --state open`, scoped to the map's sub-issues / task list), drop any with an open blocker (`issue_dependencies_summary.blocked_by > 0`, or an open issue in the `Blocked by` line) or an assignee; first in map order wins. - **Claim**: `gh issue edit --add-assignee @me` — the session's first write. -- **Resolve**: `gh issue comment --body ""`, then `gh issue close `, then append a context pointer (gist + link) to the map's Decisions-so-far. +- **Resolve**: `gh issue comment --body-file `, then `gh issue close `, then append a context pointer (gist + link) to the map's Decisions-so-far.