What happens
With engine: claude and an APM import (shared/apm.md, target: claude), the compiled agent job runs these steps in this order (gh-aw v0.88.7):
Restore APM packages — unpacks skills into <workspace>/.claude/skills/<dir>/
Checkout PR branch
Restore agent config folders from base branch — restore_base_github_folders.sh with GH_AW_AGENT_FOLDERS: ".agents .claude .github"
Step 3 either overwrites .claude from the base-branch snapshot or, when the base branch has no .claude/, runs rm -rf and logs Removed PR-injected .claude (not present in base branch). Either way the APM-installed skills are gone by the time the CLI spawns. The Claude init event then lists none of them, and Skill calls return Unknown skill.
Under engine: copilot the folder list is .agents .github, so the same import survives. That asymmetry hides the problem until a workflow is ported from copilot to claude.
Evidence
Agent job log from a private repo, excerpted. APM installs six skills, the PR checkout runs, then the restore overwrites the directory:
[*] Unpacked 6 file(s) (verified)
Restored 1 bundle(s) successfully into /home/runner/work/<repo>/<repo>
...
[command]/usr/bin/git checkout -B <pr-branch> origin/pr-head
...
No base branch snapshot for .agents, skipping
Restored .claude from base branch snapshot
The six directories APM created under .claude/skills/ were applies-to-tagging, check-contradictions, content-type-checker, docs-check-style, flag-jargon-skill, frontmatter-audit. The init event that followed listed only docs-check-style from that set — the one skill also tracked in the repo's own .claude/skills/, so it came back with the base snapshot. The other five were gone, and each Skill call for them returned Unknown skill: <name>.
The step order is visible in any compiled lock with a claude engine and an APM import, for example https://github.com/elastic/docs-actions/blob/891d5aa/.github/workflows/gh-aw-docs-review.lock.yml (Restore APM packages, then Checkout PR branch, then Restore agent config folders from base branch).
Related
#27566 and #28290 fixed this interaction for copilot's .github/skills. The claude .claude case isn't covered by that change.
Two smaller things on the same path
Skill is never in Claude's --allowed-tools. The defaults in claude_tools.go are Task, Glob, Grep, ExitPlanMode, TodoWrite, LS, Read, NotebookRead, so a skill installed by either mechanism can only be invoked under permission-mode: bypassPermissions — every call otherwise comes back as a permission_denied system event with tool_name: "Skill". Adding Skill to the defaults when skills: or an APM import is present would let workflows keep acceptEdits.
- Frontmatter
skills: restores at restore_inline_skills.sh, which runs after step 3, so it works today. Either documenting that as the supported path for claude, or moving the APM restore after step 3, would close this.
Workaround
Use frontmatter skills: instead of the APM import, set engine.permission-mode: bypassPermissions, and invoke each skill by its directory name (gh skill install keeps the source directory basename, and Claude Code registers project skills by directory name rather than frontmatter name). Verified on the same setup: six skills installed, registered in init, and invoked with results.
What happens
With
engine: claudeand an APM import (shared/apm.md,target: claude), the compiled agent job runs these steps in this order (gh-aw v0.88.7):Restore APM packages— unpacks skills into<workspace>/.claude/skills/<dir>/Checkout PR branchRestore agent config folders from base branch—restore_base_github_folders.shwithGH_AW_AGENT_FOLDERS: ".agents .claude .github"Step 3 either overwrites
.claudefrom the base-branch snapshot or, when the base branch has no.claude/, runsrm -rfand logsRemoved PR-injected .claude (not present in base branch). Either way the APM-installed skills are gone by the time the CLI spawns. The Claudeinitevent then lists none of them, andSkillcalls returnUnknown skill.Under
engine: copilotthe folder list is.agents .github, so the same import survives. That asymmetry hides the problem until a workflow is ported from copilot to claude.Evidence
Agent job log from a private repo, excerpted. APM installs six skills, the PR checkout runs, then the restore overwrites the directory:
The six directories APM created under
.claude/skills/wereapplies-to-tagging,check-contradictions,content-type-checker,docs-check-style,flag-jargon-skill,frontmatter-audit. Theinitevent that followed listed onlydocs-check-stylefrom that set — the one skill also tracked in the repo's own.claude/skills/, so it came back with the base snapshot. The other five were gone, and eachSkillcall for them returnedUnknown skill: <name>.The step order is visible in any compiled lock with a claude engine and an APM import, for example https://github.com/elastic/docs-actions/blob/891d5aa/.github/workflows/gh-aw-docs-review.lock.yml (
Restore APM packages, thenCheckout PR branch, thenRestore agent config folders from base branch).Related
#27566 and #28290 fixed this interaction for copilot's
.github/skills. The claude.claudecase isn't covered by that change.Two smaller things on the same path
Skillis never in Claude's--allowed-tools. The defaults inclaude_tools.goareTask, Glob, Grep, ExitPlanMode, TodoWrite, LS, Read, NotebookRead, so a skill installed by either mechanism can only be invoked underpermission-mode: bypassPermissions— every call otherwise comes back as apermission_deniedsystem event withtool_name: "Skill". AddingSkillto the defaults whenskills:or an APM import is present would let workflows keepacceptEdits.skills:restores atrestore_inline_skills.sh, which runs after step 3, so it works today. Either documenting that as the supported path for claude, or moving the APM restore after step 3, would close this.Workaround
Use frontmatter
skills:instead of the APM import, setengine.permission-mode: bypassPermissions, and invoke each skill by its directory name (gh skill installkeeps the source directory basename, and Claude Code registers project skills by directory name rather than frontmattername). Verified on the same setup: six skills installed, registered ininit, and invoked with results.