aere-quantum/verifiable-data/verifica.mjs
Aere Network cf8c56792f ai-trust, proof-of-ai, verifiable-data: the trust chain of an AI result, the AIP-23 envelope of an agent action, and a dataset whose answers are checkable without the data
ai-trust/ links six existing proofs (agent identity, model artifact attestation, host runtime record, policy and signed ledger,
Proof of AI envelope, on-chain witness) into one bundle judged by one verifier that checks only the links; 13/13 in the lab,
16/16 live on testnet 28001 (ledger head notarized). proof-of-ai/ is the AIP-23 envelope builder it uses. verifiable-data/
publishes append-only versions with an RFC 9162 root and a sorted index per field, range and equality queries proven correct
and complete, selective disclosure per field, availability by sampling, and the AIP-23 data envelope notarized (version 2 on
testnet 28001). agents/agent-ancora.mjs gains notarizeEnvelope({kind}), the general form of notarizeHead. Each README says what
is not built: zero-knowledge queries need a prover and are not here. No third party has reviewed any of this.
2026-10-02 11:28:14 +03:00

55 lines
5.2 KiB
JavaScript

#!/usr/bin/env node
// verifica.mjs: the reader's side of a verifiable dataset, without the data (roadmap point 20). Everything is judged against a
// COMMITMENT (a version's JSON) and prints VALID / INVALID with the reasons; exit 0 VALID, 1 INVALID, 2 could not measure.
// node verifica.mjs raspuns <answer.json> --angajament <c.json> a query answer: correct, complete, in order
// node verifica.mjs inregistrare <record.json> --angajament <c.json> one record with its proof
// node verifica.mjs consistenta <proof.json> --vechi <c1.json> --nou <c2.json> the newer version only appended
// node verifica.mjs disponibilitate --url <http://host:port/v1/vd/name> --angajament <c.json> [--esantioane 16] [--seed <hex>]
// random records fetched and verified (retrievability)
// node verifica.mjs angajament <c.json> --plic <env.json> [--verify-proof <verify-proof.mjs>] [--rpc URL --chain 28001]
// the AIP-23 envelope is this commitment's; with --rpc,
// its notarization under a post-quantum certified anchor
import fs from 'node:fs';
import path from 'node:path';
import { spawn } from 'node:child_process';
import { fileURLToPath } from 'node:url';
import { verificaRaspuns, verificaInregistrare, verificaConsistentaVersiuni, verificaPlicAngajament, esantioneaza, hashAngajament } from './baza.mjs';
const AICI = path.dirname(fileURLToPath(import.meta.url));
const a = process.argv.slice(2); const cmd = a[0];
const opt = (k, d = null) => { const i = a.indexOf(k); return i >= 0 && i + 1 < a.length ? a[i + 1] : d; };
const citeste = (f) => JSON.parse(fs.readFileSync(f, 'utf8'));
const iesi = (verdict, motive = [], extra = '') => { console.log(`${verdict}${extra ? ' ' + extra : ''}${motive.length ? '\n ' + motive.join('\n ') : ''}`); process.exitCode = verdict === 'VALID' ? 0 : verdict === 'INVALID' ? 1 : 2; };
const ruleaza = (verifyProof, envFile, { rpc, chain }) => new Promise((ok) => {
const args = [verifyProof, envFile, '--json', ...(rpc ? ['--rpc', rpc] : []), ...(chain ? ['--chain', String(chain)] : [])];
const c = spawn(process.execPath, args); let out = ''; c.stdout.on('data', (d) => { out += d; }); c.stderr.on('data', () => {});
const ceas = setTimeout(() => c.kill(), 300000); c.on('error', () => { clearTimeout(ceas); ok(null); }); c.on('close', () => { clearTimeout(ceas); try { ok(JSON.parse(out)); } catch { ok(null); } });
});
async function main() {
if (cmd === 'raspuns') { const r = verificaRaspuns(citeste(a[1]), citeste(opt('--angajament'))); return iesi(r.verdict, r.motive, `(${r.rows} rows)`); }
if (cmd === 'inregistrare') { const r = verificaInregistrare(citeste(a[1]), citeste(opt('--angajament'))); return iesi(r.ok ? 'VALID' : 'INVALID', r.motive); }
if (cmd === 'consistenta') { const r = verificaConsistentaVersiuni(citeste(a[1]), citeste(opt('--vechi')), citeste(opt('--nou'))); return iesi(r.ok ? 'VALID' : 'INVALID', r.motive); }
if (cmd === 'disponibilitate') {
const url = opt('--url'); const c = citeste(opt('--angajament')); if (!url) throw new Error('--url is required');
const ia = async (u) => { const r = await fetch(u, { headers: { accept: 'application/json' }, signal: AbortSignal.timeout(20000) }); if (!r.ok) return null; return r.json(); };
const r = await esantioneaza({ url, commitment: c, k: Number(opt('--esantioane', 16)), seed: opt('--seed', null), ia });
return iesi(r.ok ? 'VALID' : 'INVALID', r.motive, `(${r.verificate} of ${r.cerute} sampled records verified, seed ${r.seed}${r.lipsa.length ? '; not served: ' + r.lipsa.join(',') : ''})`);
}
if (cmd === 'angajament') {
const c = citeste(a[1]); const env = citeste(opt('--plic'));
if (!verificaPlicAngajament(env, c)) return iesi('INVALID', ['the envelope is not this commitment\'s (sha256/name differ, or not an aere-proof-of-data attestation)']);
const vp = opt('--verify-proof', process.env.AERE_VERIFY_PROOF || path.resolve(AICI, '..', '..', 'verificator-falcon', 'verify-proof.mjs'));
if (!fs.existsSync(vp)) return iesi('UNMEASURED', ['the AIP-23 verifier is not at ' + vp + ' (AERE_VERIFY_PROOF or --verify-proof)'], `commitment ${hashAngajament(c)} is the envelope's`);
const v = await ruleaza(vp, opt('--plic'), { rpc: opt('--rpc'), chain: opt('--chain') });
if (!v) return iesi('UNMEASURED', ['the verifier gave no JSON']);
const fin = (v.levels || []).find((l) => l.level === 'finality');
const extra = `envelope ${v.verdict}; finality ${fin ? fin.state + ': ' + String(fin.detail).slice(0, 160) : 'absent'}`;
if (v.verdict !== 'VALID') return iesi('INVALID', [], extra);
if (opt('--rpc') && !(fin && fin.state === 'PASSED')) return iesi(fin && fin.state === 'FAILED' ? 'INVALID' : 'UNMEASURED', [], extra);
return iesi('VALID', [], extra);
}
console.log('usage: verifica.mjs raspuns|inregistrare|consistenta|disponibilitate|angajament ... (see the header)'); process.exitCode = 2;
}
try { await main(); } catch (e) { iesi('UNMEASURED', [String(e.message).slice(0, 200)]); }