deploy(rf-diagnostics): fefb0f918e fefb0f918e

This commit is contained in:
ruvnet committed 2026-10-22 15:09:02 +00:00
1 parent 94df16ed46
commit a6304a2117
4 files changed
+107

No files matched your search

+48
View File
@@ -0,0 +1,48 @@
'use strict';
const M=RFDiagnostics,$=id=>document.getElementById(id),ns='http://www.w3.org/2000/svg';
let generation=0;
function render(rows){
const last=rows.at(-1),kinds=[...new Set(rows.map(r=>M.modes[r.source_kind]))];
$('mode').textContent=kinds.join(' + ')||'NO DATA';
$('count').textContent=rows.length.toLocaleString();
$('rms').textContent=last?.rms_dbfs==null?'—':last.rms_dbfs.toFixed(2);
$('rails').textContent=last?.rail_fraction==null?'—':(last.rail_fraction*100).toFixed(3)+'%';
$('gaps').textContent=rows.length?rows.reduce((n,r)=>n+BigInt(r.missing_samples),0n).toLocaleString():'—';
const reasons=new Map();
for(const r of rows)for(const reason of new Set(r.invalid_reasons))reasons.set(reason,(reasons.get(reason)||0)+1);
$('reasons').replaceChildren();
for(const [reason,count] of reasons){const li=document.createElement('li');li.textContent=reason+' · '+count.toLocaleString();$('reasons').append(li);}
$('meta').textContent=last?[
'Source: '+last.source_id,'Origin: '+last.source_kind+' (file/demo replay)',
'Rate: '+(last.sample_rate_hz||'unknown')+' samples/s',
'Centre: '+(last.center_frequency_hz??'unknown')+' Hz (unverified)',
'Run / slot: '+last.run+' / '+last.slot_index,
'Host monotonic ns: '+last.observed_monotonic_ns,
'Absolute sample start: '+(last.sample_start??'unknown'),
'Configuration verified: false','Valid for inference: false',
'TTL: '+last.ttl_ms+' ms; replay freshness unknown'
].join('\n'):'No observations';
const tail=rows.slice(-500),values=tail.map(r=>r.rms_dbfs).filter(v=>v!==null);
const low=Math.min(...values),high=Math.max(...values),span=high-low||1;
$('chart').replaceChildren();
let path='';
tail.forEach((r,i)=>{
if(r.rms_dbfs===null){path+=' ';return;}
const x=20+i*960/Math.max(1,tail.length-1),y=220-200*(r.rms_dbfs-low)/span;
path+=(i===0||tail[i-1].rms_dbfs===null?'M':'L')+x+','+y+' ';
if(r.missing_samples){const dot=document.createElementNS(ns,'circle');dot.setAttribute('cx',x);dot.setAttribute('cy',y);dot.setAttribute('r',4);dot.setAttribute('fill','#ffb66c');$('chart').append(dot);}
});
const line=document.createElementNS(ns,'path');line.setAttribute('d',path);line.setAttribute('fill','none');line.setAttribute('stroke','#71e7db');line.setAttribute('stroke-width',2);$('chart').prepend(line);
$('range').textContent=values.length?'Range '+low.toFixed(2)+' to '+high.toFixed(2)+' dBFS · '+tail.length+' latest records':'No RMS observations';
$('chart').setAttribute('aria-label',$('range').textContent);
}
$('demo').onclick=()=>{generation++;render(M.demo());$('status').textContent='Synthetic demonstration loaded. No hardware evidence.';};
$('clear').onclick=()=>{generation++;render([]);$('file').value='';$('status').textContent='Cleared. No observations retained.';};
$('file').onchange=async()=>{
const ticket=++generation,file=$('file').files[0];if(!file)return;
try{
if(file.size>M.MAX_BYTES)throw Error('File exceeds 10 MiB');
const rows=M.parse(await file.text());if(ticket!==generation)return;
render(rows);$('status').textContent='Imported '+rows.length+' records. Source labels are unverified claims; this is file replay.';
}catch(e){if(ticket!==generation)return;render([]);$('status').textContent='Import rejected: '+e.message;}
};
+12
View File
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'self'; style-src 'self'; connect-src 'none'; img-src 'none'; object-src 'none'; base-uri 'none'; form-action 'none'">
<title>RuView RF Diagnostics</title><link rel="stylesheet" href="style.css"><script defer src="model.js"></script><script defer src="app.js"></script></head>
<body><main><header><p class="eyebrow">COGNITUM / RUVIEW / W1700K</p><span id="mode" class="badge">NO DATA</span><h1>RF diagnostics.</h1><p class="intro">Understand the measurement before trusting the inference.</p></header>
<section class="controls" aria-label="Import controls"><label class="button">Import local JSONL<input id="file" type="file" accept=".jsonl,.ndjson,.json,application/json"></label><button id="demo">Load synthetic demo</button><button id="clear">Clear</button><p>Local processing only. Maximum 10 MiB and 10,000 observations. No uploads.</p></section>
<p id="status" role="status">Import bridge diagnostics or explore a clearly labelled synthetic example.</p>
<aside>ADVISORY ONLY · Configuration is unverified. These records cannot establish presence, pose or CSI accuracy. Imported files are replay, never an active hardware connection.</aside>
<section class="metrics" aria-label="Latest observation"><article><p>Latest RMS</p><strong id="rms">—</strong><small>relative dBFS, not calibrated RF power</small></article><article><p>Latest rails</p><strong id="rails">—</strong><small>samples at numeric limits</small></article><article><p>Reported missing</p><strong id="gaps">—</strong><small>sum of per record missing samples</small></article><article><p>Observations</p><strong id="count">0</strong><small>all v1 observations invalid</small></article></section>
<section class="panel"><h2>Relative RMS history</h2><p>Record order, last 500 observations. Missing metrics break the line. Orange dots flag missing samples.</p><svg id="chart" viewBox="0 0 1000 240" role="img" aria-label="Relative RMS history; import a diagnostics file"></svg><p id="range">No observations</p></section>
<div class="split"><section class="panel"><h2>Invalidation reasons</h2><ul id="reasons"><li>No observations</li></ul></section><section class="panel"><h2>Source metadata</h2><pre id="meta">No observations</pre></section></div>
<footer>RuField evidence boundary · 1 second TTL is producer metadata. Host monotonic time is not wall time; file replay cannot establish freshness.</footer></main></body></html>
+46
View File
@@ -0,0 +1,46 @@
(function(root){
'use strict';
const MAX_BYTES=10*1024*1024, MAX_RECORDS=10000;
const fields='schema source_kind source_id observed_monotonic_ns run slot_index sample_start sample_rate_hz center_frequency_hz config_verified valid invalid_reasons sample_count rms_dbfs rail_fraction missing_samples event_count overrun_slices ttl_ms'.split(' ');
const modes={synthetic:'SYNTHETIC',live:'LIVE UNVERIFIED',captured_replay:'CAPTURED REPLAY'};
function validate(r){
const fail=(s)=>{throw Error(s)};
if(!r||Array.isArray(r)||typeof r!=='object')fail('Expected an object');
for(const k of Object.keys(r))if(!fields.includes(k))fail('Unsupported field: '+k);
for(const k of fields)if(!Object.hasOwn(r,k))fail('Missing field: '+k);
if(r.schema!=='ruview.rf_diagnostics.v1')fail('Unsupported schema');
if(!Object.hasOwn(modes,r.source_kind)||r.source_id!=='w1700k')fail('Unsupported source');
for(const k of ['observed_monotonic_ns','run','slot_index','sample_rate_hz','sample_count','missing_samples','event_count','overrun_slices','ttl_ms'])
if(!Number.isSafeInteger(r[k])||r[k]<0)fail('Invalid '+k);
if(r.ttl_ms!==1000)fail('Invalid rate or TTL');
for(const k of ['sample_start','center_frequency_hz'])
if(r[k]!==null&&(!Number.isSafeInteger(r[k])||r[k]<0))fail('Invalid '+k);
if(r.rms_dbfs!==null&&(typeof r.rms_dbfs!=='number'||!Number.isFinite(r.rms_dbfs)))fail('Invalid RMS');
if(r.rail_fraction!==null&&(typeof r.rail_fraction!=='number'||!Number.isFinite(r.rail_fraction)||r.rail_fraction<0||r.rail_fraction>1))fail('Invalid rail fraction');
if(r.config_verified!==false||r.valid!==false)fail('v1 must remain unverified and invalid');
if(!Array.isArray(r.invalid_reasons)||r.invalid_reasons.length>32||!r.invalid_reasons.includes('configuration_unverified')||r.invalid_reasons.some(x=>typeof x!=='string'||!/^[a-z_]{1,64}$/.test(x)))fail('Invalid reasons');
if(![0,40000000,80000000,160000000,320000000].includes(r.sample_rate_hz))fail('Invalid sample rate');
if(r.sample_start!==null)fail('Absolute sample start is unavailable in v1');
if(r.center_frequency_hz!==null&&(r.center_frequency_hz<2000000000||r.center_frequency_hz>8000000000))fail('Invalid centre frequency');
if(![0,2048].includes(r.sample_count)||r.missing_samples%2048!==0)fail('Invalid sample count');
if(r.rms_dbfs!==null&&(r.rms_dbfs< -200||r.rms_dbfs>16||r.rail_fraction===null))fail('Invalid RMS or missing rail fraction');
const reasons=['configuration_unverified','lost','event','overrun','stale','tag_mismatch','run_change'];
if(new Set(r.invalid_reasons).size!==r.invalid_reasons.length||r.invalid_reasons.length>7||r.invalid_reasons.some(x=>!reasons.includes(x)))fail('Unsupported invalid reason');
return r;
}
function parse(text){
if(typeof text!=='string'||new TextEncoder().encode(text).length>MAX_BYTES)throw Error('File exceeds 10 MiB');
const lines=text.split(/\r?\n/).filter(x=>x.trim());
if(!lines.length||lines.length>MAX_RECORDS)throw Error('Expected 1 to 10,000 records');
return lines.map((s,i)=>{try{return validate(JSON.parse(s))}catch(e){throw Error('Record '+(i+1)+': '+e.message)}});
}
function demo(){return Array.from({length:96},(_,i)=>({
schema:'ruview.rf_diagnostics.v1',source_kind:'synthetic',source_id:'w1700k',
observed_monotonic_ns:i*100000000,run:1,slot_index:i,sample_start:null,
sample_rate_hz:40000000,center_frequency_hz:2437000000,config_verified:false,valid:false,
invalid_reasons:i%23===0?['configuration_unverified','lost']:['configuration_unverified'],
sample_count:2048,rms_dbfs:-34+Math.sin(i/8)*6,rail_fraction:i%23===0?0.03:0,
missing_samples:i%23===0?2048:0,event_count:0,overrun_slices:0,ttl_ms:1000}));}
const api={MAX_BYTES,MAX_RECORDS,modes,validate,parse,demo};
if(typeof module==='object')module.exports=api;else root.RFDiagnostics=api;
})(globalThis);
+1
View File
@@ -0,0 +1 @@
:root{color-scheme:dark;font-family:Inter,ui-sans-serif,system-ui,sans-serif;background:#080f17;color:#d9e8ee}*{box-sizing:border-box}body{margin:0;background:radial-gradient(ellipse at 85% 0,#113642,transparent 50%)}main{max-width:1200px;margin:auto;padding:48px 28px}header{position:relative}.eyebrow{letter-spacing:.2em;color:#62d9da;font-size:12px;font-weight:700}h1{font-size:clamp(38px,7vw,76px);letter-spacing:-.055em;margin:18px 0}.intro{font-size:20px;color:#a4bcc6}.badge{display:inline-block;padding:8px 14px;border:1px solid #b89851;border-radius:32px;color:#f5d18c;font-size:12px;font-weight:bold}.controls{margin-top:32px;display:flex;gap:12px;flex-wrap:wrap;align-items:center}.controls p{flex-basis:100%;font-size:13px;color:#a4bcc6}button,.button{font:inherit;font-size:14px;border:1px solid #38616f;background:#152b37;color:#e7faff;border-radius:10px;padding:13px 18px;cursor:pointer}.button{background:#77e9dd;color:#082b2c;font-weight:700;position:relative;overflow:hidden}.button input{position:absolute;inset:0;width:100%;height:100%;opacity:0;cursor:pointer}button:hover,.button:hover{filter:brightness(1.2)}button:focus-visible,.button:focus-within{outline:3px solid #fff;outline-offset:3px}aside{border-left:3px solid #e5b85e;padding:16px 20px;background:#30291c;font-size:14px;line-height:1.6;color:#f5ddab}.metrics{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin:24px 0}.metrics article,.panel{border:1px solid #25414d;background:#0d1c26;border-radius:14px;padding:22px}.metrics p{font-size:13px;color:#9cb6c1}.metrics strong{font-size:30px;color:#79eddf;display:block;margin:16px 0}.metrics small{color:#9cb6c1;font-size:11px}.panel{margin-bottom:18px}h2{font-size:18px;margin-top:0}.panel p,footer{color:#9cb6c1;font-size:13px;line-height:1.6}svg{width:100%;height:auto;display:block;background:linear-gradient(#132c37,#0d1c26);border-radius:8px}.split{display:grid;grid-template-columns:1fr 1fr;gap:18px}pre{white-space:pre-wrap;word-break:break-word;color:#b7d1da;line-height:1.7;font-size:12px}li{margin-bottom:10px;overflow-wrap:anywhere}#status{font-size:14px;min-height:22px}footer{margin:24px 0} @media(max-width:700px){main{padding:28px 16px}.metrics{grid-template-columns:1fr 1fr}.split{grid-template-columns:1fr;gap:0}.metrics article{padding:14px}.metrics strong{font-size:24px}}