Skip to content

IQ-011: a sample report nobody needs the machine to reproduce - #18

Merged
itcmsgr merged 2 commits into
mainfrom
docs/iq-011-reproducible-sample
Sep 20, 2026
Merged

itcmsgr merged 2 commits into
mainfrom
docs/iq-011-reproducible-sample

Conversation

@itcmsgr

@itcmsgr itcmsgr commented Sep 20, 2026

Copy link
Copy Markdown
Owner

Closes IQ-011.

The previous sample report was withdrawn rather than corrected: it described a retired storage schema, its source VM no longer existed, and the fields that replaced the retired ones had never been collected from it. Writing plausible values for a host nobody can re-observe would have been inventing evidence.

This replaces it with real output that does not depend on anyone still having the host.

How it was produced

A disposable Debian 12 VM was built for the purpose, the released 0.1.0-alpha1 DEB was installed on it — so the sample also demonstrates that the published artifact installs and runs — and an unprivileged user collected under ISEDRAF_STATE_ROOT. Nothing was typed by hand into either document.

What is committed is the evidence, not just the output

evidence/collected_inventory.json   the inventory as collected
evidence/state-root/                the snapshot, manifest and ledger as written
evidence/environment.txt            version, interpreter, kernel, distribution

scripts/docs/sample_report.py rebuilds both documents from those bytes by running the real report model and the real renderers. It re-verifies the ledger chain while doing so, so "verified": true in the sample is recomputed from committed preimages rather than being decorative text.

The published sample is byte-identical to what the VM produced, except evidence_root, which now honestly names the committed directory the bytes were read from.

Two identities had to be pinned or the digest would not have been a function of the evidence: the report id and generation timestamp, which NON_REPRODUCIBLE already names as values that must differ between renderings; and the inventory artifact's collection id and timestamp, which are stamped when a report is built rather than when the inventory is collected. All four are the real values from the collection that produced the committed evidence, taken from that run's own report. The artifact digest of the published sample equals the one the VM computed — that is what proves the bytes are the same collection.

D-114 in the wild

{ "name": "vda", "kernel_subsystem": "virtio", "queue_rotational": true,
  "kernel_removable": false, "scsi_peripheral_type": null, "vendor": "0x1af4" }

The kernel reports queue_rotational: true for a virtio disk whose backing store is a file on an SSD array. The retired schema would have labelled it ROTATIONAL, and been wrong. The sample records the flag, names the source in the column header, and claims no medium.

Verified on the published sample: no type, physical_medium, transport or is_aggregate; no SSD/HDD/SATA/SAS/ROTATIONAL string anywhere in the JSON.

What this does not reproduce

The collection itself. Reading /sys and /proc needs the machine, and no committed byte can stand in for it. The evidence is captured once; the report is reproducible from it. The sample says so rather than implying more.

Binding

The sample and its evidence cannot drift apart in either direction. make check-sample-report is wired into make check, and two falsification injections prove the gate fires when the document is edited by hand and when the evidence changes underneath it.

Falsification on this branch: 106 executed and detected · 8 declared skips · 0 unexpected non-firing · 0 harness errors. Gate coverage: 20 gates.

(Standing record: one prior private bytecode-injection non-detection, unresolved and non-reproducing, with two CI_EXECUTED_AND_DETECTED results on the public runner since. Not erased by later passes.)

Scope

Sample and its gate only. No roadmap changes — those follow in a separate PR. No W1-D collectors, no ARM64, no framework mappings: verified zero matches for passwd, shadow, sudoers, ISE-ACCOUNT, aarch64, arm64, alpine, BYOL under lib/ and tests/.

The released v0.1.0-alpha1 object is untouched.

Antonios Voulvoulis added 2 commits September 20, 2026 20:27
IQ-011. The previous sample report was withdrawn, not corrected: it described a
retired storage schema, its source VM no longer existed, and the fields that
replaced the retired ones had never been collected from it. Writing plausible
values for a host nobody can re-observe would have been inventing evidence.

This replaces it with real output that does not depend on anyone still having
the host.

A disposable Debian 12 VM was built for the purpose. The released 0.1.0-alpha1
DEB was installed on it - so the sample also demonstrates that the published
artifact installs and runs - and an unprivileged user collected under
ISEDRAF_STATE_ROOT. Nothing was typed by hand into either document.

What is committed is the evidence, not just the output:

  evidence/collected_inventory.json  the inventory as collected
  evidence/state-root/               the snapshot, manifest and ledger as written
  evidence/environment.txt           version, interpreter, kernel, distribution

scripts/docs/sample_report.py rebuilds both documents from those bytes by
running the real report model and the real renderers. It re-verifies the ledger
chain while doing so, so the sample demonstrates verification rather than
asserting it. The published sample is byte-identical to what the VM produced,
except for the evidence root, which now honestly names the committed directory
the bytes were read from.

Two identities had to be pinned or the digest would not have been a function of
the evidence: the report id and generation timestamp, which NON_REPRODUCIBLE
already names as values that must differ between renderings, and the inventory
artifact's collection id and timestamp, which are stamped when a report is
built rather than when the inventory is collected. All four are the real values
from the collection that produced the committed evidence, taken from that run's
own report. The artifact digest of the published sample equals the one the VM
computed, which is what proves the bytes are the same collection.

D-114 is visible in the sample, and the case is a good one: the virtio disk
reports queue_rotational=true while its backing store is a file on an SSD array.
The retired schema would have labelled it ROTATIONAL. The sample records the
kernel flag, names the source in the column header, and claims no medium.

What committed bytes cannot reproduce is the collection itself - reading /sys
and /proc needs the machine - so the evidence is captured once and the report is
reproducible from it. The sample and its evidence cannot drift apart in either
direction: two injections prove the gate fires when the document is edited by
hand and when the evidence changes underneath it.

Implements: IQ-011, D-88, D-89, GOV-002
Assisted-by: Claude (VM provisioning, capture, generator, gate authoring)
Owner decision, 2026-09-20. The lab disclosure review of the IQ-011 sample
accepts all three of the facts it discloses about the machine it ran on: the
QEMU machine description, the CPU model string, and the libvirt default network
192.168.122.0/24. None is a credential, customer data, unique private
addressing, restricted content or secret infrastructure information. They are
observations from a disposable VM.

No re-capture. Re-collecting behind a synthetic CPU and machine type purely to
make the output less specific would turn the sample into a cosmetically
sanitized synthetic host, which is not what it is for. It exists to show what
ISEDRAF actually observes.

The virtio disk is the clearest argument for keeping it as captured:
kernel_subsystem=virtio with queue_rotational=true, over storage that is
SSD-backed. The queue flag is evidence. "HDD" would have been interpretation
beyond the evidence, and a sanitized sample would have hidden the exact case
that made D-114 necessary.

Implements: IQ-011, D-90
Assisted-by: Claude (recording the owner decision)
@itcmsgr
itcmsgr merged commit b06d310 into main Sep 20, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant