Skip to content

infinityabundance/zic-rs-vendor-oracle-lab

Repository files navigation

zic-rs-vendor-oracle-lab

External vendor/platform diagnostic-oracle lab for zic-rs (milestone T16.5). It generates vendor-oracle-receipt-v1 receipts by running real vendor/platform zic binaries against the diagnostic fixture corpus. The core zic-rs repository admits those receipts (zic-rs vendor-oracle-admit --receipt <file>); it never runs this lab.

Architecture line (load-bearing): the core repo admits evidence; the external lab generates it. QEMU/VM images, OS installers, and raw logs live here, never vendored into the core repo.

Reading posture

This lab is intentionally dense.

It is not an onboarding pamphlet, marketing overview, or reviewer-friendly summary. It is a field notebook and audit trail for a vendor-oracle campaign across real infrastructure operating systems. The record preserves successful paths, failed paths, transport workarounds, image provenance, binary hashes, package ownership, diagnostic divergences, non-claims, and platform-specific anomalies.

The density is deliberate — it is a seriousness filter, not a UX failure. A reader who cannot follow long evidence chains (provenance · receipts · failed routes · per-platform caveats · hashes · package ownership · claim boundaries) is not the intended audience for this artifact. The document selects for forensic patience, systems context, evidence discipline, claim-boundary reading, and failure-path literacy.

These documents are optimised for reconstruction, auditability, and adversarial verification — not for skimming, casual approval, or administrative review.

The purpose of this document is not to make the work easy to skim. The purpose is to make the work hard to misrepresent.

A softer review may ask for shorter · cleaner · less repetitive · more digestible. For this lab those are hostile requirements: they remove the very information that protects the claims. The standing test is — a serious infra reader should be able to reconstruct the campaign, not merely skim its conclusion.

Index

This README is the full operator audit trail — the per-platform narratives, transport workarounds, boot quirks, package-ownership proofs, binary hashes, provenance caveats, and non-admissions below are the evidence, not clutter; nothing here is summarised away. Use this index to navigate, not to shorten:

  • Layout — directory map
  • Use — generate a receipt → admit it
  • Receipt admission — the core's typed admit rule
  • Status (honest)the full per-platform narratives (one entry per receipt: how it booted, how it was harvested, what was measured, what was not claimed)
  • RECEIPT-MATRIX.md — quick-index table: admit · lineage · version · tier · bloat · packaging · source authority · receipt_production_mode · receipt→log-dir mapping
  • IMAGE-PROVENANCE.md — boot-substrate ledger (image file · URL · sha256 · checksum authority · build id)
  • receipts/<platform>.json — the admitted JSON (the only artifact copied to the core)
  • logs/<dir>/ — raw per-platform stdout/stderr (see the matrix's Log dir column for the mapping)

Campaign state: 17 ecology rows / 19 receipts (18 admitted + 1 typed non-admission). macOS and OpenWrt were dropped from the campaign (operator call); they are not counted here (noted in RECEIPT-MATRIX.md → "Out of campaign scope").

Layout

fixtures/                 diagnostic corpus (malformed .zi each conformant zic must reject)
run-oracle.sh             run a zic over the corpus → emit a vendor-oracle-receipt-v1 receipt
qemu/boot-freebsd.sh      boot the FreeBSD image (KVM, serial console)
qemu/run-freebsd-oracle.py  automated boot → serial login → in-VM run → capture FreeBSD receipt
qemu/images/              VM images (downloaded; NOT vendored into core)
receipts/                 produced receipts (only the JSON is ever copied to the core, for admission)
logs/                     raw per-platform stdout/stderr (never copied to core)
IMAGE-PROVENANCE.md       exact install/live image used per receipt (file · source URL · checksum · authority)

Drop-in gauntlet tooling (distinct from the vendor-oracle receipts above)

The vendor-oracle campaign measures each platform's native zic. A separate, complementary surface — the drop-in gauntlet — asks the opposite: does zic-rs itself build and run there, producing the same 598-file TZif tree? zic-rs is a Linux ELF, so each non-Linux platform builds it from the crates.io source crate with its own rustc/cargo and runs the matrix (compile 2026b → 598 files → bundle_hash 453641ff2568d8b1…, byte-identical everywhere). The receipts live in the core repo (reports/drop-in/RECEIPT-*.md); the lab only holds the tooling that produces them:

qemu/dropin-build-run.sh      shared: build zic-rs from crates.io → compile served tzdata.zi → hash → upload
qemu/qmon.py                  drive a VGA-console guest headless via QEMU-monitor screendump/sendkey
                              (for live images with no serial console — NetBSD, DragonFly)
qemu/nbproxy.py               host HTTP relay around CDN 302-redirects that hang BSD ftp/pkg_add (NetBSD)
qemu/nb-dropin.sh / nbprobe.sh   NetBSD setup wrapper + probe (gpt+wedge build disk; pkgsrc via the relay)
qemu/df-dropin.sh / dfprobe.sh   DragonFly setup wrapper + probe (nullfs a big tmpfs over /usr/local; pkg+DNS direct)
qemu/oi-dropin-drive.py          OpenIndiana driver (illumos text ISO; loader console-forcing)
harvest-server.py             host: serves /served/tzdata.zi + accepts the evidence upload (PUT/POST /upload)

Coverage (13 drop-in receipts): Linux glibc+musl (9 distros, container/VM/source) · BSD complete (FreeBSD · OpenBSD · NetBSD · DragonFly, native source-builds) · illumos (OmniOS). Remaining: the illumos live-only images (OpenIndiana, SmartOS) — read-only pkg, no persistent toolchain; the DragonFly tmpfs-over-/usr/local trick is the candidate. The boot/space techniques (qcow2 overlay on a live .img; gpt+wedge scratch disk; RAM-backed tmpfs nullfs-mounted over a full package prefix; QEMU-monitor VGA driving when serial is dead) are the reusable lessons.

Companion crate zdump-rs (separate repo, published to crates.io): an independent Rust TZif witness (the 4th evidence-court role beside compiler/validator/oracle) used to cross-check the emitted TZif — see ../zdump-rs/README.md.

Use

# Host / local platform (pipeline proof — NOT vendor breadth):
TZDB_RELEASE=2026b ./run-oracle.sh linux_glibc_host_x86_64 /usr/bin/zic > receipts/linux_glibc_host_x86_64.json
# Receipt-corpus policy: filename == platform token (e.g. `<platform>.json`), no grandfathered exceptions.

# FreeBSD (real vendor breadth) — boot under QEMU, log in, run the in-VM oracle:
#   sh qemu/freebsd-manual-oracle.sh      # emits a vendor-oracle-receipt-v1 between BEGIN/END markers
# (headless cloud-init autorun is unavailable: FreeBSD nuageinit lacks runcmd/write_files; see Status.)

# Then the CORE admits it (this is the convergence point):
zic-rs vendor-oracle-admit --receipt receipts/freebsd_14_x86_64.json

Receipt admission (decided by the core, not the lab)

A receipt is admitted only with: named platform · known fixture_set · platform_status=admitted · oracle_run_status=completed · oracle_exit_disposition=success · zic_binary_sha256 present · oracle_invocation_identity=argv_exact · a declared receipt_hash_scope · every class/location verdict matching or a declared known-divergence. A parse failure is not an inadmissible receipt.

Status (honest)

  • linux_glibc_host_x86_64 receipt — REAL, produced + admitted. run-oracle.sh ran the host /usr/bin/zic over the corpus; the receipt carries the real binary sha256, real --version, and real per-fixture verdicts; the core admitted it (vendor-oracle-admitadmitted, exit 0). This proves the full generate→admit pipeline. It is the host platform, not vendor breadth.

  • freebsd_14_x86_64 receipt — REAL, produced + admitted (a genuinely different platform, not the host). FreeBSD 14.3's own base /usr/sbin/zic (tzcode 2022g, binary sha256 37df6061b3b346b388b89e5bf6b28c72f3de6cdf3f9fef17a5e1e75ca6c6fc18) ran the 5-fixture diagnostic corpus under QEMU/KVM and rejected all five malformed fixtures (exit ≠ 0). The core zic-rs vendor-oracle-admit --receipt receipts/freebsd_14_x86_64.jsonadmitted (exit 0), proving the generate→admit pipeline on a second, genuinely distinct vendor zic, with a real finding: FreeBSD-base zic lags upstream (tzcode 2022g vs IANA 2026b).

    • Verdicts verified by real class+location comparison (not just exit code). FreeBSD zic's actual per-fixture diagnostics were captured (logs/freebsd_14_x86_64/class-location-diagnostics.txt) and compared to zic-rs's coded classes: duplicate_zone (ZIC015, line 2 refs 1), field_count (ZIC002, line 1), nul_byte (ZIC016, line 1), unknown_line_type (ZIC013, line 1) → class+location match (4/5); continuation_without_zonedeclared divergence: FreeBSD emits the generic "input line of unknown type" (line 1) while zic-rs emits the finer ZIC014_CONTINUATION_WITHOUT_ZONE (line 1) — the intentional T13.2 divergence (zic-rs finer), confirmed against tzcode 2022g as well as upstream 2026b; both reject at line 1. It is recorded in the receipt's known_divergences, so the receipt admits honestly, not by a blanket exit-code match. (Caveat: freebsd-manual-oracle.sh/run-oracle.sh assign verdicts by exit code only; the class+location refinement above was done from the captured diagnostics — a future lab enhancement is to fold the class comparison into the script itself.)
    • How it was produced (honest provenance). The two headless transports were built but did not work here: (1) the PTY/serial driver qemu/run-freebsd-oracle.py; (2) the NoCloud cloud-init autorun qemu/run-freebsd-cloudinit.sh + seed/seed.iso. The cloud-init path is conclusively dead on this OS: FreeBSD 14.3's nuageinit applies meta-data (hostname) and the users/ssh parts of a #cloud-config but does not implement runcmd/write_files, and it mounts the NoCloud seed noexec — so no seed format can autorun the corpus. The receipt was produced via an interactive console login: the operator booted the image under QEMU/KVM, ran the corpus + /usr/sbin/zic by hand (the body is qemu/freebsd-manual-oracle.sh), and exported the three measured values (zic_binary_sha256, zic --version, the five per-fixture reject verdicts) to the host over the VM's NAT network (nc → a host listener), because the QEMU serial/graphical console would not copy the long receipt line. The vendor-oracle-receipt-v1 JSON envelope was then assembled host-side from those real FreeBSD-measured values — the binary hash, the version string, and every verdict are genuine FreeBSD zic output; only the JSON formatting happened on the host. Nothing is fabricated.
    • Reproduce fully in-VM (any environment with a working interactive QEMU): boot the image, log in, sh qemu/freebsd-manual-oracle.sh (it emits the complete receipt between the ===ZIC_RS_VENDOR_ORACLE_RECEIPT_BEGIN/END=== markers), then zic-rs vendor-oracle-admit.
    • Harvested audit evidence (logs/freebsd_14_x86_64/evidence/ + evidence-bundle.tar.gz, host-received sha256 49957007…, captured by qemu/freebsd-harvest.sh):
      • Platform: FreeBSD 14.3-RELEASE-p14, amd64 (platform.txt). zic is base system, not a pkg (pkg which /usr/sbin/zic → "not found in the database") → patch_stack_identity: freebsd_base_system is correct. Binary: -r-xr-xr-x root wheel 56552, ELF PIE FreeBSD 14.3, stripped (zic-identity.txt).
      • Code/data version skew (a second, sharper ecology finding). zic/zdump are tzcode 2022g, but /usr/share/zoneinfo/tzdata.zi is # version 2026b (base-ownership.txt): FreeBSD ships current tzdata data compiled by an old zic binary. So "FreeBSD-base lags" is about the compiler, not the data — exactly the kind of distinction T16 ecology work exists to make visible.
      • zdump (2022g) is a viable semantic oracle here (zdump.txt): it renders the valid Test/Fixed zone as PLUS5 gmtoff=18000 across the representable range; the (gmtime failed) rows are only at time_t INT64 min/max (outside renderable civil time) — expected zdump behaviour, not an error.
      • Extended corpus (8 fixtures; 3 beyond the admitted set) → 7/8 class+location match, 1 divergence. The three extra T14 lexical fixtures all match zic-rs at line 1: missing_final_newlineZIC021 ("unterminated line"), overlong_lineZIC017 ("line too long"), unterminated_quoteZIC022 ("Odd number of quotation marks"). Raw per-fixture stdout/stderr/exit in evidence/raw/. The admitted receipt's fixture_set stays the original 5; these 3 are bonus audit evidence, not a claim expansion.
    • Zone-ecology bundle (logs/freebsd_14_x86_64/zone-ecology/ + zone-ecology-bundle.tar.gz, host-received sha256 fcfa865a…, captured by qemu/freebsd-harvest2.sh) — forward-looking evidence for a future cross-platform structural+semantic comparison, not part of the admitted claim:
      • zdump identity: /usr/sbin/zdump 18272 bytes, sha256 347c4a6b…, tzcode 2022g, base system (pkg which → not in database) — matches the zic 2022g code identity.
      • FreeBSD's tzdata.zi: 107682 bytes, sha256 e033045c…, header # version 2026b (zishrink form) — the actual 2026b source FreeBSD ships, kept so the same source can be compiled by zic-rs offline.
      • ZIC_BLOAT_DEFAULT = slim (measured empirically): for every sample zone, zic -d default output is byte-size-identical to zic -b slim and smaller than -b fat (e.g. America/New_York 1744 default = 1744 slim, 3552 fat). So FreeBSD base zic defaults to slim (zic-rs defaults to fat — a default-emission divergence, not a behaviour one). default/slim/fat compiles of 6 zones are in zone-ecology/{default,slim,fat}/.
      • zdump semantic oracle viable on real installed zones: installed America/New_York renders the 1918 EST gmtoff=-18000EDT gmtoff=-14400 transitions correctly (zdump-semantic-installed.txt); (gmtime failed) only at time_t INT64 extremes (so time_t is signed 64-bit, observed). This means a semantic-witness FreeBSD row is possible later — stated as viable, not yet claimed.
  • omnios_illumos_x86_64 receipt — REAL, produced + admitted (T16.5b.2; a Solaris-family lineage, not BSD). OmniOS r151058 (illumos, SunOS 5.11, amd64) base /usr/sbin/zic (tzcode 2025a, sha256 5c9c5e8a…, not stripped) ran the corpus under QEMU/KVM; vendor-oracle-admitadmitted (exit 0). Booting needed UEFI (OVMF) + q35 (legacy BIOS handed the kernel a memory map it page-faulted on); transport was curl both ways (illumos base has no nc). Receipt: 4/5 class_location_match + 1 declared divergence — same continuation_without_zone pattern (illumos generic "input line of unknown type" vs zic-rs's finer ZIC014, both line 1); the 3 extended T14 fixtures also match (ZIC021/ZIC017/ZIC022). Evidence + full-context bundles in logs/omnios_illumos_x86_64/ (host-received sha 9e183af7… / e5bec744…).

    • Both provenance fields proven via pkg(1) (no guessing): zic and zdump are delivered by pkg:/SUNWcs@0.5.11-151058.0 (the OmniOS core OS package — patch_stack_identity), and the data is system/data/zoneinfo@2026.1 (tzdb_source_release = omnios-zoneinfo-2026.1).
    • Code/data split pinned precisely (sharper than FreeBSD's): zic/zdump code = tzcode 2025a (SUNWcs), data = 2026.1 (system/data/zoneinfo) — two different release lines inside one OS, both measured by package version.
    • /usr/share/lib/zoneinfo is the zoneinfo path (Solaris layout; no tzdata.zi source shipped — proven by find); installed UTC/New_York TZif are byte-identical to FreeBSD's (8b858467…/e9ed07d7…).
    • ZIC_BLOAT_DEFAULT = slim (default == slim < fat; zic -b supported). Cross-platform: illumos zic 2025a on the upstream 2026b tzdata.ziAmerica/New_York fat e9ed07d7… byte-identical to the reference/installed fat build (logs/omnios_illumos_x86_64/full-context/). illumos zic also emits a Solaris-specific …use tzsetup abbreviation warning (an ecology fingerprint).
    • zdump semantic viability NOT claimed (honest non-result): illumos zdump given a file path rendered every zone as GMT gmtoff=0 (even UTC and the byte-identical-to-FreeBSD New_York), unlike FreeBSD/GNU zdump on the same bytes — it likely expects a zone-name argument (TZDIR lookup), not a path. So an illumos semantic-witness row is not established (would need re-invocation by zonename).
  • openbsd_79_x86_64 receipt — REAL, produced + admitted (T16.5b.3; the most divergent vendor — a conservative/older userland). OpenBSD 7.9/amd64 base /usr/sbin/zic (sha256 2c6865f0…) ran the corpus → vendor-oracle-admitadmitted (exit 0). No ready image exists, so this was a fresh install from the official install79.iso (whole-ISO sha256 verified 7a4a92e9…) in a graphical QEMU window; transport used nc (OpenBSD base ships nc + ftp-as-HTTP-client). Evidence in logs/openbsd_79_x86_64/ (host-received sha c69bd5e9… / 6f412ffa…).

    • Receipt: 3/5 class_location_match + 2 declared divergences (still all reject; coarser/older classes): duplicate_zone/field_count/unknown_line_type match (ZIC015/ZIC002/ZIC013); continuation_without_zone → generic "input line of unknown type" vs ZIC014; nul_byte → "line too long" (no NUL-specific class) vs ZIC016. (Extended: missing_final_newline also → "line too long" vs ZIC021; only overlong_line→"line too long" and unterminated_quote→"Odd number of quotation marks" match among the T14 extras.) The older OpenBSD lexer folds NUL/unterminated-line into "line too long".
    • Old OpenBSD zic fork: no --version (zic_version_output: unavailable), no -b (no slim/fat — pre-2020a; bloat-default N/A), no -r/-R. Owned by the base set (OpenBSD has no package manager for base) → patch_stack_identity = openbsd_base_7.9.
    • tzdb_source_release MEASURED = openbsd-2023cgtz: OpenBSD ships tzdata.zi (+ zone.tab + zone1970.tab) at /usr/share/zoneinfo, header # version 2023cgtz — a deeper data lag than FreeBSD (2026b) / OmniOS (2026.1), with OpenBSD's gtz variant tag. Installed UTC/New_York/London hashes (ab1ddb33…/1e786d11…/14ef0667…) all differ from FreeBSD/OmniOS (older zic, traditional encoding).
    • zdump IS a viable semantic oracle here (unlike illumos): installed America/New_York renders correct LMT→EST 1883 and EST↔EDT 1918–1924 transitions via file path (zdump-semantic.txt) — older output format (= NULL at time_t extremes, no gmtoff= field, abbrev+isdst only), but semantically usable.
  • netbsd_101_x86_64 receipt — REAL, produced + admitted (T16.5b.4; the cleanest BSD — modern upstream tzcode). NetBSD 10.1/amd64 base /usr/sbin/zic (tzcode 2022g, same code line as FreeBSD, sha256 eae7ef6f…) → vendor-oracle-admitadmitted (exit 0). Ran from the official live image (NetBSD-10.1-amd64-live.img.gz, SHA512-verified a801ca62…) — no install needed; -cpu host + BIOS booted fine; transport nc (NetBSD ships nc+ftp). Evidence in logs/netbsd_101_x86_64/ (host-received sha 6e2268ba… / 71371be3…).

    • Receipt: 4/5 class_location_match + 1 declared divergence — only the universal continuation_without_zone (generic "input line of unknown type" vs ZIC014). Unlike OpenBSD, NetBSD's modern lexer has the dedicated classes: nul_byte → "NUL input byte" (= ZIC016 ✓) and missing_final_newline → "unterminated line" (= ZIC021 ✓); all 3 T14 extras match.
    • ZIC_BLOAT_DEFAULT = slim (default == slim < fat; zic -b supported); base-set ownership (patch_stack_identity = netbsd_base_10.1).
    • tzdb_source_release = 2026b-byte-witnessed: NetBSD ships no tzdata.zi (no header to read), but for all 6 sample zones the installed TZif is byte-identical to NetBSD-zic's own slim compile of the verified upstream 2026b tzdata.zi (logs/netbsd_101_x86_64/full-context/cross-platform-2026b.txt) — so the data release is proven 2026b by byte-witness, not header. Cross-version nuance: the fat outputs match OmniOS's (e.g. New_York e9ed07d7, London c8549507) but slim London differs (bb29fb3b vs OmniOS's 676541f0 — minor slim-encoding evolution between tzcode 2022g and 2025a), while slim New_York matches; fat is the stable-across-versions form.
    • zdump semantic-viable (file path; LMT→EST 1883, EST/EDT 1918–1920 correct, gmtoff= present).
  • dragonfly_642_x86_64 receipt — REAL, produced + admitted (T16.5b.5; the OLDEST zic fork of the set — completes the BSD-family sweep). DragonFly 6.4.2/amd64 base /usr/sbin/zic (sha256 5156168d…) → admitted (exit 0). Ran from the official live .img (MD5-verified d321c363… — MD5 is the only checksum DragonFly publishes, noted honestly); nc+fetch transport (needed dhclient em0 first — the live shell doesn't auto-config the NIC). Evidence in logs/dragonfly_642_x86_64/ (host-received sha bcaebbdd… / 8f4701ce…).

    • Oldest fork of all vendors: zic usage shows -y yearistype — a feature removed from upstream tzcode ~2015 — plus no -b/-r/--version (zic_version_output: unavailable). Pairs with OpenBSD in the "old-fork" tier. Base-set ownership (patch_stack_identity = dragonfly_base_6.4).
    • Receipt: 3/5 class_location_match + 2 declared divergences (like OpenBSD): continuation_without_zone (generic) and nul_byte → "line too long" (no NUL class; missing_final_newline also → "line too long"). The old lexer folds NUL/unterminated-line into "line too long".
    • Ships only zone.tab (no tzdata.zi, no zone1970.tab) → tzdb_source_release: unknown_unmeasured; bloat-default N/A (no -b). Installed UTC hash ab1ddb33 is identical to OpenBSD's (both old forks → same traditional UTC bytes); New_York/London differ from all others.
    • Input-compatibility GAP with upstream (the sharpest finding): DragonFly's zic cannot compile the modern 2026b tzdata.zi at all (modern_2026b_compile_exit=1) — it rejects the zishrink short forms with "invalid weekday name" (Su) and "invalid day of month" (logs/dragonfly_642_x86_64/full-context/ modern-source-compile.txt). The fork predates zishrink, so it can only ingest the expanded source files, not current IANA's distributed compressed tzdata.zi. zdump is still semantic-viable on installed zones.
  • smartos_20260528_x86_64 receipt — REAL, produced + admitted (T16.5b.6; illumos family, 2nd member). SmartOS PI joyent_20260528T000227Z global zone /usr/sbin/zic (tzcode 2025a, sha256 2a76d28d…) → admitted (exit 0). SmartOS boots its platform image into RAM from the ISO (no install) — needed the interactive setup wizard (NIC=dhcp, gateway 10.0.2.2, zpool on a blank disk, root pw) to reach the global zone; UEFI(OVMF)+q35 (illumos -cpu host+BIOS #pf, as OmniOS). Combined single-pass harvest; transport curl (global zone has nc/curl/wget/ftp/bash/ksh). Evidence in logs/smartos_20260528_x86_64/ (host-received sha 413f57de…; ISO computed sha acc931e8… — no published checksum at the -latest URL).

    • The illumos-family answer (vs OmniOS): converge on behaviour+data, distinct builds. Same tzcode 2025a, same 4/5 class_location_match + 1 declared divergence (continuation_without_zone; the modern lexer has nul_byte=ZIC016 + unterminated line=ZIC021), same fat-2026b installed zoneinfo byte-identical to OmniOS (UTC/New_York/London = 8b858467/e9ed07d7/c8549507). But a different zic binary (2a76d28d… ≠ OmniOS 5c9c5e8a…) and a different PI/build — independently compiled. Kept a distinct receipt row (panel rule); illumos convergence is not Solaris-family proof.
    • ZIC_BLOAT_DEFAULT = slim (default == slim < fat; zic -b supported) — yet ships fat zoneinfo (same as OmniOS). patch_stack_identity = smartos_platform_joyent_20260528T000227Z (RAM platform image, no pkg manager in the global zone). tzdb_source_release = 2026b-byte-witnessed (no tzdata.zi/header, but SmartOS-zic's own fat compile of the verified upstream 2026b source reproduces the installed bytes for all 6 sample zones — compile-and-compare, not bytes-alone).
  • openindiana_hipster_20260430_x86_64 receipt — REAL, produced + admitted (T16.5b.7; illumos family, 3rd member — completes the illumos triad). OpenIndiana Hipster 2026.04 (illumos-gate commit illumos-4648b9b8c3) live /usr/sbin/zic (tzcode 2025a, sha256 bcd65498…) → admitted (exit 0). Booted the official text live ISO (OI-hipster-text-20260430.iso, sha256 5f2661ef… published+verified) via UEFI(OVMF)+q35; menu option 3 (Shell) → live root shell (no install); combined single-pass harvest; curl transport. Evidence in logs/openindiana_hipster_20260430_x86_64/ (host-received sha 619090fa…).

    • The illumos triad converges completely, on three independent builds. OmniOS · SmartOS · OpenIndiana all run tzcode 2025a, all 4/5 class_location_match + 1 divergence (continuation_without_zone), all ship byte-identical fat-2026b zoneinfo (8b858467/e9ed07d7/c8549507), all slim-default — yet each builds zic independently: three distinct binaries (5c9c5e8a / 2a76d28d / bcd65498) and three packaging models (OmniOS SUNWcs pkg · SmartOS RAM platform image · OpenIndiana IPS pkg). Three distinct receipt rows; illumos convergence ≠ Solaris-family proof.
    • tzdb_source_release header-grade from pkg (like OmniOS): system/data/zoneinfo@2026.1-2026.0.0.23029openindiana-zoneinfo-2026.1. patch_stack_identity = openindiana_hipster_2026.04_illumos-4648b9b8c3 (the illumos-gate commit; the live ISO's pkg search index is degraded, so the exact zic-owning pkg wasn't resolved — the OS+commit identity is recorded instead). Cross-compile confirms installed == OI-zic fat compile of upstream 2026b for all 6 zones.
  • alpine_3234_x86_64 receipt — REAL, produced + admitted (T16.5b.8; first Linux row, first musl/BusyBox, first vendor on current tzcode). Alpine 3.23.4 (alpine-virt, sha256 f8020333… published+verified) /usr/sbin/zic (tzcode 2026b, sha256 08d28b80…) → admitted (exit 0). Booted serial-console (-nographic, no UEFI); apk add tzdata-utils tzdata installs the tz tools+data; transport BusyBox wget (fetch) + nc (upload — no curl in base). Evidence in logs/alpine_3234_x86_64/ (host-received d90f02b6…).

    • First musl-linked zic: interpreter /lib/ld-musl-x86_64.so.1 — a distinct binary class from every glibc/BSD/illumos row. First vendor on upstream-current tzcode 2026b (all others lagged: BSD 2022g, OpenBSD 2023c, illumos 2025a) — Alpine tracks IANA tightly.
    • zic/zdump ship in the tzdata-utils apk, data in tzdata (tools split from data — a clean musl-distro packaging fact). apk info --who-owns /usr/sbin/zictzdata-utils-2026b-r0 (patch_stack_identity = alpine_3.23.4:tzdata-utils-2026b-r0_musl); tzdb_source_release pkg-grade 2026b.
    • 4/5 class_location_match + 1 declared divergence (only continuation_without_zone; nul_byte=ZIC016, unterminated line=ZIC021 present — newest tzcode). Key finding: musl libc does not change zic's diagnostic behaviour — the tzcode version governs it, not the C library. ZIC_BLOAT_DEFAULT = slim; ships fat-2026b zoneinfo byte-identical to the illumos triad (8b858467/e9ed07d7/c8549507).
  • debian_13_x86_64 receipt — REAL, produced + admitted (T16.5b.9; glibc reference distro — reveals a SECOND zic lineage). Debian 13 (trixie) nocloud /usr/sbin/zic (glibc-linked, sha256 b8f99e54…) → admitted (exit 0). Booted the nocloud qcow2 (sha256 703a87c4…, SHA512 published+verified) — auto-login root on serial (-nographic), no cloud-init; combined single-pass harvest; curl transport. Evidence in logs/debian_13_x86_64/ (host-received 7a9f6ff2…).

    • The two-lineage finding (the campaign's deepest structural result): Debian's zic --versionzic (Debian GLIBC 2.41-12+deb13u3) 2.41 — it is glibc's OWN zic (glibc ships timezone/zic, version-stamped as the glibc release), owned by libc-binnot IANA tzcode zic. So the "system zic" splits into two implementation lineages: tzcode zic (BSD · illumos · Alpine via tzdata-utils) vs glibc zic (Debian, and downstream Ubuntu/RHEL/glibc). A third packaging model too (libc-bin, the essential glibc utilities pkg → zic is always preinstalled).
    • Behaviourally identical, version-labelled differently: glibc-zic gives the same 4/5 class_location_match + 1 divergence (continuation_without_zone; nul_byte=ZIC016, unterminated line=ZIC021) and byte-identical output (slim Test/NY 33a56128… == Alpine/illumos; fat New_York e9ed07d7 == reference) — glibc imports tzcode, so behaviour matches; only the version label differs. tzdb_source_release = debian-tzdata-2026b-0+deb13u1 (pkg-grade + ships tzdata.zi); slim bloat-default; fat-2026b zoneinfo byte-identical to the others.
  • nixos_2511_x86_64 receipt — REAL, produced + admitted (T16.5b.10; content-addressed store — the glibc lineage from a third distro, and a different zic locator entirely). NixOS 25.11 (BUILD_ID 25.11.11422.25f538306313, kernel 6.12.91, nix 2.31.5) → admitted (exit 0). Booted the minimal ISO (sha256 04de791f…) live; resolved zic from the Nix store (no FHS /usr/sbin/zic exists) via nix-shell -p tzdata --run 'command -v zic'; combined single-pass harvest; curl transport. Evidence in logs/nixos/.

    • The locator is a content-addressed store path, not a filesystem path — the distinguishing NixOS fact: ZIC = /nix/store/6s5jp0cchd4jjq474xkfymj18l6i5x95-glibc-2.40-224-bin/bin/zic (sha256 a8b2741d…). nix-store -q --deriver returned unknown-deriver (the path was substituted from a binary cache, no local .drv), so patch_stack_identity is keyed on the store-path hash, not a deriver — recorded honestly, never guessed.
    • Third glibc-lineage data point (reconfirms the two-lineage finding): nix-shell -p tzdata resolves zic to glibc's own ziczic (GNU libc) 2.40, from the glibc-…-bin output — not a separate IANA tzcode build. So on NixOS the tzdata attribute's compiler is the glibc zic lineage (like Debian), a distinct binary (glibc-2.40-224 here vs Debian's glibc-2.41).
    • Behaviourally convergent, byte-identical output: same 4/5 class_location_match + 1 divergence (continuation_without_zone; nul_byte=ZIC016 "NUL input byte", unterminated line=ZIC021, odd-quote=ZIC022, overlong=ZIC017 — fully modern, all 8 fixtures rejected). zic -b supported, defaults slim; slim Test/NY 33a56128… is byte-identical to Debian/Alpine/illumos, fat-2026b New_York e9ed07d7/London c8549507/UTC 8b858467 byte-identical to the whole matrix — glibc-2.40 zic (a different glibc than Debian's 2.41) produces the same bytes as tzcode.
    • Data lags the compiler's reach by one release: the installed store zoneinfo is tzdata-2026a (/nix/store/…-tzdata-2026a), so tzdb_source_release = nixpkgs-tzdata-2026a (pkg-grade via the store path) — NixOS 25.11 ships 2026a, one IANA release behind upstream 2026b. A genuine witness fell out of it: this zic fat-recompiling upstream 2026b produced output byte-identical to the installed 2026a for all six sampled zones → 2026a == 2026b for those zones (the 2026b delta did not touch them). zdump is semantic-viable here (real EST/EDT transitions on compiled Test/NY), unlike the illumos triad.
  • ubuntu_2404_x86_64 receipt — REAL, produced + admitted (T16.5b.11; the glibc lineage is version-stratified — the campaign's second structural surprise). Ubuntu 24.04.4 LTS (Noble Numbat, cloud-image serial 20260518) /usr/sbin/zicadmitted (exit 0). Fully autorun: booted the verified cloud image (sha256 53fdde89…, published+verified) behind an 8G overlay + a NoCloud cloud-init seed whose runcmd fetched and ran ubuntu-harvest.sh and uploaded the evidence with zero operator keystrokes — Ubuntu's cloud-init is the reference implementation, so runcmd works (the capability FreeBSD's nuageinit lacked). Evidence in logs/ubuntu/.

    • Fourth glibc-lineage data point, third distinct glibc: zic (Ubuntu GLIBC 2.39-0ubuntu8.7) 2.39, owned by libc-bin (like Debian), sha256 2e508bff… — glibc-zic, a distinct binary (glibc 2.39 vs Debian 2.41 vs NixOS 2.40).
    • THE FINDING — glibc-zic is not monolithic; it tracks the tzcode glibc bundled at its release. Ubuntu's glibc 2.39 gives 3/5 class_location_match + 2 divergencescontinuation_without_zone and nul_byte → "line too long" (no NUL-specific class), landing it in the old-fork-like tier (OpenBSD/DragonFly) — yet it is modern glibc, not a fork: its bundled tzcode simply predates the "NUL input byte" message that Debian's glibc 2.41 emits. So the glibc lineage splits by glibc version: 2.39 = 3/5+2 (no NUL class), 2.41 = 4/5+1 (NUL class present). (Extended fixtures confirm the older tier: missing_final_newline → "line too long" too, and overlong_line was accepted (exit 0) — a higher/absent comment-line cap.)
    • Older bloat default + slim encoding, too: zic -b supported but defaults FAT (default == -b fat == eaa570ae…), where Debian/NixOS default slim — and its slim Test/NY 39122698… differs from the Debian/NixOS slim 33a56128… (slim encoding evolved across tzcode versions; fat is the stable formeaa570ae matches across all glibc rows). So glibc 2.39 differs from 2.41 on both diagnostics and bloat default.
    • Data + convergence as expected: ships tzdata.zi + zone.tab + zone1970.tab; tzdb_source_release = ubuntu-tzdata-2026a-0ubuntu0.24.04.1 (pkg-grade, 2026a — one release behind upstream, same lag as NixOS); installed zoneinfo is fat and byte-identical to the matrix (8b858467/e9ed07d7/c8549507); fat-recompiling upstream 2026b == installed 2026a for all six zones (2026a == 2026b witnessed again); zdump semantic-viable (correct EST/EDT).
  • almalinux_9_x86_64 receipt — REAL, produced + admitted (T16.5b.12; the enterprise RPM glibc row that brackets the version-stratification transition). AlmaLinux 9.8 (Olive Jaguar, kernel 5.14.0-687.5.3.el9_8) /usr/sbin/zicadmitted (exit 0). Fully autorun (cloud-init runcmd, zero keystrokes) behind a verified qcow2 (sha256 c397eed7…, published+verified) + 10G overlay. Boot note: RHEL 9 / Alma 9 mandates x86-64-v2, so QEMU's default qemu64 CPU SIGILL'd PID 1 → "Attempted to kill init!" kernel panic; fixed with -cpu host (the only row needing it on the Linux side — Ubuntu/Debian target baseline x86-64-v1). Evidence in logs/almalinux/.

    • Fifth glibc-lineage data point, fourth distinct glibc — the oldest in the matrix: zic (GNU libc) 2.34, owned by glibc-common-2.34-266.el9_8 (RPM's analogue of Debian's libc-bin), sha256 c82bc5c9….
    • It confirms the old tier and brackets the transition. glibc 2.34 is **3/5 class_location_match
      • 2 divergences** — continuation_without_zone and nul_byte → "line too long" (no NUL class) — plus fat default (default == -b fat == eaa570ae…; slim == 39122698…, the same older slim encoding as Ubuntu). I.e. an identical behaviour profile to Ubuntu's glibc 2.39, on an even older glibc (extended fixtures match too: missing_final_newline → "line too long", overlong_line accepted). So the glibc-zic matrix is now: 2.34 (Alma 9.8) = 2.39 (Ubuntu 24.04) → old-fork-like · fat, while 2.40 (NixOS) = 2.41 (Debian) → modern · slim — the behavioural inflection (NUL class arrives, default flips to slim) sits between glibc 2.39 and 2.40, i.e. glibc imported the newer tzcode at 2.40.
    • Data + convergence as expected: ships tzdata.zi + zone.tab + zone1970.tab; tzdb_source_release = almalinux-tzdata-2026a-1.el9 (rpm-grade, 2026a — one release behind upstream); installed zoneinfo is fat, byte-identical to the matrix (8b858467/e9ed07d7/c8549507); fat-recompiling upstream 2026b == installed 2026a for all six zones (2026a == 2026b witnessed again); glibc-2.34 zic compiles the modern zishrink tzdata.zi fine (no input-compat gap); zdump semantic-viable (correct EST/EDT).
  • gentoo_20260531_x86_64 receipt — REAL, produced + admitted (T16.5b.13; the source-built ecology row — proves lineage is a distro packaging choice and bloat-default is its own packaging axis). Gentoo (base system 2.18, minimal install CD 20260531T160106Z) /usr/bin/zicadmitted (exit 0). Operator-run (minimal CD has no cloud-init → boots to a root shell): verified ISO (sha256 88e6136d…, published+verified, PGP-signed list), -cpu host, fetched + ran the harvest by hand, self-uploaded. Evidence in logs/gentoo/.

    • THE FINDING — a source distro picks the tzcode lineage, not glibc's: zic (tzcode) 2026a, owned by sys-libs/timezone-data-2026a (qfile-confirmed), sha256 9c6c3ccd… — the standalone IANA tzcode zic, not glibc's. And this despite glibc 2.42 being installed (the newest glibc in the whole matrix). So the zic lineage is a distribution packaging decision, independent of which libc is present: Debian/Ubuntu/RHEL ship glibc's zic (libc-bin/glibc-common); Gentoo ships tzcode's zic (timezone-data); Alpine ships tzcode's via tzdata-utils. glibc version ≠ zic lineage — Gentoo has the newest glibc yet runs a tzcode zic.
    • Modern diagnostic tier (4/5 + 1): tzcode 2026a has the NUL class — nul_byte"NUL input byte" (matches ZIC016); only continuation_without_zone diverges; all 8 fixtures rejected, every extended fixture matches (missing_final_newline→"unterminated line", overlong_line→"line too long" rejected, odd-quote→"Odd number of quotation marks"). Same tier as Alpine (tzcode 2026b) and the modern glibc rows.
    • Bloat-default is a packaging axis, not lineage/version-locked: Gentoo's timezone-data zic defaults FAT (default == -b fat == eaa570ae…), while Alpine's tzcode and the modern glibc rows default slim — yet its slim encoding is the modern 33a56128… (== Debian/NixOS). So the bloat default is chosen by the packager (Gentoo's ebuild), independent of the diagnostic tier — fat-default now appears in both the old-glibc builds (2.34/2.39) and a modern tzcode build (Gentoo), confirming it is its own axis.
    • Honest scope: the minimal CD ships the timezone-data tools but an essentially empty installed /usr/share/zoneinfo (no populated tree, no tzdata.zi/zone.tab), so tzdb_source_release = gentoo-timezone-data-2026a is package-grade (the sys-libs/timezone-data-2026a version), not byte-witnessed against an installed tree. The compiler itself is normal: it compiles the served upstream 2026b tzdata.zi fine, fat output byte-identical to the matrix (8b858467/e9ed07d7/c8549507); zdump semantic-viable (correct EST/EDT). Both code and data sit at tzcode/tzdata 2026a (one behind upstream).
  • opensuse_leap_16_x86_64 receipt — REAL, produced + admitted (T16.5b.14; the SUSE cross-check — proves RPM ≠ glibc-zic). openSUSE Leap 16.0 (SLES-16-based) /usr/sbin/zicadmitted (exit 0). Fully autorun (cloud-init runcmd, zero keystrokes) behind a verified qcow2 (sha256 6c3b6b2d…, published+verified) + 8G overlay, -cpu host. Evidence in logs/opensuse/.

    • THE CROSS-CHECK — RPM does not imply glibc-zic: SUSE ships the tzcode zic via the timezone RPM (zic (tzcode) 2025b, owned by timezone-2025b-160000.2.2, sha256 e05234e4…) — not glibc's zic, even though glibc 2.40 is installed. So the lineage splits within the RPM world by distro packaging policy: AlmaLinux/RHEL = glibc-zic (glibc-common) · openSUSE = tzcode-zic (timezone). Do not infer lineage from package format — lineage_selection_source = timezone_data_package here vs Alma's libc_package. A fourth packaging model for the tzcode lineage (SUSE timezone RPM), alongside Gentoo sys-libs/timezone-data, Alpine tzdata-utils, and BSD/illumos base.
    • Modern diagnostic tier (4/5 + 1), a new tzcode version (2025b): nul_byte"NUL input byte" matches ZIC016; only continuation_without_zone diverges; all 8 fixtures rejected, every extended fixture matches. tzcode 2025b slots into the lag spectrum between illumos 2025a and Gentoo/upstream 2026a/b. glibc 2.40 is present but unused for zic.
    • Slim default — reconfirms bloat-default is packaging-chosen, not lineage-locked: SUSE's timezone zic defaults slim (default==slim==33a56128), like Alpine's tzcode, unlike Gentoo's tzcode (fat). So two tzcode distros default slim (Alpine, openSUSE) and one defaults fat (Gentoo) — the packager decides.
    • Data + convergence as expected: ships tzdata.zi + zone.tab + zone1970.tab; the timezone RPM carries both tools and data at 2025b, so tzdb_source_release = opensuse-timezone-2025b-160000.2.2 (rpm-grade, code+data unified at 2025b); installed zoneinfo is fat and byte-identical to the matrix (8b858467/e9ed07d7/c8549507) — the 2025b data byte-matches a fat-2026b recompile for the six sampled zones (no change there across 2025b→2026b); zdump semantic-viable (correct EST/EDT).
  • Yocto/Poky — TWO receipts, producer vs consumer (T16.5b.15; the embedded build-system ecology). Not a "boot a VM and run zic" row — Yocto is a build system, so the build-host producer and the target consumer are captured as two distinct receipts, never collapsed. Evidence in logs/poky/.

    • yocto_poky_buildhost_native_zic_x86_64 — admitted. OE-core (master, recipes-extended/timezone) builds tzcode-native from a recipe-pinned tzcode 2026b — the zic that compiles the target's TZif. I fetched + sha-verified both tarballs against the live recipe SRC_URI (tzcode 37e9ed84… + tzdata 114543d9…), built zic/zdump per the recipe (inherit native; make CC=gcc), and ran the corpus → zic (tzcode) 2026b, 4/5 + 1 (modern; nul_byte→"NUL input byte"), slim default, compiles upstream 2026b matrix-identical. Provenance, stated plainly: behaviour is version-authentic for tzcode 2026b (version governs zic behaviour); the source is the exact recipe-pinned pair (sha-verified); the binary is lab-built per the recipe's compile step — NOT extracted from a bitbake tmp/work (a full bitbake would emit the same tzcode-2026b behaviour with a different gcc/sha). Run in-lab (no QEMU).
    • yocto_poky_target_runtime_x86_64 — typed non-admission (recipe-derived). tzcode is inherit native (host-only, never installed to the target); the tzdata recipe installs only precompiled zoneinfo to the target → a produced core-image-* is a TZif consumer with no on-device zicplatform_status=unavailablenot_admitted_platform_not_admissible (exit 1). Basis = OE-core recipe design (authoritative), explicitly labelled not a booted-image measurement (VM-confirm available).
    • Finding: the embedded build-host producer ≠ target-runtime consumer — Poky shows both sides of one pipeline in a single ecology.
  • sles_15sp7_x86_64 receipt — REAL, produced + admitted (T16.5b.16; the commercial SUSE cross-check; first container-harvested row). SUSE Linux Enterprise Server 15-SP7 (cpe:/o:suse:sles:15:sp7) /usr/sbin/zicadmitted (exit 0). Harvested from the SUSE BCI base container (registry.suse.com/bci/bci-base, config sha256 9b036947…) via podman --network=none — BCI = SUSE's freely-redistributable SLE base (built from SLES sources, no subscription needed), the legitimate way to a genuine SLES zic without a paid key. The campaign's first container harvest (vs a QEMU VM). Evidence in logs/sles/.

    • Commercial SLES = the free openSUSE Leap ecology — same zic, distinct binary. zic (tzcode) 2025b, owned by timezone-2025b-150600.91.6.2 (the SLE-15-SP6/7 150600 codestream), sha256 d349812b… — the same tzcode-zic-via-timezone-RPM lineage as openSUSE Leap 16.0, with the same tzcode 2025b, 4/5 + 1 (modern; nul_byte→"NUL input byte"; overlong→"line too long"), and slim default (default==slim==33a56128). Distinct binary from Leap (d349812b ≠ Leap's e05234e4; codestream 150600 vs Leap's 160000) — independently built, behaviourally convergent (the Debian↔NixOS↔Ubuntu / illumos-triad pattern, now for paid↔free SUSE). glibc here is 2.38 (vs Leap's 2.40) — irrelevant, since zic is from timezone, not glibc.
    • Data + convergence: ships tzdata.zi + zone.tab; installed zoneinfo is fat, byte-identical to the matrix (8b858467/e9ed07d7/c8549507); compiles served upstream 2026b (slim NY d7f2206b/London 676541f0/UTC fddce1e6, matrix-identical); tzdb_source_release = sles-timezone-2025b-150600.91.6.2 (rpm-grade); zdump semantic-viable (tzcode-2025b lineage). The paid enterprise product confirms the free distro's zic ecology — no surprises behind the subscription wall.

About

External QEMU/vendor-oracle evidence lab for zic-rs cross-platform zic/zdump receipts and VM lineage data.

Topics

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors