Configuration
nah keeps global guard state, trust, activations, records, caches, and user
guard proposals under ~/.nah/. Commands own its protected state; the
~/.nah/guards/ subtree is an inert proposal area agents may edit.
Run nah tui in an interactive terminal for the same protected configuration
surface. It has these screens:
- Guards starts in Type view, which groups built-ins by semantic family and
custom guards by name. Press
fto cycle through Type, applied State, and current Project views. Changes remain staged across views until Enter. Custom activation shows a bounded preview of covered files and pins the displayed path, scope, and full bundle hash; changed bytes are refused until reviewed again. - Projects trusts the current directory or revokes a selected trusted root.
- Runtimes installs, refreshes, or removes nah-owned integration wiring.
- Log keeps separate 200-row views for decisions and blocks. Rows name the
runtime; runtime, verdict, and
/text filters compose. Details summarize retained failures.
The TUI links to each runtime's runtime-* topic. nah tui is protected from
invocation through agent tool calls.
Built-in guards
Factory defaults follow proven risk; context-dependent protections require
opt-in.
nah guards shows live state and nah docs guards adds defaults and examples:
nah guards
nah docs guards
A human can change one built-in or custom guard:
nah guard disable git-hard-reset
nah guard enable corp-api --user
Disabling removes only that rule; another guard may still block, and otherwise
the call delegates. Structural self-protection has no persistent switch. Scope
same-named custom guards with --user or --project <root>; built-ins are
global.
New default-on secrets-store-destroy is independent of optional
secrets-store-delete: existing delete overrides do not disable permanent
destruction protection after upgrading. Change or reset each by its own name.
Global choices live in ~/.nah/built-ins.json. V2 stores sorted explicit
overrides; missing names use factory defaults. Nah reads v1 without rewriting
and writes v2 on the next guard change. Registered old names work in saved
v1/v2 state and guard enable, disable, or reset; Nah warns, preserves the
choice under its current name, and rewrites only current names on the next
change. Unknown saved names warn and are dropped alone. Malformed or conflicting
state still fails. TUI D restores built-in defaults and disables custom guards.
Configuration can only add or remove blocks; it cannot authorize a tool call.
Tighten a project before trust
A repository may add .nah/project.toml:
enable-guards = ["secrets-env", "git-hard-reset"]
This file can only enable named built-in guards. It cannot disable guards or define executable code. Unknown names warn on every affected decision. A malformed or unreadable file adds no project guards; the globally enabled guards still run. An explicit global operator disable wins over a project enablement. A default-off guard with no explicit global override may still be enabled by the project.
Trust project guards
Project guards under .nah/guards/ remain inert until a human runs the
matching command:
nah trust /absolute/project/root
nah guard enable <name> --project /absolute/project/root
The home directory itself cannot be a project root because its
~/.nah/guards/ path belongs to user guards.
Trust must be an out-of-band human action. nah blocks visible agent attempts
to invoke nah trust, nah untrust, or mutate the trust database through
guarded tools. Revoke a root and all enabled project guards tied to it with:
nah untrust /absolute/project/root
Activation pins the manifest, executable, and declared data. Changed bytes
require re-enabling. An unreadable activation database, or an activated bundle
that is missing, changed, untrusted, or cannot be cataloged, adds an evaluation
failure. The decision still completes and delegates unless another guard or
self-protection blocks. Malformed inactive proposals only warn. nah nap --all
skips custom guards with the rest of non-permanent enforcement.
User guards live under ~/.nah/guards/<name> and do not require project
trust, but they still require activation. See nah docs extending. Use
nah guards to inspect discovered and activated custom guard state without
changing it.
Temporary operator maintenance
Run nah nap in a separate interactive terminal when you intentionally want
an agent to change protected nah configuration. It pauses self-protection
globally for 10 minutes while guards remain active. Use
nah nap --all only when every non-permanent intercepted call should delegate
to the runtime, and use nah wake to resume immediately.
The window applies to every project and concurrent session using the same
~/.nah/. Persistent changes are not rolled back at expiry. Invalid or
tampered nap state fails awake; see nah docs security for the protection
boundary.
While a nap is active, nah tui banners every screen with which enforcement is
paused and how long is left, and w there confirms the same wake. The TUI
cannot start or extend a nap.
Runtime configuration
nah hook <runtime> install changes only nah-owned integration entries and
preserves unrelated runtime configuration. Each runtime has loading, trust,
and coverage limitations that nah cannot repair. Read nah docs runtimes and
the selected runtime-* topic before relying on the hook.
--fail-closed blocks explicit failures/refusals; --fail-open restores the
default. Flagless reinstall preserves a recognized mode, otherwise delegate is
used. In the TUI runtime screen, f switches the selected integration's mode;
i installs or refreshes it without changing a recognized mode.
While a hook is active, nah blocks visible install/uninstall commands,
mutations to its active wiring and standard enablement files, native removal
commands naming nah, and recognized child launches that skip the hook or
select alternate configuration. It tells the agent not to retry. Users still
own runtime hardening outside intercepted calls. Operators can run protected
commands directly there, or use nah nap when a tool must make the change.
Inspect managed files without changing them:
nah hook <runtime> status
Status reports wiring current, not configured, or reinstall required,
the detected failure policy, then the relevant install or documentation
command. Current wiring does
not prove that the runtime loaded or trusted it.