Context
The three agent-turn composites — actions/claude.plan, actions/claude.implement, actions/claude.review — duplicate their shell almost verbatim:
- The Instructions step: the
claude.agent.md escaping pipeline (backslashes → quotes → $), the prompt-file heredoc writes to $GITHUB_ENV, TURN_STARTED, and the CLAUDE_EXEC host-install probe (~20 lines × 3).
- The Verify comment-contract step (bot must post ≥1 comment per turn) in plan and implement.
Every flow refinement currently lands three times (see #96 for the latest example).
Approach (operator-decided — do not re-litigate)
Extract the duplicated bash into a shared lib, e.g. actions/claude.lib/turn.sh, sourced from each composite as . "${GITHUB_ACTION_PATH}/../claude.lib/turn.sh". This is version-safe because GitHub ships the whole repo at the action's pinned ref — the existing ${GITHUB_ACTION_PATH}/../claude.agent.md reference is the precedent — so the lib always matches the composite's ref, including on PR branches.
Explicitly out of scope: abstracting the yaml (with: blocks, step layout) — self-contained yaml is load-bearing readability when debugging a turn. Rejected alternatives, for the record: nested composite (uses: gingur/devkit/actions/claude.turn@main resolves at run time → PR changes unexercised until merged); codegen/template rendering (machinery overkill for three files).
Also include
- README enrollment runbook: add the
review.yml caller (the runbook predates claude.review; infra and hooks already carry the caller — copy from there).
- README enrollment runbook: the Infisical OIDC
boundSubject must be repo:gingur/<repo>:* (repo-scoped glob), not repo:gingur/<repo>:ref:refs/heads/main — pull_request-triggered review jobs present subject repo:gingur/<repo>:pull_request and 403 against the exact-ref binding (bit us: hooks#19 review turn, 2026-07-10; all three live identities already patched).
- README enrollment runbook: note that a PR opened before
review.yml existed on main will not fire pull_request: assigned until the PR is refreshed (close/reopen) — GitHub caches the PR'''s workflow set.
Sequencing
Blocked on #96 merging — it touches the same three composites. Plan now; implement only after #96 is in main (fresh turns branch from the post-merge main).
Acceptance criteria
Context
The three agent-turn composites —
actions/claude.plan,actions/claude.implement,actions/claude.review— duplicate their shell almost verbatim:claude.agent.mdescaping pipeline (backslashes → quotes →$), the prompt-file heredoc writes to$GITHUB_ENV,TURN_STARTED, and theCLAUDE_EXEChost-install probe (~20 lines × 3).Every flow refinement currently lands three times (see #96 for the latest example).
Approach (operator-decided — do not re-litigate)
Extract the duplicated bash into a shared lib, e.g.
actions/claude.lib/turn.sh, sourced from each composite as. "${GITHUB_ACTION_PATH}/../claude.lib/turn.sh". This is version-safe because GitHub ships the whole repo at the action's pinned ref — the existing${GITHUB_ACTION_PATH}/../claude.agent.mdreference is the precedent — so the lib always matches the composite's ref, including on PR branches.Explicitly out of scope: abstracting the yaml (
with:blocks, step layout) — self-contained yaml is load-bearing readability when debugging a turn. Rejected alternatives, for the record: nested composite (uses: gingur/devkit/actions/claude.turn@mainresolves at run time → PR changes unexercised until merged); codegen/template rendering (machinery overkill for three files).Also include
review.ymlcaller (the runbook predatesclaude.review; infra and hooks already carry the caller — copy from there).boundSubjectmust berepo:gingur/<repo>:*(repo-scoped glob), notrepo:gingur/<repo>:ref:refs/heads/main—pull_request-triggered review jobs present subjectrepo:gingur/<repo>:pull_requestand 403 against the exact-ref binding (bit us: hooks#19 review turn, 2026-07-10; all three live identities already patched).review.ymlexisted on main will not firepull_request: assigneduntil the PR is refreshed (close/reopen) — GitHub caches the PR'''s workflow set.Sequencing
Blocked on #96 merging — it touches the same three composites. Plan now; implement only after #96 is in main (fresh turns branch from the post-merge main).
Acceptance criteria
$GITHUB_ENVcontent vs today's inline bash (assert by running both paths on a fixture).