Context: Studying Claude Code source code (backup branch)

Message Ordering When Hooks Fire on SkillTool

From toolExecution.ts, the resultingMessages array builds in this order for non-MCP tools (which SkillTool is):

1. PreToolUse hook messages           (line 815)   hook_success attachments
2. PreToolUse additionalContext       (line 846)   hook_additional_context, <system-reminder> wrapped
3. [SkillTool.call() executes]
4. tool_result                        (line 1478)  SkillTool output + contextModifier
5. PostToolUse hook results           (line 1515)  pushed immediately for non-MCP tools
   (includes PostToolUse additionalContext from toolHooks.ts:133-142)
6. PostToolUse timing summary         (line 1548)  ant-only, if slow
7. newMessages from SkillTool         (line 1566)  skill metadata, SKILL.md content, attachments, permissions
8. hook_stopped_continuation          (line 1572)  if PreToolUse set preventContinuation
9. MCP hookResults                    (line 1585)  only for MCP tools, empty here

Key insight: skill content (newMessages) always lands last for non-MCP tools. No hook event fires after it. This means skill instructions have the strongest positional influence (model weighs recency).

Options to Override Skill Content

  • Edit SKILL.md directly: put instructions at the tail (strongest position within the skill block)
  • CLAUDE.md: positionally first (weakest by recency) but architecturally privileged as system prompt
  • Wrapper skill: nest the target skill, append instructions after. Outer skill’s post-invocation text lands in a later newMessages batch
  • Hook the tools the skill calls (not Skill itself): PreToolUse on Bash/Edit/Read injects context at action time
  • PostToolUse on Skill: lands before skill body (positional disadvantage), but wrapping gives some weight for strong directives