# NEEDS_INFORMATION

`NEEDS_INFORMATION` means **the authority to decide does not exist yet**. Quattrino never guesses: it does not
infer an amount, a commitment class, or consequential permission from a vague statement. Ambiguity never
expands authority.

There are two shapes. Branch on `question`.

## Shape 1 - a material term is missing (`question` is `null`)

Your request lacks a field the engine refuses to infer. Supply it and call again.

Real example - no `amount_minor`:

```json
{
  "decision": "NEEDS_INFORMATION",
  "needs_information": [{
    "code": "amount_required", "field": "amount_minor", "consequential": true,
    "message": "State the amount to authorize (integer minor units) or a task max_amount_minor. Quattrino never infers an amount.",
    "family": "INFORMATION_REQUIRED", "severity": "information",
    "remedy": "Supply the missing term; the engine never infers it.", "registry_version": "1.0.0" }],
  "question": null, "question_required": false, "missing_authority": []
}
```

Real example - consequential action under an envelope without a declared `commitment` (an unknown commitment
is **never** treated as `ONE_TIME`):

```json
{
  "decision": "NEEDS_INFORMATION", "commitment": "UNKNOWN_COMMITMENT",
  "needs_information": [{ "code": "commitment_required", "field": "commitment", "consequential": true,
    "message": "Declare the commitment class (ONE_TIME, SUBSCRIPTION, ...). An unknown commitment on a consequential action is NEVER treated as ONE_TIME.",
    "family": "COMMITMENT", "severity": "information", "remedy": "Declare the commitment class (ONE_TIME, SUBSCRIPTION, ...) explicitly." }],
  "question": { "question": "The action creates a declared commitment class commitment. Allow it for this task?",
                "dimension": "commitment", "how_to_obtain": "declare_on_request", "asked_at": "consequence_point" },
  "missing_authority": [{ "dimension": "commitment", "needed": "declared commitment class", "have": "UNKNOWN_COMMITMENT", "how_to_obtain": "declare_on_request" }]
}
```

When `how_to_obtain` is `declare_on_request`, **you** can fix it: re-send with the term declared. No human needed.

| `needs_information[].code` | field | fix |
|---|---|---|
| `amount_required` | `amount_minor` | send the amount (integer minor units) or `task.max_amount_minor` |
| `commitment_required` | `commitment` | send `ONE_TIME`, `RECURRING`, `SUBSCRIPTION`, `AUTO_RENEWAL`, `ACCOUNT_CREATION`, `CONTRACT`, `WARRANTY` or `TRIAL_THAT_CONVERTS` |
| `wallet_missing` | agent | an owner must attach a sandbox wallet / standing authority (Golden Path step 2) |
| `unknown_constraint`, `constraint_not_integer_minor`, ... | `task.*` | fix the task constraint; see `GET /api/v1/authorize/schema` |

## Shape 2 - authority is missing (`question` is an object, `question_required: true`)

The request is complete, but the compiled intent / envelope does not cover the consequential step. Quattrino
returns **exactly one** "latest safe question" for the human, `missing_authority[]` naming what is missing, and
`safe_actions_remaining` so the agent can keep doing non-consequential work meanwhile.

Real example - `"Find someone who can fix this machine."` compiled to an envelope; the agent asks to hire
Repair Co for **$32.70** (inside its $50 standing authority):

```json
{
  "decision": "NEEDS_INFORMATION",
  "needs_information": [{ "code": "action_class_not_yet_authorized", "field": "action_class", "consequential": true, "ask_when": "before_economic_commitment",
    "message": "The task authority does not (yet) cover economic commitment. The human statement did not grant it and Quattrino never infers consequential permission; the owner must confirm.",
    "family": "CATEGORY_PURPOSE", "severity": "approval", "remedy": "Ask the owner to approve this category." }],
  "question": {
    "question": "May the agent hire (Repair Co for $32.70) for this task?",
    "dimension": "purpose.allowed_action_classes", "requested_permission": "ECONOMIC_COMMITMENT",
    "why_needed": "the action is consequential and not covered by the compiled intent",
    "how_to_obtain": "owner_amendment",
    "safe_actions_remaining": ["NON_CONSEQUENTIAL_RESEARCH", "EXTERNAL_COMMUNICATION"],
    "asked_at": "consequence_point",
    "note": "research and comparison may continue meanwhile; nothing consequential executes until the owner answers" },
  "question_required": true,
  "missing_authority": [
    { "dimension": "purpose.allowed_action_classes", "needed": "ECONOMIC_COMMITMENT", "have": ["DATA_DISCLOSURE", "EXTERNAL_COMMUNICATION", "NON_CONSEQUENTIAL_RESEARCH"], "how_to_obtain": "owner_amendment" },
    { "dimension": "money.autonomous_ceiling_minor", "needed": 3270, "have": 2000, "requested_delta_minor": 1270, "how_to_obtain": "owner_approval" },
    { "dimension": "commitment", "needed": "CONTRACT", "have": "approval_required", "how_to_obtain": "owner_approval" }
  ]
}
```

> **Amount above standing authority is DENIED first.** The same hire at **$327.00** against a $50 standing policy
> returns `DENIED` (`exceeds_effective_authority`, `binding_layer: agent_standing`) - the question is still
> attached, but the decision is a denial because no owner *approval* can exceed standing authority; only an owner
> *amendment* of the policy can.

### What to do

1. **Keep working safely.** Anything in `safe_actions_remaining` is authorized now:
   `POST /authorize {"envelope_id": "env_...", "action_class": "NON_CONSEQUENTIAL_RESEARCH", "purpose": "..."}` -> `AUTHORIZED` (no money, `execution_mode: none`).
2. **Relay the one question verbatim** to the human. Do not split the action into smaller pieces, do not rephrase
   it as something already allowed, do not retry.
3. **The owner answers** in the web app (*Questions* / *Envelopes*) or via the owner API
   `POST /api/v1/org/questions/{question_id}/answer {"action": "approve" | "approve_narrower" | "deny" | "answer" | "keep", "narrower": {...}}`,
   or amends the envelope `POST /api/v1/org/envelopes/{envelope_id}/amend` (new immutable version, widening bounded by the standing policy).
4. **Ask again** with the same request. `how_to_obtain` tells you which answer unblocks it:

| `how_to_obtain` | who acts | how |
|---|---|---|
| `declare_on_request` | you | re-send with the term declared |
| `owner_approval` | owner | approves the amount / commitment (approvals inbox) - within standing authority |
| `owner_amendment` | owner | amends the envelope / task authority (purpose, action class, ceiling) |
| `policy_change` | owner | changes the standing policy (only way to exceed standing authority) |

### Ask before you act: `authority_gap`

`POST /api/v1/authority/gap` (same body as authorize) returns `would_be` + `missing_authority[]` with display values
(`needed_display: "$32.70"`, `have_display: "$20.00"`, `delta_display: "$12.70"`) **without recording anything**.
`GET /api/v1/authority/me` lists what the agent may do now (`allowed`, `conditional`, `denied`, plain language).
MCP tools: `authority_gap`, `authority_discover`.

## Never

- Never treat `NEEDS_INFORMATION` as a soft `AUTHORIZED`.
- Never invent the missing amount or commitment.
- Never loop: the same request without new information returns the same answer.
