import { z } from 'zod'; const nonnegative=z.number().finite().nonnegative(); const schema=z.object({schema:z.literal('wikideck-operations-v1'),observedAt:z.string().datetime(), native:z.object({available:z.boolean(),queued:nonnegative}), ledger:z.object({height:nonnegative,mutationQueue:nonnegative,tipAgeSeconds:nonnegative.nullable()}), peers:z.object({configured:nonnegative,connected:nonnegative}), eventLoop:z.object({meanMs:nonnegative}),disk:z.unknown(),diskSampledAt:nonnegative.nullable()}); export function checkOperations(raw:unknown,now=Date.now()){ const s=schema.parse(raw),warnings:string[]=[]; const observation=Date.parse(s.observedAt); if(Math.abs(now-observation)>60000)warnings.push('diagnostics-clock-or-freshness'); if(!s.native.available)warnings.push('native-engine-unavailable'); if(s.native.queued>=48||s.ledger.mutationQueue>=192)warnings.push('queue-pressure'); if(!s.peers.configured||!s.peers.connected)warnings.push('peer-isolation'); if(s.ledger.height===0||s.ledger.tipAgeSeconds===null||s.ledger.tipAgeSeconds>3600)warnings.push('empty-or-stale-chain'); if(s.eventLoop.meanMs>250)warnings.push('event-loop-delay'); const disk=z.object({availableBytes:nonnegative}).safeParse(s.disk); if(!disk.success||!s.diskSampledAt||now-s.diskSampledAt>90000)warnings.push('disk-sample-unavailable-or-stale'); else if(disk.data.availableBytes<512*1024*1024)warnings.push('disk-low'); return {healthy:warnings.length===0,warnings, note:'Local threshold hints only, not consensus readiness or launch approval. Reorg/rejection counters and native RSS need external time-series monitoring.'}; }