Predictions sealed before the fact: every fingerprint is public and time-stamped on Bitcoin, so none can be quietly dropped or edited. Texts are revealed and scored later.
P.length===0?html`<p><em>Nothing sealed yet.</em> The first predictions will appear here as fingerprints the day they are written; their text follows when they are revealed.</p>`:html`<div class="table-responsive"><table class="table table-sm"><thead><tr><th>ID</th><th>Sealed</th><th>SHA-256 fingerprint</th><th>Proof</th><th>Status</th></tr></thead><tbody>${P.map((p) =>html`<tr> <td>${p.id}${p.title?html`<div class="small text-muted">${p.title}</div>`:""}</td> <td>${fmt(p.date)}${p.resolves_by?html`<div class="small text-muted">resolves by ${fmt(p.resolves_by)}</div>`:""}</td> <td><code style="word-break: break-all">${p.sha256}</code></td> <td><a href="data/ots/${p.id}.ots" download>${p.id}.ots</a>${p.ots_complete?"":html`<div class="small text-muted">awaiting Bitcoin</div>`}</td> <td>${p.status==="sealed"? (p.resolves_by&&newDate(p.resolves_by) <newDate() ?html`<strong>overdue</strong>`:"sealed") : p.resolved?html`<strong>${({true:"right",false:"wrong",partial:"partly right"})[p.resolved]}</strong>`:"revealed"}</td></tr>`)}</tbody></table></div>`
ots verify reports the Bitcoin block that commits to the fingerprint, which proves the text existed no later than that block’s time. (Full local verification needs a Bitcoin node; the website verifier doesn’t.)
Why every fingerprint is listed. Publishing only the predictions that came true would make any forecaster look good. Here every sealed fingerprint appears the day it’s made, so a prediction can be revealed late but never hidden. Predictions still unrevealed after their resolution date are flagged as overdue.
The ledger is predictions/ledger.json in the public repository; the scripts are scripts/predict/seal.py and reveal.py.