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.
62 lines
4.1 KiB
JavaScript
62 lines
4.1 KiB
JavaScript
'use strict';
|
|
// Proba Proof-of-AI (B2): construieste un plic, il verifica cu ACELASI verificator AIP-23 (fara cod nou de verificare), si un
|
|
// CONTROL NEGATIV: un plic caruia i se atinge statement-ul dupa hash pica la integritate. Dovedeste teza "un standard, multe feluri".
|
|
// node proba-proof-of-ai.mjs -> 0 toate cum trebuia, 1 altfel
|
|
|
|
import fs from 'node:fs';
|
|
import os from 'node:os';
|
|
import path from 'node:path';
|
|
import { execFileSync } from 'node:child_process';
|
|
import { fileURLToPath } from 'node:url';
|
|
import { buildProofOfAi, KIND } from './proof-of-ai.mjs';
|
|
|
|
const AICI = path.dirname(fileURLToPath(import.meta.url));
|
|
// Verificatorul AIP-23: AERE_VERIFY_PROOF=<verify-proof.mjs> (copia publica, ca la agents/) sau, in depozitul de dezvoltare,
|
|
// ../aere-proof-protocol/verify.mjs; fara el proba nu poate masura nimic si iese 2 (NEMASURAT), nu verde
|
|
const VERIFY = process.env.AERE_VERIFY_PROOF || path.resolve(AICI, '..', 'aere-proof-protocol', 'verify.mjs');
|
|
if (!fs.existsSync(VERIFY)) { console.log(`NEMASURAT: verificatorul AIP-23 nu e la ${VERIFY}; AERE_VERIFY_PROOF=<verify-proof.mjs>`); process.exit(2); }
|
|
const T = fs.mkdtempSync(path.join(os.tmpdir(), 'poai-'));
|
|
let rele = 0;
|
|
const cer = (n, c) => { console.log(` [${c ? 'OK ' : 'RAU '}] ${n}`); if (!c) rele++; };
|
|
function verif(plicPath) {
|
|
try { return { cod: 0, out: execFileSync(process.execPath, [VERIFY, plicPath, '--json'], { encoding: 'utf8' }) }; }
|
|
catch (e) { return { cod: e.status ?? 2, out: (e.stdout || '') + (e.stderr || '') }; }
|
|
}
|
|
const verdict = (o) => { try { return JSON.parse(o).verdict; } catch { return '?'; } };
|
|
// verificatorul AIP-23 e in ENGLEZA (public-ready, D-402/B4): niveluri->levels, nivel->level, stare->state, TRECUT->PASSED, PICAT->FAILED
|
|
const nivel = (o, n) => { try { return JSON.parse(o).levels.find((x) => x.level === n).state; } catch { return '?'; } };
|
|
|
|
try {
|
|
const plic = buildProofOfAi({
|
|
model: { name: 'aere-fable', version: '5.1', weightsSha256: '0x' + '22'.repeat(32) },
|
|
prompt: 'rezuma documentul X',
|
|
input: 'documentul X, 12kb',
|
|
output: 'rezumatul: ...',
|
|
tools: ['retrieval', 'calculator'],
|
|
agentId: '0xa11ce00000000000000000000000000000000001',
|
|
requester: 'client-42',
|
|
createdAt: '2026-09-26T09:00:00.000Z',
|
|
});
|
|
cer('plicul are kind aere-proof-of-ai-attestation', plic.kind === KIND + '-attestation');
|
|
cer('statement-ul are model, promptHash, inputHash, outputHash, tools', !!(plic.statement.model && plic.statement.promptHash && plic.statement.inputHash && plic.statement.outputHash && Array.isArray(plic.statement.tools)));
|
|
cer('nu contine continut brut (doar digesturi)', !JSON.stringify(plic).includes('rezuma documentul X') && !JSON.stringify(plic).includes('rezumatul: ...'));
|
|
|
|
const f = path.join(T, 'ai.json'); fs.writeFileSync(f, JSON.stringify(plic, null, 1));
|
|
const r = verif(f);
|
|
cer('verificatorul AIP-23 il valideaza (fara cod nou)', verdict(r.out) === 'VALID' && nivel(r.out, 'integrity') === 'PASSED' && r.cod === 0);
|
|
|
|
// CONTROL NEGATIV: schimb outputHash dupa ce statementHash e fixat -> integritate PICAT
|
|
const rau = JSON.parse(JSON.stringify(plic)); rau.statement.outputHash = '0x' + '33'.repeat(32);
|
|
const fr = path.join(T, 'ai-rau.json'); fs.writeFileSync(fr, JSON.stringify(rau, null, 1));
|
|
const rr = verif(fr);
|
|
cer('CONTROL: iesire schimbata dupa hash -> INVALID', verdict(rr.out) === 'INVALID' && nivel(rr.out, 'integrity') === 'FAILED' && rr.cod === 1);
|
|
|
|
// acelasi statement -> acelasi hash (determinist)
|
|
const plic2 = buildProofOfAi({ model: { name: 'aere-fable', version: '5.1', weightsSha256: '0x' + '22'.repeat(32) }, prompt: 'rezuma documentul X', input: 'documentul X, 12kb', output: 'rezumatul: ...', tools: ['retrieval', 'calculator'], agentId: '0xa11ce00000000000000000000000000000000001', requester: 'client-42', createdAt: '2026-09-26T09:00:00.000Z' });
|
|
cer('determinist: acelasi continut -> acelasi statementHash', plic2.statementHash === plic.statementHash);
|
|
} finally {
|
|
fs.rmSync(T, { recursive: true, force: true });
|
|
}
|
|
console.log(`\nB2 proof-of-ai: ${6 - rele}/6 cum trebuia`);
|
|
process.exit(rele ? 1 : 0);
|