// Proba judecatii organizatiei (organizatie.mjs; B2, roadmap master 41 si 43). Pe artefacte PRODUSE de uneltele reale (fixturi-organizatie.mjs: // vectorii suitei de conformitate, ceruti egali cu amprenta lor din INDEX.json, plus starea Shield si raportul PQ facute acum de sidecar, de // planificator, de executor si de raport-conformitate.mjs), nu scrise de mana. Masoara: // - acoperirea, DERIVATA: fiecare fel judecat de adaptorul suitei are domeniu si clasificare; fiecare cheie pe care adaptorul o citeste (din // sursa lui) si fiecare cheie din cei 791 de vectori e clasificata; // - compunerea: pachetul bun (un artefact din fiecare din cele 25 de feluri, contextul derivat) da pentru fiecare artefact EXACT verdictul, // regulile si starile nivelurilor din vectorul lui; domeniul e cel mai slab artefact; rezumatul e cel mai slab domeniu cerut; // - cate un artefact stricat din fiecare fel, fiecare refuzat pentru regula lui, si numai domeniul lui atins; // - paznicii: domeniul neprezentat, verificatorul care nu porneste (adaptorul lipsa, verificatorul de referinta lipsa, un adaptor care da // mai putine verdicte sau unul incoerent), increderea adusa de organizatie, ceasul pachetului, listele de stare adaugate de cel care // verifica, verdictele scrise de pachet, reteaua (--online), felul necunoscut, id-ul repetat, cheile KEM private, contextul care ar // scrie artefactul, starea Shield in fiecare fel in care se strica, linia de comanda si codurile ei; // - atacurile reviziei adversariale (2026-10-21), fiecare aratat ROSU pe codul de dinainte: arbitrul pietei si faptele reputatiei alese de // organizatie, 64 de liste ale pachetului care imping afara rechemarea celui care verifica, un raport PQ rescris si legat din nou, raportul PQ // lipsa din retea, o masina trimisa la --online, finalitatea pe testnet nenumita, un adaptor care raspunde in alta ordine, un "VALID" pe care // nivelurile lui nu il dau, un artefact lent care lua cu el tot lotul, o executie Shield rupta de planul ei, ordinea ceasului din README. // AERE_ORG_MODUL= judeca o copie (controlul negativ planteaza in ea); AERE_ORG_DOAR= ruleaza numai randurile care contin a sau b. // node proba-organizatie.mjs [--online] iesire 0 = toate cum trebuia, 1 = una rosie, 2 = nu s-a putut rula // --online citeste si testnetul 28001 (un plic notarizat acolo, finalitatea lui); fara el randul acela e scris NEMASURAT, nu numarat. import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; import { spawnSync } from 'node:child_process'; import { fileURLToPath, pathToFileURL } from 'node:url'; import { pachetulBun, inlocuieste, vectorul, imparte, indexul, dosarulSuitei } from './fixturi-organizatie.mjs'; const AICI = path.dirname(fileURLToPath(import.meta.url)); const MODUL = process.env.AERE_ORG_MODUL ? path.resolve(process.env.AERE_ORG_MODUL) : path.join(AICI, 'organizatie.mjs'); const M = await import(pathToFileURL(MODUL).href); const ONLINE = process.argv.includes('--online'); const DOAR = (process.env.AERE_ORG_DOAR || '').split(',').map((x) => x.trim()).filter(Boolean); const eq = (a, b) => JSON.stringify(a) === JSON.stringify(b); const nemasurat = (m) => { console.log('NEMASURAT: ' + m); process.exit(2); }; let F; try { F = await pachetulBun(); } catch (e) { nemasurat('fixturile nu s-au putut face: ' + e.message); } const SUITA = dosarulSuitei(); if (!SUITA) nemasurat('lipsesc vectorii suitei de conformitate'); const ADAPTOR = path.join(SUITA, 'implementare-aere.mjs'); // verificatorul de referinta AIP-23, din acelasi loc din care il ia suita (AERE_VERIFY_PROOF, altfel cel al depozitului de dezvoltare): fara el, // plicurile ar iesi NOT_MEASURED (corect) si randul compunerii rosu dintr-un motiv care nu e al judecatii const { VERIFY_PROOF } = await import(pathToFileURL(path.join(SUITA, 'reguli.mjs')).href); if (!fs.existsSync(VERIFY_PROOF)) nemasurat(`verificatorul de referinta AIP-23 nu e la ${VERIFY_PROOF}: AERE_VERIFY_PROOF=`); const ctx = (byArtifact) => ({ v: 1, kind: M.CONTEXT_KIND, byArtifact }); const judeca = (pack, o = {}) => M.judecaPachetul(pack, { context: F.context, ...o }); const art = (o, id) => o.artifacts.find((x) => x.id === id); const dom = (o, d) => o.domains.find((x) => x.domain === d); const stari = (levels) => (levels || []).map((l) => l.state); const stariAsteptate = (lv) => ['integrity', 'authenticity', 'anchoring', 'finality'].map((l) => lv[l]); const T = fs.mkdtempSync(path.join(os.tmpdir(), 'proba-org-')); const randuri = []; const rand = (nume, f) => randuri.push([nume, f]); let O0 = null; // judecata pachetului bun, facuta o data const bun = async () => (O0 ||= await judeca(F.pack)); // ---- acoperirea, derivata rand('acoperire: fiecare fel al suitei are domeniu si clasificare, si numai ele (plus cele doua ale planului de control)', async () => { const R = await import(pathToFileURL(path.join(SUITA, 'reguli.mjs')).href); const aleSuitei = Object.values(R.VERIFICATOARE).flatMap((v) => v.artifacts).sort(); const aleNoastre = Object.keys(M.DOMENIUL).filter((k) => !M.FELURI_PROPRII.includes(k)).sort(); const domenii = M.DOMENII.map((d) => d.id); const ok = aleSuitei.length >= 23 && eq(aleSuitei, aleNoastre) && eq(Object.keys(M.INTRARI).sort(), Object.keys(M.DOMENIUL).sort()) && Object.values(M.DOMENIUL).every((d) => domenii.includes(d)) && domenii.every((d) => Object.values(M.DOMENIUL).includes(d)); return [ok, `suita ${aleSuitei.length} feluri, aici ${aleNoastre.length}; lipsa aici: ${aleSuitei.filter((x) => !aleNoastre.includes(x)).join(',') || '-'}; in plus: ${aleNoastre.filter((x) => !aleSuitei.includes(x)).join(',') || '-'}`]; }); /** cheile pe care adaptorul le citeste, pe fel, din SURSA lui: ramurile de sus ale lui judeca() (doua spatii), `input.X`, listele `for (const k of [..])`, * "tot inputul" (destructurat intreg sau dat intreg verificatorului: atunci si modulul si functia lui), si daca ramura citeste lantul (`plic(`, `online`) */ function cheileAdaptorului(src, feluri) { const i0 = src.indexOf('async function judeca('), i1 = src.indexOf('async function unul('); if (i0 < 0 || i1 < 0) return null; const harta = {}; for (const b of src.slice(i0, i1).split(/\n {2}(?:\} )?(?:else )?if \((?=artifact)/).slice(1)) { const cap = b.split('\n')[0]; // conditia ramurii e pe primul ei rand const ale = [...cap.matchAll(/artifact === '([a-z0-9-]+)'/g)].map((m) => m[1]); const pref = cap.match(/artifact\.startsWith\('([a-z-]+)'\)/); if (pref) ale.push(...feluri.filter((f) => f.startsWith(pref[1]))); const chei = new Set([...b.matchAll(/\binput\.([A-Za-z_]\w*)/g)].map((m) => m[1])); for (const m of b.matchAll(/for \(const k of \[([^\]]*)\]\) if \(input\[k\]/g)) for (const q of m[1].matchAll(/'([A-Za-z]+)'/g)) chei.add(q[1]); const tot = /\}\s*=\s*input\s*;/.test(b) || /\(input\)/.test(b); const modul = (b.match(/incarca\('(\w+)'\)/) || [])[1] || null, fn = (b.match(/\bM\.(\w+)\(/) || [])[1] || null; const lant = /\bplic\(|\bonline\b/.test(b); for (const f of ale) harta[f] = { chei: [...new Set([...(harta[f]?.chei || []), ...chei])], tot: tot || !!harta[f]?.tot, modul, fn, lant: lant || !!harta[f]?.lant }; } return harta; } /** cheile pe care le citeste MODULUL caruia adaptorul ii da tot inputul: `.X` in sursa lui si listele `exact(, [...])` */ function cheileModulului(src, fn) { const p = (src.match(new RegExp('function ' + fn + '\\((\\w+)\\)')) || [])[1]; if (!p) return null; const chei = new Set([...src.matchAll(new RegExp('\\b' + p + '\\.([A-Za-z_]\\w*)', 'g'))].map((m) => m[1])); for (const m of src.matchAll(new RegExp('exact\\(' + p + ', \\[([^\\]]*)\\]\\)', 'g'))) for (const q of m[1].matchAll(/'([A-Za-z]\w*)'/g)) chei.add(q[1]); return [...chei]; } rand('acoperire: fiecare cheie pe care adaptorul o citeste (derivata din sursa lui) e clasificata pe felul ei, si la felurile date intregi fiecare cheie a modulului', async () => { const feluri = Object.keys(M.DOMENIUL).filter((k) => !M.FELURI_PROPRII.includes(k)); const h = cheileAdaptorului(fs.readFileSync(ADAPTOR, 'utf8'), feluri); const R = await import(pathToFileURL(path.join(SUITA, 'reguli.mjs')).href); const deModul = (f) => { const x = h[f]; if (!x || !x.tot || !x.modul || !x.fn) return null; try { return cheileModulului(fs.readFileSync(R.caleModul(x.modul), 'utf8'), x.fn); } catch { return null; } }; // controlul pozitiv al metodei: chei care SIGUR sunt citite trebuie gasite, altfel nicio lipsa de mai jos nu inseamna nimic (revizia B2: si cheile // modulelor date intregi, arbitrul pietei si faptele reputatiei, pe care organizatia le alegea singura) const mt = deModul('market-timeline'), rp = deModul('device-reputation'); const pozitiv = h && h['identity-presentation']?.chei.includes('trustedIssuers') && h['travel-rule-message']?.chei.includes('kem') && h['device-reputation']?.tot && h['market-timeline']?.tot && h.envelope?.chei.includes('raw') && feluri.every((f) => h[f]) && mt && ['constants', 'job', 'events'].every((k) => mt.includes(k)) && rp && ['facts', 'params', 'claimed'].every((k) => rp.includes(k)); if (!pozitiv) return [false, 'derivarea din sursa adaptorului sau a modulelor nu a gasit cheile care sigur exista (metoda moarta)']; const lipsa = []; let nModul = 0; for (const f of feluri) { const cls = M.INTRARI[f]; if (!(cls && typeof cls === 'object')) { lipsa.push(`${f}: fara clasificare pe chei`); continue; } for (const k of h[f].chei) if (!Object.hasOwn(cls, k)) lipsa.push(`${f}.${k}`); if (h[f].tot) { const km = deModul(f); if (!km) { lipsa.push(`${f}: cheile modulului nu s-au putut deriva`); continue; } nModul += km.length; for (const k of km) if (!Object.hasOwn(cls, k)) lipsa.push(`${f}.${k} (modulul)`); if (cls['*'] !== 'artifact') lipsa.push(`${f}: dat intreg modulului, dar o cheie necunoscuta nu ajunge la el ca a artefactului`); } else if (Object.hasOwn(cls, '*')) lipsa.push(`${f}: '*' la un fel pe care adaptorul nu il da intreg`); } return [!lipsa.length, `${feluri.length} feluri, ${feluri.reduce((n, f) => n + h[f].chei.length, 0)} chei citite de adaptor, ${nModul} de modulele date intregi; neclasificate: ${lipsa.join(', ') || '-'}`]; }); rand('acoperire: felurile judecate citind lantul cu --online sunt exact cele ale adaptorului (derivate din sursa lui), plus raportul PQ prin plicul lui', async () => { const feluri = Object.keys(M.DOMENIUL).filter((k) => !M.FELURI_PROPRII.includes(k)); const h = cheileAdaptorului(fs.readFileSync(ADAPTOR, 'utf8'), feluri); const derivate = [...feluri.filter((f) => h[f] && h[f].lant), 'pq-compliance-report'].sort(); const pozitiv = derivate.includes('envelope') && derivate.includes('ai-trust-bundle') && !derivate.includes('identity-presentation'); return [pozitiv && eq(derivate, [...M.CITESC_LANTUL].sort()), `derivate ${derivate.join(',')}; aici ${[...M.CITESC_LANTUL].sort().join(',')}`]; }); rand('acoperire: fiecare cheie de intrare din toti vectorii suitei e clasificata (inputurile reale ale producatorilor)', async () => { const { j, dir } = indexul(); const lipsa = []; for (const v of j.vectors) { const x = JSON.parse(fs.readFileSync(path.join(dir, ...v.id.split('/')) + '.json', 'utf8')); try { imparte(v.artifact, x.input); } catch (e) { lipsa.push(e.message); } } return [!lipsa.length && j.vectors.length >= 791, `${j.vectors.length} vectori; ${lipsa.slice(0, 3).join('; ') || 'toti clasificati'}`]; }); rand('vectorii folositi sunt cei scrisi de generator (amprenta din INDEX.json, ceruta la citire)', async () => { const ids = Object.values(F.ales).flatMap((x) => [x.bun.id, x.rau.id]); return [ids.length === 46 && new Set(ids).size === 46, `${ids.length} vectori (un bun si un frate stricat pentru fiecare din cele 23 de feluri ale suitei)`]; }); // ---- compunerea, pe pachetul bun rand('pachetul bun: fiecare artefact are exact verdictul, regulile si starile nivelurilor din vectorul lui (25 de feluri)', async () => { const o = await bun(); const rele = []; for (const [id, e] of Object.entries(F.asteptat)) { const r = art(o, id); if (!r || r.verdict !== e.verdict || !eq(r.failed, e.failed) || (e.levels && !eq(stari(r.levels), stariAsteptate(e.levels)))) rele.push(`${id}: ${r ? r.verdict + ' ' + r.failed.join(',') + (r.error ? ' ' + r.error : '') + (r.capped ? ' capped' : '') : 'lipsa'} fata de ${e.verdict}`); } return [!rele.length && o.artifacts.length === 25, `${o.artifacts.length} artefacte; ${rele.join('; ') || 'toate ca vectorii lor'}`]; }); const domeniulAsteptat = (o, d) => M.celMaiSlab(o.artifacts.filter((r) => r.domain === d).map((r) => F.asteptat[r.id].verdict)); rand('pachetul bun: fiecare domeniu e cel mai slab artefact al lui (asteptat din vectori)', async () => { const o = await bun(); const rele = o.domains.filter((d) => d.verdict !== domeniulAsteptat(o, d.domain)).map((d) => `${d.domain} ${d.verdict}`); return [!rele.length && o.domains.length === 8, rele.join(', ') || o.domains.map((d) => d.domain + ' ' + d.verdict).join(', ')]; }); rand('pachetul bun: rezumatul (toate domeniile cerute, implicit) e cel mai slab domeniu, si il numeste', async () => { const o = await bun(); const asteptat = M.celMaiSlab(o.domains.map((d) => domeniulAsteptat(o, d.domain))); const slabe = o.domains.filter((d) => domeniulAsteptat(o, d.domain) === asteptat).map((d) => d.domain); return [o.summary.verdict === asteptat && asteptat !== 'VALID' && eq(o.summary.weakest, slabe) && o.required.domains.length === 8, `${o.summary.verdict} (asteptat ${asteptat}), cel mai slab ${o.summary.weakest.join(',')}`]; }); rand('pachetul bun, cerute numai domeniile VALID: rezumatul VALID; domeniul necerut e numit alaturi', async () => { const o0 = await bun(); const valide = o0.domains.filter((d) => d.verdict === 'VALID').map((d) => d.domain); const o = await judeca(F.pack, { require: valide }); return [o.summary.verdict === 'VALID' && valide.length >= 6 && Object.keys(o.summary.outsideRequired).length === 8 - valide.length && M.codulIesirii(o.summary.verdict) === 0, `${o.summary.verdict}, cerute ${valide.length}, in afara: ${JSON.stringify(o.summary.outsideRequired)}`]; }); // ---- cate un artefact stricat din fiecare fel for (const [fel, s] of Object.entries(F.stricate)) { rand(`stricat ${fel}: refuzat pentru ${s.failed.join(',')}, domeniul lui INVALID, celelalte neatinse, rezumatul INVALID`, async () => { const o0 = await bun(); const o = await judeca(inlocuieste(F.pack, s.id, s.artifact)); const r = art(o, s.id); const d = dom(o, r.domain); const altele = o.domains.filter((x) => x.domain !== r.domain).every((x) => x.verdict === dom(o0, x.domain).verdict); const ok = r.verdict === 'INVALID' && eq(r.failed, s.failed) && (!s.levels || eq(stari(r.levels), stariAsteptate(s.levels))) && d.verdict === 'INVALID' && eq(d.failed, s.failed) && altele && o.summary.verdict === 'INVALID' && eq(o.summary.weakest, [r.domain]); return [ok, `${r.verdict} ${r.failed.join(',')}${r.error ? ' ' + r.error : ''}; domeniul ${d.domain} ${d.verdict}; rezumat ${o.summary.verdict} (${o.summary.weakest.join(',')})${s.vector ? '; vectorul ' + s.vector : ''}`]; }); } // ---- paznicii judecatii rand('domeniu neprezentat: NOT_PRESENTED (nu verde), iar rezumatul cu el cerut e NOT_MEASURED si il numeste', async () => { let p = F.pack; for (const a of F.pack.artifacts.filter((x) => M.DOMENIUL[x.artifact] === 'devices')) p = inlocuieste(p, a.id, null); const o = await judeca(p); const d = dom(o, 'devices'); return [d.verdict === 'NOT_PRESENTED' && !d.artifacts.length && o.summary.verdict === 'NOT_MEASURED' && o.summary.notPresented.includes('devices') && o.summary.weakest.includes('devices'), `devices ${d.verdict}; rezumat ${o.summary.verdict}, neprezentate ${o.summary.notPresented.join(',')}`]; }); rand('domeniu neprezentat si necerut: rezumatul nu e atins de el', async () => { const o0 = await bun(); const valide = o0.domains.filter((d) => d.verdict === 'VALID' && d.domain !== 'devices').map((d) => d.domain); let p = F.pack; for (const a of F.pack.artifacts.filter((x) => M.DOMENIUL[x.artifact] === 'devices')) p = inlocuieste(p, a.id, null); const o = await judeca(p, { require: valide }); return [o.summary.verdict === 'VALID' && dom(o, 'devices').verdict === 'NOT_PRESENTED', `${o.summary.verdict}`]; }); rand('adaptorul suitei lipsa: artefactele lui NOT_MEASURED (nu VALID, nu INVALID), numite; Shield tot judecat; rezumatul NOT_MEASURED', async () => { const o = await judeca(F.pack, { adaptor: path.join(T, 'nu-exista', 'implementare-aere.mjs') }); const prinAdaptor = o.artifacts.filter((r) => !M.FELURI_PROPRII.includes(r.artifact)); const ok = prinAdaptor.length === 23 && prinAdaptor.every((r) => r.verdict === 'NOT_MEASURED' && /conformance adapter is not at/.test(r.error || '')) && art(o, 'shield-console-1').verdict === 'VALID' && o.summary.verdict === 'NOT_MEASURED'; return [ok, `${prinAdaptor.filter((r) => r.verdict === 'NOT_MEASURED').length}/23 NOT_MEASURED; shield ${art(o, 'shield-console-1').verdict}; raport ${art(o, 'pq-compliance-report-1').verdict}; rezumat ${o.summary.verdict}`]; }); rand('verificatorul de referinta AIP-23 lipsa: ce cere plicuri iese NOT_MEASURED cu motivul numit, restul neatins', async () => { const vechi = process.env.AERE_VERIFY_PROOF; process.env.AERE_VERIFY_PROOF = path.join(T, 'nu-exista', 'verify-proof.mjs'); let o; try { o = await judeca(F.pack); } finally { if (vechi === undefined) delete process.env.AERE_VERIFY_PROOF; else process.env.AERE_VERIFY_PROOF = vechi; } const o0 = await bun(); const cazute = o.artifacts.filter((r) => r.verdict === 'NOT_MEASURED'); const ok = ['envelope-1', 'pq-compliance-report-1'].every((id) => art(o, id).verdict === 'NOT_MEASURED') && cazute.every((r) => /reference verifier/.test(r.error || '')) && o.artifacts.filter((r) => r.verdict !== 'NOT_MEASURED').every((r) => r.verdict === art(o0, r.id).verdict) && art(o, 'identity-presentation-1').verdict === 'VALID'; return [ok, `${cazute.length} NOT_MEASURED: ${cazute.map((r) => r.id).join(', ')}`]; }); const stub = (nume, corp) => { const f = path.join(T, nume); fs.writeFileSync(f, `import fs from 'node:fs'; const a = process.argv.slice(2); const lista = JSON.parse(fs.readFileSync(a[a.indexOf('--batch') + 1], 'utf8'));\nconst felul = (x) => JSON.parse(fs.readFileSync(x.file, 'utf8')).artifact;\n${corp}\n`); return f; }; // un verdict in forma suitei (kind, artifact = felul cerut), cu starile date; `cauza` pe nivelurile nemasurate const VERD = (verdict, failed, stari, cauza = 'not-judged') => `({ v: 1, kind: 'aere-conformance-verdict', artifact: felul(x), verdict: ${JSON.stringify(verdict)}, failed: ${JSON.stringify(failed)}, levels: ${JSON.stringify(['integrity', 'authenticity', 'anchoring', 'finality'].map((l, i) => ({ level: l, state: stari[i], rules: stari[i] === 'FAILED' ? failed : [], ...(stari[i] === 'NOT_MEASURED' ? { cause: typeof cauza === 'string' ? cauza : cauza[i] } : {}), reason: 'x' })))} })`; const REALUL = JSON.stringify(path.join(SUITA, 'implementare-aere.mjs')); rand('un adaptor care da in lot mai putine verdicte decat artefacte: lotul nu e crezut, fiecare artefact e judecat SINGUR si are verdictul lui', async () => { // adaptorul real, care in lot (mai mult de un artefact) pierde ultimul verdict; singur, raspunde intreg const f = stub('putine.mjs', `import { spawnSync } from 'node:child_process'; const r = spawnSync(process.execPath, [${REALUL}, ...a], { encoding: 'utf8', maxBuffer: 1 << 28 });\nconst l = r.stdout.split('\\n').filter((x) => x.trim()); process.stdout.write((lista.length > 1 ? l.slice(0, -1) : l).join('\\n') + '\\n');`); const o0 = await bun(); const o = await judeca(F.pack, { adaptor: f }); const rele = o.artifacts.filter((r) => r.verdict !== art(o0, r.id).verdict || (r.failed || []).join() !== (art(o0, r.id).failed || []).join()).map((r) => `${r.id} ${r.verdict}${r.error ? ' ' + r.error.slice(0, 80) : ''}`); return [!rele.length && o.artifacts.length === 25, `${o.artifacts.length} artefacte; altfel decat judecata directa: ${rele.join('; ') || '-'}`]; }); rand('un adaptor care da un verdict incoerent (VALID cu o regula refuzata): NOT_MEASURED, nu VALID', async () => { const f = stub('incoerent.mjs', `for (const x of lista) console.log(JSON.stringify(${VERD('VALID', ['identity.form'], ['FAILED', 'NOT_MEASURED', 'NOT_MEASURED', 'NOT_MEASURED'])}));`); const o = await judeca(F.pack, { adaptor: f }); const prin = o.artifacts.filter((r) => !M.FELURI_PROPRII.includes(r.artifact)); return [prin.every((r) => r.verdict === 'NOT_MEASURED') && o.summary.verdict === 'NOT_MEASURED', `${prin.filter((r) => r.verdict === 'NOT_MEASURED').length}/${prin.length} NOT_MEASURED`]; }); rand('un adaptor care spune VALID cu integritatea nemasurata, sau peste o afirmatie nemasurata: verdictul nu e cel pe care il dau nivelurile lui, NOT_MEASURED', async () => { const f1 = stub('fara-integritate.mjs', `for (const x of lista) console.log(JSON.stringify(${VERD('VALID', [], ['NOT_MEASURED', 'NOT_MEASURED', 'NOT_MEASURED', 'NOT_MEASURED'])}));`); const f2 = stub('afirmatie.mjs', `for (const x of lista) console.log(JSON.stringify(${VERD('VALID', [], ['PASSED', 'NOT_MEASURED', 'NOT_MEASURED', 'NOT_MEASURED'], [null, 'not-judged', 'claim-not-checked', 'not-judged'])}));`); const a = await judeca(F.pack, { adaptor: f1 }), b = await judeca(F.pack, { adaptor: f2 }); const prin = (o) => o.artifacts.filter((r) => !M.FELURI_PROPRII.includes(r.artifact)); const ok = [a, b].every((o) => prin(o).length === 23 && prin(o).every((r) => r.verdict === 'NOT_MEASURED' && /not a verdict of the suite's form/.test(r.error || ''))); return [ok, `integritate nemasurata: ${prin(a).filter((r) => r.verdict === 'NOT_MEASURED').length}/23; afirmatie nemasurata: ${prin(b).filter((r) => r.verdict === 'NOT_MEASURED').length}/23 NOT_MEASURED`]; }); rand('finalitatea citita isi numeste lantul: una pe un testnet e spusa ca atare in iesire si in rezumat, nu doar in motivul nivelului (adaptor de proba)', async () => { // fara retea: un adaptor care raspunde coerent, cu finalitatea in forma adaptorului real ("(chain 28001, a testnet; the finality is that chain's)") const f = stub('final.mjs', `for (const x of lista) { const v = ${VERD('VALID', [], ['PASSED', 'PASSED', 'PASSED', 'PASSED'])}; v.levels[3].reason = 'the post-quantum certificate of the covering anchor verified (chain 28001, a testnet; the finality is that chain\\'s)'; console.log(JSON.stringify(v)); }`); const n = notarizat(); const o = await M.judecaPachetul(n.pack, { context: n.context, adaptor: f }); return [art(o, 'notar').verdict === 'VALID' && eq(o.network.finality, [{ id: 'notar', chain: 28001, testnet: true }]) && /final only on a testnet \(chain 28001\)/.test(o.summary.reason), `${art(o, 'notar').verdict}; ${JSON.stringify(o.network.finality)}; ${o.summary.reason}`]; }); rand('un adaptor care raspunde in alta ordine: niciun raspuns al lotului nu e crezut (artefactul stricat nu primeste verdictul altuia)', async () => { const f = stub('invers.mjs', `import { spawnSync } from 'node:child_process'; const r = spawnSync(process.execPath, [${REALUL}, ...a], { encoding: 'utf8', maxBuffer: 1 << 28 });\nprocess.stdout.write(r.stdout.split('\\n').filter((x) => x.trim()).reverse().join('\\n') + '\\n');`); const s = F.stricate['identity-presentation']; const o = await judeca(inlocuieste(F.pack, s.id, s.artifact), { adaptor: f }); const prin = o.artifacts.filter((r) => !M.FELURI_PROPRII.includes(r.artifact)); return [prin.length === 23 && prin.every((r) => r.verdict === 'NOT_MEASURED' && /order of its answers/.test(r.error || '')) && art(o, s.id).verdict === 'NOT_MEASURED' && dom(o, 'identity').verdict !== 'VALID', `${prin.filter((r) => r.verdict === 'NOT_MEASURED').length}/23 NOT_MEASURED; identitatea stricata ${art(o, s.id).verdict}`]; }); rand('un artefact care tine adaptorul pe loc nu ia cu el verdictele celorlalte din lot (fiecare e judecat singur, cel lent NOT_MEASURED)', async () => { // un esantion al unui set de zece milioane de inregistrari, cu k ales de pachet: adaptorul nu termina in plafonul de timp dat const v = vectorul('identity-presentation/direct.valid'), iv = imparte('identity-presentation', v.input); const ds = vectorul(F.ales['dataset-sample'].bun.id), id = imparte('dataset-sample', ds.input); const lent = JSON.parse(JSON.stringify({ ...id.pack, ...id.context })); lent.commitment.size = 1e7; lent.k = 1e7; const pack = { v: 1, kind: M.PACK_KIND, artifacts: [{ id: 'kyc', artifact: 'identity-presentation', input: iv.pack }, { id: 'lent', artifact: 'dataset-sample', input: lent }] }; const o = await M.judecaPachetul(pack, { context: ctx({ kyc: iv.context }), timeoutS: 8 }); const k = art(o, 'kyc'), l = art(o, 'lent'); return [k.verdict === v.expected.verdict && l.verdict === 'NOT_MEASURED' && /did not finish in 8 s/.test(l.error || '') && /judged alone/.test(l.error || ''), `kyc ${k.verdict}${k.error ? ' ' + k.error.slice(0, 100) : ''}; lent ${l.verdict} ${String(l.error || '').slice(0, 160)}`]; }); rand('pachet fara context: intrarile verificatorului aduse de organizatie nu dau VALID (self-supplied, numite); ceasul pachetului aruncat', async () => { // fiecare artefact cu inputul INTREG al vectorului (si increderea, si ceasul, in pachet), fara context const p = JSON.parse(JSON.stringify(F.pack)); const asteptPartial = []; for (const a of p.artifacts) { const e = F.asteptat[a.id]; if (!e.vector) continue; const v = vectorul(e.vector); a.input = v.input; const c = imparte(a.artifact, v.input).context; if (Object.keys(c).some((k) => M.INTRARI[a.artifact][k] === 'verifier') && e.verdict === 'VALID') asteptPartial.push(a.id); } const o = await M.judecaPachetul(p, { context: null, at: '2026-10-20T09:00:00Z' }); const rele = asteptPartial.filter((id) => { const r = art(o, id); return r.verdict === 'VALID' || !r.inputs.selfSupplied.length; }); const cuNow = p.artifacts.filter((a) => a.input && Object.hasOwn(a.input, 'now')).map((a) => art(o, a.id)); const ceasOk = cuNow.length > 5 && cuNow.every((r) => r.inputs.dropped.includes('now') && r.inputs.now.source === '--at'); return [asteptPartial.length >= 10 && !rele.length && ceasOk && o.summary.verdict !== 'VALID', `${asteptPartial.length} artefacte cu incredere adusa de pachet; VALID totusi: ${rele.join(',') || '-'}; ceasul aruncat pe ${cuNow.length}`]; }); rand('atac: emitentii de incredere ai organizatiei nu inlocuiesc pe ai celui care verifica (identity.issuer-trusted)', async () => { const b = vectorul('identity-presentation/direct.valid'), m = vectorul('identity-presentation/direct.issuer-trusted'); const pack = { v: 1, kind: M.PACK_KIND, artifacts: [{ id: 'kyc', artifact: 'identity-presentation', input: b.input }] }; // pachetul isi aduce increderea lui const o = await M.judecaPachetul(pack, { context: ctx({ kyc: imparte('identity-presentation', m.input).context }) }); const r = art(o, 'kyc'); return [r.verdict === 'INVALID' && eq(r.failed, m.expected.failed) && r.inputs.fromContext.includes('trustedIssuers') && !r.inputs.selfSupplied.includes('trustedIssuers'), `${r.verdict} ${r.failed.join(',')}`]; }); rand('ceasul pachetului nu se foloseste niciodata: prezentarea veche pe ceasul celui care verifica (identity.freshness)', async () => { // pachetul isi aduce ceasul de cand prezentarea era proaspata; cel care verifica nu da ceas in context, ci il ruleaza la ora lui (--at) const b = vectorul('identity-presentation/direct.valid'), m = vectorul('identity-presentation/direct.freshness'); const { now: _faraCeas, ...c } = imparte('identity-presentation', m.input).context; const pack = { v: 1, kind: M.PACK_KIND, artifacts: [{ id: 'kyc', artifact: 'identity-presentation', input: { ...imparte('identity-presentation', b.input).pack, now: b.input.now } }] }; const o = await M.judecaPachetul(pack, { context: ctx({ kyc: c }), at: m.input.now }); const r = art(o, 'kyc'); return [r.verdict === 'INVALID' && eq(r.failed, m.expected.failed) && r.inputs.dropped.includes('now') && r.inputs.now.source === '--at' && b.input.now !== m.input.now, `${r.verdict} ${r.failed.join(',')}; now ${r.inputs.now && r.inputs.now.source}`]; }); rand('o lista de stare adusa de cel care verifica se adauga celor din pachet: revocarea retinuta de organizatie e gasita', async () => { const b = vectorul('identity-presentation/direct.valid'), m = vectorul('identity-presentation/direct.credential-revoked-second-list'); const ib = imparte('identity-presentation', b.input); const pack = { v: 1, kind: M.PACK_KIND, artifacts: [{ id: 'kyc', artifact: 'identity-presentation', input: ib.pack }] }; // numai lista curata const o = await M.judecaPachetul(pack, { context: ctx({ kyc: { ...ib.context, statusLists: [m.input.statusLists[1]] } }) }); const r = art(o, 'kyc'); return [r.verdict === 'INVALID' && eq(r.failed, m.expected.failed) && r.inputs.stapled.statusLists === 'context+pack', `${r.verdict} ${r.failed.join(',')}; listele: ${r.inputs.stapled.statusLists}`]; }); rand('atac: 64 de liste de rechemare curate in pachet nu imping afara rechemarea adusa de cel care verifica (device.manufacture-revoked)', async () => { // verificatorul masinilor judeca primele 64 de liste; cu listele pachetului inainte, rechemarea celui care verifica era a 65-a si INVALID devenea PARTIAL const b = vectorul('device-bundle/sold-once.valid'), m = vectorul('device-bundle/sold-once.manufacture-revoked'); const ib = imparte('device-bundle', b.input), im = imparte('device-bundle', m.input); const curata = ib.pack.statusLists[0], revoca = im.pack.statusLists; const pack = { v: 1, kind: M.PACK_KIND, artifacts: [{ id: 'dev', artifact: 'device-bundle', input: { ...im.pack, statusLists: Array.from({ length: 64 }, () => curata) } }] }; const o = await M.judecaPachetul(pack, { context: ctx({ dev: { ...im.context, statusLists: revoca } }) }); const r = art(o, 'dev'); return [!!curata && revoca.length > 0 && r.verdict === 'INVALID' && eq(r.failed, m.expected.failed) && r.inputs.stapled.statusLists === 'context+pack', `${r.verdict} ${r.failed.join(',')}; listele ${r.inputs.stapled.statusLists}`]; }); rand('atac: arbitrul pietei e al celui care verifica: o disputa rezolvata de organizatia care se numeste singura arbitru nu e VALID (market.arbiter)', async () => { const b = vectorul('market-timeline/s2-slashed.valid'), m = vectorul('market-timeline/s2.arbiter'); const inp = JSON.parse(JSON.stringify(m.input)); inp.constants.arbiter = inp.events.find((e) => e.name === 'DisputeResolved').from; // arbitrul ales de pachet const pack = { v: 1, kind: M.PACK_KIND, artifacts: [{ id: 'mt', artifact: 'market-timeline', input: inp }] }; const cu = art(await M.judecaPachetul(pack, { context: ctx({ mt: { constants: b.input.constants } }) }), 'mt'); const fara = art(await M.judecaPachetul(pack, { context: null }), 'mt'); return [cu.verdict === 'INVALID' && eq(cu.failed, m.expected.failed) && cu.inputs.fromContext.includes('constants') && fara.verdict === 'PARTIAL' && fara.inputs.selfSupplied.includes('constants'), `cu constantele celui care verifica: ${cu.verdict} ${cu.failed.join(',')}; fara context: ${fara.verdict} (din pachet: ${fara.inputs.selfSupplied.join(',')})`]; }); rand('atac: faptele reputatiei sunt ale celui care verifica (derivate de el din jurnal): cifrele pe faptele altui jurnal nu sunt VALID (reputation.figures)', async () => { const h = vectorul('device-reputation/honest.h1.valid'), s = vectorul('device-reputation/sparse.h1.valid'); const pack = { v: 1, kind: M.PACK_KIND, artifacts: [{ id: 'rep', artifact: 'device-reputation', input: h.input }] }; // organizatia isi aduce faptele const cu = art(await M.judecaPachetul(pack, { context: ctx({ rep: { facts: s.input.facts } }) }), 'rep'); const fara = art(await M.judecaPachetul(pack, { context: null }), 'rep'); return [cu.verdict === 'INVALID' && eq(cu.failed, ['reputation.figures']) && fara.verdict === 'PARTIAL' && fara.inputs.selfSupplied.includes('facts'), `cu faptele celui care verifica: ${cu.verdict} ${cu.failed.join(',')}; fara context: ${fara.verdict} (din pachet: ${fara.inputs.selfSupplied.join(',')})`]; }); rand('atac: un raport PQ cu rezumatul rescris peste propriile constatari si legat din nou de plic nu e VALID (pqreport.derivation)', async () => { const a = F.pack.artifacts.find((x) => x.artifact === 'pq-compliance-report'); const RC = await import(pathToFileURL(path.join(AICI, 'raport-conformitate.mjs')).href); // constructorul de plicuri din acelasi loc din care il ia raport-conformitate.mjs: langa planul de control (copia publica) sau in tools/ const pk = [path.join(AICI, '..', 'proof-kinds', 'proof-kinds.mjs'), path.join(AICI, '..', '..', 'tools', 'proof-kinds', 'proof-kinds.mjs')].find((p) => fs.existsSync(p)); if (!pk) return [false, 'constructorul de plicuri (proof-kinds.mjs) nu e nici langa planul de control, nici in tools/']; const { buildProof } = await import(pathToFileURL(pk).href); const rep = JSON.parse(JSON.stringify(a.input.report)); const expuse = rep.findings.filter((f) => f.exposedToday === true).length; rep.summary.verdict = 'no quantum-vulnerable public-key algorithm in what was measured'; rep.summary.exposedToday = 0; const env = buildProof('compliance', { subject: rep.organization, policy: rep.version, result: rep.summary.verdict, evidenceHash: RC.sha256Canonic(rep), createdAt: rep.date + 'T00:00:00Z' }); const o = await M.judecaPachetul({ v: 1, kind: M.PACK_KIND, artifacts: [{ id: 'r', artifact: 'pq-compliance-report', input: { report: rep, envelope: env } }] }, { context: null }); const r = art(o, 'r'); return [expuse > 0 && RC.verifyReport(rep, env).ok && r.verdict === 'INVALID' && eq(r.failed, ['pqreport.derivation']) && art(await bun(), a.id).verdict === 'VALID', `${expuse} constatari expuse azi sub un rezumat "fara algoritmi vulnerabili", legat: ${RC.verifyReport(rep, env).ok}; ${r.verdict} ${r.failed.join(',')}`]; }); rand('un raport PQ al carui plic cere o notarizare e numit in network.needed fara --online', async () => { const a = JSON.parse(JSON.stringify(F.pack.artifacts.find((x) => x.artifact === 'pq-compliance-report'))); a.input.envelope.notarization = { chainId: 28001, notary: '0x' + '11'.repeat(20), txHash: '0x' + '22'.repeat(32), block: 1, firstSeen: 1 }; const o = await M.judecaPachetul({ v: 1, kind: M.PACK_KIND, artifacts: [a] }, { context: null }); const r = art(o, a.id); return [r.verdict === 'PARTIAL' && eq(o.network.needed, [a.id]) && /notarization that was not read \(no --online\)/.test(o.summary.reason), `${r.verdict}; ${JSON.stringify(o.network)}`]; }); rand('o masina a carei notarizare se judeca pe citirile celui care verifica: numita in network.readings, nu in needed, si nimic nu cere --online cand e dat', async () => { const v = vectorul('device-bundle/notarization-not-read.partial'), i = imparte('device-bundle', v.input); const o = await M.judecaPachetul({ v: 1, kind: M.PACK_KIND, artifacts: [{ id: 'dev', artifact: 'device-bundle', input: i.pack }] }, { context: ctx({ dev: i.context }), online: true }); return [art(o, 'dev').verdict === 'PARTIAL' && eq(o.network.readings, ['dev']) && !o.network.needed.length && !/no --online/.test(o.summary.reason) && /relying party's own readings/.test(o.summary.reason), `${art(o, 'dev').verdict}; ${JSON.stringify(o.network)}`]; }); rand('ceasul: un `now` pe artefact sau pe fel al contextului, apoi --at, apoi `now` global al contextului (cum spune README-ul)', async () => { const v = vectorul('identity-presentation/direct.valid'), i = imparte('identity-presentation', v.input); const { now: _n, ...c } = i.context; const pack = { v: 1, kind: M.PACK_KIND, artifacts: [{ id: 'kyc', artifact: 'identity-presentation', input: i.pack }] }; const a = await M.judecaPachetul(pack, { context: { ...ctx({ kyc: c }), now: '2026-01-01T00:00:00Z' }, at: v.input.now }); const b = await M.judecaPachetul(pack, { context: { ...ctx({ kyc: { ...c, now: v.input.now } }), now: '2026-01-01T00:00:00Z' }, at: '2026-01-02T00:00:00Z' }); const d = await M.judecaPachetul(pack, { context: { ...ctx({ kyc: c }), now: v.input.now } }); const ok = a.clock.source === '--at' && art(a, 'kyc').inputs.now.source === '--at' && art(b, 'kyc').inputs.now.source === 'context' && art(b, 'kyc').inputs.now.value === v.input.now && d.clock.source === 'context' && art(d, 'kyc').verdict === 'VALID'; return [ok, `--at peste now global: ${a.clock.source}; now pe artefact peste --at: ${art(b, 'kyc').inputs.now.source}; numai now global: ${d.clock.source} ${art(d, 'kyc').verdict}`]; }); rand('verdictele scrise de pachet sunt ignorate, iar cele care difera de masuratoare sunt numite', async () => { const s = F.stricate['identity-presentation']; const p = inlocuieste(F.pack, s.id, { ...s.artifact, verdict: 'VALID', expected: { verdict: 'VALID' } }); p.summary = { verdict: 'VALID' }; p.verdict = 'VALID'; const o = await judeca(p); const unde = o.selfReport.suspect.map((x) => x.where); return [o.summary.verdict === 'INVALID' && art(o, s.id).verdict === 'INVALID' && ['pack.verdict', 'pack.summary.verdict', `artifact ${s.id}: verdict`, `artifact ${s.id}: expected.verdict`].every((w) => unde.includes(w)), `rezumat ${o.summary.verdict}; suspecte: ${unde.join(' | ')}`]; }); const notarizat = () => { const v = vectorul('envelope/notarized-28001.valid'); const i = imparte('envelope', v.input); return { v, pack: { v: 1, kind: M.PACK_KIND, artifacts: [{ id: 'notar', artifact: 'envelope', input: i.pack }] }, context: ctx({ notar: i.context }) }; }; rand('fara --online: un plic notarizat e PARTIAL, finalitatea "claim-not-checked", si e numit ca cerand reteaua', async () => { const n = notarizat(); const o = await M.judecaPachetul(n.pack, { context: n.context }); const r = art(o, 'notar'); return [r.verdict === 'PARTIAL' && r.levels[3].cause === 'claim-not-checked' && o.network.online === false && eq(o.network.needed, ['notar']) && /notarization that was not read/.test(o.summary.reason), `${r.verdict}, ${r.levels[3].cause}; network ${JSON.stringify(o.network)}`]; }); rand('cu --online catre un capat inchis: adaptorul chiar citeste (finalitatea nemasurabila, numita), nu mai e "claim-not-checked"', async () => { const n = notarizat(); const vechi = process.env.AERE_CONFORMANCE_RPC_28001; process.env.AERE_CONFORMANCE_RPC_28001 = 'http://127.0.0.1:9'; let o; try { o = await M.judecaPachetul(n.pack, { context: n.context, online: true }); } finally { if (vechi === undefined) delete process.env.AERE_CONFORMANCE_RPC_28001; else process.env.AERE_CONFORMANCE_RPC_28001 = vechi; } const r = art(o, 'notar'); return [r.verdict === 'PARTIAL' && r.levels[3].cause === 'unmeasurable' && o.network.online === true && !o.network.needed.length && eq(o.network.unmeasured, ['notar']) && /the chain could not be read for 1 artifact/.test(o.summary.reason) && !o.network.finality.length, `${r.verdict}, ${r.levels[3].cause}; ${JSON.stringify(o.network)}`]; }); rand('un fel pe care nu il judeca nimeni aici: nejudecat, numit, si rezumatul nu mai poate fi VALID', async () => { const o0 = await bun(); const valide = o0.domains.filter((d) => d.verdict === 'VALID').map((d) => d.domain); const p = JSON.parse(JSON.stringify(F.pack)); p.artifacts.push({ id: 'oracol-1', artifact: 'quantum-oracle', input: { says: 'VALID' } }); const o = await judeca(p, { require: valide }); return [o.summary.verdict === 'PARTIAL' && o.unjudged.length === 1 && o.unjudged[0].id === 'oracol-1' && o.artifacts.length === 25, `${o.summary.verdict}; nejudecate ${o.unjudged.map((u) => u.id).join(',')}`]; }); rand('un id repetat: primul judecat, al doilea NOT_MEASURED si numit; domeniul nu mai e VALID', async () => { const p = JSON.parse(JSON.stringify(F.pack)); const a = p.artifacts.find((x) => x.id === 'identity-presentation-1'); p.artifacts.push(JSON.parse(JSON.stringify(a))); const o = await judeca(p); const doi = o.artifacts.filter((r) => r.id === 'identity-presentation-1'); return [doi.length === 2 && doi[0].verdict === 'VALID' && doi[1].verdict === 'NOT_MEASURED' && /more than once/.test(doi[1].error) && dom(o, 'identity').verdict === 'NOT_MEASURED', `${doi.map((r) => r.verdict).join(',')}; identity ${dom(o, 'identity').verdict}`]; }); rand('pachet necitibil sau context necitibil: NOT_MEASURED cu motivul, niciun domeniu judecat', async () => { const a = await M.judecaPachetul({ kind: 'altceva' }); const b = await M.judecaPachetul(F.pack, { context: { kind: 'altceva' } }); return [a.summary.verdict === 'NOT_MEASURED' && /pack cannot be read/.test(a.summary.reason) && b.summary.verdict === 'NOT_MEASURED' && /context cannot be read/.test(b.summary.reason) && a.domains.every((d) => d.verdict === 'NOT_PRESENTED'), `${a.summary.reason} | ${b.summary.reason}`]; }); rand('cheile KEM private nu se citesc din pachet: aruncate si numite; fara cele din context mesajul nu se judeca (NOT_MEASURED)', async () => { const v = vectorul('travel-rule-message/sealed.valid'); const i = imparte('travel-rule-message', v.input); const pack = { v: 1, kind: M.PACK_KIND, artifacts: [{ id: 'msg', artifact: 'travel-rule-message', input: v.input }] }; // cheile private in pachet const { kem, ...faraKem } = i.context; const o = await M.judecaPachetul(pack, { context: ctx({ msg: faraKem }) }); const r = art(o, 'msg'); const o2 = await M.judecaPachetul(pack, { context: ctx({ msg: i.context }) }); const r2 = art(o2, 'msg'); return [kem && r.verdict === 'NOT_MEASURED' && r.inputs.dropped.includes('kem') && r2.verdict === 'VALID' && r2.inputs.fromContext.includes('kem'), `fara context: ${r.verdict} (${r.error || ''}); cu context: ${r2.verdict}`]; }); rand('un context nu poate scrie artefactul organizatiei: cheia lui e ignorata si numita', async () => { const s = F.stricate['identity-presentation']; const c = JSON.parse(JSON.stringify(F.context)); c.byArtifact['identity-presentation-1'].presentation = s.artifact.input.presentation; const o = await judeca(F.pack, { context: c }); const r = art(o, 'identity-presentation-1'); return [r.verdict === 'VALID' && r.inputs.contextIgnored.includes('presentation'), `${r.verdict}; ignorate ${r.inputs.contextIgnored.join(',')}`]; }); // ---- starea Shield, in fiecare fel in care se strica (consola.mjs o judeca; aici se masoara ca refuzul ajunge cu regula lui) const shieldCu = async (f) => { const i = JSON.parse(JSON.stringify(F.pack.artifacts.find((a) => a.id === 'shield-console-1').input)); await f(i); return art(await judeca(inlocuieste(F.pack, 'shield-console-1', { id: 'shield-console-1', artifact: 'shield-console', input: i })), 'shield-console-1'); }; rand('Shield: o intrare a jurnalului schimbata (lantul rupt) -> shield.audit-chain', async () => { const r = await shieldCu((i) => { i.bundle.entries[0].proof.statement.host = 'ATACATOR'; i.bundle.chainOk = undefined; }); return [r.verdict === 'INVALID' && r.failed.includes('shield.audit-chain'), `${r.verdict} ${r.failed.join(',')}`]; }); rand('Shield: lant refacut coerent, dar un plic cu statementHash mincinos -> numai shield.envelope-integrity', async () => { const { caleaSidecarului } = await import(pathToFileURL(path.join(AICI, 'consola.mjs')).href); const { hashIntrare } = await import(pathToFileURL(caleaSidecarului()).href); const r = await shieldCu((i) => { const b = i.bundle; b.entries[0].proof.statement.host = 'ATACATOR'; let prev = '0x' + '00'.repeat(32); for (const e of b.entries) { e.prev = prev; e.hash = hashIntrare(e.seq, e.prev, e.proof); prev = e.hash; } b.head = prev; }); return [r.verdict === 'INVALID' && eq(r.failed, ['shield.envelope-integrity']), `${r.verdict} ${r.failed.join(',')}`]; }); rand('Shield: burafu declara chainOk:false peste un lant intreg -> shield.self-report', async () => { const r = await shieldCu((i) => { i.bundle.chainOk = false; }); return [r.verdict === 'INVALID' && eq(r.failed, ['shield.self-report']), `${r.verdict} ${r.failed.join(',')}`]; }); rand('Shield: un buraf fara intrari -> shield.bundle-form (nimic nu e dovada unei desfasurari)', async () => { const r = await shieldCu((i) => { i.bundle.entries = []; }); return [r.verdict === 'INVALID' && eq(r.failed, ['shield.bundle-form']), `${r.verdict} ${r.failed.join(',')}`]; }); rand('Shield: un plan fara lista planificatorului -> shield.plan-form', async () => { const r = await shieldCu((i) => { i.plan = { ceva: [1] }; }); return [r.verdict === 'INVALID' && eq(r.failed, ['shield.plan-form']), `${r.verdict} ${r.failed.join(',')}`]; }); // executia refacuta dintr-o lista de inregistrari, cu lantul executorului insusi (un lant intreg: ce se masoara e legatura cu planul, nu lantul) const executiaDin = async (recs) => { const { lantulExecutiei } = await import(pathToFileURL(path.join(AICI, 'executa-migrare.mjs')).href); const l = lantulExecutiei(); for (const r of recs) l.adauga(r); return { version: 'x', records: l.lista() }; }; rand('Shield: o executie din care lipseste o actiune automata a planului (lant refacut intreg) -> shield.execution-plan', async () => { const r = await shieldCu(async (i) => { const recs = i.execution.records.map((e) => e.record); const k = recs.findIndex((x) => x.ref); recs.splice(k, 1); i.execution = await executiaDin(recs); }); return [r.verdict === 'INVALID' && eq(r.failed, ['shield.execution-plan']), `${r.verdict} ${r.failed.join(',')}`]; }); rand('Shield: executia unui plan, alaturi de alt plan (fara actiunile automate) -> shield.execution-plan', async () => { const r = await shieldCu((i) => { i.plan = { ...i.plan, actions: i.plan.actions.filter((a) => a.method !== 'auto-aere') }; }); const g = await shieldCu((i) => { i.plan = { ...i.plan, actions: [] }; }); return [r.verdict === 'INVALID' && eq(r.failed, ['shield.execution-plan']) && g.verdict === 'INVALID' && eq(g.failed, ['shield.execution-plan']), `alt plan: ${r.verdict} ${r.failed.join(',')}; plan gol: ${g.verdict} ${g.failed.join(',')}`]; }); rand('Shield: o executie al carei rand de sfarsit nu isi numara inregistrarile -> shield.execution-plan', async () => { const r = await shieldCu(async (i) => { const recs = i.execution.records.map((e) => e.record); recs[recs.length - 1] = { ...recs[recs.length - 1], summary: { ...recs[recs.length - 1].summary, ok: 3, dryRun: 0 } }; i.execution = await executiaDin(recs); }); return [r.verdict === 'INVALID' && eq(r.failed, ['shield.execution-plan']), `${r.verdict} ${r.failed.join(',')}`]; }); rand('Shield: o intrare care poarta o semnatura pe care consola nu o judeca -> PARTIAL, numita', async () => { const { caleaSidecarului } = await import(pathToFileURL(path.join(AICI, 'consola.mjs')).href); const { hashIntrare } = await import(pathToFileURL(caleaSidecarului()).href); // semnatura sta in afara declaratiei (statementHash neatins), dar intra in hash-ul intrarii: lantul se reface coerent, ca de o gazda care semneaza const r = await shieldCu((i) => { const b = i.bundle; b.entries[1].proof.signature = { scheme: 'ml-dsa-65', publicKey: 'AA', signature: 'AA' }; let prev = '0x' + '00'.repeat(32); for (const e of b.entries) { e.prev = prev; e.hash = hashIntrare(e.seq, e.prev, e.proof); prev = e.hash; } b.head = prev; }); return [r.verdict === 'PARTIAL' && r.levels[1].cause === 'claim-not-checked', `${r.verdict} ${r.levels && r.levels[1].cause}`]; }); // ---- linia de comanda rand('linia de comanda: --json si codurile de iesire (0 VALID, 1 INVALID, 2 NOT_MEASURED, 3 PARTIAL)', async () => { const o0 = await bun(); const valide = o0.domains.filter((d) => d.verdict === 'VALID').map((d) => d.domain).join(','); const pf = path.join(T, 'pack.json'), cf = path.join(T, 'context.json'), sf = path.join(T, 'stricat.json'); fs.writeFileSync(pf, JSON.stringify(F.pack)); fs.writeFileSync(cf, JSON.stringify(F.context)); const s = F.stricate['payment-receipt']; fs.writeFileSync(sf, JSON.stringify(inlocuieste(F.pack, s.id, s.artifact))); const cli = (...a) => { const r = spawnSync(process.execPath, [MODUL, ...a], { encoding: 'utf8', maxBuffer: 64 << 20 }); let j = null; try { j = JSON.parse(r.stdout); } catch { /* text */ } return { c: r.status, j, out: r.stdout }; }; const a = cli('--pack', pf, '--context', cf, '--require', valide, '--json'); const b = cli('--pack', sf, '--context', cf, '--json'); const c = cli('--pack', pf, '--context', cf, '--require', 'devices,shield'); const d = cli('--pack', pf, '--context', cf); const e = cli('--pack', pf, '--context', cf, '--require', 'nu-e-domeniu'); const ok = a.c === 0 && a.j && a.j.kind === M.OUT_KIND && a.j.summary.verdict === 'VALID' && /^0x[0-9a-f]{64}$/.test(a.j.pack.sha256) && b.c === 1 && b.j.summary.verdict === 'INVALID' && c.c === 0 && /ORGANIZATION JUDGEMENT/.test(c.out) && d.c === 3 && /PARTIAL/.test(d.out) && e.c === 2; return [ok, `coduri ${a.c},${b.c},${c.c},${d.c},${e.c}`]; }); rand('linia de comanda: un domeniu cerut si neprezentat iese cu 2 (NOT_MEASURED)', async () => { const p = inlocuieste(F.pack, 'shield-console-1', null); const pf = path.join(T, 'fara-shield.json'), cf = path.join(T, 'context2.json'); fs.writeFileSync(pf, JSON.stringify(p)); fs.writeFileSync(cf, JSON.stringify(F.context)); const r = spawnSync(process.execPath, [MODUL, '--pack', pf, '--context', cf, '--require', 'shield', '--json'], { encoding: 'utf8', maxBuffer: 64 << 20 }); let j = null; try { j = JSON.parse(r.stdout); } catch { /* */ } return [r.status === 2 && j && j.summary.verdict === 'NOT_MEASURED' && eq(j.summary.notPresented, ['shield']), `cod ${r.status}`]; }); // ---- reteaua adevarata (numai cu --online): un plic notarizat pe testnetul 28001, finalitatea lui citita let neRulat = null; if (ONLINE) { rand('cu --online pe testnetul 28001: plicul notarizat e VALID, ancorarea si finalitatea PASSED, iar iesirea spune ca finalitatea e a unui testnet (28001)', async () => { const n = notarizat(); const o = await M.judecaPachetul(n.pack, { context: n.context, online: true }); const r = art(o, 'notar'); return [r.verdict === 'VALID' && r.levels[2].state === 'PASSED' && r.levels[3].state === 'PASSED' && !o.network.needed.length && eq(o.network.finality, [{ id: 'notar', chain: 28001, testnet: true }]) && /final only on a testnet \(chain 28001\)/.test(o.summary.reason), `${r.verdict} ${stari(r.levels).join(',')}; finality ${JSON.stringify(o.network.finality)}`]; }); } else neRulat = 'randul care citeste testnetul 28001 (finalitatea unui plic notarizat): NEMASURAT fara --online, nenumarat'; let bune = 0, rele = 0; try { for (const [nume, f] of randuri) { if (DOAR.length && !DOAR.some((d) => nume.includes(d))) continue; let ok = false, detaliu = ''; try { [ok, detaliu] = await f(); } catch (e) { ok = false; detaliu = 'a aruncat: ' + String(e.stack || e.message).split('\n').slice(0, 2).join(' '); } console.log(` [${ok ? 'OK ' : 'RAU '}] ${nume}${ok ? '' : ' -- ' + detaliu}`); if (ok) bune++; else rele++; } } finally { fs.rmSync(T, { recursive: true, force: true }); } if (neRulat && !DOAR.length) console.log(' ' + neRulat); console.log(`\norganizatie: ${bune}/${bune + rele} cum trebuia${DOAR.length ? ' (numai randurile cerute: ' + DOAR.join(', ') + ')' : ''}`); process.exitCode = rele ? 1 : 0;