Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Filesystem

The filesystem channel watches one or more paths and feeds each change into the agent loop or the SOP engine. It is gated by the channel-filesystem build feature (default on).

This is a SOP event source. For trigger syntax and path matching, see SOP Fan-In: Filesystem. This page covers what is watched and the safety scoping.

Configuration

The full field list, derived from the live schema. For a basic watcher you set paths.

allow_broad_roots bool · default false

Watch broad system roots (/, /home, /etc, /var, /proc, /sys, /dev, /tmp) despite the deny-broad-roots default. On macOS this also covers /Users and each folder in it (its home directories and Shared), /Volumes and each mounted volume in it, /private, and /private/etc, /private/tmp, and /private/var. On Windows this also covers every drive, volume, and network share root, any device path that names something else, and, beneath a drive root, Windows, Windows\Temp, Users, each profile in Users, Program Files, Program Files (x86), and ProgramData. A path is refused when it names one of these as written, resolves to one on disk, or cannot be resolved. A home directory elsewhere, such as root’s /var/root on macOS, is not recognized. The pseudo-filesystems /proc and /sys would surface kernel object paths in SOP payloads and flood the watcher with events. Off unless explicitly enabled.

Set it on any surface:

Gateway dashboard

Open /config/channels/filesystem and set the channels.filesystem.<alias>.allow_broad_roots field.

zerocode

In the Config pane, set the channels.filesystem.<alias>.allow_broad_roots field.

zeroclaw config

zeroclaw config set channels.filesystem.<alias>.allow_broad_roots <value>

Environment variable

Export the override (POSIX shells; drop into ~/.bashrc, ~/.zshrc, .env, or a Dockerfile). Replace <alias> with the literal alias:

export ZEROCLAW_channels__filesystem__<alias>__allow_broad_roots=
debounce_ms integer · default 500

Collapse rapid repeated events per path/kind within this window.

Set it on any surface:

Gateway dashboard

Open /config/channels/filesystem and set the channels.filesystem.<alias>.debounce_ms field.

zerocode

In the Config pane, set the channels.filesystem.<alias>.debounce_ms field.

zeroclaw config

zeroclaw config set channels.filesystem.<alias>.debounce_ms <value>

Environment variable

Export the override (POSIX shells; drop into ~/.bashrc, ~/.zshrc, .env, or a Dockerfile). Replace <alias> with the literal alias:

export ZEROCLAW_channels__filesystem__<alias>__debounce_ms=
events string[] · default ["created","modified","deleted","renamed"]

Event kinds to emit (created, modified, deleted, renamed).

Set it on any surface:

Gateway dashboard

Open /config/channels/filesystem and set the channels.filesystem.<alias>.events field.

zerocode

In the Config pane, set the channels.filesystem.<alias>.events field.

zeroclaw config

zeroclaw config set channels.filesystem.<alias>.events <value>

Environment variable

Export the override (POSIX shells; drop into ~/.bashrc, ~/.zshrc, .env, or a Dockerfile). Replace <alias> with the literal alias:

export ZEROCLAW_channels__filesystem__<alias>__events=
exclude string[] · default []

Glob patterns to exclude. Applied after include.

Set it on any surface:

Gateway dashboard

Open /config/channels/filesystem and set the channels.filesystem.<alias>.exclude field.

zerocode

In the Config pane, set the channels.filesystem.<alias>.exclude field.

zeroclaw config

zeroclaw config set channels.filesystem.<alias>.exclude <value>

Environment variable

Export the override (POSIX shells; drop into ~/.bashrc, ~/.zshrc, .env, or a Dockerfile). Replace <alias> with the literal alias:

export ZEROCLAW_channels__filesystem__<alias>__exclude=
excluded_tools string[] · default []

Tools excluded from this channel’s tool spec.

Set it on any surface:

Gateway dashboard

Open /config/channels/filesystem and set the channels.filesystem.<alias>.excluded_tools field.

zerocode

In the Config pane, set the channels.filesystem.<alias>.excluded_tools field.

zeroclaw config

zeroclaw config set channels.filesystem.<alias>.excluded_tools <value>

Environment variable

Export the override (POSIX shells; drop into ~/.bashrc, ~/.zshrc, .env, or a Dockerfile). Replace <alias> with the literal alias:

export ZEROCLAW_channels__filesystem__<alias>__excluded_tools=
follow_symlinks bool · default false

Follow symlinks when reading event-path metadata, hash, and content. Off by default: a symlink under a watched root is rejected before any metadata/hash/content handling so its target cannot escape the root. When on, the canonical target must still resolve inside a configured root.

Set it on any surface:

Gateway dashboard

Open /config/channels/filesystem and set the channels.filesystem.<alias>.follow_symlinks field.

zerocode

In the Config pane, set the channels.filesystem.<alias>.follow_symlinks field.

zeroclaw config

zeroclaw config set channels.filesystem.<alias>.follow_symlinks <value>

Environment variable

Export the override (POSIX shells; drop into ~/.bashrc, ~/.zshrc, .env, or a Dockerfile). Replace <alias> with the literal alias:

export ZEROCLAW_channels__filesystem__<alias>__follow_symlinks=
include string[] · default []

Glob patterns to include. Empty matches all paths under the roots.

Set it on any surface:

Gateway dashboard

Open /config/channels/filesystem and set the channels.filesystem.<alias>.include field.

zerocode

In the Config pane, set the channels.filesystem.<alias>.include field.

zeroclaw config

zeroclaw config set channels.filesystem.<alias>.include <value>

Environment variable

Export the override (POSIX shells; drop into ~/.bashrc, ~/.zshrc, .env, or a Dockerfile). Replace <alias> with the literal alias:

export ZEROCLAW_channels__filesystem__<alias>__include=
max_content_bytes integer? · default 65536

Maximum file content bytes admitted into a payload when read_content, and the size ceiling for hashing. Some(n) caps reads and hashing at n bytes; oversize files are skipped rather than truncated. None removes the ceiling entirely (unbounded reads). Defaults to Some(65536) (64 KiB), so the cap applies by default whenever read_content or hashing runs.

Set it on any surface:

Gateway dashboard

Open /config/channels/filesystem and set the channels.filesystem.<alias>.max_content_bytes field.

zerocode

In the Config pane, set the channels.filesystem.<alias>.max_content_bytes field.

zeroclaw config

zeroclaw config set channels.filesystem.<alias>.max_content_bytes <value>

Environment variable

Export the override (POSIX shells; drop into ~/.bashrc, ~/.zshrc, .env, or a Dockerfile). Replace <alias> with the literal alias:

export ZEROCLAW_channels__filesystem__<alias>__max_content_bytes=
paths string[] · default []

Root paths to watch. At least one is required.

Set it on any surface:

Gateway dashboard

Open /config/channels/filesystem and set the channels.filesystem.<alias>.paths field.

zerocode

In the Config pane, set the channels.filesystem.<alias>.paths field.

zeroclaw config

zeroclaw config set channels.filesystem.<alias>.paths <value>

Environment variable

Export the override (POSIX shells; drop into ~/.bashrc, ~/.zshrc, .env, or a Dockerfile). Replace <alias> with the literal alias:

export ZEROCLAW_channels__filesystem__<alias>__paths=
read_content bool · default false

Read file content into the event payload. Opt-in.

Set it on any surface:

Gateway dashboard

Open /config/channels/filesystem and set the channels.filesystem.<alias>.read_content field.

zerocode

In the Config pane, set the channels.filesystem.<alias>.read_content field.

zeroclaw config

zeroclaw config set channels.filesystem.<alias>.read_content <value>

Environment variable

Export the override (POSIX shells; drop into ~/.bashrc, ~/.zshrc, .env, or a Dockerfile). Replace <alias> with the literal alias:

export ZEROCLAW_channels__filesystem__<alias>__read_content=
recursive bool · default true

Watch nested paths beneath each root.

Set it on any surface:

Gateway dashboard

Open /config/channels/filesystem and set the channels.filesystem.<alias>.recursive field.

zerocode

In the Config pane, set the channels.filesystem.<alias>.recursive field.

zeroclaw config

zeroclaw config set channels.filesystem.<alias>.recursive <value>

Environment variable

Export the override (POSIX shells; drop into ~/.bashrc, ~/.zshrc, .env, or a Dockerfile). Replace <alias> with the literal alias:

export ZEROCLAW_channels__filesystem__<alias>__recursive=
settle_ms integer · default 250

Wait this long after the last event before reading metadata or content, giving atomic writes and slow copies time to finish.

Set it on any surface:

Gateway dashboard

Open /config/channels/filesystem and set the channels.filesystem.<alias>.settle_ms field.

zerocode

In the Config pane, set the channels.filesystem.<alias>.settle_ms field.

zeroclaw config

zeroclaw config set channels.filesystem.<alias>.settle_ms <value>

Environment variable

Export the override (POSIX shells; drop into ~/.bashrc, ~/.zshrc, .env, or a Dockerfile). Replace <alias> with the literal alias:

export ZEROCLAW_channels__filesystem__<alias>__settle_ms=

Full field reference: config reference.

Scoping what is watched

paths lists the roots to watch; recursive controls whether subdirectories are included. include and exclude globs narrow which paths emit events, and events narrows by change kind. debounce_ms and settle_ms collapse bursts of rapid changes into a single settled event.

Safety

When the listener starts, it refuses to watch the broad system roots /, /home, /etc, /var, /proc, /sys, /dev, and /tmp unless allow_broad_roots is set. On macOS it also refuses:

  • /Users and each folder in it: its home directories (/Users/<name>) and /Users/Shared
  • /Volumes and each mounted volume in it (/Volumes/<name>), including the startup disk’s entry, which links to /
  • /private, and /private/etc, /private/tmp, and /private/var, the directories that /etc, /tmp, and /var link to

On macOS, paths match case-insensitively, as a default macOS volume resolves them, and repeated or trailing / are ignored, so /TMP and //Users are refused as well.

On Windows it also refuses:

  • every drive root (C:\), volume root, and network share root (\\server\share)
  • beneath a drive root: Windows, Windows\Temp, Users, each user profile in Users (C:\Users\<name>), Program Files, Program Files (x86), and ProgramData
  • any device path that names something other than a drive, volume, or share, such as \\?\GLOBALROOT\Device\HarddiskVolume1\, because it can open a whole volume

The listener checks each path twice: as written, and as it resolves on disk, which follows .. segments, symlinks, junctions, substituted drives, and short names such as C:\PROGRA~1. It refuses the path when either form is a broad root, refuses a path it cannot resolve, such as one that does not exist, and keeps watching the path as written.

Written Windows paths match case-insensitively with either separator, ignoring repeated and trailing separators. Outside \\?\ paths, . and .. segments and trailing dots and spaces resolve as Windows resolves them. The \\?\ and \\.\ device spellings (\\?\C:\, \\?\UNC\server\share) match the drive or share they name. A drive-relative spelling such as C: or C:Windows is read from the drive’s root, because the check cannot know that drive’s current folder.

The check never reads $HOME, so its result does not depend on the account the daemon runs as. macOS and Windows instead reject home directories in their standard location (/Users/<name>, C:\Users\<name>). A home directory elsewhere, such as root’s /var/root on macOS, is not recognized. Linux and other Unix systems accept a home directory such as /home/<name>. On every platform, point paths at the folder your SOPs need rather than a whole home directory.

Symlink event paths are rejected before any metadata, hash, or content read by default; follow_symlinks opts in but still requires the canonical target to resolve inside a watched root.

Troubleshooting

SymptomLikely causeFix
Listener does not starta path names or resolves to a broad root, or cannot be resolved because it does not existPoint paths at an existing folder below the broad roots, or set allow_broad_roots to watch a broad root
Change ignoredexcluded by glob, or outside events kindsCheck include, exclude, and events against the changed file
SOP not startingtrigger path glob does not matchVerify the trigger path matches and the file is in watch scope

See also