Configuration reference
Current YAML layout, fields, constraints, defaults and activation rules.
Documentation for Nookins 0.42.1-alpha.1 · Public alpha
Bundle layout
config/
nookins.yaml
owners.yaml
channels.yaml
retention.yaml
agents.d/<agent_id>.yaml
addons.d/<instance_id>.yaml
automations.d/<automation_id>.yaml
mcp.d/<server_id>.yaml
hooks.d/<hook_id>.yamlThe four top-level files and at least one agent file are required. Other
resource directories may be absent when unused. A filename is the stable
resource ID. IDs use 1–64 ASCII letters, digits, _, or -, cannot begin with
_ or -, and are unique ignoring ASCII case where portability requires it.
config.d overlays are not supported. Nookins rejects unknown fields, duplicate
keys, anchors, aliases, merge keys, tags, multiple YAML documents, and
non-.yaml resource fragments.
Bootstrap writes all generated singleton defaults. The schema permits omission only where the typed default or empty named collection is defined; loading does not silently rewrite an operator's file. The explicit migration emits a complete canonical schema-19 bundle from supported schema-8 through schema-18 input. Runtime startup accepts schema 19 only; earlier schemas require the protected migration path.
Installation intent
nookins.yaml contains the schema, listening address, default reasoning policy, bounded supervision concurrency, speech
provider choices, intrinsic Sentinel posture, and governed skill-evolution
controls:
schema_version: 19
listen: 127.0.0.1:8790
supervision:
reasoning_workers: 2
concurrent_turns_per_worker: 4
concurrent_image_generations: 1
speech:
transcription: disabled # disabled | whisper | soniox
text_to_speech: local # disabled | local | soniox
soniox:
region: us # us | eu | jp
sentinel:
enabled: false
mode: summoned # summoned | aware | watch | participate
budget: standard # low | standard | high
retention: standard # short | standard | extended
skill_evolution:
enabled: true
# Collection remains active, but provider work is inert without this runtime.
curator_runtime: null
qualification_runtimes: []
budget:
per_agent_daily_runs: 1
global_daily_runs: 4
episode_sample: 8
max_episode_characters: 15000
max_turns: 12
daily_tokens: 200000The three supervision fields are local-operator-only and restart-applied.
reasoning_workers is 1–16, concurrent_turns_per_worker is 1–16, and
concurrent_image_generations is 1–8. Including dedicated per-agent workers,
configured reasoning capacity may not exceed 128 turns. One conversation lane
still serializes its own turns. These values bound parallel work; they do not
grant authority or make one conversation concurrent with itself.
Main listen: 127.0.0.1:8790 owns the bind address and port. It is editable in
Settings → Overview and requires a restart. An explicit 0.0.0.0:8790 binds all
IPv4 interfaces; [::]:8790 binds IPv6. A fixed nonzero port is required.
Authentication remains enforced on every interface. Local health checks and
transports connect to the corresponding loopback address for wildcard binds.
The OCI image retains its container-interface bridge for loopback-configured
listeners; an explicitly configured interface is honored.
An authored value wins. For existing files that omit listen, the established
--listen, then NOOKINS_LISTEN, then 127.0.0.1:8790 fallback remains available.
Exports materialize the effective address. A nondefault port requires the
corresponding --url for control-API CLI commands. When changing ports, use the
old running URL to apply the change and the new URL after restart.
The OpenRouter setup guide includes exact file locations,
provider selection, a complete free-router example, agent inheritance, activation
and troubleshooting. Main-file exports include every authored root section and
comments; reasoning.openrouter: null makes the disabled policy visible without
authorizing a provider. This additive surface remains schema 19 with database 26.
Owners and channels
owners.yaml is a direct owner-ID map:
owner:
display_name: Owner
identities:
personal:
- 15551234567@s.whatsapp.netWith one owner, Nookins infers the primary. With multiple owners, exactly one body
must contain primary: true. The primary designation selects legacy/default
delivery routes; it does not make that owner more powerful. Every configured
owner is an equal fleet custodian when invoking the primary agent through an
authenticated direct DM or an owner-bound local interactive session.
channels.yaml is a direct account-ID map:
personal:
channel: whatsapp
enabled: true
sender_roles:
"+15551234568": trusted
alerts:
channel: telegram
enabled: false
sender_roles: {}Telegram secret references are derived, never authored. Account alerts reads
NOOKINS_TELEGRAM_ALERTS_TOKEN; hyphens become underscores.
Ordered reasoning fallback
Schema 19 uses explicit provider and native model fields. Targets are unique
provider/model pairs, with one to five entries in effective attempt order.
codex and openrouter are the supported providers; default selects Codex's
native default. Omit an entry's reasoning_effort to use its provider default.
The retired schema-19 target string is accepted only by explicit migration.
Main nookins.yaml owns the default chain and provider ceiling. For example,
replace provider-slug with an authorized OpenRouter serving-provider slug:
reasoning:
model_chain:
- provider: codex
model: default
reasoning_effort: medium
- provider: openrouter
model: openrouter/free
openrouter:
allowed_providers: [provider-slug]
data_collection: deny
zero_data_retention: true
max_run_cost_usd: "0"
max_daily_cost_usd: "0"Use allowed_providers: ["*"] to explicitly permit automatic selection across
serving providers; the wildcard must appear alone. Privacy and spending ceilings
still apply. Named provider lists retain their existing restrictive behavior, and
an agent cannot replace a restricted main list with "*".
Omitting reasoning.openrouter disables OpenRouter. Its provider allowlist and
privacy rules are ceilings for every agent. The daily USD ceiling applies across
all agents on a UTC day and is enforced atomically with spend reservation. Zero
USD is valid: only requests quoted at zero cost are allowed. This does not grant
unlimited requests or waive provider rate limits. The host key is
NOOKINS_OPENROUTER_API_KEY in secrets.env; it is never agent YAML or model input.
An agent's omitted or empty model_chain inherits reasoning.model_chain. A
nonempty chain replaces the whole default; entries are never implicitly merged.
An agent may supply an openrouter policy with narrower allowed providers,
stricter privacy restrictions, or lower run/daily budgets. All fields of that
optional policy are supplied together. Omitting it inherits the main policy for
an OpenRouter chain. Agent daily limits coexist with the installation-wide cap.
A Codex-only effective chain cannot declare an agent OpenRouter override.
Only structured availability, quota, authentication, rate-limit or compatibility failures advance the chain. Refusal, invalid input, cancellation, exhausted Nookins budgets, unknown failures and any failure after tool dispatch stop execution. Reservations survive failure/uncertainty. OpenRouter completion is stateless; images and raw Codex response capture cannot move to OpenRouter in this version. Shared provider cooldowns survive runs. After repairing authentication or credit, explicit configuration activation resets provider health without erasing spending.
openrouter/free is an explicit supported router model, not a fixed endpoint.
Nookins checks fresh free-model metadata, retains the provider/privacy restrictions,
and sends zero maximum prices. Before returning content or tool calls it requires
a qualified returned model, authorized provider and confirmed zero usage cost.
Unverifiable or incompatible routing fails closed. Other OpenRouter router IDs
are not supported. Fixed-model requests retain endpoint-specific preflight and
provider pinning; provider fallback remains disabled.
/model shows the effective chain and its source. /model list lists visible
Codex choices and configured OpenRouter targets. /model codex MODEL_ID or
/model openrouter AUTHOR/MODEL selects the conversation's first choice for
subsequent turns and retains configured fallback entries without duplicates.
The existing bare Codex model command remains available. /model auto removes
the override and restores the configured chain, including inherited defaults.
Owner/trusted authorization is required; OpenRouter selections must already be
in the agent's effective configured chain. Commands cannot enable egress or raise
budgets. Changes never retarget a running turn.
Protected schema-19 migration splits target strings into provider/model fields, keeps explicit agent chains, and constructs a main policy covering the union of previous provider permissions. Each agent retains its old restrictions. The main daily ceiling is the sum of predecessor agent daily caps, preserving previous aggregate authority without silently introducing paid fallback. Protected source bundles retain exact predecessor bytes for rollback. Core migration 26 preserves older spending records and adds global caps and zero-cost reservations.
See setup and testing.
Agents
agents.d/main.yaml owns the agent’s complete intent, including routes and
outgoing links:
display_name: Nookin
instructions: >-
Serve with discretion, initiative, warmth, and exact respect for authority.
model_chain:
- provider: codex
model: default
reasoning_effort: medium
features:
administration: {}
schedules:
audience: owner_only
sentinel:
audience: owner_only
web:
access: restricted # disabled | public | restricted
domains: [docs.example.com]
workspace:
capabilities: [files, downloads, execution]
allowed_network_domains: [api.example.com]
interaction:
busy_input: append # append | queue
acknowledgement_reaction: true
background_result: brief # brief | digest | full | silent
routes:
owner_dm:
account: personal
conversation: "+15551234567"
activation:
mode: all_messages
access:
roles: [owner]
senders: []
family:
account: personal
conversation: family-group-id
activation:
mode: addressed
hotwords:
- literal: computer
- regex: '(?i)hey\s+nookin'
access:
roles: [owner, trusted, member]
senders: []
links:
research:
capabilities: [ask, history]
addons: [weather]With one agent, Nookins infers the primary. With multiple agents, exactly one
agent body must contain primary: true. Downloads and execution imply files.
A route activation section has a mode of commands, addressed, or
all_messages. addressed retains commands, native mentions, and replies,
always matches the bound agent's current display name, and may contain up to 16
reviewed literal or regex hotword matchers. Literal matching uses NFKC,
Unicode lowercase, collapsed whitespace, and Unicode-aware word boundaries.
Regex matchers use Rust regex syntax against the original text and are compiled
with bounded, non-backtracking automata before configuration can be staged.
Explicit matchers are limited to 2,048 bytes total; each literal is at most 64
characters and each regex at most 256. Voice notes follow the same activation
rules as text: an addressed route requires a native mention, a reply to Nookins,
or a command/hotword in the original caption. A bound unaddressed recording may
be transcribed for ambient context when transcription is enabled, but does not
start an agent turn. Transcript text is never searched for activation hotwords.
With transcription disabled, an unaddressed recording is retained without agent
work. Queued transcription retries recheck the original request against routing.
A non-empty allowed_network_domains list grants networked execution and
therefore requires execution. web.access: restricted requires at least one
domain; other access modes require an empty list.
Nookins-owned features are compiled into the product and configured directly on
the agent. addons contains only instance IDs for installed extension
packages; both package: ward and package: nookins are reserved and rejected for third-party add-ons.
The strict feature keys are:
| Feature | Configuration |
|---|---|
administration | Empty object; primary agent only and always custodian-only. |
browser | audience, plus optional paired isolation: nookins_managed_profile and exact profile. |
forge | audience. |
google_calendar | audience, state, connection_id, calendar_ids, access, and writes_require_approval. |
host | audience. |
house | audience. |
mcp | audience. |
media_recovery | audience. |
schedules | audience. |
sentinel | audience; the managed installation policy remains in top-level sentinel. |
social_media | audience, required anonymous-media acknowledgement, and optional paired authenticated-YouTube acknowledgement/profile. |
Every audience is owner_only by default or agent_callers. Use
nookins feature catalog and nookins feature inspect FEATURE for the compiled
catalog. The primary agent can propose durable typed changes with
Nookins.feature.propose; built-in features deliberately have no enable-once
lease.
Instructions remain in agent YAML. Existing persona.md, tools.md, and
heartbeat.md context files retain their separate roles.
Resource files
Each file contains one body; its ID comes from the filename.
addons.d/weather.yaml:
package: acme_weather
addon: weather
audience: owner_only
settings: {}automations.d/investigate_failure.yaml keeps the typed when, run,
optional delivery, and limits contract.
mcp.d/catalog.yaml keeps enabled, required, and an HTTP or stdio
transport. Nookins owns the MCP timeout:
enabled: true
required: false
transport: http
url: https://mcp.example.com
bearer_token_env: NOOKINS_CATALOG_TOKENhooks.d/audit.yaml keeps module identity and events. Nookins owns the fuel
budget:
enabled: true
module: audit.wasm
sha256: 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
events: [management.proposal.review_requested]Retention
retention.yaml is the complete human data-lifetime policy:
operational_history: 30d
audit: 90d
effect_payloads: 7d
social_media:
sources: 30d
derived: 90dDurations here are whole days from 1d through 3650d. Nookins derives internal
tombstone, count, and cleanup mechanics without broadening these lifetimes.
Harness defaults and explanation
Derived values are read-only. Inspect them through authenticated config status or the harness explanation namespace:
nookins config status
nookins config explain /harness/scheduler/tick
nookins config explain /harness/workspace/quotas/workspace_sizeChanging a harness default requires a new schema and migration decision; it is never smuggled into hidden legacy state.
Validate, migrate, export, and activate
nookins config validate
nookins config diff
nookins config apply --dry-run
nookins config apply
# Breaking schema-8 through schema-18 to schema-19 migration:
nookins config migrate
nookins service stop
nookins config migrate --write
nookins service start
# Restore the exact digest-fenced predecessor.
nookins service stop
nookins config migrate --restore <migration-id>
# Atomically materialize an exact schema-19 source bundle in a new directory.
nookins config export --view exact --directory ./nookins-config-exportMigration composes legacy overlays, writes canonical resource files, reports
every non-default tuning replaced by the current harness defaults, and blocks
ambiguous web policy, noncanonical Telegram secret references, and resource-ID
collisions. --write requires Nookins to be stopped and protects the exact
predecessor and forward bundles before activation.
Agent interaction policy
interaction.private_records_without_confirmation is an optional boolean,
false when omitted. It permits only the authenticated requester's creator-only
Records mutations described in operations.
interaction.quiet_hours is optional and contains an IANA timezone plus 1–32
windows. Each window has nonempty days (mon through sun), exact HH:MM
start and end, and allowed_roles drawn from owner, trusted, member.
An empty role list silences the agent in that window; blocked is invalid.
Distinct start/end times are required. Overnight windows use the starting day;
multiple active windows intersect roles. These restrictions never grant access.
features.google_calendar.personal_calendar_ids is an optional set, empty when
omitted. It must be a subset of the selected calendar_ids on a read-write
feature. writes_require_approval remains true for all actions outside that
standing scope. The connecting user must explicitly grant the conditional
calendar.acls.readonly OAuth scope before Nookins can verify personal-calendar
eligibility. Missing verification retains confirmation.
interaction.custom_roles is an optional agent-local map from arbitrary
role names to account maps of sender-identity sets. quiet_hours.windows.allowed_roles
accepts these names alongside the built-in roles. Custom roles grant reply-policy
membership only, never global tool authority. The settings catalogue exposes the
entire membership map atomically; unknown accounts/roles and built-in-name
collisions are invalid.
Role-aware interaction guidance
Each agent may configure interaction.role_prompts as an ordered list. It defaults
to empty and uses the existing owner, trusted, member, and blocked security
roles or names declared in that agent's interaction.custom_roles.
interaction:
custom_roles:
family:
personal: ["+15551234567"]
role_prompts:
- role: trusted
prompt: "Use concise answers and offer relevant available tools."
- role: family
prompt: "Use a warm, familiar tone."Role guidance supplements the base persona in groups and DMs. All matching entries apply in order; later entries override earlier conflicting style preferences. Entries are private system instructions configured through the existing owner configuration proposal workflow. They never grant permissions or bypass approval, route admission, quiet hours, or blocked status. Custom roles retain their existing agent/account-scoped identity matching and have no security authority.
Each prompt must contain non-whitespace text and be at most 4 KiB of UTF-8. The serialized list, including role labels, is bounded to 16 KiB. Unknown custom-role references are rejected. Removing a custom role requires removing its prompt references in the same validated configuration change. Existing configuration requires no migration.
Only the authenticated current caller selects guidance; other participants and quoted or forwarded messages do not. Background, scheduled and delegated work do not inherit these interactive prompts. Caller identity and selected guidance are part of the prompt fingerprint, so role changes and alternating group callers cannot reuse another caller's prompt configuration.