Skip to main content
Human readers: the fastest way to get started with daemons is to work directly with Charlie.Charlie can help you suggest where to start and add your first daemon. Use the prompts below to ask Charlie in Slack, GitHub, or Linear.
Explain what daemons are and how they work.

Use this page when a daemon file already exists and you need to roll it out safely, observe its behavior, and tighten or widen it over time.

Start with the rollout mindset

Early testing is not about proving the daemon can do everything. Early testing is about proving the daemon behaves correctly and quietly under narrow, intentional conditions. Use your team’s normal activation workflow for rollout. A daemon becomes eligible for live activations after both are true:
  • the updated DAEMON.md is merged to the repo’s default branch
  • Charlie has ingested that merged version
Once both are true, the daemon is live:
  • current watch conditions can begin matching
  • a current schedule can begin driving scheduled activations
  • the first question is not “can it do more?” but “can it behave correctly under narrow conditions?”
Start narrow. Prefer low-blast-radius outputs first. Widen only after repeated correct behavior. Use the daemon file itself to enforce narrowness. Do not rely on people remembering to be careful during rollout.

Keep the file model straight

The authored frontmatter fields are:
  • id
  • purpose
  • watch
  • routines
  • deny
  • schedule
schedule uses standard five-field cron syntax. The markdown body can include headings like Policy, Output format, Limits, Scope, Coordination, and Ignore patterns, but those headings are recommended conventions, not frontmatter schema. Activation-mode labels such as Watch-only, Schedule-only, and Hybrid are runtime-derived from watch and schedule. Authors do not write them as frontmatter fields.

What you can observe today

Today, there is no dedicated daemon activity or logs page in the Charlie dashboard. Observe daemon behavior on native surfaces:
  • GitHub
  • Slack
  • Linear
Because there is no dedicated activity page today, the main verification surface is the daemon’s visible work on those systems.

Containment levers

Use these authoring levers to reduce blast radius before rollout.

Narrow watch

Make watch conditions as specific as possible for early rollout. Examples of narrow testing patterns:
  • only react to PRs opened by the person creating and testing the daemon
  • only react to a labeled test PR
  • only react to a deliberately narrow category of change
  • only react to a surface where the tester can inspect every result closely

Narrow Scope

Limit where the daemon pays attention. Examples:
  • only a specific directory or file family
  • only PRs targeting one branch or branch pattern
  • only one issue label or PR label category
  • only a sandbox repo for the first rollout

Add Ignore patterns

Skip noise early. Examples:
  • ignore bot-authored activity
  • ignore generated files
  • ignore surfaces or categories that would create noisy false positives during testing

Add stronger deny

If the daemon could take risky actions, deny them during early rollout and widen later only if needed.

Add Limits

Constrain the daemon’s output volume. Examples:
  • at most N items per activation
  • no more than N visible actions per day
  • stop producing new work when too much prior daemon work is still waiting on humans

Add Coordination

Coordination rules are a containment lever, not just a cleanup detail. Examples:
  • do not comment where a human review is already in progress
  • do not duplicate work another daemon already started
  • use a label or ownership convention so other daemons can filter early-rollout work

Constrain output surfaces first

Prefer outputs that only the tester or a very small audience will see first. Examples:
  • send Slack DMs to the daemon author first
  • comment only on a labeled test PR
  • keep early outputs on one low-blast-radius surface

Constrain who or what the daemon touches first

Keep the first target set intentionally small. Examples:
  • only act on PRs opened by the daemon author
  • only act in a sandbox repo first
  • only act on a test branch pattern first
  • only act on one issue label or PR label first

Testing by activation type

Event wakes respond to a triggering signal. Scheduled wakes survey their scope and prioritize within it. Hybrid daemons need both postures, so test them separately at first.

Watch-driven daemons

Use watch-driven testing when the daemon should react to a discrete event. Current rollout facts that matter:
  • event-driven wakes are currently available for GitHub signals
  • watch conditions are interpreted semantically, so concrete observable phrasing is more reliable than vague wording
A good rollout pattern for a watch-driven daemon is:
  1. make watch narrow
  2. constrain Scope, Ignore patterns, and Coordination
  3. add strong deny and Limits
  4. create a small number of deliberate test events
  5. inspect visible output on GitHub, Slack, or Linear
  6. tighten or widen the file and repeat
If the daemon is noisy, first ask:
  • did it wake for the wrong event?
  • or did it wake correctly and act too broadly once awake?
Wrong wakes usually point to watch, Scope, or Ignore patterns. Wrong actions usually point to routines, deny, Limits, Coordination, or other body guidance.

Schedule-driven daemons

Use schedule-driven testing when the daemon should wake on time and survey what needs attention inside a defined scope. Current rollout facts that matter:
  • invalid cron strings are rejected when daemon config is refreshed
If a schedule update is invalid and a previous valid schedule already exists, Charlie keeps the previous valid schedule until the cron value is fixed.
  • schedule-based activations do not replay a full backlog of missed ticks
  • after downtime, the scheduler catches up at most one missed tick, then continues from current time
A good rollout pattern for a schedule-driven daemon is:
  1. start with conservative body guidance and low-blast-radius outputs
  2. add strong Limits
  3. make Scope intentionally narrow
  4. choose a schedule that lets the tester observe the first activations closely
  5. inspect the resulting visible actions
  6. widen gradually only after behavior is consistently correct
If the daemon is too noisy on schedule:
  • tighten Scope
  • add or strengthen Limits
  • narrow the routines to the minimum correct work
If the daemon is too passive on schedule:
  • inspect whether Scope is too narrow
  • inspect whether deny or Limits are over-constraining it
  • inspect whether routines describe the intended action clearly enough

Hybrid daemons

Use hybrid testing when the daemon needs both event-driven reaction and scheduled review. Do not test both wake paths broadly at once. Get one wake path behaving well first, then add the second. A good order is:
  1. test the lower-blast-radius path first
  2. keep the other path narrow or conservative
  3. observe several correct activations
  4. widen one dimension at a time

What actually wakes daemons today

Today:
  • event-driven wakes are currently GitHub-based
  • watch matching is semantic
  • schedule drives scheduled activations
  • activation mode is derived from watch and schedule, not authored as its own field
For safe rollout, the important distinction is whether the daemon woke because of a signal or because a schedule fired.

How to verify whether a daemon is working

Check the daemon against its own file. For each activation, ask:
  • Did it wake for the right reason?
  • Did it follow the daemon’s purpose?
  • Did it perform one or more of its routines?
  • Did it avoid anything in deny?
  • Did it follow the body guidance for Policy, Limits, Output format, Scope, Coordination, and Ignore patterns?
  • Did it produce work on the right native surface?
  • Did it do the minimum correct work for this activation?
Separate wake context from action scope. watch and schedule explain why the daemon woke now. They do not expand what the daemon is allowed to do. Permission still comes from the daemon’s purpose, routines, deny, and body guidance. Because there is no dedicated activity page today, verification usually means reading the daemon’s visible work on GitHub, Slack, and Linear.

A simple iteration loop

Use this loop:
  1. narrow the daemon file before rollout
  2. activate it through the team’s normal rollout workflow
  3. observe a small number of live activations
  4. inspect the visible outputs
  5. decide whether the problem is:
    • wrong wake
    • wrong action
    • missing Limit
    • missing Scope or Ignore patterns
    • missing Coordination rule
    • missing deny
  6. edit the daemon file
  7. merge or activate the tighter or wider version
  8. repeat
The main debugging surface is the daemon file itself. DAEMON.md is the daemon’s canonical operating brief and primary role policy. When the daemon behaves incorrectly, fix the authored policy and guidance rather than trying to prompt around the problem.

What to change first when something goes wrong

If the daemon wakes too often

Look first at:
  • watch
  • schedule
  • Scope
  • Ignore patterns

If the daemon wakes correctly but is too chatty

Look first at:
  • routines
  • Limits
  • Output format
  • Coordination

If the daemon takes actions it should not take

Look first at:
  • deny
  • Scope
  • Policy

If the daemon is too passive

Look first at:
  • whether Scope is too narrow
  • whether routines are too weak or vague
  • whether deny rules are over-constraining it

Widening scope safely

Widen one dimension at a time. Examples:
  • from “only PRs opened by the tester” to “one small team’s PRs”
  • from tester-only Slack DMs to a small shared channel
  • from one labeled test PR to one label category
  • from a sandbox repo to one low-risk production repo area
  • from one test branch pattern to one broader branch target
  • from a narrow directory to a broader repo area
  • from a small activation volume to a larger one
Do not widen scope, output audience, routine breadth, and schedule intensity all at once. There is no fixed required number of successful activations defined here. In practice, widen only after several quiet, correct, low-blast-radius activations. Signals that a daemon is still too broad or under-constrained include:
  • it comments where humans are already actively working
  • it repeats work another daemon already did
  • it produces more visible output than the team can review
  • it touches targets outside the intended early rollout set
  • it escalates too late, or not at all, on ambiguous cases

Dampening or stopping a noisy daemon

If a daemon is producing noise, merge a more restrictive daemon file quickly. Typical dampening moves:
  • tighten watch
  • narrow Scope
  • add Ignore patterns
  • add or strengthen deny
  • add or strengthen Limits
  • add stronger Coordination rules
  • escalate instead of acting directly
  • reduce visible output breadth
  • route early outputs back to low-blast-radius surfaces
For scheduled daemons, removing schedule is the normal way to stop future timed activations. In rare stale-state windows, that change may not take effect instantly, so confirm on native surfaces before assuming the schedule path is fully stopped.

Testing checklist

Before widening a daemon, confirm:
  • the daemon woke only in the situations you expected
  • the daemon’s visible outputs were easy to review
  • the daemon followed its own purpose and routines
  • the daemon respected deny and Limits
  • the daemon respected Scope, Coordination, and Ignore patterns
  • the daemon did not create more work than the team could absorb
  • the next widening step is small and deliberate
If any of those are not true, tighten the daemon and test again.