Cuneyt Ozturk commited on
Commit
dca3127
·
1 Parent(s): 9df3806

exact canonicalization via registry shared module (approximate emit kept as labeled fallback); anchor hash-mismatch guard; examples use bare 64-hex dataset.hash

Browse files
Files changed (1) hide show
  1. index.html +26 -3
index.html CHANGED
@@ -225,7 +225,7 @@ comparator: ">="
225
  threshold: 0.92
226
  dataset:
227
  id: imagenet-val-2012
228
- hash: sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
229
  seed: 42
230
  producer:
231
  id: falsify.dev
@@ -276,7 +276,7 @@ comparator: ">="
276
  threshold: 0.92
277
  dataset:
278
  id: imagenet-val-2012
279
- hash: sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
280
  seed: 42
281
  producer:
282
  id: falsify.dev
@@ -303,8 +303,21 @@ function sortObject(o) {
303
  return o;
304
  }
305
 
306
- // Approximate js-yaml canonical dump matching PyYAML safe_dump(default_flow_style=false, sort_keys=true, allow_unicode=true)
 
 
 
 
 
 
 
307
  function canonicalise(obj) {
 
 
 
 
 
 
308
  if (typeof jsyaml === 'undefined') throw new Error('YAML lib not loaded');
309
  let s = jsyaml.dump(sortObject(obj), {
310
  indent: 2,
@@ -363,6 +376,7 @@ async function update() {
363
 
364
  const h = await sha256(canon);
365
  hashEl.textContent = 'sha256:' + h;
 
366
  srcMsg.className = 'ok';
367
  srcMsg.textContent = 'canonical';
368
  }
@@ -423,6 +437,15 @@ $('anchor').addEventListener('click', async () => {
423
  throw new Error('registry returned ' + res.status);
424
  }
425
  const data = await res.json();
 
 
 
 
 
 
 
 
 
426
  showResults(data);
427
  } catch (e) {
428
  btn.textContent = 'anchor failed: ' + e.message;
 
225
  threshold: 0.92
226
  dataset:
227
  id: imagenet-val-2012
228
+ hash: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
229
  seed: 42
230
  producer:
231
  id: falsify.dev
 
276
  threshold: 0.92
277
  dataset:
278
  id: imagenet-val-2012
279
+ hash: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
280
  seed: 42
281
  producer:
282
  id: falsify.dev
 
303
  return o;
304
  }
305
 
306
+ // Exact canonicalization: import the registry's own canonical.js (the same
307
+ // module its server commits with, vector-gated in CI). Falls back to the older
308
+ // approximate js-yaml emit if the module fails to load; the status pill says which.
309
+ let sharedCanon = null;
310
+ import('https://registry.falsify.dev/vendor/canonical.js')
311
+ .then(m => { sharedCanon = m; update(); })
312
+ .catch(() => { /* approximate fallback stays active */ });
313
+
314
  function canonicalise(obj) {
315
+ if (sharedCanon) return sharedCanon.canonicalize(obj);
316
+ return canonicaliseApprox(obj);
317
+ }
318
+
319
+ // Approximate js-yaml canonical dump matching PyYAML safe_dump(default_flow_style=false, sort_keys=true, allow_unicode=true)
320
+ function canonicaliseApprox(obj) {
321
  if (typeof jsyaml === 'undefined') throw new Error('YAML lib not loaded');
322
  let s = jsyaml.dump(sortObject(obj), {
323
  indent: 2,
 
376
 
377
  const h = await sha256(canon);
378
  hashEl.textContent = 'sha256:' + h;
379
+ try { srcMsg.textContent = sharedCanon ? 'canonical (exact, registry module)' : 'canonical (approximate fallback)'; } catch (_) {}
380
  srcMsg.className = 'ok';
381
  srcMsg.textContent = 'canonical';
382
  }
 
437
  throw new Error('registry returned ' + res.status);
438
  }
439
  const data = await res.json();
440
+ const localHash = (hashEl.textContent || '').replace(/^sha256:/, '');
441
+ const remoteHash = (data.hash || '').replace(/^sha256:/, '');
442
+ if (localHash && remoteHash && localHash !== remoteHash) {
443
+ btn.textContent = 'HASH MISMATCH — registry disagrees with this page';
444
+ btn.disabled = false;
445
+ alert('Hash mismatch.\n\nThis page computed ' + localHash + '\nthe registry returned ' + remoteHash
446
+ + '\n\nDo not use this receipt. Re-verify with the Python CLI (falsify lock) and report this at github.com/studio-11-co/falsify-registry.');
447
+ return;
448
+ }
449
  showResults(data);
450
  } catch (e) {
451
  btn.textContent = 'anchor failed: ' + e.message;