Skip to content

Observability options ​

One top-level block that answers "what happened": eventLog, the trail the daemon writes.

yaml
eventLog:
  enabled: true
  path: .the-loop/logs/events.jsonl

Who hears about it is a different question, answered on a different page — channels options. The CLI config used to carry an operator collaborators list and a daemon-side notifications.events filter beside the event log; both were removed in issue-304 because no code read either of them. See what replaced them.

Event log ​

Every routing, dispatch and session decision the CLI makes — by the receiver, the poller and the sessions command — is appended as one JSON object per line. It is the end-to-end observability trail, queried with the-loop events.

The file is plain JSONL, so grep, jq and tail -f work directly on it. Writes are append-only and multi-process safe, and a broken log never breaks ingress.

Record schema and agent guidance: observability reference. Why JSONL and not SQLite: decision-025.

eventLog.enabled ​

  • Type: boolean
  • Default: true

Emit the event log. false turns emission off entirely.

eventLog.path ​

  • Type: string
  • Default: <state.root>/logs/events.jsonl

Append-only JSONL file; git-ignored runtime state. Unset, it resolves under state.root — .the-loop/logs/events.jsonl with the default root.

Where the notifications went ​

Until issue-304 this page also documented two blocks that looked like notification config and were not:

RemovedWhat it claimedWhat actually happened
collaboratorsthe operator's own recipients, resolved by rolenothing read the list
notifications.eventsfour daemon events → roles (work-item-spawned, dispatch-failed, session-died, event-dropped-unauthorized)those event names are raised by no code; the filter was never consulted

An operator who filled them in configured nothing, and nothing said so. They are gone, and the-loop migrate-config strips them from an existing config and bumps its version — a config still carrying either is refused at load, naming the key and the fix, rather than loaded half-configured.

What to use instead:

  • To be notified: channels.slack. One bot for the whole daemon — botTokenEnv, a channel id, and an events allow-list you subscribe to the event names you care about. It carries replies back, too.
  • To say who may drive the daemon:routing.authorizedUsers (GitHub logins).
  • To say whose Slack reply is acted on:channels.slack.authorizedUsers (Slack member ids).

Those two lists are the only places human identity is declared. Per-person notification routing is not built: a notification goes to a channel, not to a person.

The harness config carries no notification routing either

harness-config.yaml used to carry its own notifications.events taxonomy — decision-pending, phase-approval-pending, and friends. issue-352 removed it: the process graph's notify hook publishes the graph's own events on the bus, and the channels options decide who hears them.

Next ​

Released under the MIT License.