30-second answer
A Run is one resource evaluated: always a file. A RunSet is the
evaluation of many: always a directory. An Assessment is what a person
archives and sends: the RunSet plus the evidence, the versions, the
manifest and the digests, split into a canonical half that is hashed and
a derived half (the human reports) that is not. A Comparison relates two
Assessments. The assessment_id derives from the canonical digests, so
the same inputs produce the same identity, on any machine, at any hour.
What this proves
- That the archive is self-verifying.
verifyrecomputes the canonical digests and compares; it is deliberately independent ofbuild, so the code that writes an Assessment is never the code that vouches for it. - That identity follows content. Removing one field from the
evidence inside the engine's
three-resourcesfixture changed the evidence digest and therefore theassessment_id. An assessment whose evidence changed is a different assessment, by construction. - That reports can be regenerated. Only the canonical half is hashed. A derived report can be re-rendered, translated or rebranded without touching the identity of what it describes.
What it does not prove
- When it was really made.
created_atis an input to the build, not a clock read, precisely so that the same inputs produce the same bytes. The timestamp is a claim carried inside the verified envelope, not a fact the envelope proves. - That the evidence was true. The digests bind the report to the evidence; the evidence's own provenance is what binds it to a tenant.
PowerShell
# Build and independently verify an Assessment from a RunSet
m365-governance assess --run-set .\runs\classification `
--created-at 2026-08-10T09:00:00Z --out .\assessment
m365-governance verify .\assessmentExample output
assessment_id : a-bdd9082a
canonical : verified (manifest, run set, evidence, versions, hashes)
derived : reports (not part of identity)Explanation
The split answers a question auditors actually ask: which bytes am I trusting? The canonical half is the answer, and it is small and mechanical. Everything a reader touches, the rendered report, lives on the derived side, where it can be wrong, regenerated or improved without forging anything. Two guard rails keep the model honest: duplicate evidence for one resource raises an error rather than averaging, and a Comparison refers to Assessments by id plus canonical digest, never by path, refuses to compare two different tenants, and refuses an assessment that does not verify. Attribution inside a Comparison is never marked established without factors and a method, and an outcome may not be listed among its own causes.
Production considerations
- Archive the Assessment directory, not the report PDF. The report is
derived; the directory is the thing
verifycan defend years later. - If your pipeline stamps
created_atfrom the build clock, two identical evaluations will produce two different artifacts and your dedup story dies. Pass the timestamp in.
Related governance rules
SPO-CLASS-001,SPO-CLASS-003: the rules inside the engine's real classification Assessment fixture, built by the engine from a sanitized observation
References
- Architecture (m365-governance-as-code)
- Assessment schema 4.0.0 (m365-governance-as-code)
Found something wrong? Suggest a correction. The article source is not public; the engine it cites is.