> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stateset.com/llms.txt
> Use this file to discover all available pages before exploring further.

# NSR Skill

> Skill file for agents using StateSet NSR — verified decisions with cited proofs, teaching rules, verifying proofs, and reporting outcomes.

Use this when a task needs a decision you can **defend** — refunds, eligibility, policy compliance,
safety approvals — or a machine-checkable proof rather than a guess. It drives the NSR reasoning
API at `api.nsr.stateset.com` directly over HTTP or through the `stateset-nsr-mcp` MCP server.

NSR returns one of exactly three accountable outcomes — `approved`, `denied`, or `refused` — with
cited rules, a replayable derivation, and a sha256 policy pin. There is no path from an ungrounded
model answer to a confident approval.

## Connect

Base URL: `https://api.nsr.stateset.com`. On every call send `X-API-Key: nsr_…` and
`X-Org-ID: <your org>` (a `Authorization: Bearer nsr_…` header is accepted in place of the API-key
header). Get a key in the console: `nsr.stateset.com` → API setup → Organization API keys; the
secret is shown once.

Prefer MCP if your harness speaks it — 36 typed tools, retry-safe, with client-side validation:

```bash theme={null}
claude mcp add nsr \
  --env NSR_API_URL=https://api.nsr.stateset.com \
  --env NSR_API_KEY=nsr_your_key \
  -- npx -y stateset-nsr-mcp
```

`nsr_decide` is the flagship tool; `nsr_verify_proof`, `nsr_record_outcome` and `nsr_calibration`
close the proof and outcome loops.

## Make a verified decision

`POST /v1/decisions`

```json theme={null}
{
  "query": "Can order_9412 be refunded?",
  "action": "issue_refund",
  "mode": "safe",
  "facts": [
    { "predicate": { "name": "return_received", "args": ["order_9412"] } }
  ],
  "rules": [
    {
      "name": "refund_ok",
      "if": [{ "name": "return_received", "args": ["?o"] }],
      "then": [{ "name": "may_refund", "args": ["?o"] }],
      "effect": "permit"
    }
  ],
  "authorization_goal": { "name": "may_refund", "args": ["order_9412"] },
  "external_ref": "order_9412",
  "hydrate_org_context": false
}
```

Read from the response:

* `decision` — `approved` | `denied` | `refused`. Treat `refused` as "stop and verify", never as a
  soft yes.
* `proof.cited_rules`, `proof.derivation` — the rules and replayed steps the verdict stands on.
  `proof.request_policy_hash` pins the exact policy inputs.
* `refusal.missing_facts` — unsatisfied premises `[{predicate, args, needed_by_rule}]`. Look each
  one up with **your** tools, assert it, and retry. Absent on safety-gated refusals; those need a
  human, not a retry.
* `verifiable_bundle` — present only on approvals that declared an `authorization_goal`; see below.

## Verify the proof independently

An approval's `verifiable_bundle` (`{facts, rules, proof, org_id}`) is self-contained. POST it
verbatim to `POST /v1/proofs/verify` — a stateless kernel that reads no tenant state — and require
`{"verified": true}` before acting on a high-stakes approval. A failure returns the located reason
and step.

## Report what actually happened

Send `external_ref` (your order or ticket id) on the decide, then close the loop:

```
POST /v1/decisions/outcome-by-ref
{"external_ref": "order_9412", "outcome": "honored"}
```

Outcomes: `honored` | `reversed` | `overridden` | `escalated`. This feeds
`GET /v1/decisions/calibration` — ECE and reliability bins — which tells you whether NSR's stated
confidence can be trusted at each level.

## Teach durable policy

* `POST /api/v1/rules` — store an org rule. Shape: `head_predicate`, `head_args`,
  `body: [{predicate, args, negated?}]`. Intent comes from head naming (`may_*` permits,
  `*_blocked` denies, `*_requires_review`) or an explicit `effect`.
* `POST /api/v1/rules/lint` before install; `POST /api/v1/rules/batch` to load a book. Decide with
  `hydrate_org_context: true` to use stored policy.
* `POST /api/v1/facts` and entities for org knowledge; `POST /api/v1/backward-chain` proves against
  the stored org KB only.

## Two encodings that trip agents up

1. Facts are an **envelope**: `{"predicate": {"name": "…", "args": […]}}` — not a flat atom.
2. Request-scoped rules use `if` / `then` atoms keyed by `name`; **stored** rules use
   `head_predicate` / `head_args` / `body` atoms keyed by `predicate`. The error messages do not
   always say which one was expected.

## Guardrail

Before any consequential action — refund, access grant, data change — decide first, act only on
`approved`, and log `decision_id` and `proof.request_policy_hash` with the action. On `refused`,
gather the named missing facts and retry. On `requires_human_review`, escalate.

## Further reading

* [Verified Decisions API](/stateset-nsr-decisions) — the contract in depth
* [NSR API reference](/api-reference/nsr/overview) — all 259 endpoints
* [NSR MCP server](/stateset-nsr-mcp) — the 36 tools
* Endpoint map for agents: `https://nsr.stateset.com/llms.txt`
