Sunstead trust scoring project
0

Configure Feed

Select the types of activity you want to include in your feed.

at main 2.4 kB View raw
1// Tangled-native overlay (PRD 7.4). UI only: it reads the same /score API the 2// dashboard does and injects a "trust hat" pill next to contributor DIDs on 3// tangled.org. The brain stays in the service; this never touches DuckDB. 4// 5// ponytail: vanilla content script, no build step (same call as the built-in 6// pages) over the Bun/oxlint/zod toolchain. CONFIRM the DID selector against the 7// real tangled.org DOM — like the NSIDs, this is a best-guess until verified. 8 9const API = "http://127.0.0.1:8000"; 10const DID_RE = /did:(?:plc:[a-z2-7]+|web:[a-z0-9.\-]+)/gi; 11const COLOR = { fast_lane: "#1a7f37", normal_queue: "#9a6700", needs_human: "#cf222e" }; 12 13const cache = new Map(); 14 15async function score(did) { 16 if (cache.has(did)) return cache.get(did); 17 const p = fetch(`${API}/score/${encodeURIComponent(did)}`) 18 .then((r) => (r.ok ? r.json() : null)) 19 .catch(() => null); // service down -> render nothing, never break the page 20 cache.set(did, p); 21 return p; 22} 23 24function pill(s) { 25 const el = document.createElement("span"); 26 el.className = "tangled-trust-hat"; 27 el.dataset.did = s.did; 28 el.textContent = ` ${Math.round((s.calibrated_prob ?? 0) * 100)}% `; 29 const factors = (s.explanation?.top_factors || []).join("\n"); 30 el.title = `${s.decision}\n${factors}`; 31 Object.assign(el.style, { 32 background: COLOR[s.decision] || "#57606a", 33 color: "#fff", borderRadius: "999px", padding: "1px 7px", 34 fontSize: "11px", fontWeight: "600", marginLeft: "6px", verticalAlign: "middle", 35 }); 36 return el; 37} 38 39// Find text-node occurrences of a DID and tag their parent once. 40async function scan() { 41 const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT); 42 const hits = []; 43 for (let n = walker.nextNode(); n; n = walker.nextNode()) { 44 const m = n.nodeValue.match(DID_RE); 45 if (m) hits.push({ node: n, dids: [...new Set(m)] }); 46 } 47 for (const { node, dids } of hits) { 48 const host = node.parentElement; 49 if (!host || host.querySelector(":scope > .tangled-trust-hat")) continue; 50 for (const did of dids) { 51 const s = await score(did); 52 if (s) host.appendChild(pill(s)); 53 } 54 } 55} 56 57scan(); 58// tangled.org is an SPA; re-scan on DOM changes (debounced). 59let t; 60new MutationObserver(() => { 61 clearTimeout(t); 62 t = setTimeout(scan, 400); 63}).observe(document.body, { childList: true, subtree: true });