# InterGenOS R001.1 — Provenance Index

**What this document is.** An index of where every published piece of InterGenOS
R001.1 comes from, and how to check that claim yourself. Every row states a measured
value and the exact command that produces it. Nothing here asks you to take the
project's word for anything: each entry is either something you can recompute, or it
is marked as a limit of what this release can prove.

**How the values were measured.** Every number below was produced by running the
stated command against the published artifacts over the public network, on
2026-08-20. If you run the same command and get a different answer, the divergence is
the finding — not this document. Section 6 is where that covenant was exercised
against this release's own bill of materials, and it found something.

---

## 1. The source of record

The tree R001.1 was built from is a single commit on `master`, and that commit is
signed by an annotated tag.

| Item | Value |
|---|---|
| Repository | `https://github.com/InterGenJLU/intergenos.git` |
| Signed tag | `R001.1` |
| Tag object | `ede473c11c9ea033ada862c2ee48713e02bb4a1d` |
| Tagged commit | `f21545b5fe8df389626a7cd14809c691c915d8f7` |
| Tag signature | Good, by signing subkey `D7AA641D81ACD690C5AD865E7276E14DD8886BFE` |
| Signature made | 2026-08-20 15:37:26 CDT |
| Signing primary key | `5597A3E0587B253006D0DD7B8C50826182083050` |
| `packages/` tree object | `04bb56eb6f6aa393a1069967be650cc8f0f721db` |
| Preceding major release tag | `R001`, at commit `7716421faea22c9e65eaf63207706d4bc717c02a` |

**Verify the tag:**

```sh
git clone https://github.com/InterGenJLU/intergenos.git && cd intergenos
curl -sS https://repo.intergenos.org/keys/intergenos-release-key.asc | gpg --import
git tag -v R001.1
git ls-remote --tags https://github.com/InterGenJLU/intergenos R001.1
```

**Verify that the package definitions you are reading are the ones this release was
built from.** The `packages/` tree object is the thing to compare, because it is
unchanged by commits that touch documentation only:

```sh
git rev-parse R001.1:packages
git rev-parse master:packages
```

Both print `04bb56eb6f6aa393a1069967be650cc8f0f721db`. Every count in section 6 was
derived against that exact tree object.

**A limit, stated plainly.** The tag pins the source tree; it does not attest the
machine that compiled it. See section 7.

---

## 2. The installation image

| Item | Value |
|---|---|
| URL | `https://repo.intergenos.org/iso/intergenos-r001.1.iso` |
| Size | 10,414,972,928 bytes |
| SHA-256 | `31b6e0a38ff74170a927413037e8b03b441e7178385d12ed8074c5041e0cd527` |
| Checksum file | `https://repo.intergenos.org/iso/intergenos-r001.1.iso.sha256` |
| Checksum file SHA-256 | `7ab89e73c906dd5f5cfa5ec2446369e1182672e2721b4d09bbc77bfcf1781a08` |
| Signature over the checksum file | `https://repo.intergenos.org/iso/intergenos-r001.1.iso.sha256.asc` |
| Signature SHA-256 | `b796630b5ac94735ff6e29cfdb22209f46ab417f7d54714ff873d9ec3dea9ea5` |
| Signature made | 2026-08-20 14:37:52 CDT, by subkey `D7AA641D…` |
| Server `Last-Modified` (image) | Thu, 20 Aug 2026 13:28:57 GMT |

**Verify, signature first:**

```sh
curl -O https://repo.intergenos.org/iso/intergenos-r001.1.iso
curl -O https://repo.intergenos.org/iso/intergenos-r001.1.iso.sha256
curl -O https://repo.intergenos.org/iso/intergenos-r001.1.iso.sha256.asc

gpg --export 5597A3E0587B253006D0DD7B8C50826182083050 > release-key.gpg
gpgv --keyring ./release-key.gpg \
     intergenos-r001.1.iso.sha256.asc intergenos-r001.1.iso.sha256   # Good signature
sha256sum -c intergenos-r001.1.iso.sha256                            # OK
```

The signature over the served checksum file was fetched and verified against the
release key for this index; the byte count in the table equals the `Content-Length`
the server advertises for the image.

**A second, independent attestation of the same digest.** The image-assembly step
writes a provenance manifest recording the SHA-256 of every input artifact it
consumed — the signed bootloader and the three signed unified kernel images, and the
squashfs — together with the SHA-256 of the image it produced. That manifest records
the output digest — SHA-256 `31b6e0a38ff74170a927413037e8b03b441e7178385d12ed8074c5041e0cd527` — as the same value the published checksum file carries. The two were produced by different steps at
different times: one by the assembler as it wrote the image, one by the publish path
as it staged it.

**A limit, stated plainly.** The signature attests the checksum file, not your copy
of the image. Verifying it proves the checksum you are about to compare against is
the project's; comparing the image to that checksum is a separate step you have to
run, and it is the one that catches a truncated download or a substituted image.
Neither step says anything about the machine that built the image — see section 7.

---

## 3. The signed package index

The mirror's index is a signed manifest of the entire repository. One signature
covers every package entry, and each entry carries that package's own SHA-256 — so
verifying one signature transitively attests the bytes of every published package.

| Item | Value |
|---|---|
| Index URL | `https://repo.intergenos.org/x86_64/current/InterGenOS.db` |
| Signature URL | `https://repo.intergenos.org/x86_64/current/InterGenOS.db.sig` |
| Index SHA-256 | `c8231549132f5f89206fdac965f5884fe1f78a7bd03eee56eae49d1e5a22df1d` |
| Signature SHA-256 | `fc6510d5f9d3793a09619e3053ee7ecdc69fe2070e5dc906a61852869b40335f` |
| Signature made | 2026-08-20 15:11:37 CDT, by subkey `D7AA641D…` |
| Index generated | 2026-08-20T20:07:56Z (from the index's own `generated` field) |
| Packages in index | 1,125 |
| Entries carrying a SHA-256 | 1,125 of 1,125 |
| Format | gzip-compressed JSON |

**Verify the signature:**

```sh
curl -O https://repo.intergenos.org/x86_64/current/InterGenOS.db
curl -O https://repo.intergenos.org/x86_64/current/InterGenOS.db.sig
gpg --export 5597A3E0587B253006D0DD7B8C50826182083050 > release-key.gpg
gpgv --keyring ./release-key.gpg InterGenOS.db.sig InterGenOS.db
```

Expect `Good signature from "InterGenOS Project Signing Key (primary)"`.

**The index describes the bytes the mirror actually serves.** That was checked rather
than assumed, by downloading a published archive and hashing it:

```sh
curl -O https://repo.intergenos.org/x86_64/current/acl-2.3.2.igos.tar.gz
sha256sum acl-2.3.2.igos.tar.gz
# sha256 76e3c0610c56b11f6fc0f35bf7e29b627f7f5e2cd349038de443feef1fb5cd73
gzip -dc InterGenOS.db | python3 -c '
import json,sys; print(json.load(sys.stdin)["packages"]["acl"]["sha256"])'
# sha256 76e3c0610c56b11f6fc0f35bf7e29b627f7f5e2cd349038de443feef1fb5cd73
```

The two agree. Section 6 records the same comparison run across the whole corpus.

---

## 4. The source-archive corpus

| Measurement | Value |
|---|---|
| Source archives published | 1,131 |
| Published binaries in the signed index | 1,125 |
| Binaries with a name-and-version-matching source archive | 1,085 |
| Binaries with no matching source archive | 40 |
| Source archives with no corresponding published binary | 46 |

**Reproduce these counts:**

```sh
curl -sS https://repo.intergenos.org/x86_64/current/sources/ \
  | grep -o 'href="[^"]*\.igos\.src\.tar\.gz"' | sed 's/href="//;s/"//' | sort > sources.txt
wc -l sources.txt                      # 1131

curl -sS -O https://repo.intergenos.org/x86_64/current/InterGenOS.db
gzip -dc InterGenOS.db | python3 -c '
import json,sys
db = json.load(sys.stdin)["packages"]
want = {f"{n}-{e[\"version\"]}-{e[\"release\"]}.igos.src.tar.gz" for n, e in db.items()}
have = set(open("sources.txt").read().split())
print("binaries          :", len(db))
print("matched           :", len(want & have))
print("binary, no source :", len(want - have))
print("source, no binary :", len(have - want))'
```

**What the 40 are.** Packages that declare no upstream source, so there is nothing to
publish: the project's own configuration, branding, font and theme packages, the
meta-packages whose whole content is a dependency list, and the helper recipes that
fetch a proprietary application from its vendor at install time rather than building
it. The publish pipeline enforces the correspondence rule and derives this exemption
set from the package definitions themselves at publish time, printing every exempted
name rather than consulting a hidden allowlist.

**What the 46 are.** Build-stage intermediates — names ending `-pass1`, `-pass2`,
`-core`, `-tmp` or `-bootstrap`. A from-source bootstrap builds some packages more
than once, at different stages, with different capabilities available. Their source
is published; their built binaries deliberately are not, because a build intermediate
is not a package a user installs.

**A limit, stated plainly.** The signed index covers binary archives. Source archives
are not listed in it and are therefore not covered by its signature. Verifying a
source archive is a checksum comparison against the pins inside it and in the recipe,
not a signature check.

---

## 5. The release key and where it is served

R001.1 is signed by the same key as R001. One primary key, served from three
independent places. All three serve the same key material; the ASCII-armored bytes
differ between them because each keyserver normalises packet order and strips
third-party certifications differently, which is why the fingerprint — not the file
hash — is the thing to compare.

| Location | URL or command |
|---|---|
| Project mirror | `https://repo.intergenos.org/keys/intergenos-release-key.asc` |
| keys.openpgp.org | `gpg --keyserver keys.openpgp.org --recv-keys 5597A3E0587B253006D0DD7B8C50826182083050` |
| keyserver.ubuntu.com | `gpg --keyserver keyserver.ubuntu.com --recv-keys 5597A3E0587B253006D0DD7B8C50826182083050` |

| Key component | Fingerprint | Role |
|---|---|---|
| Primary | `5597A3E0587B253006D0DD7B8C50826182083050` | Certification and signing; **this is the fingerprint to compare** |
| Subkey | `D7AA641D81ACD690C5AD865E7276E14DD8886BFE` | Signed this release's image checksum and package index, and the `R001` tag |

The copy served from the project mirror at the time of measurement has SHA-256 `18b15b6fb975f0ab55dc3fd7cc0dc85087619c39354732a90db1c20cb51e7da6`. Do not treat that
value as the thing to check — compare the fingerprint, for the reason given above.

**A limit, stated plainly.** Three sources agreeing raises the cost of substituting a
key; it does not by itself prove the key belongs to this project. That is what key
certification is for, and it is your decision to make, not something a release
document can settle on your behalf.

---

## 6. The software bill of materials

| Item | Value |
|---|---|
| File | `intergenos-r001.1.sbom.spdx.json` |
| SHA-256 | `30b9c72cb3337f96aa6ce8cdd675bff623de58cf4012752703a5fef733b78be8` |
| Format | SPDX 2.3, JSON |
| Created | 2026-08-20T12:32:39Z (from the document's own `creationInfo`) |
| Total entries | 862 |
| — components carrying an archive SHA-256 | 861 |
| — the image record, which carries no archive checksum by design | 1 |
| Generated by | `scripts/iso-sbom-gen.py`, from the tree object in section 1 |

**The shipped set is derived, not curated.** The generator imports the same parser
the build pipeline uses and reads each package's resolved `iso_include` value, so the
set in the bill of materials and the set the build ships are the same computation and
cannot drift apart. A package that cannot be identified is a loud refusal naming it,
and no document is written at all.

**The checksums in this bill of materials agree with the signed index.** Measured
against the served index for this document:

| Result | Count |
|---|---|
| Component checksum equal to the signed index | 842 |
| Component checksum differing | 0 |
| Component absent from the index — never-published build intermediates | 19 |
| Entries with no archive checksum — the image record | 1 |

**Reproduce it:**

```sh
gzip -dc InterGenOS.db > db.json
python3 -c '
import json
sbom = json.load(open("intergenos-r001.1.sbom.spdx.json"))
idx  = json.load(open("db.json"))["packages"]
same = diff = absent = nohash = 0
for p in sbom["packages"]:
    ck = [c["checksumValue"] for c in p.get("checksums", []) if c["algorithm"] == "SHA256"]
    if not ck: nohash += 1; continue
    e = idx.get(p["name"])
    if e is None: absent += 1; continue
    same += ck[0] == e["sha256"]; diff += ck[0] != e["sha256"]
print("equal:", same, " differ:", diff, " absent:", absent, " no checksum:", nohash)'
```

So the bill of materials inherits the index signature's attestation rather than
making an independent claim.

**This section is also a record of a defect this document's own verification found,
and of its correction before publication.** The first verification pass for this
index compared the bill of materials against the index then being served and found
842 components matching and a large majority differing, with the version and release
identical on both sides — the same version, different archive bytes. Investigation
established the cause: earlier publishes had overlaid only those packages whose
version or release had changed onto a baseline predating the from-source build, so
names carried forward unchanged continued to serve older builds than the ones the
release evaluated. The bill of materials was correct; the served corpus was not. The
full evaluated corpus was re-staged, the index regenerated and signed again, and the
corrective publish completed before this release was announced. The table above is
measured against that corrected, served index.

Two things follow, and both are worth stating rather than leaving implicit. The
index remains the download-time authority: it is signed, and every entry carries the
SHA-256 of the archive the mirror serves. And a bill of materials is only as useful
as the check that compares it to something — this divergence existed for as long as
nobody ran that comparison, and it was found the first time somebody did.

**Licenses in the bill of materials.** Every component entry carries a
`licenseDeclared` value taken from the package definition — 72 distinct SPDX
identifiers across the set. Every entry's `licenseConcluded` is `NOASSERTION`, which
is the honest SPDX encoding: "declared" is what the package states, "concluded" is
what an analyst determined, and no analyst pass was run. That is a statement of what
was not done, not a gap discovered.

---

## 7. What this release does not prove

Stated here rather than left for you to discover.

- **The image checksum is signed, but the signature covers the checksum file and not
  your copy of the image.** Verifying it and then hashing the image are two separate
  steps, and only running both establishes that the file on your disk is the released
  image. See section 2.
- **Source archives are not covered by the index signature.** See section 4.
- **The bill of materials describes the package set the image ships, derived from the
  package definitions — not an inventory taken by opening the image's filesystem.**
  Those two answer the same question from different directions, and only the first is
  claimed here.
- **This index does not attest the build environment.** It records what was published
  and how to check it. A formal attestation of the machine and toolchain that
  produced the artifacts is a separate mechanism and is not part of R001.1.
