30-second answer
Six outcomes, answering three different kinds of question. They are not degrees
of the same thing, and unknown is never a pass.
The six
| Outcome | Question it answers | Whose fact is it |
|---|---|---|
pass | The rule decided, and the resource is within it | The resource |
fail | The rule decided, and the resource is outside it | The resource |
not-applicable | The rule had nothing to say here | The resource |
unknown | The engine could not tell | The collection |
invalid-evidence | The document did not match its schema | The collector |
error | The engine itself failed | The engine |
The third column is the one to read twice. Only three of the six are statements about the thing being governed.
Why unknown is a result and not a failure
unknown means the evidence did not settle the question. The engine will not
round it up, and the summary says so in the document:
2 rules could not be decided. That is not compliance: missing evidence is
a fact about collection, not about the resource.A tool that reported unknown as pass would produce its cleanest reports
from its weakest collections, which is the exact opposite of useful.
The most common cause is a collector that was not asked for the expensive
part. Run permissions without --count-unique-scopes and the scope count
comes back not-supported, so SPO-LIST-002 returns unknown rather than
passing on a number nobody took.
Why invalid-evidence is separate from unknown
unknown says the evidence did not answer the question. invalid-evidence
says the evidence was malformed: it did not match the schema.
That is a defect in the collector, not a finding about the resource, and the engine says so rather than filing it as governance:
this is a defect in the collector, not a finding about the resourceMerging the two would send somebody to fix a tenant when the thing to fix is a script.
Why a rule cannot author the error message
outcomes in a rule file requires five messages: pass, fail, unknown,
not_applicable, invalid_evidence. error is absent on purpose. It
describes the engine and not the resource, so a rule may not author its
message.
Why three of the messages may not interpolate
The unknown, not_applicable and invalid_evidence messages may not contain
{, and the schema enforces it.
Those three are printed precisely when the evidence is missing, out of scope or malformed. A field cannot be both the reason the rule could not decide and a value the rule prints.
In a pipeline
evaluate --fail-on unresolved counts unknown, invalid-evidence and
error alongside fail. It is the setting for a build that must not go green
on evidence the engine could not read.
m365-governance explain <outcome> prints all of this from the executable.