# n_OS_tr Agent Guide: Handling n_signer v0.0.16 Changes

This is a short operational guide for the n_OS_tr agent after the approval-model update in `n_signer`.

## What changed

- `n_signer` is now **deny-by-default**.
- First-time caller/index combinations require approval unless preapproved.
- `nostr_index` values can be auto-derived on approval.
- Policy decisions are visible in activity labels: `:preapprove`, `:session-grant`, `:prompt`, `:no-match`.

## What the agent should do

1. **Always send explicit selector options** in the last `params` item:
   - Prefer `{"nostr_index": N}` for service identities.
2. **Expect `policy_denied` on first contact** if caller/index is not preapproved.
3. **Do not retry blindly** on `policy_denied`.
   - Surface a clear status: "approval needed".
4. **Treat `unknown_role` as actionable**:
   - If using `nostr_index`, request again only after human approval or valid preapprove config.
5. **Use stable caller identity** (service name / VM identity) so preapprove rules match reliably.

## Required startup pattern for n_OS_tr services

Launch `n_signer` with explicit `--preapprove` entries for each boot service that must sign without prompts.

Example:

```ini
ExecStart=/usr/bin/n_signer \
  --preapprove caller=qubes:nostr-relay,role=main \
  --preapprove caller=qubes:dm-handler,nostr_index=1 \
  --preapprove caller=qubes:contacts,nostr_index=2 \
  --preapprove caller=qubes:zaps,nostr_index=3
```

## Agent error-handling policy (recommended)

- `policy_denied` → stop, mark as "awaiting approval/preapprove".
- `unknown_role` with `nostr_index` → stop, mark as "identity not yet approved/created".
- `purpose_mismatch` / `curve_mismatch` → configuration bug; fail hard and alert.
- `ambiguous_role_selector` → client bug; send exactly one selector field.

## Observability checks

When troubleshooting, inspect n_signer activity lines:

- `ALLOWED:preapprove` → expected for boot services.
- `ALLOWED:session-grant` → interactive approval happened earlier this session.
- `ALLOWED:prompt` → just approved now.
- `DENIED:no-match` → no policy entry matched caller/index.

## Operational rule of thumb

For n_OS_tr system services, rely on `--preapprove` at startup.
For ad-hoc/manual clients, rely on interactive prompt approvals.