<< All versions

Skill v1.0.1

currentAutomated scan100/100
slaveoftime/open-relay/oly-daemon

+2 new

──Details
PublishedOctober 28, 2026 at 10:21 PM
Content Hashsha256:7eb1ac7d31a37c53...
Git SHA71faed3f57bf
Bump Typepatch
Compare with v1.0.0
──Files
Files (1 file, 9.8 KB)
SKILL.md9.8 KBactive
SKILL.md · 169 lines · 9.8 KB

name: oly-daemon description: Use when reading or updating oly daemon configuration, checking hot-reload behavior, or configuring prompt and session-resume hints. For running and supervising sessions, use the oly skill instead. metadata: version: "1.0.1"


Configure the oly daemon

Configuration lives at <STATE_DIR>/config.json. Read the existing file before editing and preserve unrelated fields and generated secrets.

  • Flat JSON only: Keys are top-level, not JSON-with-comments and not nested under limits, notify, or web_push.
  • Validation: Malformed JSON, out-of-range values, invalid regexes, or removed byte-cap keys fail startup and reject hot reload (preserving the last good config on reload). Unknown keys are ignored with a warning naming each key.

1) Locate state and precedence

Run oly daemon status to inspect ROOT (<STATE_DIR>), LOGS, SESSIONS, HTTP, Auth, and ID-PUB-KEY. The same command appends a read-only health summary: readiness, supervised component states, disk capacity, failure-record paths, and affected sessions. oly daemon status --node <NAME> relays that summary from a secondary's daemon, and --json prints it for tooling.

PlatformDefault state directory
Override$OLY_STATE_DIR (must be set before daemon launch)
Windows%LOCALAPPDATA%\oly
macOS~/Library/Application Support/oly
Linux$XDG_STATE_HOME/oly or ~/.local/state/oly

Linux default IPC names are scoped to the canonical state directory and WSL_DISTRO_NAME. OLY_SOCKET_NAME overrides routing; if set, use the same value for CLI and daemon, and unique values for independent environments. When upgrading from the old global Linux socket, finish work and stop the old daemon with the old binary before replacement. Do not stop a daemon whose ownership is unclear: WSL distributions can share abstract sockets even when its PID and state files are invisible locally. Other platforms retain their previous IPC defaults.

Startup precedence is CLI flag > `config.json` > built-in default (for web_push_proxy: CLI > `OLY_WEB_PUSH_PROXY` > file > default). CLI flags keep winning across hot reloads for the lifetime of the daemon process.

Startup flagConfig field
--bind <ADDR>http_bind (legacy alias: bind)
--port <PORT>http_port
--notification-hook <COMMAND>notification_hook
--web-push-proxy <URL>web_push_proxy

--no-http and --no-auth are startup-only flags, not JSON keys.

Persisted node resources

oly node manages remote peers through the running daemon, not config.json. SQLite nodes is the source of truth for inbound authorization and outbound pins, with one key per configured peer. Role describes the remote: primary requires URL and local claimed --as name; secondary authorizes inbound and rejects those fields. See oly skill for setup commands.

Use oly node ls/info NAME for runtime state, last_error, and next_retry_at; waiting is an enabled inbound authorization. Mutation success means persisted/applied, not connected. disable retains configuration and blocks reconnection across restart; enable persists; rm deletes config/auth and closes federation only, never the owning daemon's sessions. Offline mutations fail without direct database/file writes. Runtime status is not stored. Back up all stopped state, including the database and identity keys; there is no active joins.json. A restored enabled primary peer can reconnect even with --no-http, so isolate federation transport during restore drills. Never rotate keys or remove trust without operator authorization and independent key verification.

2) Config keys and hot-reload boundaries

The daemon polls config.json mtime every 2 seconds. Duration settings in seconds are clamped/validated within 1..=31536000 (365 days).

Flat JSON keyDefaultWhen it takes effect
http_bind127.0.0.1Restart required; must be an IP address
http_port15443Restart required; 1..=65535
notification_min_interval_seconds10Live (>= 1)
notification_hooknoneLive; null/empty disables hook
prompt_patternsDEFAULT_PROMPT_PATTERNSLive on monitor tick; [] disables regex matching only
resume_patterns[]Live for future completed-output scans
web_push_subjectnoneLive; rebuilds push channels
web_push_vapid_public_keygenerated on first loadLive; rebuilds push channels
web_push_vapid_private_keygenerated on first loadLive; secret
web_push_proxynoneLive (unless overridden by CLI/env)
log_levelinfoLive tracing-filter reload
trusted_apps_enabledfalseLive; enables trusted /apps/ and wwwroot overrides
max_running_sessions50Live at session start (0..=1000; 0 blocks new starts)
session_eviction_seconds15Live runtime-eviction delay after exit (>= 1)
screen_scrollback_rows5000New sessions only (0..=100000)
silence_seconds10Live silence fallback (>= 1)
stop_grace_seconds5Live HTTP stop default when grace is omitted (>= 1)
journal_retention_days0Hourly sweep of stopped/killed/failed sessions (0..=36500; 0 keeps all)
disk_guard_enabledfalseLive; opt-in admission guard refuses new starts when the state volume is below disk_min_free_bytes (never kills running sessions)
disk_min_free_bytes1073741824Live; guard floor; refused when the newest sample is unknown or older than disk_sample_max_age_seconds
disk_warn_free_bytes2147483648Live; always-on warning line; must be >= disk_min_free_bytes
disk_sample_interval_seconds30Live; bounded background sampling cadence (5..=86400)
disk_sample_max_age_seconds120Live; samples older than this refuse starts while the guard is enabled (5..=86400, >= disk_sample_interval_seconds)

Readiness checks task liveness and, when enabled, disk admission. Unknown/stale samples stay unknown in status; public /api/ready only reports component/admission states, not private failure text. diagnostic_errors means a status report is incomplete; an unknown affected-session total is not zero. The guard never reserves bytes: concurrent starts can pass one sample.

Removed keys (max_journal_bytes_per_session, max_output_log_bytes, max_journal_bytes_per_session_legacy) fail explicitly; remove them and use journal_retention_days or OS disk quotas.

Edit and verify

  1. Validate syntax before saving: jq . <STATE_DIR>/config.json >/dev/null.
  2. Inspect <STATE_DIR>/logs/daemon.log after ~2s for:
  • config.json reloaded changed=... (internal diff names: hook, min_interval_seconds, patterns, bind, port, subject, vapid_public_key, vapid_private_key, proxy)
  • config changes require a daemon restart to take effect changed=...
  • config reload failed; keeping current configuration
  1. Never restart a shared daemon without operator approval — oly daemon stop terminates all live sessions. If a sandbox reports Access is denied, retry with escalation rather than starting a second daemon.

3) Prompt hints: prompt_patterns

The monitor checks the last 15 rendered live-screen lines (ANSI stripped) once per second with 5s activity suppression and notification_min_interval_seconds debounce. Attaching/input/resizing suppress automatic alerts; pausing does not notify for input-driven echoes/redraws or a retained status report already seen/acted on. Candidates are rechecked for new user activity before delivery. New independent output or a newer status report can notify after suppression; an open attachment alone is not a permanent mute. OSC 7501 program_status reports take precedence over regex/silence heuristics (working suppresses attention; idle/done/blocked/error set input_needed immediately while running, independently of notification delivery).

  • Omitted `prompt_patterns`: uses DEFAULT_PROMPT_PATTERNS.
  • `"prompt_patterns": []`: disables regex matching, while silence-based attention hints/notifications remain.
  • Nonempty array: replaces the full list (copy defaults below and append to extend).

DEFAULT_PROMPT_PATTERNS

Matches src/config.rs (wrap in { ... } for a full JSON file):

json
"prompt_patterns": [
"[>❯›\\$#%]\\s*$",
"❯\\s+",
"^\\s*>\\s+\\S",
">>>\\s*$",
"(?i)[\\(\\[](y/n|yes/no)[\\)\\]]",
"(?i)(?:password|api[_ ]?key|token|secret)\\s*:",
"^\\?\\s",
"(?i)(?:do you|are you sure|allow\\b).{0,80}\\?",
"(?i)continue\\?\\s*$",
"(?i)press (?:enter|return|any key)"
]

Custom override example:

json
{
"notification_min_interval_seconds": 30,
"prompt_patterns": ["(?i)ok to proceed\\?\\s*$", "(?i)approve\\?"]
}

4) Resume hints: resume_patterns

Rules scan the rendered journal tail after child exit, PTY EOF, and journal durability. The latest match populates resume_command (oly info <ID> --json, oly ls --json) as an untrusted suggestion (never auto-executed). No rules are built in.

Each rule requires:

  • program: child executable basename (case-insensitive, without .exe/.cmd/.bat; shell wrappers like bash do not match the inner tool).
  • pattern: Rust regex with at least one capture group.
  • command: non-empty template using $1, $2, etc.
json
{
"resume_patterns": [
{
"program": "codex",
"pattern": "(?i)(?:^|[^a-z0-9_])codex(?:\\.exe)?[ \\t]+resume[ \\t]+([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:$|[^a-z0-9-])",
"command": "codex resume $1"
},
{
"program": "pi",
"pattern": "(?i)(?:^|[^a-z0-9_])pi(?:\\.exe)?[ \\t]+--session[ \\t]+(\"[a-z0-9_./:\\\\~ -]{1,1024}\"|'[a-z0-9_./:\\\\~ -]{1,1024}'|[a-z0-9_./:\\\\~-]{1,1024})",
"command": "pi --session $1"
}
]
}
← v1.0.0All versions