1.0.0b4
Pre-releaseA collection now reports what it is doing while it does it, and says what it
managed to do when it stops. Both were missing, and the second one is a new
contract.
A collection had no account of itself. The only thing a caller could read
was a process exit code, and a run that reached two hundred of three hundred
sites and then lost its connection had the same value as one that never
authenticated. The first produced evidence worth two hundred sites. That
collapse is made nowhere else here: coverage keeps requested and completed
apart, and a rule answers unknown rather than failing when the gap could
change its answer.
A new contract: collection/1.0.0
A collection-manifest.json is written beside the evidence, on every path
including the failure that produced no evidence at all. It carries the state,
the facts behind it, what was asked for, what was observed, the identity that
looked, the coverage as a union of the artefacts' own, every artefact with a
digest over its bytes, and a digest over itself.
Why a manifest, and not a field in each evidence document. An evidence
document is about one resource and a collection is a batch, so a field in each
would be one truth written once per document — and it could not answer the case
the contract exists for: a collection that stops 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.
Full contract: docs/COLLECTION-MANIFEST.md
Consumers re-vendor. A collection state that lived only in a consumer would
be that consumer's opinion about an exit code.
Also in this release
- Four states where there was a boolean:
completed,partial,failed,
cancelled.partialis not a failure andcollectexits0for it.
cancelledis set by the caller and never inferred from an exit code. - The collector's output streams. It was buffered until the process exited,
socollect sitesagainst a large tenant printed nothing for however long it
took and then printed everything, including the line saying how many sites
the identity had enumerated. evaluatestates the bound before the results where a manifest exists,
on stderr. Where none exists it says nothing: evidence collected before this
contract carries no account of its own completeness, and inventing one would
report a gap that was never measured as an absence of gaps.- Two collections into one directory no longer destroy each other's record.
- The canonical form moved to
m365_governance/canonical.py, because two
documents now publish a digest a recipient recomputes.
Defects this found
Three came from printing a manifest the code had just written, and none was
visible in the code: a clean exit that wrote nothing reported completed; a
dry run had a state at all; and the reason an area was not read arrived as a
Python dict repr where a sentence belonged.
One came from adding the schema: the model generator emitted three records
called Versions and two called Coverage into one namespace, all different
shapes. Every file individually correct, the bundle would not have compiled —
which nothing here would have said, because nothing here compiles it. It
refuses now.
Not in this release
An assessment still does not record which collection produced its evidence or
in what state that collection ended. That costs an assessment contract version
and is the next step.
Install
pip install m365-governance-as-code==1.0.0b4