Feature request: event-triggered skills (skill frontmatter `on:` triggers or hook action type `skill`)

Open 💬 0 comments Opened Jul 4, 2026 by AdrianNachev91

Problem

There is no deterministic way to run a skill in response to a harness event. Hooks can observe
events and inject context, but cannot invoke a skill. Skills can only be triggered by the model's
judgment or an explicit user /command.

The concrete need is housekeeping skills that ride on observable events. My example is a
stale-sweep skill that stages dead files for archiving. It should run whenever the agent re-reads
the project's anchor files (ROADMAP, plan, CLAUDE.md), which happens after /clear, on resuming
ongoing work, or after compaction. It should run at most once per session, and never in sessions
that don't touch the project. Today the only trigger is a standing CLAUDE.md rule asking the
model to remember to run it. That is a probabilistic trigger for what should be a deterministic
one.

What exists today (verified)

  • SessionStart hooks can return reloadSkills: true (v2.1.152) - makes skills available,

does not invoke them.

  • PostToolUse hookSpecificOutput.additionalContext does reach the model. I verified this

empirically on 2.1.178. A hook matched on Read injected a directive, and the model followed
it. So a soft workaround exists. A hook on anchor-file reads can inject "invoke skill X now",
with a hand-rolled session-id marker file for once-per-session.

  • But the workaround is still a suggestion the model may ignore. And every skill author must

reinvent the trigger matching and once-per-session bookkeeping per project. In short, the
signal delivery is already reliable, and the composable last mile is what's missing.

Proposal

Either or both of:

  1. Skill frontmatter event triggers (preferred - the trigger travels with the skill):

``yaml
---
name: stale-sweep
description: ...
on: PostToolUse(Read, glob: "**/ROADMAP.md") # or SessionStart(clear), etc.
once-per-session: true
---
``

The harness invokes the skill when the event fires, and once-per-session bookkeeping
becomes the harness's job instead of every author's marker-file hack. Triggers stay
composable and portable (plugins, repos).

  1. Hook action type skill: a hook can return { "type": "skill", "skill": "stale-sweep" }

instead of / in addition to injected context. Same shape #12892 proposed.

Why not a dedicated ContextRegain hook event instead? Context-regain is model intent, not an
observable harness event. What the harness can observe is the proxy - reads of per-project
anchor files. Event-triggered skills make that proxy composable and let each project pick its own
anchor files, instead of Anthropic hardcoding a heuristic.

The same shape covers dependency-freshness checks, todo/roadmap reconciliation, or license/secret
scans that should ride on project onboarding rather than on a timer or on every session start.

Relation to the existing hook contract

Today hooks can only tighten, never force. Deny rules beat hook approvals, and hook output can
inject context but cannot make the model do anything. Letting a trigger invoke a skill crosses
from observe-and-restrict into initiate. That line seems reasonable to move. A skill
invocation is still subject to normal permission gating once it runs, so the safety model holds.
I'm naming the crossing here so it's a deliberate design decision, not an accident.

Prior art

  • #12892 asked for exactly this (hook type: "skill"), created 2025-12-02, and was auto-closed

by the triage bot as a duplicate of #5442. #5442 is about auto-reading CLAUDE.md on session
start - a different request. The real ask never got a maintainer answer. Please treat this as
the follow-up to #12892, not as a duplicate of #5442.

  • #69750 (open): session lifecycle hooks with a proactive model turn (autoPrompt). Adjacent but

different. It would give hooks a forced model turn, which a skill invocation could ride on, but
it does not name skills.

How this was found

I hit this gap during normal Claude Code use (the stale-sweep skill above is real, and so is its
unreliable CLAUDE.md trigger). The workaround verification was done in-product, using Claude Code
to drive a headless Claude Code session with the test hook. Claude helped research and draft this
issue, and I reviewed everything before filing.

Environment

  • Claude Code 2.1.178, Windows 10, desktop app + CLI
  • Verification of the PostToolUse workaround: headless claude -p with a project-level

PostToolUse hook on Read. The injected context was delivered and acted on, and a marker file
confirmed hook execution.

View original on GitHub ↗