Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.charlielabs.ai/llms.txt

Use this file to discover all available pages before exploring further.

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 Charlie or another agent is creating a new daemon file or improving an existing one. Use DAEMON.md reference for the exact contract. Use this page to make the file good, not just valid.

The default stance

Write the narrowest daemon that can do the job. A good daemon file is:
  • narrow
  • explicit
  • concise
  • predictable
  • easy to review and iterate on
Start with:
  • one purpose
  • usually 2–3 routines
  • clear deny guidance
  • only the body sections that materially improve behavior
Do not write a broad, impressive-looking daemon that is hard to trust.

Frontmatter vs body

Use frontmatter for the concise declarative contract:
  • identity
  • purpose
  • wake conditions
  • core routines
  • hard prohibitions
  • schedule
Use the body for operating guidance that makes behavior more consistent:
  • decision policy
  • verification and freshness policy
  • output format
  • communication behavior
  • limits
  • target-selection details that cannot fit cleanly in frontmatter
  • priority
  • thresholds
  • conventions
  • coordination and concurrency behavior
  • ignore patterns
  • examples
Authors set watch and/or schedule. The runtime derives activation mode from those fields; do not add activationMode as a frontmatter field. A daemon must include at least one of watch or schedule. If something is a stable authored field, it belongs in frontmatter. If something is operating guidance or judgment-shaping prose, it belongs in the body. Do not duplicate purpose, watch, routines, or deny in body sections. If a body section only restates frontmatter, delete it or move the hard rule into frontmatter. Hard target boundaries usually belong in watch, routines, or deny. Use the body for nuanced target-selection policy, not for generic restatements of what the daemon is.

Create mode

When creating a new daemon:

1. Write the purpose as outcome, not mechanics

A strong purpose says what the daemon exists to achieve. Good:
  • “Keeps repository docs current and easy to discover.”
Weak:
  • “Scans for stale markdown files and suggests updates.”
The daemon’s purpose should make sense as the role’s job statement.

2. Choose the wake model

Use watch when the daemon should react to discrete events. Write watch with concrete event or signal language available when the daemon wakes. If the daemon needs a follow-up query or derived analysis to know whether action is needed, put that check in execution guidance instead of the wake condition. Use schedule when the daemon should wake on time and survey what needs attention. Use both only when the same daemon role genuinely needs both immediate reaction and periodic review. A daemon must include at least one of watch or schedule.

3. Write a small number of concrete routines

Routines should be concrete, finite operations. Good routines are things you can tell whether the daemon did or did not do. Good:
  • “propose clearer PR titles and summaries”
  • “identify missing test evidence in PR descriptions”
  • “suggest focused follow-up tasks when context is incomplete”
Weak:
  • “help with pull requests”
  • “improve code quality”
  • “manage the repo”
As a default, start with 2–3 routines.

4. Add deny rules for adjacent risks

The most important deny rules are not random safety slogans. They are the risky actions the daemon might reasonably attempt as a natural extension of its routines. Examples from the authoring guidance:
  • “Do not merge pull requests”
  • “Do not approve pull requests on behalf of humans”
  • “Do not push commits directly to protected branches”
  • “Do not delete files or directories”
If a daemon can plausibly take a risky shortcut, decide explicitly whether to deny it.

5. Add body guidance only where it improves behavior

The body is not decorative. Use it to make the daemon more predictable. A small daemon does not need every possible section. Add sections when they materially improve consistency, reduce noise, or make outputs easier to review. Good body guidance usually answers questions that frontmatter cannot answer on its own:
  • when to act and when to stop/no-op
  • what evidence is enough
  • what freshness checks are required before writes
  • what verification the daemon must run before consequential changes
  • when to comment, react, resolve, hide, edit, push, or stay silent
  • how to avoid duplicate work with humans or other daemon activations

Edit mode

Editing is not the same as creation. When editing an existing daemon:

1. Read before rewriting

Inspect the current daemon file first. Preserve:
  • the daemon’s identity
  • the intended role
  • any guidance that is already working
Do not rewrite a daemon from scratch unless the role itself is wrong or the file is too weak to repair incrementally.

2. Diagnose the failure mode

Before changing the file, decide whether the problem is:
  • the daemon wakes for the wrong things
  • the daemon wakes correctly but acts too broadly
  • the daemon lacks enough operating guidance
  • the daemon is missing limits
  • the daemon is over-constrained and too passive
Different problems require different edits.

3. Tighten vague or brittle watch conditions

Turn state-based or catch-all watch entries into specific, observable events. Prefer edits like:
  • “when a pull request is opened”
  • “when a maintainer comments “/daemon help” in a PR”
  • “when files matching docs/**/*.md are changed”
Over vague entries like:
  • “when the repo needs attention”
  • “when code changes”
Keep the daemon’s role the same. Make the wake logic more precise, not broader. Do not make watch depend on state that is not available in the event or signal that wakes the daemon. If the daemon needs a follow-up query or derived analysis to know whether action is needed, wake on the closest observable event and inspect that state during execution. Avoid overlapping watch entries that usually describe the same underlying trigger. One inclusive, concrete watch condition is usually easier to route and less likely to create duplicate activations than several broad entries.

4. Narrow or split broad routines

If one routine covers several jobs, split it. If a routine sounds like an abstract responsibility, rewrite it as a concrete operation. Prefer the smallest set of routines that still captures the daemon’s real job.

5. Add missing deny rules

Look for risky shortcuts the daemon might naturally attempt as the fastest way to satisfy its routines. Add deny rules for those nearby risks rather than generic safety slogans.

6. Reduce noise without changing the daemon’s identity

If the daemon is doing the right kind of work but too often, too broadly, or too noisily, do not change the purpose first. Instead, tighten the parts that bound behavior:
  • add Limits to control volume or pacing
  • add target boundaries or Ignore patterns to filter surfaces early
  • add Coordination to avoid overlap with humans or other daemon activations
This keeps the daemon’s role intact while making repeated activations more trustworthy.

7. Prefer targeted improvement over full rewrite

Prefer the smallest change that clearly improves behavior. Rewrite only when the file’s role definition is fundamentally wrong or the current file is too inconsistent to repair incrementally.

How to write strong frontmatter

id

id must exactly match the daemon ID and path slug. Good:
  • pr-check-repair
Bad:
  • PR Check Repair

purpose

Write the intended outcome, not the mechanics. Good:
  • “Keeps repository docs current and easy to discover.”
Bad:
  • “Scans for stale markdown files and suggests updates.”

watch

Each watch entry should describe a specific, observable event. Good:
  • “when a pull request is opened”
  • “when a maintainer comments “/daemon help” in a PR”
  • “when files matching docs/**/*.md are changed”
Weak:
  • “when code quality is low”
  • “when the repo needs attention”
  • “when code changes”
Use watch entries that describe something the system can observe as an event. Watch matching is semantic rather than deterministic rule matching, so concrete observable phrasing is more reliable than vague state-based phrasing. Be specific, but not brittle. Avoid both “wake on everything” and conditions that overfit to one temporary actor, exact phrase, or implementation detail unless that detail is part of the daemon’s durable activation contract. Do not write watch conditions that require data unavailable in the event or signal that wakes the daemon. For example, if a desired state can only be known by querying an API or analyzing repo state, use watch for the closest observable event and put the state check in routines, deny, or body policy. Avoid overlapping watch entries that usually describe the same underlying trigger. Prefer one inclusive observable event over several broad entries that may create duplicate activations. Current watch behavior is GitHub-first; Slack and Linear watch support is coming soon.

routines

Each routine should be a concrete, finite operation. Good:
  • “propose clearer PR titles and summaries”
  • “identify missing test evidence in PR descriptions”
  • “suggest focused follow-up tasks when context is incomplete”
Weak:
  • “help with pull requests”
  • “improve code quality”
  • “manage the repo”

deny

Write deny rules for the most important nearby risks. If a daemon might reasonably try a risky action because it seems like the fastest path to its goal, decide explicitly whether to deny that action. Deny rules are the right place for hard boundaries: targets the daemon must not touch, actions it must not take, and cases where it must stop/no-op. If author identity, target resource, issue ID, validity, ownership, permissions, or freshness cannot be established, prefer fail-closed behavior unless the daemon explicitly allows best-effort action.

Activation and execution safety

watch gets the daemon activated. It does not prove action is safe. Use routines, deny, and body policy to make the daemon re-check current truth before acting. For mutating daemons, state what must be re-fetched or re-validated immediately before writes, pushes, or external updates.

schedule

Use schedule for timer-based wakes. Schedules use standard five-field cron in UTC. This is for time-based survey or follow-up work, not for describing event conditions. The runtime may derive activation-mode labels from watch and schedule. Do not write activationMode as a frontmatter field. Examples:
  • 0 9 * * * — daily at 09:00 UTC
  • 0 */6 * * * — every 6 hours
  • 30 14 * * 1-5 — weekdays at 14:30 UTC

How to write strong body guidance

Use only the sections that materially improve behavior.

Decision policy

Use when the daemon needs decision rules, standards, or team opinions about what good looks like. Prefer compact “act when / stop when” rules, allow-lists, thresholds, and action matrices. Use examples to clarify judgment, not as a substitute for policy. Define ambiguous terms once. If the daemon depends on concepts like “valid,” “fixed,” “duplicate,” “straightforward,” “non-human,” or “blocked,” make those terms explicit.

Output format

Use when the daemon produces comments, reports, or other structured visible output and you want consistency.

Communication policy

Use when the daemon may communicate or mutate visible state. Define exactly when it should comment, react, resolve, hide, edit, push, or stay silent. Separate routine no-ops from comment-worthy cases. No-op silently for stale triggers, already-handled work, unsupported states, missing context, or ambiguity. Comment only when human input is specifically needed or visible action needs explanation.

Verification and freshness

Use when the daemon performs consequential writes or relies on mutable external state. State what the daemon must re-fetch or re-validate before acting. State what verification it must run, and what it should do if verification cannot run, fails, or fails for unrelated reasons.

Limits

Use when the daemon could otherwise create too much output or work. Limits can control:
  • batch size
  • rate
  • pacing relative to human capacity

Target selection

Use when the daemon needs nuanced filtering that cannot fit cleanly in watch, routines, or deny. Prefer domain-specific headings when they are clearer, such as Candidate discovery, Triage items, Issue inference, or Repair policy.

Priority

Use when several valid targets may compete for the daemon’s attention.

Thresholds

Use when numeric or qualitative cutoffs should affect detection or action.

Conventions

Use when the team has norms the daemon should follow.

Coordination

Use when the daemon might overlap with human work or other daemon activations. Define this daemon’s own boundary. Avoid naming sibling daemons unless another daemon is part of the activation contract or a true authority source.

Human authority

Use when human-authored input should govern the daemon’s behavior. Say when human input is a source of truth, and say when human-authored input should not be modified, adjudicated, or acted on automatically.

Ignore patterns

Use when specific files, directories, labels, authors, or event patterns should be skipped entirely.

Examples

Use when the daemon’s job includes subjective judgment and concrete examples will improve consistency. Examples are secondary to policy. Add them only when they clarify judgment that rules cannot capture.

What to include only when it matters

Not every daemon needs every body section. Add these only when they materially improve behavior:
  • Add Limits when the daemon could otherwise create more work or noise than the team can absorb.
  • Add Output format when the daemon produces comments, reports, or other recurring visible output and consistency matters.
  • Add Communication policy when the daemon may make visible comments or state changes.
  • Add Verification and freshness when the daemon writes, pushes, or updates external state.
  • Add Coordination when overlap with humans or other daemon activations is plausible.
  • Add Target selection or Ignore patterns when the daemon listens to a high-volume surface or only part of the repo or workflow is relevant.
  • Add Examples only when the daemon’s job depends on subjective judgment that policy alone does not capture.

Common mistakes

These are the most common daemon-file mistakes:

Vague watch conditions

A watch entry must describe an event, not a general state.

Brittle watch conditions

A watch entry should not depend on data unavailable in the event or signal that wakes the daemon. Use execution-time checks for state that requires a follow-up query or derived analysis.

Overlapping watch conditions

Multiple broad watch entries for the same underlying trigger can cause duplicate activations. Prefer one inclusive watch condition when event families overlap.

Unbounded routines

If you cannot tell whether the daemon completed the routine, the routine is too vague.

Missing deny rules

If a risky nearby action is plausible, decide explicitly whether to deny it.

Duplicating frontmatter in the body

Do not add body sections that only restate purpose, watch, routines, or deny.

Undefined decision terms

If a daemon relies on terms like “valid,” “fixed,” “duplicate,” or “straightforward,” define them once.

Missing freshness or verification policy

If a daemon writes, pushes, resolves, edits, or updates external state, say what current state it must re-check and what verification it must run before acting.

No limits where output can sprawl

A daemon without limits can produce more work or noise than the team can absorb.

Invented frontmatter fields

Do not invent fields. Use the authored fields from DAEMON.md reference.

Treating body headings like schema

Headings such as Decision policy, Limits, or Target selection belong in the markdown body, not as new frontmatter fields.

Generic filler in the body

If a section does not change what the daemon will actually do, tighten it or remove it.

Stale terminology after edits

After changing policy, search for old daemon names, old terms, duplicate constraints, and contradictory allow/deny language.

Final consistency scan

Before merging a daemon file, scan it once from top to bottom and check:
  • Frontmatter contains the durable contract, and the body does not repeat it.
  • watch describes observable wake events, not derived state that must be queried during execution.
  • Hard boundaries are in deny, watch, or routines; nuanced selection policy is in the body.
  • Decision terms are defined once and used consistently.
  • Mutating behavior has freshness and verification requirements.
  • Communication behavior says when to comment, react, resolve, hide, edit, push, or stay silent.
  • Stop/no-op behavior is explicit for ambiguous identity, target, ownership, permissions, freshness, or validity.
  • The file has no stale section names, duplicate constraints, or contradictory allow/deny language left over from earlier edits.

Critique rubric

Use this rubric when reviewing a draft daemon file.

Purpose

  • Is the purpose written as outcome, not mechanics?
  • Is the role narrow enough to explain in one sentence?

Wake logic

  • Are watch conditions actual events?
  • Are watch conditions specific without being brittle?
  • Do watch conditions avoid relying on unavailable derived state?
  • Do overlapping watch entries risk duplicate activations?
  • Does the schedule serve a real time-based need?
  • Is the daemon using both watch and schedule only when both are justified?
  • If the daemon is noisy, can the wake logic be made more specific without changing the role?

Routines

  • Are routines concrete and finite?
  • Would a human be able to tell whether the daemon did them?
  • Does each routine describe one kind of operation, or should any be split?

Constraints

  • Are the main adjacent risks denied?
  • Are limits present when the daemon could create noise?
  • Would target-selection policy, coordination, or ignore patterns make the daemon more predictable?
  • Does the daemon fail closed on important ambiguity?

Body guidance

  • Does the body add real behavioral guidance?
  • Are the sections specific, or are they generic filler?
  • Are ambiguous terms defined?
  • Are freshness, verification, communication, and concurrency rules present when the daemon needs them?
  • Does the file avoid coupling to named sibling daemons unless they are a true authority or activation source?

Overall

  • Is this the narrowest useful daemon?
  • If it is noisy, can you fix that with tighter watch logic, routines, or body guidance before changing the purpose?
  • Would you trust this file to be activated repeatedly?
  • Has the file been scanned for stale terms and duplicated or contradictory rules?
If the answer is “no” to any of those, edit the file before rollout.

How to use examples while writing or editing

Start with the nearest example daemon from the examples repo README. Use examples to copy:
  • structure
  • level of specificity
  • the kind of constraints that belong with a daemon role
Do not copy:
  • irrelevant routines
  • irrelevant deny rules
  • irrelevant scope or limits
  • team-specific conventions that do not apply here
A good example gives you the right shape. It does not remove the need to adapt the daemon to the repo’s real role.