import fs from 'node:fs/promises' const url = 'ws://192.168.110.96:8301/ws/deviceStatus' const seconds = Number(process.argv[2] || 180) const label = process.argv[3] || 'capture' const startedAt = new Date().toISOString() const frames = [] const errors = [] const socket = new WebSocket(url) const finish = async () => { socket.close() const deltas = frames.filter(row => row.frame.type !== 'cockpitSubscribed') const report = { url, label, windowSeconds: seconds, startedAt, endedAt: new Date().toISOString(), frames, errors, verdict: frames.some(row => row.frame.type === 'cockpitSubscribed') ? 'subscription-confirmed' : 'subscription-failed', deltaFrames: deltas.length, scope: 'Read-only subscription; no authenticate, no business writes. Absence of deltas means only "no change observed in this window" and must be cross-checked against the database or the operator log before being called a defect.', } await fs.writeFile(`.scratch/cockpit-real-data-wayfinding/verify/artifacts/t18/ws-${label}.json`, JSON.stringify(report, null, 2)) console.log(JSON.stringify({ verdict: report.verdict, deltaFrames: report.deltaFrames, frames: frames.length })) process.exit(0) } socket.addEventListener('open', () => socket.send(JSON.stringify({ type: 'cockpitSubscribe', scope: 'all' }))) socket.addEventListener('message', event => { try { frames.push({ receivedAt: new Date().toISOString(), frame: JSON.parse(String(event.data)) }) } catch { errors.push('non-json-frame') } }) socket.addEventListener('error', () => errors.push('websocket-error')) setTimeout(finish, seconds * 1000)