30-second answer
The engine has six outcomes: pass, fail, unknown, not-applicable,
invalid-evidence and error. Two of them describe the machinery rather
than the tenant, and they differ by the fix. unknown means the
evidence was not there to read: collect again, with the access you were
missing. invalid-evidence means the evidence was there and malformed:
repair the collector or the schema. Confuse them and you send an
administrator to fix a permission when the defect is in your own
pipeline.
What this proves
- Where the work is. The engine's shipped example of
unknownis a real shape:ownersrefused with permission-denied because the identity lacked the scope, and 13 rules evaluated with 0 producing an answer. Nothing in that tenant needs fixing; the collection identity does. - That an absent value cannot leak into a conclusion. Every fact carries a collection state (observed, missing, not-supported, permission-denied, partial, invalid), and an empty array means observed with none present, never absence.
What it does not prove
- Compliance. The engine's trust model states it directly: unknown is a valid result, unknown is preferable to a false pass, and evidence that was not collected must never become compliance. A report that renders unknown as amber "nearly compliant" is inventing a fact.
PowerShell
# Reproduce the engine's shipped unknown example against its own fixture
m365-governance evaluate `
.\src\m365_governance\data\fixtures\sharepoint\site-owners-not-collected.jsonExample output
Not collected: owners (permission-denied: identity lacks Sites.FullControl.All)
13 rules evaluated. 0 produced an answer.
Unknown: 13Explanation
The two outcomes stay honest because the resolution order is fixed in
the contract, not chosen by the engine. For every rule: first, any
required path in invalid state resolves invalid-evidence; second, a
false applicability resolves not-applicable; third, any required path
absent, or in missing, not-supported or permission-denied state, when
the outcome depends on it, resolves unknown; only then pass or fail. The
order is written down because an engine free to reorder could evaluate
applicability first and let a malformed value vanish under a
not-applicable, which is a pass with better manners.
Production considerations
- Route the two outcomes to two queues. Unknown belongs to whoever owns collection access; invalid-evidence belongs to whoever owns the collector. A shared queue guarantees both wait.
- Count unknowns on the report's first page. A run that saw almost nothing must not read as a clean bill; the engine's attention model refuses exactly that presentation.
Related governance rules
SPO-SITE-001: the owners rule at the centre of the engine's shipped unknown example
References
- Evidence schema, section 12: resolution order (m365-governance-as-code)
- Trust model (m365-governance-as-code)
- Generated example: unknown (m365-governance-as-code)
Found something wrong? Suggest a correction. The article source is not public; the engine it cites is.