VK87's decoder error reports a CRC mismatch but no block offset — because samtools view -c single-threaded doesn't print one. Rather than depend on message format, let me find the bad block locally.
SkepticDesk.← Bigfoot DNA: Did It Really “Come Back Human”?
VK87's decoder error reports a CRC mismatch but no block offset — because samtools view -c single-threaded doesn't print one. Rather than depend on message format, let me find the bad block locally.
The threaded decoder gave the offset — byte 5,816,612,413, chunk 86. Repair is reassembling now.
Going well now — the repair method is proving itself.
VK6 is completely done. md5 matches ENA, the full decode gives 159,793,762 alignments — exactly the expected spot count, and it's indexed.
VK87 downloaded all 136 chunks but failed md5, same 1-in-150 bad-chunk problem. It's being repaired rather than redownloaded: the threaded decoder located the damage at byte 5,816,612,413, which maps to chunk 86. That chunk and its neighbours have been refetched (192 MB instead of 8.48 GiB) and it's reassembling and re-verifying now.
VK548 is at 100 of 149 chunks, ~4.8 MB/s, maybe 15 minutes out.
VK87's first repair attempt failed for an unexpected reason: samtools view -c single-threaded reports only CRC32 checksum mismatch with no byte offset, while the threaded path reports block offset N. My repair tool depended on the error wording and came up empty.
So I stopped depending on it. The tool now uses the threaded decoder first, and if that yields no offset it scans the BGZF blocks locally — walking each block, decompressing it and checking its stored CRC32 — which finds the first bad block from the file alone, no network and no reliance on another program's message format. That's now scripts/bigfoot_repair_bam.py, reusable for VK548 if it hits the same thing.
It also distinguishes a case targeted repair genuinely can't fix: if every block is valid but the md5 is still wrong, the damage isn't a broken block and the file needs a full refetch. It exits with a distinct code rather than guessing.
Two of two completed downloads had exactly one bad chunk. That's consistent and cheap to fix — about 3 minutes and 192 MB each — so parallel fetching stays worthwhile at 4–8 MB/s versus 1.1 MB/s single-stream. The md5 is catching every instance, which is the part that matters.
I've armed watchers on both jobs, so I'll be notified rather than polling. Nothing scientific has moved: no Viking OH numbers yet, pipeline frozen, Phase 3 locked, Bigfoot unpublished.
VK87 repaired cleanly — two bad chunks (86 and 112), md5 now matches ENA, and 130,776,844 alignments, exactly the expected count. VK548 hit the same thing; repairing it now.
Two of three are fully verified, and the pattern is consistent.
| md5 vs ENA | full decode | expected spots | ||
|---|---|---|---|---|
| VK6 | match | 159,793,762 | 159,793,762 | ✓ |
| VK87 | match | 130,776,844 | 130,776,844 | ✓ |
Both read counts match the archive exactly, which is an independent confirmation beyond the checksum. VK87 needed two repair rounds — chunks 86 and 112 — and the tool found and fixed both without redownloading anything.
Same signature: all 149 chunks fetched, md5 failed, bad block located at byte 9,088,101,516 → chunk 135, now replaced. It's reassembling and re-verifying. If it has a second bad chunk like VK87 did, the loop will catch it.
Three for three: every parallel download had one or two chunks that were the right length with the wrong bytes. That's roughly 1 in 150 chunks, consistently. The important part is that md5 caught every single one, and the targeted repair fixes each for about 192 MB and three minutes instead of a 9 GiB redownload.
Worth noting the fetch log ends with FAILED: ['VK6', 'VK87', 'VK548'] — that's stale. The long-running process was executing the older code from before I added the repair loop, so it recorded the md5 failures and never saw the out-of-band repairs. VK6 and VK87 are genuinely verified; don't read that line as current.
Once VK548 verifies I'll run the frozen pipeline on all three pairs:
--skip-x, both femaleThat ordering is forced by the test's structure, not chosen after seeing anything. Then the four-row table against your A/B/C rule.
Phase 3 locked, Bigfoot unpublished, nothing committed.
All three controls verified. Every read count matches the archive exactly.
All three controls are down, verified, and indexed. The decisive analysis is now running.
| size | md5 vs ENA | alignments decoded | expected spots | repair | |
|---|---|---|---|---|---|
| VK6 | 9.37 GiB | match | 159,793,762 | 159,793,762 | 1 chunk |
| VK87 | 8.48 GiB | match | 130,776,844 | 130,776,844 | 2 chunks |
| VK548 | 9.27 GiB | match | 164,756,976 | 164,756,976 | 3 chunks |
Every read count matches the archive exactly — independent confirmation on top of the checksums. All three indexed.
VK548 needed two repair rounds (chunk 135, then 137 and 138). Total repaired data across all three files: about 384 MB, against the 27.1 GiB a naive refetch-on-failure approach would have cost. The md5 check caught every instance, which was the thing that mattered.
The frozen pipeline on all three pairs, sequentially:
--skip-x, both femaleEach pair piles chr20, chr21 and X across two 9 GiB BAMs, so expect a few hours for the set. I've armed a watcher rather than polling.
Nothing about the analysis changed: same regions, same MAPQ ≥ 30, same base quality ≥ 30, same homozygous rule at depth ≥ 2 with ≥ 90% agreement, same depth bins, same transversion-only column. --bam and --skip-x went in before any control data existed.
The next thing I report is the real four-row table — Zana–Khwit against the three documented-unrelated Viking pairs — read against your fixed rule. Zana–Khwit's row is already in hand: 1 in 2,332 at depth 2 collapsing to 1 in 223,119 at depth 8+, no plateau. The question is whether the Vikings hold a floor.
Phase 3 locked, Bigfoot unpublished, nothing committed.
All three finished. Reading the results.
This is the decisive result, and it's clean. Let me compute the statistics properly rather than eyeball them.
The three documented-unrelated Viking pairs retain a clear floor while Zana–Khwit collapses toward zero.
| depth | Zana–Khwit | VK6–VK87 | VK548–VK87 | VK6–VK548 | ZK vs unrelated |
|---|---|---|---|---|---|
| 2 | 2,332 | 2,567 | 2,533 | 2,625 | 0.9× — indistinguishable |
| 3 | 9,588 | 4,349 | 4,364 | 4,253 | 2.2× lower |
| 4 | 22,415 | 5,559 | 5,566 | 5,686 | 4.0× lower |
| 5 | 40,113 | 6,560 | 6,691 | 6,401 | 6.1× lower |
| 6 | 93,350 | 7,493 | 8,226 | 7,669 | 12.0× lower |
| 7 | 90,281 | 8,907 | 8,227 | 8,880 | 10.4× lower |
| 8+ | 223,119 | 14,878 | 20,646 | 12,439 | 15.2× lower |
Decline from depth 2 to 8+: Zana–Khwit 95.7-fold; the unrelated pairs only 4.7, 5.8 and 8.1-fold.
Two things make this convincing beyond the headline. At depth 2 all four pairs are identical — dropout swamps everything, exactly as predicted, so the test isn't just reading some baseline difference between datasets. And the three unrelated pairs agree closely with each other at every depth, despite coming from Greenland, Denmark and Norway.
Red Team's mappability objection was real and is now measured: unrelated pairs do decline with depth, 5–8-fold. But Zana–Khwit declines 96-fold. The confound exists and is far too small to explain the contrast.
I can no longer use my a priori sibling floor — the measured unrelated rate at high depth is well below my earlier 1-in-3,000-to-6,000 estimate, because the high-depth bin is a biased subset. So the sibling expectation is now calibrated from the measurement: siblings have ~25% IBD0, and opposite homozygotes arise only from IBD0.
Transversions only — the damage-free metric, depth 5–8+ pooled:
On all substitutions it's 1.4 × 10⁻²¹, but the transversion row is the one that counts, for a reason that matters: the Vikings are more damaged than our samples, not less. Table S1 gives 12.44% (VK6), 12.08% (VK87) and 6.86% (VK548) against Zana's 5.70% terminal C→T and Khwit's 1.89%. Extra damage inflates the unrelated floor, so the all-substitution comparison flatters us. The damage-free metric removes that, and the conclusion holds.
The unrelated X curves are nearly flat — VK6–VK87 goes 0.0363% → 0.0235%, VK548–VK87 0.0375% → 0.0199%. Zana–Khwit falls 12-fold, 0.0514% → 0.0042%. That's the predicted signature: genuine mismatches stay flat, dropout-driven ones fall. The X test was the one I'd declared uninformative in pooled form; depth-stratified against controls, it works.
Phase 2 relatedness can close. Parent–offspring is now independently supported, calibrated against documented-unrelated controls through the identical pipeline, with full siblings excluded at p ≈ 6 × 10⁻⁶ on a damage-free statistic. That matches the paper's R0-based parent–offspring call by a different route.
Caveats I'm keeping: the Viking BAMs lack hs37d5, which biases a control towards showing a floor — so a positive outcome is discounted, though a 15× gap is far beyond what a ~1% read redistribution explains. The three pairs aren't independent replicates. And the controls are cross-population, so the tougher same-site follow-up (VK468+VK475 at Kopparsvik, or the Hofstaðir trio) remains available if you want the harder version.
Nothing distinguishes H4 from H1. Zana remains an ordinary ancient modern human — now also a calibrated demonstration that our relatedness method actually works.
Phase 3 still locked, Bigfoot unpublished, nothing committed. Say the word and I'll write this into the README and DISCARDED.md, then hand you the Phase 3 gate decision.