30-second answer
A collection writes collection-manifest.json beside its evidence, saying what
it managed to do. Four words, and one of them is not a failure:
| State | Means |
|---|---|
completed | Everything the slice asked for |
partial | Usable evidence, incomplete coverage, with the reason |
failed | No usable artefact |
cancelled | Stopped deliberately, and what was written is kept |
A folder of evidence files is not a collection. It is what a collection left behind, and the two are only the same thing when nothing went wrong.
Why it is a separate document
An evidence document is about one resource. A collection is a batch.
Putting the state of the batch inside each document would write one truth once per document. It would also leave the case the manifest exists for unanswerable:
A collection that stopped halfway has to say what it did not read, and the documents that would carry that sentence are exactly the ones that were never written.
So the manifest describes the collection, and the documents go on describing evidence.
What it replaced
Nothing, and that is the point. Before this contract the only account of a collection was a process exit code, so a run that reached two hundred of three hundred sites and then lost its connection was indistinguishable from one that never authenticated.
The first produced evidence worth two hundred sites. The second produced
nothing. Reading them as the same result is the collapse this engine refuses
everywhere else: coverage keeps requested and completed apart, and a rule
answers unknown rather than failing when the gap could change its answer.
Partial is a result
A collection that reached half a tenant produced evidence worth exactly half a
tenant. collect exits 0 for it, and evaluating it is valid: where the gap
could change an answer, a rule returns unknown rather than a pass.
The exit code is published in the manifest as a raw fact and is not the verdict.
0 does not mean everything was read.
What it carries
| Member | What it is |
|---|---|
collection_id | The document's own digest, so a recipient can recompute it |
state | One of the four above |
because | The facts that produced the state. Never empty |
requested | The addresses it was pointed at. The half that survives a total failure |
observed | The tenant the evidence says it is about, or null |
identity | Which kind of identity looked, and the app registration |
coverage | requested, completed, unavailable, by area name |
artefacts | Every document written: path, digest over the bytes, size, whether it parsed |
versions | Engine, contract, collector |
Nothing in it is inferred from the exit code. The tenant, the identity kind,
the collector version and the coverage are all read back from documents that
were actually written, and are null or empty where none were.
The coverage is a union, and never a count
An area is completed only where every artefact that asked for it read it.
One document reading an area another could not is not the collection having got
all of it.
There are no percentages anywhere in it, deliberately. A total computed here would be a second authority on how much of a tenant was seen, agreeing with the documents until the day it did not.
What the digest proves, and what it does not
It proves that the manifest and the documents it names are the bytes that were written, so a truncated transfer or an edited file is detectable.
It proves nothing about who produced them. Anybody who can edit the manifest can recompute the digest. Authenticity is a signature, and this engine does not claim one. The same canonical form as an assessment: keys sorted, no whitespace between tokens, UTF-8 with nothing escaped that does not have to be, see canonical JSON and digests.
Two collections, one folder
The documented layout gives each slice its own directory, so the plain filename is the ordinary case. A second collection into the same folder never replaces the first one's account: it carries its own short identity in the filename instead.
evidence/sites/collection-manifest.json
evidence/sites/collection-manifest.4f2a91c0e7b3.jsonOverwriting would destroy the only record that the earlier one was partial. The evidence it wrote would still be there, and evidence describes a resource, not a batch, so nothing would be left to say so.
Consumers glob collection-manifest*.json.
A manifest is not evidence
It is a .json file sitting among the documents it describes, and both
directions of that mistake are closed: collect does not count one as something
it wrote, and evaluate does not hand one to the evaluator.
No manifest means nobody said
evaluate states the bound before the results where a manifest exists:
1 collections produced this evidence, 1 of them incomplete. What follows is
bounded by what was read:
sites: partial
2 evidence documents were written
contoso.json: owners not read (owners: permission-denied — ...)Where none exists it says nothing at all. Evidence collected before this contract, or exported from another tool, carries no account of its own completeness.
Silence is not completeness. An absent manifest means nobody said, never that everything was collected, which is exactly the mistake of treating a folder with some artefacts in it as a finished collection.
Where to go deeper
collect: the states as the command reports them, and the exit codes.- Incomplete evidence and lower bounds: what a rule may still decide across a gap.
- Coverage and bounds: what a number is allowed to claim.