> ## 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.

# DAEMON.md reference

> Exact DAEMON.md authored contract, validation rules, and support-tree semantics.

<Tip>
  **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.
</Tip>

<CodeGroup>
  ```markdown Learn about daemons theme={null}
  Explain what daemons are and how they work.
  ```

  ```markdown Daemon use cases theme={null}
  What are some use cases for daemons?
  Which would you recommend starting with?
  ```

  ```markdown Add a daemon theme={null}
  Open a PR to add a simple daemon to my repo.
  Explain what the daemon does and why you think it's a good place to start.
  ```
</CodeGroup>

***

This page defines the authored `DAEMON.md` contract.

A daemon is not a Unix daemon, cron job, GitHub Action, or generic background agent. In this system, `DAEMON.md` is the authored control surface for a repo-local Charlie role, while runtime metadata such as activation mode is derived rather than authored directly.

Use this page when you need the exact file format, field definitions, validation rules, and support-tree semantics.

For guidance on when to use a daemon, read [Choosing daemons](/daemons/choosing-daemons).

For guidance on how to write a good daemon, read [Writing and editing `DAEMON.md`](/daemons/writing-and-editing-daemon-md).

For concrete examples, start from the examples repo README/index.

## Directory structure

A daemon is a directory containing a `DAEMON.md` file.

```text theme={null}
.agents/daemons/<daemon-id>/
  DAEMON.md
  scripts/      # optional
  references/   # optional
```

## Full file format

`DAEMON.md` must contain:

1. `---`-delimited YAML frontmatter that parses to an object/map
2. a markdown body below the closing frontmatter delimiter

The authored file shape is:

```md theme={null}
---
id: <daemon-id>
purpose: <what this daemon achieves>
watch:
  - <event condition>
routines:
  - <operation>
deny:
  - <thing this daemon is told not to do>
schedule: "<cron expression>"
---
<Markdown content: decision policy, limits, communication behavior, verification, and other guidance>
```

The file is invalid if:

* the opening or closing `---` delimiter is missing
* the frontmatter is malformed YAML
* the frontmatter does not parse to an object/map

## Field-by-field reference

### Authored frontmatter fields

| Field      | Required | Type            | Meaning                                                               |
| ---------- | -------- | --------------- | --------------------------------------------------------------------- |
| `id`       | Yes      | string          | Canonical daemon identifier. Must exactly match the daemon path slug. |
| `purpose`  | Yes      | string          | One sentence describing the daemon’s intended outcome.                |
| `watch`    | No       | list of strings | Event conditions that wake the daemon. Natural language.              |
| `routines` | Yes      | list of strings | Operations the daemon performs when activated. Natural language.      |
| `deny`     | No       | list of strings | Behavioral prohibitions for the daemon. Natural language.             |
| `schedule` | No       | string          | Timer-based wake configuration. Standard five-field cron.             |

### `id`

`id` is the canonical daemon identifier.

Rules:

* required
* non-empty
* must exactly match the daemon directory name

### `purpose`

`purpose` is one sentence describing the daemon’s intended outcome.

Write intent, not mechanics.

### `watch`

`watch` is a list of natural-language event conditions that can wake the daemon.

Rules:

* optional
* if present, must be a YAML list of non-empty strings
* should describe discrete, observable events

Use provider-visible event language rather than raw webhook names. Keep provider-specific examples and routing requirements in [Writing and editing `DAEMON.md`](/daemons/writing-and-editing-daemon-md) and the relevant integration docs.

Use `schedule` for cron-based wakes. Do not put cron timing in `watch`.

### `routines`

`routines` is a list of natural-language operations the daemon performs when it wakes.

Rules:

* required
* must be a YAML list of non-empty strings
* must include at least one entry
* each entry should describe a concrete, finite operation

### `deny`

`deny` is a list of things the daemon is told not to do.

Rules:

* optional
* if present, must be a YAML list of non-empty strings

### `schedule`

`schedule` is timer-based wake configuration.

Rules:

* optional
* when present with meaningful text, must be a string
* blank or whitespace-only values are treated as `null`
* must be valid standard five-field cron
* evaluated in UTC

Supported cron semantics today:

* standard five-field cron only
* comma-separated lists
* ranges
* stepped ranges
* `7` in day-of-week is treated as `0` (Sunday)

Day matching follows normal cron-style rules:

* if both day-of-month and day-of-week are wildcard, any day matches
* if one is wildcard, the other controls
* if both are restricted, the scheduler matches `day-of-month OR day-of-week`

## Validation rules

These are the key authored validation rules.

* `id` is required.
* `id` must exactly match the daemon path slug.
* `purpose` is required.
* `routines` is required.
* `routines` must be a YAML list of strings and must contain at least one non-empty entry.
* `watch`, when present, must be a YAML list of non-empty strings.
* `deny`, when present, must be a YAML list of non-empty strings.
* `schedule`, when present with meaningful text, must be a string.
* Blank or whitespace-only `schedule` values are treated as `null`.
* At least one activation field must be present: `watch` or `schedule`.
* `schedule` must be a valid five-field cron expression.
* Activation mode is derived from `watch` and `schedule`; do not author it directly.

Runtime-derived activation labels are:

* **Watch-only**: `watch` present, `schedule` absent
* **Schedule-only**: `schedule` present, `watch` absent
* **Hybrid**: both present

## Validate with the CLI

Use the daemon CLI to validate runtime daemon files in a repository.

```bash theme={null}
bunx @charlie-labs/daemons validate .agents/daemons/pr-metadata/DAEMON.md
bunx @charlie-labs/daemons validate --all
bunx @charlie-labs/daemons validate --all --json
```

`validate <path>` checks one file. `validate --all` discovers `.agents/daemons/**/DAEMON.md` files from the current repository. Add `--json` when automation needs structured output.

Validation checks the runtime file contract: frontmatter syntax, allowed and required fields, activation fields, cron syntax, a non-empty markdown body, and path-aligned IDs.

## Field name disambiguation

Use the authored field names exactly as written in this page.

| Use this   | Do not use    |
| ---------- | ------------- |
| `id`       | `name`        |
| `purpose`  | `description` |
| `watch`    | `triggers`    |
| `routines` | `actions`     |
| `deny`     | `disallowed`  |

`name` is not a valid authored field. Use `id`.

Do not invent extra frontmatter fields.

Do not add runtime-derived labels such as activation mode to frontmatter.

## Body semantics

The markdown body below the frontmatter is freeform.

It is meaningful at runtime: the body is carried into execution and interpreted as part of the daemon’s operating brief.

Because the body is interpreted at runtime, do not use it for install-time setup, copy-time adaptation, or tutorial notes.

Use it for operational guidance such as:

* decision policy
* communication policy
* verification policy
* freshness policy
* concurrency policy
* output format
* limits
* priority
* thresholds
* conventions
* ignore patterns
* examples

There are no required body headings.

Headings such as `Decision policy`, `Limits`, `Communication policy`, and `Verification and freshness` are conventions, not schema.

## Support tree semantics

A daemon directory may include optional subdirectories alongside `DAEMON.md`:

```text theme={null}
.agents/daemons/<daemon-id>/
  DAEMON.md
  scripts/
  references/
```

Use:

* `scripts/` for executable helpers or deterministic utilities the daemon can call
* `references/` for policy docs, templates, style guides, or other context the daemon can read but should not modify

If a daemon relies on a helper script, document the required inputs, output shape, pagination or completeness expectations, and what the daemon should do when the script cannot return complete context safely.

## Authoring conventions that help avoid validation issues

Use these conventions consistently:

1. **Canonical field order.** When fields are present, use this order:
   Treat this order as a consistency/readability convention; parsers must not require it.
   * `id`
   * `purpose`
   * `watch`
   * `routines`
   * `deny`
   * `schedule`
2. **Path-aligned IDs.** Keep the directory name and the `id` value exactly aligned.
3. **Stable naming.** Use only the canonical authored field names: `id`, `purpose`, `watch`, `routines`, `deny`, and `schedule`.

## Examples

For concrete patterns, use the examples repo index: [Examples repo README](https://github.com/charlie-labs/daemons/blob/master/README.md).
