[FEATURE] semantic / self-monitoring triggers for skills (a "daemon" layer complementing event hooks)
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)
Problem Statement
Skills are invoked either manually (/skill-name) or, at the model's
discretion, when a request matches the skill's description. There is no way to
auto-activate a skill based on the assistant's own working state — e.g.
"debugging has degraded into wild guessing / three fix attempts have failed" or
"the context window is near its limit." These are exactly the moments the
highest-leverage skills are meant for, yet also the moments the assistant is
least able to prompt itself: a model stuck in a "fix tunnel" is the least likely
to notice it should step out of it. Event hooks don't help here — they fire on
mechanical events (PreToolUse, Stop, …), not on semantic, self-monitored states.
Proposed Solution
Add a lightweight daemon layer (borrowing the OS term): a persistent watcher
pairing a trigger (a condition on the assistant's own working state,
model-evaluated) with an action (invoke a skill). It complements event hooks
rather than replacing them — hooks fire on mechanical events; daemons fire on
semantic states only the model can assess. Sketch:
daemon: debug-watcher
trigger: debugging has turned into guessing, or ~3 fix attempts have failed
action: invoke skill bisect-debug
cooldown: <debounce so it doesn't re-fire every turn>
mode: auto | suggest # act directly, or prompt the user first
Alternative Solutions
- Description-based auto-invocation (today): best-effort and
model-discretion; unreliable for meta-states about the assistant's own
process, and weakest precisely in the failure state (fix tunnel) where it's
needed most.
- Event hooks (today): can't express semantic conditions like "guessing" or
"phase completed with window ~80% full."
- Structured built-in signals only (e.g.
context_fill > 0.85,
consecutive_failed_edits >= 3): reliable but can't cover fuzzy conditions
like "degraded into guessing." A mix of structured signals + natural-language
predicates is probably the sweet spot.
- Rely on the user to remember to invoke the skill: the status quo — fails
exactly because the right moment is a failure the user isn't watching for.
Priority
Low - Nice to have
Feature Category
Other
Use Case Example
A — Debug-watcher. Trigger: debugging degrades into guessing, or ~3
immediate fix attempts have failed. Action: activate bisect-debug (stop
fixing, start isolating). Notable: this trigger condition is already written
verbatim into that skill's description field ("roughly 3+ failed immediate fix
attempts, or whenever the next fix would be a guess") — the intent to auto-fire
already exists; only the mechanism is missing.
B — Context-window guard. Trigger: context window approaches a critical
limit, or a work phase just completed while the window is relatively full.
Action: inform the user and offer to run the session-reset sequence
(end_session → clear → start_session). Users already build the actions by
hand (custom "Memento handoff" skills that persist state across a reset); what's
missing is the trigger.
Additional Context
Design questions worth discussing:
- Trigger language: structured signals where they exist (context fill,
failed-edit count) + natural-language predicates otherwise (guessing).
- Evaluation cost: self-checking every turn costs tokens — likely a cheap
gating check plus debounce/cooldown.
- auto vs. suggest: some daemons should just act (
bisect-debug); others
must ask first (a session reset destroys context, so it must be user-confirmed).
- Loop safety: a daemon whose action re-satisfies its own trigger must not
thrash (cooldown / one-shot-per-episode).
- Scope: global vs. project-local, same as skills.
The condensed versions of the referred skills are:
---
name: start_session
description: >-
Invoke at the start of a working session to recover from context loss — the
wake-up counterpart to end_session. Reconstructs the current project state from
the repo alone (Planning/status.md, the recent git history, and the relevant
plan docs), surfaces any open decisions the user still owes, and hands back a
short orientation report ending in the single next action — without starting to
act on it.
---
# start_session: waking up with amnesia
Checklist: (1) read Planning/status.md — focus, progress, "Next step (resume
here)", open decisions, caveats; (2) check recent git history and reconcile a
dirty tree against status.md; (3) pull the relevant static plans from
Planning/contents.md, reading toward the next step only; (4) resolve uncertainty
— ask the user about genuinely ambiguous points before acting; (5) print an
orientation report and then stop, awaiting the user's go-ahead.
---
name: end_session
description: >-
Invoke at the end of a working session to prepare for context loss — the
"Memento" handoff. Ensures Planning/status.md reflects reality (especially the
"Next step (resume here)" pointer), durable findings are written into Planning,
and all changes are committed and pushed, so a fresh Claude starting from a
cold context can orient and resume immediately from the repo + memory alone.
---
# end_session: the Memento handoff
Checklist: (1) take stock — git status + full session diff, list background jobs
that won't survive; (2) update Planning/status.md, especially the "Next step
(resume here)" pointer; (3) push durable findings into Planning/ docs; (4) the
"Memento test" — could a fresh Claude resume from repo + memory alone?; (5)
commit and push; (6) print a short handoff report.
---
name: bisect-debug
description: >-
Use when a bug resists direct fixes — roughly 3+ failed immediate fix
attempts, or whenever the next fix would be a guess about an uncertain root
cause. Switches the goal from *repairing* the bug to *locating* it by
quasi-bisection: halve the hypothesis space with each experiment via subsystem
ablation, extreme-value probes, and oracle/sanity checks. Also invoke manually
with /bisect-debug when a debugging session is visibly flailing.
---
# Bisect-debug: stop fixing, start isolating
## When this applies
You have tried ~3 direct fixes and the bug is still there — or you are about to
make another change that is really a **guess** about a root cause you do not
actually understand. That is the trigger. The failure mode this counters is the
"fix tunnel": firing off plausible patches faster than you learn anything,
each one changing several things at once, none of them backed by evidence.
## The mindset shift
**Under uncertainty, the immediate goal is not to fix the bug — it is to learn
as much as possible about it.** A run that doesn't fix anything but rules out
half the hypotheses is a success.
(… full method: enumerate hypothesis space → design a cut that halves it →
predict both outcomes before running → change one variable → prefer decisive
instruments: subsystem ablation, extreme values, oracle/self-check, minimal
reproduction → read the invariants → iterate until the cause is forced. Guardrails
on confounds, flattering fixes, noisy init, and a written escalation list. Closes
with a worked PPO Tic-Tac-Toe example.)This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗