betterwithage commited on
Commit
ccf530d
·
verified ·
1 Parent(s): c8b462b

feat(console): Receipt Fingerprint Graph tab (B3, P-GNN anchor-set); byte-identical to GitHub 1cb1e82b

Browse files
Files changed (1) hide show
  1. pages/console.html +141 -0
pages/console.html CHANGED
@@ -10543,5 +10543,146 @@ window.warboard_init=warboard_init; window.warboard_all=warboard_all;
10543
  })();
10544
  </script>
10545
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10546
  </body>
10547
  </html>
 
10543
  })();
10544
  </script>
10545
 
10546
+ <script>
10547
+ /* receipt-fingerprint-tab (B3) — P-GNN anchor-set structural fingerprints over the
10548
+ LIVE Khipu receipt DAG, rendered as a D3 force graph. Adapts the anchor-set
10549
+ distance-encoding idea from P-GNN (You/Ying/Leskovec, ICML 2019, arXiv:1906.04817)
10550
+ to give every receipt a position-aware structural fingerprint h_v, used for
10551
+ fork detection / anomalous-agent (structurally isolated) detection / capability
10552
+ similarity. HONEST: the fingerprint is a structural HEURISTIC, never a proof; it
10553
+ does NOT change the locked-8 set and is not a trust oracle. 0 runtime CDN (d3 is
10554
+ vendored in-image). Reads REAL receipts; if none are present it says so. Additive
10555
+ only — registers one new VIEWS entry + one nav item, idempotent. */
10556
+ (function(){
10557
+ "use strict";
10558
+ var E=window.el, esc=window.esc, getPublic=window.getPublic;
10559
+ var TEAL=(window.TEAL||'#5fb3a3'), GOLD=(window.GOLD||'#c9b787'), RED='#b06a5a';
10560
+ function H(id,h){ var e=E&&E(id); if(e) e.innerHTML=h; }
10561
+
10562
+ /* ---- anchor-set fingerprint math (P-GNN-style) -------------------------- */
10563
+ // Build an undirected adjacency over the receipt DAG (prev_hash -> hash edges),
10564
+ // pick k anchors (genesis + evenly-spaced checkpoints), BFS hop-distance to each
10565
+ // anchor, fingerprint = [ 1/(1+d_i) ] per anchor (the P-GNN distance kernel
10566
+ // w_phi(d)=1/(1+d)). Cosine similarity between fingerprints = structural affinity.
10567
+ function buildGraph(recs){
10568
+ var byHash={}, nodes=[], idx={};
10569
+ recs.forEach(function(r,i){ var id=r.hash||('seq'+(r.seq!=null?r.seq:i));
10570
+ nodes.push({id:id,seq:(r.seq!=null?r.seq:i),kind:r.kind||'rcpt',prev:r.prev_hash||null});
10571
+ byHash[id]=i; idx[id]=i; });
10572
+ var adj=nodes.map(function(){return [];});
10573
+ nodes.forEach(function(n,i){ if(n.prev!=null && idx[n.prev]!=null){ var j=idx[n.prev];
10574
+ adj[i].push(j); adj[j].push(i); } });
10575
+ return {nodes:nodes,adj:adj,idx:idx};
10576
+ }
10577
+ function bfsDist(adj,src){ var d=adj.map(function(){return Infinity;}); d[src]=0;
10578
+ var q=[src]; while(q.length){ var u=q.shift(); adj[u].forEach(function(v){ if(d[v]===Infinity){ d[v]=d[u]+1; q.push(v); } }); } return d; }
10579
+ function pickAnchors(n,k){ if(n<=0) return []; k=Math.min(k,n); var a=[];
10580
+ for(var i=0;i<k;i++){ a.push(Math.round(i*(n-1)/Math.max(1,k-1))); } // genesis..head, evenly spaced
10581
+ return Array.from(new Set(a)); }
10582
+ function fingerprints(g,k){
10583
+ var n=g.nodes.length; var anchors=pickAnchors(n,k);
10584
+ var dmaps=anchors.map(function(a){ return bfsDist(g.adj,a); });
10585
+ var fps=g.nodes.map(function(_,i){ return anchors.map(function(_,ai){ var d=dmaps[ai][i];
10586
+ return isFinite(d)?(1/(1+d)):0; }); });
10587
+ return {anchors:anchors,fps:fps};
10588
+ }
10589
+ function cosine(a,b){ var dot=0,na=0,nb=0; for(var i=0;i<a.length;i++){ dot+=a[i]*b[i]; na+=a[i]*a[i]; nb+=b[i]*b[i]; }
10590
+ return (na&&nb)?(dot/(Math.sqrt(na)*Math.sqrt(nb))):0; }
10591
+
10592
+ /* ---- render ------------------------------------------------------------- */
10593
+ window.renderReceiptFP=function(c){
10594
+ c.innerHTML='<div class="kpis">'
10595
+ +'<div class="kpi"><div class="k">Receipts</div><div class="v teal" id="rfp-n">\u2014</div><div class="d">live command-log</div></div>'
10596
+ +'<div class="kpi"><div class="k">Anchor set</div><div class="v" id="rfp-k">\u2014</div><div class="d">P-GNN anchors</div></div>'
10597
+ +'<div class="kpi"><div class="k">Chain</div><div class="v" id="rfp-ch">\u2014</div><div class="d">hash-chain re-walk</div></div>'
10598
+ +'<div class="kpi"><div class="k">Structural flags</div><div class="v warn" id="rfp-flag">\u2014</div><div class="d">heuristic only</div></div></div>'
10599
+ +'<div class="card"><div class="card-h"><span class="card-t">Receipt fingerprint graph \u2014 anchor-set structural embedding</span>'
10600
+ +'<span class="card-ep">P-GNN distance kernel \u00b7 d3-force (BSD/ISC, vendored)</span></div>'
10601
+ +'<div id="rfp-svg" style="height:460px;border:1px solid rgba(201,183,135,0.12);border-radius:8px;overflow:hidden;background:#080a09"></div>'
10602
+ +'<div class="brain-note" id="rfp-note"><span style="color:'+GOLD+'">gold ring = anchor receipt</span>, '
10603
+ +'<span style="color:'+TEAL+'">teal = ordinary receipt</span>, <span style="color:'+RED+'">red = structurally isolated (anomaly heuristic)</span>. '
10604
+ +'Edge drawn where fingerprint cosine \u2265 0.92 (structural affinity). This is a structural <b>heuristic</b> for fork / spoof / isolated-agent detection \u2014 <b>not</b> a proof and not a trust oracle. '
10605
+ +'\u039b remains Conjecture 1; locked-proven stays exactly 8 {F1,F4,F7,F11,F12,F18,F19,F22}.</div></div>'
10606
+ +(window.HONEST||'');
10607
+ (function(){
10608
+ function go(){
10609
+ getPublic('/api/a11oy/v2/operator/command-log',12000).then(function(cl){
10610
+ var recs=(cl.receipts||[]).slice(-80);
10611
+ H('rfp-n', recs.length); H('rfp-ch', cl.chain_verified?('verified \u00b7 depth '+(cl.depth!=null?cl.depth:'')):'unverified');
10612
+ var host=E('rfp-svg'); if(!host) return;
10613
+ if(!recs.length){ host.innerHTML='<div class="row mono dim" style="padding:1rem">no receipts emitted in this runtime yet \u2014 nothing to fingerprint (honest empty state)</div>';
10614
+ H('rfp-k','0'); H('rfp-flag','0'); return; }
10615
+ var g=buildGraph(recs); var k=Math.min(5,Math.max(2,Math.round(Math.sqrt(g.nodes.length))));
10616
+ var R=fingerprints(g,k); H('rfp-k', R.anchors.length);
10617
+ // edges by fingerprint cosine affinity (plus the real prev_hash chain edges)
10618
+ var anchorSet={}; R.anchors.forEach(function(a){ anchorSet[a]=true; });
10619
+ var links=[]; var deg=g.nodes.map(function(){return 0;});
10620
+ // real chain edges
10621
+ g.nodes.forEach(function(n,i){ if(n.prev!=null && g.idx[n.prev]!=null){ links.push({source:i,target:g.idx[n.prev],kind:'chain'}); deg[i]++; deg[g.idx[n.prev]]++; } });
10622
+ // structural-affinity edges
10623
+ for(var i=0;i<g.nodes.length;i++){ for(var j=i+1;j<g.nodes.length;j++){
10624
+ if(cosine(R.fps[i],R.fps[j])>=0.92){ links.push({source:i,target:j,kind:'affinity'}); deg[i]++; deg[j]++; } } }
10625
+ var isolated=[]; g.nodes.forEach(function(n,i){ if(deg[i]===0 && !anchorSet[i]) isolated.push(i); });
10626
+ H('rfp-flag', isolated.length);
10627
+ H('rfp-note', E('rfp-note').innerHTML + (isolated.length?(' <b style="color:'+RED+'">'+isolated.length+' structurally isolated receipt(s) flagged.</b>'):' No structural anomalies in this window.'));
10628
+ drawD3(host, g, R, links, anchorSet, isolated);
10629
+ }).catch(function(e){ var host=E('rfp-svg'); if(host) host.innerHTML='<div class="row mono dim" style="padding:1rem">live command-log unavailable: '+esc(e.message)+'</div>';
10630
+ H('rfp-n','offline'); });
10631
+ }
10632
+ if(window.a11oyPoll){ window.a11oyPoll(go); } else { go(); }
10633
+ })();
10634
+ };
10635
+
10636
+ function drawD3(host, g, R, links, anchorSet, isolated){
10637
+ host.innerHTML='';
10638
+ if(!window.d3 || !d3.forceSimulation){ host.innerHTML='<div class="row mono dim" style="padding:1rem">d3-force unavailable</div>'; return; }
10639
+ var W=host.clientWidth||720, Hh=460;
10640
+ var iso={}; isolated.forEach(function(i){ iso[i]=true; });
10641
+ var nodes=g.nodes.map(function(n,i){ return {i:i,seq:n.seq,kind:n.kind,anchor:!!anchorSet[i],iso:!!iso[i]}; });
10642
+ var svg=d3.select(host).append('svg').attr('width','100%').attr('height','100%').attr('viewBox','0 0 '+W+' '+Hh);
10643
+ var lsel=svg.append('g').selectAll('line').data(links).enter().append('line')
10644
+ .attr('stroke',function(d){return d.kind==='chain'?'rgba(201,183,135,0.30)':'rgba(95,179,163,0.18)';})
10645
+ .attr('stroke-width',function(d){return d.kind==='chain'?1.1:0.7;});
10646
+ var nsel=svg.append('g').selectAll('circle').data(nodes).enter().append('circle')
10647
+ .attr('r',function(d){return d.anchor?9:5;})
10648
+ .attr('fill',function(d){return d.iso?RED:(d.anchor?'transparent':TEAL);})
10649
+ .attr('stroke',function(d){return d.iso?RED:(d.anchor?GOLD:TEAL);})
10650
+ .attr('stroke-width',function(d){return d.anchor?2:1.2;});
10651
+ nsel.append('title').text(function(d){return '#'+d.seq+' '+(d.kind||'')+(d.anchor?' (anchor)':'')+(d.iso?' (isolated)':'');});
10652
+ var sim=d3.forceSimulation(nodes)
10653
+ .force('link',d3.forceLink(links).distance(function(d){return d.kind==='chain'?34:60;}).strength(0.4))
10654
+ .force('charge',d3.forceManyBody().strength(-60))
10655
+ .force('center',d3.forceCenter(W/2,Hh/2))
10656
+ .on('tick',function(){
10657
+ lsel.attr('x1',function(d){return d.source.x;}).attr('y1',function(d){return d.source.y;})
10658
+ .attr('x2',function(d){return d.target.x;}).attr('y2',function(d){return d.target.y;});
10659
+ nsel.attr('cx',function(d){return d.x=Math.max(10,Math.min(W-10,d.x));}).attr('cy',function(d){return d.y=Math.max(10,Math.min(Hh-10,d.y));});
10660
+ });
10661
+ setTimeout(function(){ try{ sim.stop(); }catch(e){} }, 4200); // settle then freeze (no perpetual CPU)
10662
+ }
10663
+
10664
+ /* ---- register + nav (idempotent, waits for VIEWS) ----------------------- */
10665
+ function reg(){ if(!window.VIEWS){ return setTimeout(reg,120); }
10666
+ if(window.VIEWS.receiptfp) return;
10667
+ window.VIEWS.receiptfp={
10668
+ title:'Receipt Fingerprint Graph',
10669
+ badge:'P-GNN ANCHOR-SET \u00b7 STRUCTURAL FINGERPRINT',
10670
+ sub:'Position-aware structural fingerprints over the live Khipu receipt DAG (anchor-set distance encoding, after P-GNN \u2014 You/Ying/Leskovec, ICML 2019). Each receipt gets a fingerprint from its hop-distances to anchor receipts; structural affinity (cosine \u2265 0.92) and isolation surface fork / spoof / anomalous-agent signals. A structural heuristic \u2014 never a proof, never a trust oracle; \u039b stays Conjecture 1, locked-proven stays 8.',
10671
+ render:async function(c){ window.renderReceiptFP(c); }
10672
+ };
10673
+ }
10674
+ reg();
10675
+ function injectNav(){
10676
+ var anchor=document.querySelector('.nav-item[data-view="ledger3d"]')||document.querySelector('.nav-item[data-view="chain"]')||document.querySelector('.nav-item');
10677
+ if(!anchor){ return setTimeout(injectNav,250); }
10678
+ if(document.getElementById('rfp-nav')){ return; }
10679
+ var n=document.createElement('div'); n.className='nav-item'; n.id='rfp-nav';
10680
+ n.setAttribute('data-view','receiptfp'); n.setAttribute('onclick',"go('receiptfp')");
10681
+ n.innerHTML='<span class="ico">\u25c9</span>Receipt Fingerprint';
10682
+ anchor.parentNode.insertBefore(n, anchor.nextSibling);
10683
+ }
10684
+ if(document.readyState==='loading'){ document.addEventListener('DOMContentLoaded',injectNav); } else { injectNav(); }
10685
+ })();
10686
+ </script>
10687
  </body>
10688
  </html>