Uncertainty policy · fail-closed

JNSP — saying "I don't know" is a valid signal

Saying "I don't know how" is a valid signal, not a failure. SDD Mode always prefers an honest JNSP answer to a confident but invented one — and it tools this preference end to end: verdicts, pre-commit hook, exit codes.

Why inventing costs more than doubting

An AI agent is trained to produce a plausible answer — including when it lacks the information to decide. This default confidence has a hidden cost: what is invented today reappears tomorrow as drift, as a production bug or as a regulatory violation. The JNSP policy (Je Ne Sais Pas — "I don't know") reverses the slope: when the agent cannot decide, it says so, structures what it is missing, and hands the decision back to the human. It is the natural extension of Human Authorship: when in doubt about the intent, the agent ASKS — it does not invent.

The situations that mandate a JNSP verdict

The agent MUST emit a JNSP verdict (UNKNOWN for English-language outputs) in the following cases:

Situations mandating a JNSP verdict
SituationVerdictSkill / Command
Intent not formulated by an identifiable humanJNSPhuman-authorship-check
Acceptance criterion not unambiguously testableJNSPears-validator, /sdd spec
Tier 1 governance not decidableUNKNOWN = VETO (fail-closed)regulatory-veto
SQS partially unscorable?/5 → Gate UNKNOWNsqs-scoring, /sdd gate
Missing @spec annotations during a drift-checkUNKNOWN (≠ OK)drift-detection, traceability
Context file not fully readableJNSPcontext-budget, /sdd resume

The common pattern: no absence of information ever scores "OK". A Gate that cannot be computed comes out UNKNOWN, not open; code without @spec annotations comes out UNKNOWN, not "no drift".

The form in code: TODO-JNSP

When uncertainty arises mid-implementation, it materialises as a marker in the diff:

// TODO-JNSP: <precise question for the human>
Blocking at commit time

The pre-commit hook (.aiad/hooks/pre-commit.sh) blocks any diff containing an unresolved TODO-JNSP:. The git commit --no-verify bypass exists but is discouraged: it amounts to committing a question without an answer.

This mechanism guarantees that areas of uncertainty do not silently sediment into the code: either the human answers and the marker disappears, or the commit waits.

The form in a text answer

A JNSP is not a shrug — it is a structured three-line answer that makes the question actionable:

JNSP — <short title>
What is known: <verified facts, files read>
What is missing: <information needed to decide>
Question for the human: <actionable rephrasing, finite choice if possible>

The discipline of form matters: "what is known" proves the agent did the research work; "what is missing" circumscribes the uncertainty; the final question, as a finite choice where possible, minimises the human decision effort.

CLI exit codes: 2 is not an error

The policy goes all the way up to the npx aiad-sdd CLI and CI pipelines:

CLI exit code semantics
CodeSemantics
0Success / PASS verdict
1Failure, error or FAIL verdict
2JNSP verdict — human decision required (not an error)

Distinguishing code 2 from code 1 is essential: a FAIL has a known correction; a JNSP is an open question that must be escalated to the human. Downgrading a JNSP into a FAIL "to keep things moving" is explicitly forbidden — as is downgrading it into a PASS.

Fail-closed: protection against self-clearance

The uncertainty policy is above all a protection against silent self-clearance: an agent that, facing a check it cannot perform, would conclude "nothing to report". In SDD Mode, doubt is fail-closed: an undecidable Tier 1 governance check equals VETO; an incomplete traceability matrix equals GAP and blocks the CI (--fail-on-gap treats UNKNOWN as a failure). We prefer a false positive that demands human clarification to a silent false negative — that is the price, deliberately accepted, of a verifiable chain of trust.