agents: the chain as the witness of an agent's ledger - a notarized head, read through the AIP-23 verifier under a post-quantum certified anchor, bounds entry times from below; run on testnet 28001 with its evidence

This commit is contained in:
Aere Network 2026-09-30 09:43:10 +03:00
parent 7812e44e98
commit 01c0c5e211
7 changed files with 811 additions and 4 deletions

View File

@ -14,7 +14,7 @@ notarization command of the verification layer, and the agents' x402 wallet (EIP
| [`proof-kinds/`](proof-kinds/) | the AIP-23 envelope builder the verification layer uses: fourteen proof kinds, one envelope format, digests instead of raw content |
| [`readiness/`](readiness/) | the post-quantum readiness scanner of a public hostname: real TLS handshakes (hybrid only, hybrid preferred, TLS 1.2), HSTS, the certificate; no connection to an address not proven public; a rate limit per client that X-Forwarded-For cannot bypass |
| [`control-plane/`](control-plane/) | from findings to a finished migration: a prioritized plan from the inventory and the scanner, its execution through the gateway, KMS and PKI with consent per action and a measured proof afterwards, recipes for the servers the products do not touch and a rescan that judges them, a compliance report against NIST IR 8547, the EU roadmap and optionally CNSA 2.0, and a console that checks it all again |
| [`agents/`](agents/) | limits an AI agent cannot break unseen: a post-quantum identity (ML-DSA-65), a policy (spending per time window, allowed tools and recipients, which actions need human approval), a signed ledger of every action judged against the policy, approvals and revocation signed by people, and a verifier that re-runs the policy over the whole ledger without trusting the agent; two branches of one ledger are a proof of equivocation anyone can check; and a wallet that pays over x402 only what the agent's ledger records and its policy allows, either holding the payment key for the owner or co-signing from a 2-of-2 contract wallet that neither the agent nor the owner can spend alone; both run on the public testnet with their evidence |
| [`agents/`](agents/) | limits an AI agent cannot break unseen: a post-quantum identity (ML-DSA-65), a policy (spending per time window, allowed tools and recipients, which actions need human approval), a signed ledger of every action judged against the policy, approvals and revocation signed by people, and a verifier that re-runs the policy over the whole ledger without trusting the agent; two branches of one ledger are a proof of equivocation anyone can check; and a wallet that pays over x402 only what the agent's ledger records and its policy allows, either holding the payment key for the owner or co-signing from a 2-of-2 contract wallet that neither the agent nor the owner can spend alone; both run on the public testnet with their evidence; and the chain as the witness of a ledger: a notarized head, read through the AIP-23 verifier under a post-quantum certified anchor, bounds entry times from below (a backdated entry is caught) |
| [`identity/`](identity/) | post-quantum credentials: an issuer signs claims (hybrid Ed25519 + ML-DSA-65, both required), the holder shows only the claims it picks (selective disclosure in the manner of SD-JWT, RFC 9901, in a format of its own), bound to the verifier's audience and nonce; delegation to a phone, an agent or a ten-minute session key that can only narrow; revocation and an issuer status list in the manner of W3C Bitstring Status List; all checked offline from the files |
Each component's README says what it is **not** and what is **not measured**. No third party has reviewed any of them.
@ -36,7 +36,7 @@ test, counts as a failure of the control. Results measured on 2026-09-29 (Node.j
| readiness | 6/6 (`node proba-adrese-private.mjs`: the private-address rules, and a local listener no scan may touch) | the rate limit and the queue bound are tested where the service runs, not here (its README says so) |
| control-plane | planner 30/30, command line 9/9, execution 30/30 on real products started locally, remediation 33/33 on real TLS servers, compliance report 27/27 (with the AIP-23 verifier), console 8/8; the console viewer in a real Chromium, phone and desktop, 26/26 (`node proba-consola-web.mjs`, measured 2026-09-30; needs `playwright-core` and a Chromium, otherwise it exits 2) | remediation 7/7, compliance report 3/3 in this repository; viewer 8/8 (`node control-negativ-consola-web.mjs`) |
| identity | 43/43 (`node proba-identity.mjs`, with the AIP-23 verifier for its envelope test; without it that test is reported as skipped and the exit code is 2), measured 2026-09-30 | 46/46 (`node control-negativ-identity.mjs`) |
| agents | policy 27/27 with the AIP-23 verifier (without it 25 run, 2 are reported as skipped and the exit code is 2), ledger 51/51, approval and revocation 39/39, command line 23/23 through files and processes only (on Linux and macOS one more test checks the key file mode; not measured here); x402 wallet 25/25, 2-of-2 co-signing 16/16 and payment verifier 14/14 without a network; on the public testnet 28001, 9/9 with the wallet key and 13/13 with the 2-of-2 contract wallet (`x402/proba-x402-testnet.mjs`, `x402/proba-cosign-testnet.mjs`, each needs a funded testnet key); the contract's artifact recompiles byte for byte with solc 0.8.23 (`node x402/recompileaza-contract.mjs --solc <solc>`) | 26/26 (`node control-negativ-aprobare.mjs`); x402 30/30 (`node x402/control-negativ-wallet.mjs`); the contract's own tests (7) and their negative control (4/4) run in the Aere Network contracts project, not in this repository |
| agents | policy 27/27 with the AIP-23 verifier (without it 25 run, 2 are reported as skipped and the exit code is 2), ledger 51/51, approval and revocation 39/39, the chain as witness 26/26 without a network and 7/7 on testnet 28001 on 2026-09-30 (`proba-agent-ancora-testnet.mjs`, needs a funded testnet key and the AIP-23 verifier), command line 23/23 through files and processes only (on Linux and macOS one more test checks the key file mode; not measured here); x402 wallet 25/25, 2-of-2 co-signing 16/16 and payment verifier 14/14 without a network; on the public testnet 28001, 9/9 with the wallet key and 13/13 with the 2-of-2 contract wallet (`x402/proba-x402-testnet.mjs`, `x402/proba-cosign-testnet.mjs`, each needs a funded testnet key); the contract's artifact recompiles byte for byte with solc 0.8.23 (`node x402/recompileaza-contract.mjs --solc <solc>`) | 26/26 (`node control-negativ-aprobare.mjs`); the chain as witness 11/11 (`node control-negativ-ancora.mjs`); x402 30/30 (`node x402/control-negativ-wallet.mjs`); the contract's own tests (7) and their negative control (4/4) run in the Aere Network contracts project, not in this repository |
Code comments, most function and variable names (also many exported between the files of a component), test names and control
messages are in Romanian, and so are the two command words of the KMS HSM tool (explained in its README). Error codes, error
@ -45,4 +45,4 @@ interface, command line and data (`definePolicy`, `verifyLedger`, `approve`, ...
## Licence
MIT, see [LICENSE](LICENSE). Files: 139 (pq-gateway 6, pq-kms 10, pq-pki 6, crypto-inventory 42, verify-layer 8, proof-kinds 3, control-plane 19, agents 34, identity 5, readiness 4).
MIT, see [LICENSE](LICENSE). Files: 144 (pq-gateway 6, pq-kms 10, pq-pki 6, crypto-inventory 42, verify-layer 8, proof-kinds 3, control-plane 19, agents 39, identity 5, readiness 4).

View File

@ -60,12 +60,37 @@ wallet (`AereAgentWallet2of2`, ERC-1271) the money leaves only with the agent's
neither the agent nor the owner can spend alone. Both were run end to end on the public testnet 28001 on 2026-09-29, and the
evidence is there with a verifier anyone can run. See `x402/README.md`.
## The chain as the witness of the ledger (2026-09-30)
Without a witness, an entry's time is only the statement of whoever holds the agent key. `agent-ancora.mjs` makes the chain that
witness: the ledger's head (sequence number and hash) becomes an AIP-23 envelope, its hash is notarized on AereNotary, and the
first-seen time the contract records, read through the AIP-23 reference verifier under a post-quantum certified anchor (a Merkle
proof in the certified state), becomes an anchor `{seq, hash, at}` for `verify --anchors`.
```
node agent-ancora.mjs head --ledger ledger.json --out head.json # no network
node agent-ancora.mjs notarize --head head.json --rpc <url> --key-file <key> --out notarized.json # needs ethers (x402/)
node agent-ancora.mjs anchors --ledger ledger.json --head notarized.json --rpc <url> \
--chain 2800 --verify-proof <verify-proof.mjs from aere-node> --out anchors.json # --chain: the chain whose time you accept
node agent-cli.mjs verify --ledger ledger.json --policy policy.json --anchors anchors.json
```
With the anchor, an entry after the notarized head cannot claim a time before its first-seen time (minus the 300 s tolerance), an
entry up to the head cannot claim a time after it, and a branch that does not contain the head does not verify. The time is the
chain's, not the agent's and not the notarizer's: whoever notarizes can only notarize late, which weakens the bound, not move it
earlier. Only the hash of the head's statement goes on chain, nothing of the ledger. The anchors file is the output of the
verifier's own run, with the RPC endpoint and the AIP-23 verifier it chose; an anchors file handed over by the party being verified
proves nothing. `anchors` answers not measured (exit 2) while the finality is pending or when the verifier cannot be run, never an
anchor it did not certify. `notarize` reads the chain id from the endpoint and refuses chain 2800 (a real transaction paid by the
key's account) unless `AERE_CONFIRM_MAINNET=yes`.
## What the verifier can and cannot see
- **Time.** An entry's time is the statement of whoever holds the agent key. The verifier bounds it from above with its clock. It
bounds it from below only with a witness: `anchors` (ledger heads seen by a witness at a known time, for example notarized) or
`notBefore`. Without one, the key holder can backdate entries into past windows and spend the limit several times; the result
says so (`time.lowerBound: "none..."`). With anchors, backdating is limited to the interval between two anchors. The library
says so (`time.lowerBound: "none..."`). With anchors, backdating is limited to the interval between two anchors; the chain itself
can be that witness (above). The library
itself refuses to write an entry more than 300 seconds away from its clock.
- **One ledger per agent and policy.** The ledger's session is derived from the agent and the policy hash, so a "second ledger" is
a branch of the same one. Two branches signed by the agent are a proof of equivocation (`findEquivocation`, `verifyEquivocation`)
@ -85,6 +110,9 @@ Measured on 2026-09-29 (Node.js 24.14.1, Windows):
| `node proba-agent-ledger.mjs` | 51/51: limits over the ledger, identity, tampering, a re-signed false decision, a looser policy under the real hash, backdating (refused when written; caught with anchors or `notBefore`), a branch, equivocation proofs, resuming |
| `node proba-agent-aprobare.mjs` | 39/39: threshold, unnamed or repeated approvers, classical keys, another action or other tool arguments, reused nonces (also after a restart), expiry, approvals across branches, revocation, an omitted revocation |
| `node proba-agent-cli.mjs` | 23/23 on Windows, through files and processes only; on Linux and macOS one more test checks the 0600 mode of the key (not measured here) |
| `node proba-agent-ancora.mjs` | 26/26 without a network (the AIP-23 verifier's answer in its own form): the head, the time read from the finality level (pending, failed, a mismatched or unknown form: no anchor), an envelope that claims another time, backdating caught with the anchor and not without it, another branch, the refusals before any transaction (a modified head, chain 2800 without confirmation, no contract at the notary) |
| `AERE_TESTNET_KEY_FILE=<funded testnet key> node proba-agent-ancora-testnet.mjs` | 7/7 on the public testnet 28001, measured 2026-09-30: a real ledger's head notarized, post-quantum finality from the published AIP-23 verifier within 20 s, the certified time equal to the contract's first-seen time, the honest continuation valid with the anchor, a backdated continuation valid without it and caught with it, another branch refused; evidence in `dovezi-ancora-28001/` |
| `node control-negativ-ancora.mjs` | 11/11: each anchoring guard removed in a copy turns its named test red |
| `node control-negativ-aprobare.mjs` | 26/26: each guard is removed in a copy, one at a time, and the named test must fail for that reason; a test that stops before its summary counts as a failure of the control |
The data format is version 2 (2026-09-29). Code comments, test names and most internal names are in Romanian; messages, data and

185
agents/agent-ancora.mjs Normal file
View File

@ -0,0 +1,185 @@
#!/usr/bin/env node
// agent-ancora.mjs: LANTUL ca martor al registrului unui agent (punctul 22, pista B, 2026-09-30).
//
// Ce ramasese deschis dupa B-17 (spus in README): momentul unei intrari e declaratia celui care tine cheia agentului; verificatorul il
// margineste de SUS cu ceasul lui, dar de JOS numai daca primeste ancore de la un martor (`anchors` in verifyLedger), iar fara martor
// cine tine cheia poate antedata intrari. Aici martorul e AereNotary: capul registrului (seq, hash) devine un plic AIP-23
// (`aere-agent-ledger-head`), se noteaza pe lant, iar momentul `firstSeen` pe care il tine contractul, citit prin verificatorul AIP-23 de
// referinta sub un certificat post-cuantic de ancora (dovada Merkle in starea certificata), devine ancora {seq, hash, at}. De aici:
// - o intrare de DUPA cap nu poate declara un moment sub firstSeen - toleranta (antedatarea e prinsa);
// - o intrare de PANA LA cap nu poate declara un moment peste firstSeen + toleranta;
// - un registru care nu contine capul notarizat (alta ramura a aceluiasi agent) nu verifica cu aceasta ancora.
// Momentul nu il alege nici agentul, nici cine noteaza: il scrie lantul. Cine noteaza poate numai sa INTARZIE notarizarea (atunci
// marginea e mai slaba), nu sa o mute inainte. Nimic din registru (actiuni, sume) nu ajunge pe lant: numai hash-ul declaratiei capului.
//
// Fisierul de ancore il produce VERIFICATORUL, cu RPC-ul si verificatorul AIP-23 alese de el; o lista de ancore primita de la cel
// verificat nu dovedeste nimic (ar fi declaratia lui).
//
// node agent-ancora.mjs head --ledger l.json [--seq N] [--out head.json] the head as an AIP-23 envelope (no network)
// node agent-ancora.mjs notarize --head head.json --rpc URL --key-file f [--notary 0x..] [--out notarized.json]
// refuses chain 2800 (mainnet: a real transaction paid by the key's account) unless AERE_CONFIRM_MAINNET=yes
// node agent-ancora.mjs anchors --ledger l.json --head n1.json [--head n2.json ...] --rpc URL [--verify-proof verify-proof.mjs]
// [--chain 28001] [--out anchors.json] anchors for `agent-cli.mjs verify --anchors`, each read through the AIP-23 verifier
// Iesiri: 0 da; 1 nu (un cap nu e al registrului, notarizarea sau finalitatea pica); 2 folosire gresita sau NEMASURAT (finalitate
// in asteptare, verificator lipsa).
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import crypto from 'node:crypto';
import { spawn } from 'node:child_process';
import { fileURLToPath, pathToFileURL } from 'node:url';
export const HEAD_KIND = 'aere-agent-ledger-head';
export const NOTARI = { 2800: '0x4aB392c4Aca7D9D4C16c0b60a9514c5025bd58c7', 28001: '0x70099E62735500AA2F85B60C518551a57B202d54' };
const AICI = path.dirname(fileURLToPath(import.meta.url));
const sha = (s) => '0x' + crypto.createHash('sha256').update(Buffer.from(s, 'utf8')).digest('hex');
const H32 = /^0x[0-9a-f]{64}$/;
const HASH_INTRARE = /^[0-9a-f]{64}$/; // hash-ul unei intrari de registru: 64 hex, fara 0x (agent-ledger.mjs)
/** Capul registrului la `seq` (implicit ultima intrare), ca plic AIP-23. Declaratia numeste agentul, sesiunea, politica, seq si hash-ul. */
export function ledgerHeadEnvelope(ledger, { seq = null, createdAt = new Date().toISOString() } = {}) {
if (!ledger || !Array.isArray(ledger.entries) || !ledger.entries.length) throw new Error('agent-ancora: a ledger with at least one entry is required');
const s = seq == null ? ledger.entries.length - 1 : Number(seq);
const e = ledger.entries[s];
if (!Number.isInteger(s) || !e || e.seq !== s || !HASH_INTRARE.test(String(e.hash))) throw new Error(`agent-ancora: the ledger has no entry ${seq}`);
const statement = { v: 1, kind: HEAD_KIND, agentId: ledger.agentId, session: ledger.session, policyHash: String(ledger.policyHash).toLowerCase(), seq: s, hash: e.hash, createdAt };
return { v: 1, kind: HEAD_KIND + '-attestation', statement, statementHash: sha(JSON.stringify(statement)) };
}
/** Plicul e un cap de registru intreg (statementHash se reface) si numeste o intrare a ACESTUI registru? */
export function headMatchesLedger(env, ledger) {
const st = env && env.statement;
if (!st || env.kind !== HEAD_KIND + '-attestation' || st.kind !== HEAD_KIND) return { ok: false, motiv: `not an ${HEAD_KIND} attestation` };
if (!H32.test(String(env.statementHash)) || sha(JSON.stringify(st)) !== env.statementHash) return { ok: false, motiv: 'the statementHash does not match the statement (modified envelope)' };
if (st.agentId !== ledger.agentId || st.session !== ledger.session || String(st.policyHash).toLowerCase() !== String(ledger.policyHash).toLowerCase()) return { ok: false, motiv: 'the head names another agent, session or policy' };
const e = Number.isInteger(st.seq) ? ledger.entries[st.seq] : null;
if (!e || e.hash !== st.hash) return { ok: false, motiv: `the head names seq ${st.seq} with a hash this ledger does not have there (another branch or another ledger)` };
return { ok: true, seq: st.seq, hash: st.hash };
}
/** Cheia secp256k1 dintr-un fisier: hex singur (cu sau fara 0x) sau un rand `d=` / `PRIVATE_KEY=`; nu se tipareste niciodata. */
export function cheiaDinFisier(f) {
const randuri = fs.readFileSync(f, 'utf8').split(/\r?\n/).map((l) => l.trim()).filter(Boolean);
const r = randuri.find((l) => /^(d|PRIVATE_KEY)=/.test(l)) || (randuri.length === 1 ? randuri[0] : '');
const hex = r.replace(/^(d|PRIVATE_KEY)=/, '').replace(/^0x/, '').trim();
if (!/^[0-9a-fA-F]{1,64}$/.test(hex)) throw new Error('the key file holds no secp256k1 key (a hex key, or a d= / PRIVATE_KEY= line)');
return '0x' + hex.padStart(64, '0');
}
/** Pune statementHash-ul capului pe AereNotary. Lantul se citeste de pe RPC, nu se crede din argument; cheia din fisier, netiparita. */
export async function notarizeHead({ envelope, rpc, keyFile, ethers, notary = null, confirmMainnet = process.env.AERE_CONFIRM_MAINNET === 'yes' }) {
const taie = (s) => String(s ?? '').replace(/(0x)?[0-9a-fA-F]{40,}/g, '<hex>').slice(0, 300);
const st = envelope && envelope.statement;
if (!st || envelope.kind !== HEAD_KIND + '-attestation' || st.kind !== HEAD_KIND || !H32.test(String(envelope.statementHash))) return { ok: false, cod: 2, motiv: `REFUSED: not an ${HEAD_KIND} attestation with a 32-byte statementHash` };
if (sha(JSON.stringify(st)) !== envelope.statementHash) return { ok: false, cod: 1, motiv: 'REFUSED: statementHash does not match the statement (modified envelope)' };
try {
const provider = new ethers.JsonRpcProvider(rpc);
const chainId = Number((await provider.getNetwork()).chainId);
if (chainId === 2800 && !confirmMainnet) return { ok: false, cod: 3, motiv: 'REFUSED: this RPC serves chain 2800 (Aere Network mainnet); a notarization there is a real transaction paid by the key\'s account. Set AERE_CONFIRM_MAINNET=yes to send it.' };
const adr = notary || NOTARI[chainId];
if (!adr || !/^0x[0-9a-fA-F]{40}$/.test(adr)) return { ok: false, cod: 2, motiv: `REFUSED: no known notary on chain ${chainId}; pass --notary` };
const cod = await provider.getCode(adr);
if (!cod || cod === '0x') return { ok: false, cod: 1, motiv: `REFUSED: there is no contract at ${adr} on chain ${chainId}` };
const wallet = new ethers.Wallet(cheiaDinFisier(keyFile), provider);
const c = new ethers.Contract(adr, ['function notarize(bytes32 h) external', 'function firstSeen(bytes32) view returns (uint64)'], wallet);
let txHash = null, block = null;
if (!(Number(await c.firstSeen(envelope.statementHash)) > 0)) {
const tx = await c.notarize(envelope.statementHash); const rc = await tx.wait(1, 180000);
if (!rc || rc.status !== 1) return { ok: false, cod: 1, motiv: 'the notarization transaction failed' };
txHash = rc.hash; block = rc.blockNumber;
}
const firstSeen = Number(await c.firstSeen(envelope.statementHash));
if (!(firstSeen > 0)) return { ok: false, cod: 1, motiv: 'firstSeen is still 0 after the notarization' };
return { ok: true, envelope: { ...envelope, notarization: { chainId, notary: adr, firstSeen, ...(txHash ? { txHash, block } : { already: true }) } } };
} catch (e) { return { ok: false, cod: 1, motiv: 'the notarization failed: ' + taie(e.shortMessage || e.message) }; }
}
// verificatorul AIP-23 intoarce momentul in detaliul nivelului de finalitate, "as first seen at <ISO> (<unix>)"; il citim de acolo si
// cerem ca cele doua forme sa fie acelasi moment. Daca forma detaliului se schimba, raspunsul e NEMASURAT, nu o ancora ghicita.
const PRIMA_VEDERE = /as first seen at (\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?Z) \((\d+)\)/;
export function firstSeenFromVerdict(v) {
const f = v && Array.isArray(v.levels) ? v.levels.find((x) => x.level === 'finality') : null;
if (!f) return { stare: 'NEMASURAT', motiv: 'the verifier gave no finality level' };
if (f.state !== 'PASSED') return { stare: f.state === 'FAILED' ? 'FAILED' : 'NEMASURAT', motiv: `finality ${f.state}: ${String(f.detail).slice(0, 200)}` };
const m = PRIMA_VEDERE.exec(String(f.detail));
if (!m || Math.floor(Date.parse(m[1]) / 1000) !== Number(m[2])) return { stare: 'NEMASURAT', motiv: 'finality PASSED, but its detail does not state the first-seen time in the form this tool reads' };
return { stare: 'PASSED', at: Number(m[2]) };
}
/** Ruleaza verificatorul AIP-23 pe un plic si intoarce JSON-ul lui (sau null). */
export function ruleazaVerificatorul(verifyProof, envFile, { rpc, chain }) {
return 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); } });
});
}
/**
* Ancorele registrului din capete notarizate: fiecare cap trebuie sa fie al registrului si sa aiba finalitate post-cuantica PASSED
* la verificatorul AIP-23 (rulat de `ruleaza`, implicit verify-proof.mjs). Intoarce {stare: 'OK'|'FAILED'|'NEMASURAT', anchors, randuri}.
*/
export async function anchorsFromNotarizedHeads(ledger, envelopes, { verifyProof, rpc, chain = null, ruleaza = ruleazaVerificatorul, tmpDir = null } = {}) {
const anchors = [], randuri = []; let stare = 'OK';
const dir = fs.mkdtempSync(path.join(tmpDir || os.tmpdir(), 'aere-agent-ancora-'));
try {
for (const env of envelopes) {
const m = headMatchesLedger(env, ledger);
if (!m.ok) { randuri.push({ head: env && env.statementHash, pass: false, detail: m.motiv }); stare = 'FAILED'; continue; }
const f = path.join(dir, `${m.seq}.json`); fs.writeFileSync(f, JSON.stringify(env));
// lantul: cel cerut de verificator; altfel cel declarat de plic (spus in ancora, ca un timp de testnet sa nu treaca drept unul de 2800)
const lant = chain || (env.notarization && Number(env.notarization.chainId)) || null;
const v = await ruleaza(verifyProof, f, { rpc, chain: lant });
if (!v) { randuri.push({ head: env.statementHash, seq: m.seq, pass: null, detail: 'the AIP-23 verifier did not answer' }); if (stare === 'OK') stare = 'NEMASURAT'; continue; }
if (v.statementHash && String(v.statementHash).toLowerCase() !== env.statementHash) { randuri.push({ head: env.statementHash, seq: m.seq, pass: false, detail: 'the verifier judged another statementHash' }); stare = 'FAILED'; continue; }
const fs2 = firstSeenFromVerdict(v);
if (fs2.stare === 'FAILED') { randuri.push({ head: env.statementHash, seq: m.seq, pass: false, detail: fs2.motiv }); stare = 'FAILED'; continue; }
if (fs2.stare !== 'PASSED') { randuri.push({ head: env.statementHash, seq: m.seq, pass: null, detail: fs2.motiv }); if (stare === 'OK') stare = 'NEMASURAT'; continue; }
anchors.push({ seq: m.seq, hash: m.hash, at: fs2.at, statementHash: env.statementHash, chainId: lant, chainAsked: !!chain, witness: 'AereNotary first-seen under a post-quantum certified anchor' });
randuri.push({ head: env.statementHash, seq: m.seq, pass: true, detail: `seq ${m.seq} first seen on chain ${lant}${chain ? '' : ' (the chain the envelope declares; pass --chain to require one)'} at ${new Date(fs2.at * 1000).toISOString()}` });
}
} finally { fs.rmSync(dir, { recursive: true, force: true }); }
return { stare, anchors: anchors.sort((a, b) => a.seq - b.seq), randuri };
}
// ---------------------------------------------------------------- linia de comanda
class Folosire extends Error {}
async function main(argv) {
const [cmd, ...rest] = argv;
const get = (f) => { const i = rest.indexOf(f); return i >= 0 ? rest[i + 1] : undefined; };
const toate = (f) => rest.flatMap((a, i) => (a === f && rest[i + 1] != null ? [rest[i + 1]] : []));
const citeste = (f, ce) => { if (!f) throw new Folosire(`--${ce} is required`); try { return JSON.parse(fs.readFileSync(f, 'utf8')); } catch (e) { throw new Folosire(`cannot read ${ce} file ${f}: ${e.message}`); } };
const scrie = (o, f) => { const s = JSON.stringify(o, null, 1) + '\n'; if (f) fs.writeFileSync(f, s); else process.stdout.write(s); };
if (cmd === 'head') {
const env = ledgerHeadEnvelope(citeste(get('--ledger'), 'ledger'), { seq: get('--seq') != null ? Number(get('--seq')) : null });
scrie(env, get('--out')); if (get('--out')) console.log(`head seq ${env.statement.seq}: ${env.statementHash}`); return 0;
}
if (cmd === 'notarize') {
if (!get('--rpc') || !get('--key-file')) throw new Folosire('notarize --head head.json --rpc URL --key-file f [--notary 0x..] [--out f]');
const { incarcaEthers } = await import(pathToFileURL(path.join(AICI, 'x402', 'wallet.mjs')).href);
let ethers; try { ethers = incarcaEthers(); } catch (e) { console.error(e.message); return 2; }
const r = await notarizeHead({ envelope: citeste(get('--head'), 'head'), rpc: get('--rpc'), keyFile: get('--key-file'), ethers, notary: get('--notary') || null });
if (!r.ok) { console.error(r.motiv); return r.cod; }
scrie(r.envelope, get('--out'));
const n = r.envelope.notarization; console.log(`notarized on chain ${n.chainId} at ${n.notary}: firstSeen ${n.firstSeen}${n.txHash ? `, block ${n.block}` : ' (already notarized)'}`);
return 0;
}
if (cmd === 'anchors') {
const verifyProof = get('--verify-proof') || process.env.AERE_VERIFY_PROOF;
if (!verifyProof || !fs.existsSync(verifyProof)) { console.error('NEMASURAT: the AIP-23 reference verifier is needed (--verify-proof <verify-proof.mjs> or AERE_VERIFY_PROOF)'); return 2; }
if (!get('--rpc')) throw new Folosire('anchors needs --rpc <url>: the chain is read, not trusted from the envelope');
const heads = toate('--head'); if (!heads.length) throw new Folosire('anchors needs at least one --head notarized.json');
const r = await anchorsFromNotarizedHeads(citeste(get('--ledger'), 'ledger'), heads.map((f) => citeste(f, 'head')), { verifyProof, rpc: get('--rpc'), chain: get('--chain') ? Number(get('--chain')) : null });
for (const x of r.randuri) console.error(`${x.pass === true ? 'ok' : x.pass === false ? 'FAIL' : '--'} ${x.detail}`);
if (r.stare === 'OK') scrie(r.anchors, get('--out'));
console.error(r.stare === 'OK' ? `${r.anchors.length} anchor(s): pass them to agent-cli.mjs verify --anchors` : r.stare === 'FAILED' ? 'FAILED: no anchors written' : 'NOT MEASURED: no anchors written (finality pending or the verifier did not answer)');
return r.stare === 'OK' ? 0 : r.stare === 'FAILED' ? 1 : 2;
}
throw new Folosire('usage: agent-ancora.mjs head|notarize|anchors ... (see README.md)');
}
if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
main(process.argv.slice(2)).then((c) => { process.exitCode = c; }, (e) => { console.error(`agent-ancora: ${e.message}`); process.exitCode = e instanceof Folosire ? 2 : 1; });
}

View File

@ -0,0 +1,53 @@
// Controlul negativ al lantului ca martor (agent-ancora.mjs, proba-agent-ancora.mjs): fiecare paznic scos intr-o COPIE a dosarului
// trebuie sa inroseasca proba NUMITA, cu proba chiar rulata (rezumatul ei exista); pe copia neatinsa, verde. Trei stari: un tipar care
// nu apare exact o data sau o proba care nu ajunge la rezumat e STRICAT si se numara esec.
// node control-negativ-ancora.mjs iesire 0 = martorul verde si toate plantarile rosii pe proba lor
import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path';
import { spawn } from 'node:child_process'; import { fileURLToPath } from 'node:url';
const AICI = path.dirname(fileURLToPath(import.meta.url));
const A = 'agent-ancora.mjs';
const PLANTARI = [
// [nume, tipar, inlocuire, proba (inceputul numelui ei)]
['un cap al altei ramuri primit', 'if (!e || e.hash !== st.hash) return', 'if (false) return', '5. o alta ramura a agentului'],
['un plic atins (statementHash nerefacut) primit', "if (!H32.test(String(env.statementHash)) || sha(JSON.stringify(st)) !== env.statementHash) return { ok: false, motiv: 'the statementHash does not match", "if (false) return { ok: false, motiv: 'the statementHash does not match", '1. CONTROL: un cap cu hash-ul schimbat'],
['un cap care numeste alt agent primit', "if (st.agentId !== ledger.agentId || st.session !== ledger.session", "if (false && st.session !== ledger.session", '1. CONTROL: un cap care numeste alt agent'],
['o finalitate FAILED citita ca moment', "if (f.state !== 'PASSED') return", 'if (false) return', '2. CONTROL: finalitate FAILED'],
['ISO si unix nu mai trebuie sa fie acelasi moment', "if (!m || Math.floor(Date.parse(m[1]) / 1000) !== Number(m[2])) return", 'if (!m) return', '2. CONTROL: ISO si unix'],
['plicul judecat de verificator nu mai trebuie sa fie acesta', 'if (v.statementHash && String(v.statementHash).toLowerCase() !== env.statementHash) {', 'if (false) {', '3. CONTROL: verificatorul a judecat alt statementHash'],
['momentul ancorei luat din plic, nu din certificat', 'anchors.push({ seq: m.seq, hash: m.hash, at: fs2.at,', 'anchors.push({ seq: m.seq, hash: m.hash, at: Number(env.notarization && env.notarization.firstSeen) || fs2.at,', '3. CONTROL: momentul ancorei e cel certificat'],
['finalitatea in asteptare data drept ancora', "if (fs2.stare !== 'PASSED') {", 'if (false) {', '3. CONTROL: finalitate in asteptare'],
['notarizarea pe 2800 fara confirmare', 'if (chainId === 2800 && !confirmMainnet) return', 'if (false) return', '6. un nod al lantului 2800'],
['notarul fara contract primit', "if (!cod || cod === '0x') return", 'if (false) return', '6. niciun contract la adresa notarului'],
['un plic atins notarizat', "if (sha(JSON.stringify(st)) !== envelope.statementHash) return { ok: false, cod: 1, motiv: 'REFUSED", "if (false) return { ok: false, cod: 1, motiv: 'REFUSED", '6. notarizarea refuza un cap atins'],
];
const FISIERE = [A, 'proba-agent-ancora.mjs', 'agent-policy.mjs', 'agent-ledger.mjs', 'agent-aprobare.mjs'];
function copie() { const t = fs.mkdtempSync(path.join(os.tmpdir(), 'aere-anc-ctl-')); for (const f of FISIERE) fs.copyFileSync(path.join(AICI, f), path.join(t, f)); return t; }
function ruleaza(t) {
return new Promise((resolve) => {
const c = spawn(process.execPath, [path.join(t, 'proba-agent-ancora.mjs')], { env: { ...process.env, AERE_VERIFY_PROOF: '' } }); let out = '';
const ceas = setTimeout(() => c.kill(), 120000);
c.stdout.on('data', (x) => { out += x; }); c.stderr.on('data', (x) => { out += x; });
c.on('close', (cod) => { clearTimeout(ceas); resolve({ cod, rulat: /agent-ancora: \d+\/\d+/.test(out), rosii: out.split('\n').filter((l) => l.startsWith(' RAU ')) }); });
});
}
async function planteaza([nume, din, inl, tinta]) {
const t = copie();
try {
const f = path.join(t, A); const src = fs.readFileSync(f, 'utf8');
if (src.split(din).length !== 2) return [false, ` STRICAT ${nume}: tiparul apare de ${src.split(din).length - 1} ori`];
fs.writeFileSync(f, src.replace(din, inl));
const r = await ruleaza(t);
if (!r.rulat) return [false, ` STRICAT ${nume}: proba nu a ajuns la rezumat (cod ${r.cod})`];
if (r.rosii.some((l) => l.startsWith(' RAU ' + tinta))) return [true, ` ROSU cum trebuia ${nume} (proba '${tinta}' pica)`];
return [false, ` CONTROL CAZUT ${nume}: proba '${tinta}' a ramas verde (${r.rosii.length} rosii altundeva)`];
} finally { fs.rmSync(t, { recursive: true, force: true }); }
}
let rele = 0;
const t0 = copie(); const m = await ruleaza(t0); fs.rmSync(t0, { recursive: true, force: true });
if (m.rulat && m.cod === 0 && !m.rosii.length) console.log(' OK martorul: copia neatinsa verde'); else { rele++; console.log(` STRICAT martorul nu e verde (cod ${m.cod}, ${m.rosii.length} rosii)`); }
const rez = new Array(PLANTARI.length); let i = 0;
await Promise.all(Array.from({ length: 4 }, async () => { while (i < PLANTARI.length) { const k = i++; rez[k] = await planteaza(PLANTARI[k]); } }));
for (const [bun, linie] of rez) { console.log(linie); if (!bun) rele++; }
console.log(rele ? `CONTROL NEGATIV: ${rele} probleme` : `DOVEDIT: martorul verde, ${PLANTARI.length} din ${PLANTARI.length} paznici scosi -> proba lor rosie`);
process.exitCode = rele ? 1 : 0;

View File

@ -0,0 +1,347 @@
{
"v": 1,
"kind": "aere-agent-ledger-anchor-evidence",
"network": "eip155:28001",
"rpc": "https://testnet-rpc.aere.network",
"policy": {
"v": 1,
"kind": "aere-agent-policy",
"agentId": "aere-agent:55c675e87838a1ad7d73a1a72f3d9c5aa0515681",
"spend": {
"amount": "1000",
"windowSeconds": 3600,
"asset": "AERE"
},
"tools": null,
"recipients": [
"0xbbbb"
]
},
"policyHash": "0x83082335a1ece1c6ef89812c74144cf63c1d7e586339fd9348bf79c455550cc2",
"ledgerBefore": {
"version": "aere-agent-ledger/2 (2026-09-29)",
"agentId": "aere-agent:55c675e87838a1ad7d73a1a72f3d9c5aa0515681",
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\n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\nS/VdNIoE\n-----END PUBLIC KEY-----\n",
"policyHash": "0x83082335a1ece1c6ef89812c74144cf63c1d7e586339fd9348bf79c455550cc2",
"session": "ac8e86e12a35e2d5355e0ab4e804dd17",
"entries": [
{
"seq": 0,
"prev": "0000000000000000000000000000000000000000000000000000000000000000",
"body": {
"v": 2,
"agentId": "aere-agent:55c675e87838a1ad7d73a1a72f3d9c5aa0515681",
"policyHash": "0x83082335a1ece1c6ef89812c74144cf63c1d7e586339fd9348bf79c455550cc2",
"session": "ac8e86e12a35e2d5355e0ab4e804dd17",
"at": 1790749508,
"action": {
"kind": "payment",
"to": "0xbbbb",
"amount": "10",
"at": 1790749508
},
"decision": {
"allowed": true,
"reason": "under the limit"
},
"provenance": null,
"seq": 0
},
"signature": "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",
"hash": "2ba3bcd648ecbd7599765851afa12c64ad149333626aad48558918a8c28eb22f"
},
{
"seq": 1,
"prev": "2ba3bcd648ecbd7599765851afa12c64ad149333626aad48558918a8c28eb22f",
"body": {
"v": 2,
"agentId": "aere-agent:55c675e87838a1ad7d73a1a72f3d9c5aa0515681",
"policyHash": "0x83082335a1ece1c6ef89812c74144cf63c1d7e586339fd9348bf79c455550cc2",
"session": "ac8e86e12a35e2d5355e0ab4e804dd17",
"at": 1790749513,
"action": {
"kind": "payment",
"to": "0xbbbb",
"amount": "10",
"at": 1790749513
},
"decision": {
"allowed": true,
"reason": "under the limit"
},
"provenance": null,
"seq": 1
},
"signature": "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",
"hash": "d1aa55127d1722227e98427bef5f1e6ee9d723b596efb0d3e361db68234a1ec4"
}
]
},
"notarizedHead": {
"v": 1,
"kind": "aere-agent-ledger-head-attestation",
"statement": {
"v": 1,
"kind": "aere-agent-ledger-head",
"agentId": "aere-agent:55c675e87838a1ad7d73a1a72f3d9c5aa0515681",
"session": "ac8e86e12a35e2d5355e0ab4e804dd17",
"policyHash": "0x83082335a1ece1c6ef89812c74144cf63c1d7e586339fd9348bf79c455550cc2",
"seq": 1,
"hash": "d1aa55127d1722227e98427bef5f1e6ee9d723b596efb0d3e361db68234a1ec4",
"createdAt": "2026-09-30T06:40:08.555Z"
},
"statementHash": "0xf8824c9dc9cd6cf038b384b3c01a51b612cbc30120402e30e27d0941120bee52",
"notarization": {
"chainId": 28001,
"notary": "0x70099E62735500AA2F85B60C518551a57B202d54",
"firstSeen": 1790750410,
"txHash": "0x25ce12e7350fd8e5d70685af6ead8f2292e8d8c6bd51a8e0039a1ca191819995",
"block": 4089598
}
},
"anchors": [
{
"seq": 1,
"hash": "d1aa55127d1722227e98427bef5f1e6ee9d723b596efb0d3e361db68234a1ec4",
"at": 1790750410,
"statementHash": "0xf8824c9dc9cd6cf038b384b3c01a51b612cbc30120402e30e27d0941120bee52",
"chainId": 28001,
"chainAsked": true,
"witness": "AereNotary first-seen under a post-quantum certified anchor"
}
],
"honest": {
"version": "aere-agent-ledger/2 (2026-09-29)",
"agentId": "aere-agent:55c675e87838a1ad7d73a1a72f3d9c5aa0515681",
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIHsjALBglghkgBZQMEAxIDggehAJs2I+v6sK8cUJKOUknFCej9kZX9PhP1LKnJ\n5bm6/JczC7zMxDbb9F8/0GZ1L2KlaQ31H1YMzh6oXapbxtc13VPoQ3kgHTPz0RAs\nudabZhXyn1iH6hjEo9HQjgjAn5s2iJ044Sg13Q+E53//4PKulelcxMccVt/hbf8A\nGRK4idJGhWk6U2smo0kqvY5a12nLDj2g2bDjzl4JRSEXCPWQiRniB4wJwxDS/GN2\n28+zmfkZvilfq1K/pVnHtCScL/AlD1R7Zro8vDsHlcWPHVQgGfVw6+gx2oN+azyC\nIUtXcrvHzsM2D0axX0sXCGTK8Hn3Tbik65rsZQuTz1M7j5WihsL70svNZDH4CEKd\nG3F0wJFfOXrFFjRPo4JgdozBNmCFJvZ5bhJgjtEbRMOIR8f67WlOsAVpOXD+y7HK\nHid3H+IReDmrvAIst4mwFBnuqXDHSMg66buxg7MJ8TR6fLjrdUncYNV8Q96bcLo2\ncDOdhBXhp2QIJPYlopTAVX05BjSvshCeO/bl7y6zGaaLCH+89hB60CLGNoSN0VUK\nvLOxOry1VVR7NVWA3HLp+o6Ca+KkD6fKfgAuNhLwJyKyTuAzw8VhAwqmkZOL7lkt\nV4CXCIBuOh5KSU8VQ6c3HFJC07gP7cltlfmup82uqDU7Co07ej7WoAmEZCVQVsT4\noolfJOHeUTM1eeadF71V5jROuUGBZLfx0qIRnDyZ4o6YBsnyOFPbg2VlJZpmsUSv\nTS7cvDzwgqM1mK/6VkmzK3sF+368R84lMSawymgpOnR/YqCWILryM4WkP3IGXTto\ny0v52vEsY6a/By/VRXVzYFB5SfOcOFazz+Jg+5Q9EKi02X984hPD2T9Ez40//g0r\nt5KQNDeWK/446I2YcZOIXL4ew6oLaqbjArnfcsV/j0ywcpDoAXLIX9GGrPugIrF/\nnn2lcs5qo0WgQrflABaOlfZi8CQ8n9++Z+ZIdiTZxKDusvBqqXOFDy4ojCUuPUAM\nKCq6xGxxCrZdgQVGqG/njzNKn7CkvOzLdxuLOzUtElwncYMx8mF2j2/tfgJdgmX/\nSaVfDzfvHLsYCejhAGtV4fbszHQBs/5A/lNEYUzcoTwPp0T3IDcozQG4cvnJjRnK\nAs7hBCdhnfqlbS4lB6IWgJ0n4zFsxsJ+cCqOp/7m+FLcjcGk3srRD/GnIBcwQM42\nsycKvoX51A6Vg/atY1A9AGvPaek/srVl/qSW8F/8O2eUhceEeJzSVMnpK4OooxzE\nkbHhmSp7Z975WyeWk0Hfgd3mjYyvVmZPUm8SHcNue+l1x3hWTXW+JQ4oeNWWWokf\niWkErpPx2Xv8DsP1Do/BsHMMMUywdAKuGxvZ0XYiE9OrvCkhLyVVxC2KOVF/Ei1k\n/ZXc2IaPgKXYrEfssOTnX8wHX99HG5QKLsXFMuQ/igbAORDzsXymUEVr3l7sWddb\nyoaJrGlmRtx5jNoNmi2TF5++Zoi2hOqBs86msImXV9QDyBPAphZjE+IpNx2gotnK\nfvw+F8DfKwwMAmOcga1i38pldRnMmt8/E9QC2pxjzQeEzSUQCVYLR5AWad478he6\nVUZDOU7iKnlJwfk6jfFRaTyHI87zvbPqQmLml3rQw33OXiJ1j6tOWg7KPzTFHSd3\nA2i7lEMeyi1YYVNwT+NTuDSehHwgokXGuizOPyfaBn9JwzSAY1bCZOwt0/CzbB+h\nk6rCMDA8wKqw451s33VInIDqwKoIJYR9zF9ck//lQ8dHElvJW++pGH4ODgrgCORb\nN388y4KyNsOAaMUkO2yJmr6qCPki+/0ftcvbAt2pTr7q2/fGWNnlrSG8iKOTdFKj\nW7Jwpilz7EwYE3gGSLn/aKOW7/rT7+8lN3OdsWW79z99zfnIScB7xzWkOmrdUCfj\nxg8Jn++58snJLDR8Op6NDhYO5oCwV9ljhAb+tyGLBt9bw30XJBRiOFGI1Io4Znnv\nTJgxMD8155qCziOcoV5pF7ziTi8NxlgyYN7iKoQs9QdnA78BCj/xqsc2E3HJCl1Z\nRDSdqfJXhkiFEpY7FZLkbSlZlzEX8AaZl9L8lWTr3MK1k/F+87pHOKWYpfj4cFkU\nNBQCx3YwK63/AyBJUVGbNKo8iFy+REP7+nyMg+vRck0AMOWsQqrirJEViwroup8p\nXEEE8Z7kqIGjd0VCvedHHcl/LNgtQDMKY2LUVufBgrQNHeSiuRH7Ci3qj0Pdw1tN\neCDfxtlfFhQpLk0sZDbTabwahDZQH3ycd721IUlWDGeEzGQtK8xJnzNJKOCWxVEI\nad70CILer7phpA7gfDFg2m5lqHvDy88lp+l5vOLyR1mcjtyxD9CAUcEwOlYdiN+I\nDdKzemZswapw5aPjYEvye/KrSdEqM+JBBiEXQgaIwjolax5p5pJl6tlAptsWdzlj\nuxDkbdk4NTuBIsHLdJtPR/2VnFnG/STw0pD4rTrWQ5X7Pkk5p8Qva92j7GRQVhrv\n2io7SvyA9Yc+Qigv+YFxLJ3taJO3apmzh2XwlGCbn34AEwYcqLIpOQvPOpwyHwQk\nauBRu4ailAr2SbBTX7BNfq6ilmnvph3SJ9yJABFMKH07mgh5qZ1im20ZgbiR0uaB\nS/VdNIoE\n-----END PUBLIC KEY-----\n",
"policyHash": "0x83082335a1ece1c6ef89812c74144cf63c1d7e586339fd9348bf79c455550cc2",
"session": "ac8e86e12a35e2d5355e0ab4e804dd17",
"entries": [
{
"seq": 0,
"prev": "0000000000000000000000000000000000000000000000000000000000000000",
"body": {
"v": 2,
"agentId": "aere-agent:55c675e87838a1ad7d73a1a72f3d9c5aa0515681",
"policyHash": "0x83082335a1ece1c6ef89812c74144cf63c1d7e586339fd9348bf79c455550cc2",
"session": "ac8e86e12a35e2d5355e0ab4e804dd17",
"at": 1790749508,
"action": {
"kind": "payment",
"to": "0xbbbb",
"amount": "10",
"at": 1790749508
},
"decision": {
"allowed": true,
"reason": "under the limit"
},
"provenance": null,
"seq": 0
},
"signature": "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",
"hash": "2ba3bcd648ecbd7599765851afa12c64ad149333626aad48558918a8c28eb22f"
},
{
"seq": 1,
"prev": "2ba3bcd648ecbd7599765851afa12c64ad149333626aad48558918a8c28eb22f",
"body": {
"v": 2,
"agentId": "aere-agent:55c675e87838a1ad7d73a1a72f3d9c5aa0515681",
"policyHash": "0x83082335a1ece1c6ef89812c74144cf63c1d7e586339fd9348bf79c455550cc2",
"session": "ac8e86e12a35e2d5355e0ab4e804dd17",
"at": 1790749513,
"action": {
"kind": "payment",
"to": "0xbbbb",
"amount": "10",
"at": 1790749513
},
"decision": {
"allowed": true,
"reason": "under the limit"
},
"provenance": null,
"seq": 1
},
"signature": "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",
"hash": "d1aa55127d1722227e98427bef5f1e6ee9d723b596efb0d3e361db68234a1ec4"
},
{
"seq": 2,
"prev": "d1aa55127d1722227e98427bef5f1e6ee9d723b596efb0d3e361db68234a1ec4",
"body": {
"v": 2,
"agentId": "aere-agent:55c675e87838a1ad7d73a1a72f3d9c5aa0515681",
"policyHash": "0x83082335a1ece1c6ef89812c74144cf63c1d7e586339fd9348bf79c455550cc2",
"session": "ac8e86e12a35e2d5355e0ab4e804dd17",
"at": 1790750428,
"action": {
"kind": "payment",
"to": "0xbbbb",
"amount": "10",
"at": 1790750428
},
"decision": {
"allowed": true,
"reason": "under the limit"
},
"provenance": null,
"seq": 2
},
"signature": "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",
"hash": "9f1503f28e6b6497d87607458316acd73ba40e8dcb2e0004326c259106c485c6"
}
]
},
"backdated": {
"version": "aere-agent-ledger/2 (2026-09-29)",
"agentId": "aere-agent:55c675e87838a1ad7d73a1a72f3d9c5aa0515681",
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\n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\nS/VdNIoE\n-----END PUBLIC KEY-----\n",
"policyHash": "0x83082335a1ece1c6ef89812c74144cf63c1d7e586339fd9348bf79c455550cc2",
"session": "ac8e86e12a35e2d5355e0ab4e804dd17",
"entries": [
{
"seq": 0,
"prev": "0000000000000000000000000000000000000000000000000000000000000000",
"body": {
"v": 2,
"agentId": "aere-agent:55c675e87838a1ad7d73a1a72f3d9c5aa0515681",
"policyHash": "0x83082335a1ece1c6ef89812c74144cf63c1d7e586339fd9348bf79c455550cc2",
"session": "ac8e86e12a35e2d5355e0ab4e804dd17",
"at": 1790749508,
"action": {
"kind": "payment",
"to": "0xbbbb",
"amount": "10",
"at": 1790749508
},
"decision": {
"allowed": true,
"reason": "under the limit"
},
"provenance": null,
"seq": 0
},
"signature": "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",
"hash": "2ba3bcd648ecbd7599765851afa12c64ad149333626aad48558918a8c28eb22f"
},
{
"seq": 1,
"prev": "2ba3bcd648ecbd7599765851afa12c64ad149333626aad48558918a8c28eb22f",
"body": {
"v": 2,
"agentId": "aere-agent:55c675e87838a1ad7d73a1a72f3d9c5aa0515681",
"policyHash": "0x83082335a1ece1c6ef89812c74144cf63c1d7e586339fd9348bf79c455550cc2",
"session": "ac8e86e12a35e2d5355e0ab4e804dd17",
"at": 1790749513,
"action": {
"kind": "payment",
"to": "0xbbbb",
"amount": "10",
"at": 1790749513
},
"decision": {
"allowed": true,
"reason": "under the limit"
},
"provenance": null,
"seq": 1
},
"signature": "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",
"hash": "d1aa55127d1722227e98427bef5f1e6ee9d723b596efb0d3e361db68234a1ec4"
},
{
"seq": 2,
"prev": "d1aa55127d1722227e98427bef5f1e6ee9d723b596efb0d3e361db68234a1ec4",
"body": {
"v": 2,
"agentId": "aere-agent:55c675e87838a1ad7d73a1a72f3d9c5aa0515681",
"policyHash": "0x83082335a1ece1c6ef89812c74144cf63c1d7e586339fd9348bf79c455550cc2",
"session": "ac8e86e12a35e2d5355e0ab4e804dd17",
"at": 1790749558,
"action": {
"kind": "payment",
"to": "0xbbbb",
"amount": "10",
"at": 1790749558
},
"decision": {
"allowed": true,
"reason": "under the limit"
},
"provenance": null,
"seq": 2
},
"signature": "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",
"hash": "5473e55f7499999ea8a749d7895f9ebae3b1b6baf3022b85582e5be67ecb546a"
}
]
},
"otherBranch": {
"version": "aere-agent-ledger/2 (2026-09-29)",
"agentId": "aere-agent:55c675e87838a1ad7d73a1a72f3d9c5aa0515681",
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\n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\nS/VdNIoE\n-----END PUBLIC KEY-----\n",
"policyHash": "0x83082335a1ece1c6ef89812c74144cf63c1d7e586339fd9348bf79c455550cc2",
"session": "ac8e86e12a35e2d5355e0ab4e804dd17",
"entries": [
{
"seq": 0,
"prev": "0000000000000000000000000000000000000000000000000000000000000000",
"body": {
"v": 2,
"agentId": "aere-agent:55c675e87838a1ad7d73a1a72f3d9c5aa0515681",
"policyHash": "0x83082335a1ece1c6ef89812c74144cf63c1d7e586339fd9348bf79c455550cc2",
"session": "ac8e86e12a35e2d5355e0ab4e804dd17",
"at": 1790749508,
"action": {
"kind": "payment",
"to": "0xbbbb",
"amount": "10",
"at": 1790749508
},
"decision": {
"allowed": true,
"reason": "under the limit"
},
"provenance": null,
"seq": 0
},
"signature": "935OtWsRdZudDuhihRTRvH/9hnxS+Rvj4BiU9tjEYQOQCQkzOSP6DCkQHtC0GyVOPgOmpW/5tCK2Wt1rfo+fcrV7lwPnkazVAX+HqyNZVE6959jbhokBQdg5Qr7LQREB4fR8sV8zDwqPNmjTEn1UHMP8x+y/AvqdEykH4FEYzkSq2NBLxiGJM2YRzNwGo20OsGlgASK4k4ITG5hnx4XTAte9VSPwEc0WLUc/mMUPnwcfUW+Bgjk+KT0R005JITrIHoAIWOf68e+fPzklk9pvT3PDBlCwABRbj6qGeLOWeqIUj9x6MV1t2QZQIMS2fEACXL6W9i2b8HHykPo4vGcz8x9Keg3RFcyTLD4LBbhr0GHDiyA3o8ZaWIPFNpp1/9cmU9DL83dWEl+i7Kg4AbPC/so+ALmll2vueogeMdDSuRsDyW/cXNbWde/DUx4hEI1eQfYnj+MD0hiF7rl/MMeapaQXOPQNTx/t+coE0+uq5BqupQ0JeqEn2TaMaAo9ImWa+f7PpQBqHt93C4E9WuQxpih2u8xbzJIIXx2xzdXfaapCY72XkX7bkXOPVO3DWfthSQo1gqMUY8TYxdjipB06Ttv62HcUTL8pULrX3P6qKWXykTI0fjtTmY8PULZn9NWcaPn4DyuHYcMK8MjcZERpz0cGtun481b0AILq7F9rKm4ev6Rvq3s9k6f+NM6jPASAQ1uCNJkQC4JXgFv/EgO0nB7QMqgyUAlpmpXThwbYftqadyU3yVS9G3TQx22bHowNfkkPDCZWLGnywGdqBxgraMG7KTclaMw9J7q1rpKv+7jyH0r3K0HREk6Xc16XPSnXkqS2q49nNCiisTgQdflq21b6YiKRDtkMQu6JeqMmjBaTc6RRAG5di9PzHlhuoKRqltO6Jsq8DFfKzI4QQsPlCYu/jgfSx1cpzgCTm56cPay6mp39AQSgWHabMmpJhuLbKRku8AvxrKJHpmC9r5a0uqng1bPPB5k4lIHL2xWs5g/JJqKgZkxFtkp2WOoIOzhcukkSv46DA5hQFCgwlJLJLKB6VPYsFJkV3Nw70PCS1U2iDAYMbAmNa9BWsdY+eVmiT+1uwCSyVruUukd9sk1ZhcY3Tb0jq2BWgINahGkOxYBF5M8dzj4p+FML5q4wvzBySmJsxn6W71X1hmi4j/4dbIduRIffvj4m8NnpDMV/WaYxa2naeKWJ0tM6frOUM+APLTLRHYKV4GJlWpoRl9sdww916VP/HnQnJ+Tdf5fANGB1Jdc4YvAaX8a5x2UDYtMz75EQrUmgxcDtlC2EEFyJhBv/oRmy7r8ClC/VWnfUC5+T0o8UyYaVL77jlYAxcwXh/OS/AZyHc54mkvxmiEel79xZc/JoZDx16hbpL92VUWP3T8LWl8o22GMJeqxNgzROndaLBAmqIKy/KCU88rqmNn0GSEPbCUWLHA7sXk8pTdJKhj7Zv0WlIkz08CAqLkoPKtoh1oeK076AzR3msqzOddNIT5iGrhjWQNsApN1BMQWKgE4UoPupU7fTQt5e4IXbOeFMyAWqdPrvlZRee+2P1gl5nTjGtzrPTLyfTbopzTCx0YrzDI6LJKC7zmHHNh4cLd2kbRL/DgJ3ufGJVZOyRqpnpQFkOU4qYOdcSl0yBT3SBiTqDLCfs4Nw13s5A0RbFjRvFHApiHnigderRRSlMoVYN0o+1PADt8Gqmou98VK2tAqQ8TSdN6yDok+N/4ejmtebN3Ah3VRy6IqCCw1JByuMSQeZ257Zv4oDsRU3SQd4oYmGbxat+0mhA3fa3qS0YsAyfmK1yPHOLkFIZWW20vqtuXeew7LxmDUPfLuBRDz0KPOg8R6SCgbmRQ2ZD36PshBm6bEIa68OkgXwpExLDSCV3n0+/PrmxLHOXQ0LCBdz7/JiQ+h6j8rZ1ACY6DI4cu17w8e/ME0xFpQwrdkY7Np5JhvEReFk/5jH8QFkMtrAoUCiVl74rfKFQMwoiry8wvIDo8hTi5yT/yVTi/SHIBhL7+3YhtgOXAjvbQgxuP/LTfQisBqTrgoJcPjfsV4AZ0bZTA7FDW+0FREM7OjILsl1OqROUyMd94ClfUShDmMvnstFxW1FDQktegFQpbPM5+YpLFQW5mHZNuUt/rb7ji+vWxJwOzbh2F8AHT4ViaIPmriy9xdPNkJjydKKS3qeDsr6d6LdC5jwhoojf000qgdHr91Y2V+NjgRk5CisfSXDC7m4I+xD/6TsG9Ws3itaHtaIpmoNoT/D2c0KH8/HOiDLANobXNZ0quLDz5F1lahtrD/AmYLSXr1YFm6nnmKZyfq0L1t2aUXE6VjoB/pKMQSidjRMdBaOFye7tPI7vkOATMXcPI6w0sDR7t9E8L2Exewlix1E1ToH1ctIqye5Yxfwomyvw4y00fX8uucvsMb/XqXGDRYRnKHjuKU/qpHLxr8bvcGG+VcmtJLX9vJQrKkTWjXkgUfJdmLAnNcS0B0HMaIrBOBVz8//irjFTvT34ExvLxUdfUgQW3F1WIBPC2ItWh7jd11lQc7xxSxVzYMRnRcWjbIxBJAPkW0kFQwG6Hd9qCT8neK+5Lhg774+Eq4ldDNJwXdMvemB5chKv+lVg5gGph/eVhdZfOYeex+wzhPpJqUaLE9huGdfBB/w89R+PVpF3hp3yBeWj7wX5/GIgbySeUXoM56/gA8NaLZH5Ws3UpfMtK1likb6iKvve8dM+rIvToe76lYR4xZcR7PEvfnD47WGhINOdMjV2aYZ+iV0mulYe1NRGLS1iQ2N5EQteUe5mjuNWNAwGWQ1vJwaHN6/EouaOubDh+F1QRlMVUH08QoBKroFytKUcP21pv09COk0u308HfB8MhIVPG2NK0VmfJNpoJ5CS01c/ssprpO/Hu1Q+RuzTO8t4Occ/Z+dIkXGnsbXlLJIkN/vLepjQf4b1uCz0Gz18lCRDTr0HNh9SjaOzDlBgghUtG5jLjgTqMfW3t8yAXBfC723U4YKxlmRjD7nEZlGvcAHBYOXWln2hsz7QNtQbVdciizysf6bkK6+VPA/OdjWFQ8fHc7CvAT3L4JIQWEsS3fcExsoUiDEY9+cSmvZIcBJ0ftUQPnXhr21Ua1NqTF+LSmxbMN4ERHlvMR6CFDbD3B2mrp1gJSJB3cUp47oqY5f7Rx21dXnAaoi8mBHEfCTQJDlUmoEhEDEHqFxLgAWPFWlaJtGgO60QqpUBVh8ik9fH6JjdQ1s6ZiPPo6g05jkluBVCVeJD9pGlcS6ox+7RX1ggIs3QI0YuEXGIkCWbaAo8kGmmxqbZCmw49O4O7XNPCSXdmN4TYIIcXs0XAZ79Z8xqXLTjCXycTa1gw8fBup5HjY7AWS7hNtz+6m7joDT8+na7RnHzM/BYtQvonxgxKvtdeQwRn8O19U0KD04evYlXZ4CPg3SIq8PF6ao4WIJtKQAjKcPfDbPUKUgFKoFdLP8+BWk5yMf2Mjr1q/ejzyPPpX3T8l5FRGLx5RoWcpl0I6SKo1ZTq9gP7eMG7mJNcghjz8PaaQjFoAuqbGjEMiNq0lC5ZFtWa4iBusKYARwtmTzoJPREBY50K6dMiO9qmyBJVxAdz7jNHGpqf/xHmU/OcmKLAzb0ooKwUu/H10/04dJPJmS2Y117Zse1vxNnND8F9sSF1bGuAlQsEx7dRB8sWzw+6r19pNaAwx/IcYhG/Wix7q0r/wBcA6g+nN8L1H5nHOk4s8uH1xNnN1WspIuORHy1UxGTUB4HBrFllriWdNfA270EMYHOMbz8kk7ghqFHc/T7C2V+VNDTYA1cXJlxo+EG4grAYrioPihtM9h6lZ28YBmoIRy7C+cWVkPGYvaPhSuT7XJGoAYxqPjO19LI4umLANFBoe4JWGtgnt67O1zhxr0RC7glH7Yk8iYfNhZEwQUZzIh9aDWFFHhz10qt9FxVp7IMYDlhrosBCWTNDYo73ufDFBW/7Oz+7OBRpXM1QxdzJyWsIz0fGkEgVvl9y8yoRMGGB1FRoyG8DRutSFYqoozpWb1jt565khAwuLBfVwuvn8LSecouDrAD4qUuz2z2QzzBhcS4BazSGAPIsRjkRwqwLRTdgJqkN+8wMYRWEbN00bfOm0dV9Iimf2Q/pluJUbigOW+ciQnZRxrtHkxnj1LcaJsmyzkIA7szhecFPqqVwX6lshWVEpE+t8arQVhKE6AoszyLxcjhFp6yICQ/lApq794MjbEBUtnlzgRaNcBrykwAg1TJk9m4/ZLg+Sr9u/SLhI69PeZJINOab8x7sM8UJPlNPuGsCHF0RkXqiLSpWvbn1/0XUyM87hfu8pTWw9KvaOC4IOaNW3iCEe/vOFfZ4iJvA02csPH4vL8UFlhi7Ti6gUJYm92g4a9xu78DaEXGmx6fAAAAAAAAAAAAAAAAAAAAAAABQ0UHyEm",
"hash": "e2da3def2507b3dccb42387da5864e9da7c05ca45bf329ab53dfbe099bf4686b"
},
{
"seq": 1,
"prev": "e2da3def2507b3dccb42387da5864e9da7c05ca45bf329ab53dfbe099bf4686b",
"body": {
"v": 2,
"agentId": "aere-agent:55c675e87838a1ad7d73a1a72f3d9c5aa0515681",
"policyHash": "0x83082335a1ece1c6ef89812c74144cf63c1d7e586339fd9348bf79c455550cc2",
"session": "ac8e86e12a35e2d5355e0ab4e804dd17",
"at": 1790749513,
"action": {
"kind": "payment",
"to": "0xbbbb",
"amount": "99",
"at": 1790749513
},
"decision": {
"allowed": true,
"reason": "under the limit"
},
"provenance": null,
"seq": 1
},
"signature": "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",
"hash": "0c626959f21bb136ac24da66f06f398ecfde95adf1c6796560acfae38d959331"
}
]
},
"verdicts": {
"honestWithAnchor": true,
"backdatedWithoutAnchor": true,
"backdatedWithAnchor": false,
"backdatedError": "entry declares 1790749558, before the anchor at seq 1 that precedes it was witnessed (1790750410): backdated",
"otherBranch": "FAILED"
}
}

View File

@ -0,0 +1,73 @@
// Proba lantului ca martor al registrului unui agent, CAP LA CAP pe testnetul public 28001: capul unui registru real se noteaza pe
// AereNotary cu cheia de dezvoltator a testnetului, verificatorul AIP-23 publicat ii da finalitatea post-cuantica, iar momentul
// firstSeen devine ancora cu care verifyLedger prinde o intrare antedatata si o alta ramura. Refuza orice alt lant decat 28001
// (citeste eth_chainId). Cheia de dezvoltator se citeste din fisierul dat in AERE_TESTNET_KEY_FILE, in proces, si nu se tipareste.
// Scrie dovada (registrele, capul notarizat, ancorele, verdictele; nicio cheie privata) in dovezi-ancora-28001/.
// AERE_TESTNET_KEY_FILE=<fisier> AERE_VERIFY_PROOF=<verify-proof.mjs> node proba-agent-ancora-testnet.mjs [--rpc URL]
// Iesire 0 = toate cum trebuia; 1 = una rosie; 2 = NEMASURAT (fara cheie, fara verificator, lantul nu e 28001, finalitatea n-a venit)
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { definePolicy } from './agent-policy.mjs';
import { newAgentIdentity, openLedger, resumeLedger, verifyLedger } from './agent-ledger.mjs';
import { ledgerHeadEnvelope, notarizeHead, anchorsFromNotarizedHeads, NOTARI } from './agent-ancora.mjs';
import { incarcaEthers } from './x402/wallet.mjs';
const AICI = path.dirname(fileURLToPath(import.meta.url));
const argv = process.argv.slice(2); const RPC = argv.includes('--rpc') ? argv[argv.indexOf('--rpc') + 1] : 'https://testnet-rpc.aere.network';
const kf = process.env.AERE_TESTNET_KEY_FILE;
const DEV_VERIFY = path.resolve(AICI, '..', '..', 'verificator-falcon', 'verify-proof.mjs');
const VERIFY = process.env.AERE_VERIFY_PROOF || (fs.existsSync(DEV_VERIFY) ? DEV_VERIFY : '');
if (!kf || !fs.existsSync(kf)) { console.log('NEMASURAT: AERE_TESTNET_KEY_FILE nu numeste un fisier cu cheia de dezvoltator a testnetului'); process.exit(2); }
if (!VERIFY || !fs.existsSync(VERIFY)) { console.log('NEMASURAT: lipseste verificatorul AIP-23 (AERE_VERIFY_PROOF=<verify-proof.mjs>)'); process.exit(2); }
let ethers; try { ethers = incarcaEthers(); } catch (e) { console.log('NEMASURAT: ' + e.message); process.exit(2); }
const provider = new ethers.JsonRpcProvider(RPC);
const chainId = Number((await provider.getNetwork()).chainId);
if (chainId !== 28001) { console.log(`NEMASURAT: ${RPC} serveste lantul ${chainId}, nu 28001`); process.exit(2); }
let ok = 0, rau = 0; const cer = (c, ce, d = '') => { console.log(` ${c ? 'OK ' : 'RAU'} ${ce}${c || !d ? '' : ' -- ' + d}`); c ? ok++ : rau++; };
const acum = () => Math.floor(Date.now() / 1000);
const id = newAgentIdentity();
const { policy, policyHash } = definePolicy({ agentId: id.agentId, spend: { amount: '1000', windowSeconds: 3600 }, recipients: ['0xbbbb'] });
// intrarile 0 si 1 scrise acum 15 minute (ceasul registrului injectat), capul (seq 1) notarizat acum: firstSeen ~ acum
const T0 = acum() - 900; let t = T0; const ceas = () => t;
const L = openLedger({ identity: id, policy, policyHash, now: ceas });
L.record({ kind: 'payment', to: '0xbbbb', amount: '10' }); t += 5; L.record({ kind: 'payment', to: '0xbbbb', amount: '10' });
const inainte = L.export();
const cap = ledgerHeadEnvelope(inainte, { seq: 1 });
const n = await notarizeHead({ envelope: cap, rpc: RPC, keyFile: kf, ethers });
cer(n.ok && n.envelope.notarization.chainId === 28001 && n.envelope.notarization.notary === NOTARI[28001], `1. capul (seq 1) notarizat pe 28001${n.ok ? `: firstSeen ${n.envelope.notarization.firstSeen}, bloc ${n.envelope.notarization.block}` : ''}`, n.motiv);
if (!n.ok) { console.log(`\nagent-ancora-testnet: ${ok}/${ok + rau} cum trebuia`); process.exit(1); }
const notarizat = n.envelope;
// finalitatea post-cuantica vine la urmatoarea ancora certificata: se asteapta pana la 6 minute
let r = null; const start = Date.now();
while (Date.now() - start < 360000) {
r = await anchorsFromNotarizedHeads(inainte, [notarizat], { verifyProof: VERIFY, rpc: RPC, chain: 28001 });
if (r.stare !== 'NEMASURAT') break;
await new Promise((ok2) => setTimeout(ok2, 20000));
}
if (r.stare === 'NEMASURAT') { console.log('NEMASURAT: finalitatea post-cuantica nu a venit in 6 minute: ' + JSON.stringify(r.randuri)); process.exit(2); }
cer(r.stare === 'OK' && r.anchors.length === 1, `2. verificatorul AIP-23 publicat da finalitate post-cuantica si ancora ${r.anchors[0] ? `{seq ${r.anchors[0].seq}, at ${r.anchors[0].at}}` : ''} (dupa ${Math.round((Date.now() - start) / 1000)} s)`, JSON.stringify(r.randuri));
const anc = r.anchors;
cer(anc[0] && anc[0].at === notarizat.notarization.firstSeen, '2. momentul certificat post-cuantic = firstSeen citit din contract');
// dupa notarizare: o continuare cinstita (acum) si una ANTEDATATA (T0 + 50, sub firstSeen - 300), semnate cu cheia agentului
t = acum(); const cinstit = resumeLedger({ identity: id, policy, policyHash, ledger: inainte, now: ceas }); cinstit.record({ kind: 'payment', to: '0xbbbb', amount: '10' });
t = T0 + 50; const antedatat = resumeLedger({ identity: id, policy, policyHash, ledger: inainte, now: ceas }); antedatat.record({ kind: 'payment', to: '0xbbbb', amount: '10' });
const vC = verifyLedger(cinstit.export(), { policy, anchors: anc });
cer(vC.ok && vC.time.lowerBound === 'witnessed', '3. continuarea cinstita, cu ancora lantului: ok, marginea de jos "witnessed"', JSON.stringify(vC).slice(0, 200));
const vA0 = verifyLedger(antedatat.export(), { policy });
cer(vA0.ok, '3. MARTORUL MASURII: fara ancora, continuarea antedatata trece');
const vA = verifyLedger(antedatat.export(), { policy, anchors: anc });
cer(!vA.ok && /backdated/.test(vA.error || ''), '3. cu ancora lantului, continuarea antedatata e prinsa', JSON.stringify(vA).slice(0, 200));
// alta ramura a agentului: aceeasi sesiune, intrarea 1 diferita
t = T0; const ramura = openLedger({ identity: id, policy, policyHash, now: ceas }); ramura.record({ kind: 'payment', to: '0xbbbb', amount: '10' }); t += 5; ramura.record({ kind: 'payment', to: '0xbbbb', amount: '99' });
const rR = await anchorsFromNotarizedHeads(ramura.export(), [notarizat], { verifyProof: VERIFY, rpc: RPC, chain: 28001 });
cer(rR.stare === 'FAILED' && !verifyLedger(ramura.export(), { policy, anchors: anc }).ok, '4. o alta ramura nu are capul notarizat: FAILED, si verifyLedger o refuza cu ancora');
// dovada, fara nicio cheie privata
const D = path.join(AICI, 'dovezi-ancora-28001'); fs.mkdirSync(D, { recursive: true });
const zi = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
fs.writeFileSync(path.join(D, `ancora-agent-${zi}.json`), JSON.stringify({ v: 1, kind: 'aere-agent-ledger-anchor-evidence', network: 'eip155:28001', rpc: RPC, policy, policyHash,
ledgerBefore: inainte, notarizedHead: notarizat, anchors: anc, honest: cinstit.export(), backdated: antedatat.export(), otherBranch: ramura.export(),
verdicts: { honestWithAnchor: vC.ok, backdatedWithoutAnchor: vA0.ok, backdatedWithAnchor: vA.ok, backdatedError: vA.error, otherBranch: rR.stare } }, null, 1) + '\n');
console.log(`\nagent-ancora-testnet: ${ok}/${ok + rau} cum trebuia (dovada in dovezi-ancora-28001/ancora-agent-${zi}.json)`);
process.exitCode = rau ? 1 : 0;

View File

@ -0,0 +1,121 @@
// Proba lantului ca martor al registrului unui agent (agent-ancora.mjs), OFFLINE: verificatorul AIP-23 e inlocuit de un raspuns in
// forma lui (niveluri, finality PASSED cu "as first seen at <ISO> (<unix>)"), ca fiecare garda sa fie judecata fara retea. Drumul
// intreg, cu notarizarea reala pe testnetul 28001 si verificatorul AIP-23 publicat, e in proba-agent-ancora-testnet.mjs.
// Fiecare afirmatie cu perechea ei negativa.
// node proba-agent-ancora.mjs iesire 0 = toate cum trebuia
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import { spawnSync } from 'node:child_process';
import { fileURLToPath } from 'node:url';
import { definePolicy } from './agent-policy.mjs';
import { newAgentIdentity, openLedger, resumeLedger, verifyLedger } from './agent-ledger.mjs';
import { ledgerHeadEnvelope, headMatchesLedger, firstSeenFromVerdict, anchorsFromNotarizedHeads, notarizeHead, HEAD_KIND } from './agent-ancora.mjs';
const AICI = path.dirname(fileURLToPath(import.meta.url));
let ok = 0, rau = 0;
const cer = (c, ce, d = '') => { console.log(` ${c ? 'OK ' : 'RAU'} ${ce}${c || !d ? '' : ' -- ' + d}`); c ? ok++ : rau++; };
const clon = (o) => JSON.parse(JSON.stringify(o));
// o exceptie din anchorsFromNotarizedHeads devine un rezultat (stare EXCEPTIE), ca proba sa ajunga la rezumat si randul sa iasa RAU
const sigur = async (...a) => { try { return await anchorsFromNotarizedHeads(...a); } catch (e) { return { stare: 'EXCEPTIE: ' + e.message, anchors: [], randuri: [{ detail: String(e.message) }] }; } };
const id = newAgentIdentity();
const { policy, policyHash } = definePolicy({ agentId: id.agentId, spend: { amount: '1000', windowSeconds: 3600 }, recipients: ['0xbbbb'] });
// intrarile 0 si 1 scrise la T0; capul (seq 1) vazut de lant la F = T0 + 1200
const T0 = 1_790_000_000, F = T0 + 1200;
let t = T0; const now = () => t;
const L = openLedger({ identity: id, policy, policyHash, now });
L.record({ kind: 'payment', to: '0xbbbb', amount: '10' }); t += 5; L.record({ kind: 'payment', to: '0xbbbb', amount: '10' });
const inainte = L.export();
const cap = ledgerHeadEnvelope(inainte, { seq: 1, createdAt: new Date(T0 * 1000 + 6000).toISOString() });
// un raspuns al verificatorului AIP-23 in forma lui, pentru un statementHash dat
const verdict = (h, stare = 'PASSED', t2 = F) => ({ verdict: stare === 'PASSED' ? 'VALID' : 'PARTIAL', statementHash: h, levels: [
{ level: 'form', state: 'PASSED', detail: 'kind=' + HEAD_KIND + '-attestation' }, { level: 'integrity', state: 'PASSED', detail: 'sha256(statement) == statementHash' },
{ level: 'signature', state: 'ABSENT', detail: 'the envelope carries no signature' },
{ level: 'finality', state: stare, detail: stare === 'PASSED' ? `post-quantum: the state of block 9, the parent of anchor 10 whose post-quantum certificate verified here, records this statementHash in AereNotary 0x70099E62735500AA2F85B60C518551a57B202d54 as first seen at ${new Date(t2 * 1000).toISOString()} (${t2}); first seen in block 5` : 'notarized at ..., after ...; the next anchor will cover it' }] });
const stub = (raspuns) => async (_vp, f) => raspuns(JSON.parse(fs.readFileSync(f, 'utf8')));
const notarizat = { ...cap, notarization: { chainId: 28001, notary: '0x70099E62735500AA2F85B60C518551a57B202d54', firstSeen: F } };
// ---------------------------------------------------------------- capul
cer(cap.kind === HEAD_KIND + '-attestation' && cap.statement.seq === 1 && cap.statement.hash === inainte.entries[1].hash && cap.statement.session === inainte.session,
'1. capul numeste agentul, sesiunea, politica, seq si hash-ul intrarii; statementHash = sha256 al declaratiei');
cer(headMatchesLedger(cap, inainte).ok, '1. capul e al registrului');
const alt = clon(cap); alt.statement.hash = '0x' + '11'.repeat(32);
cer(!headMatchesLedger(alt, inainte).ok && /modified envelope/.test(headMatchesLedger(alt, inainte).motiv), '1. CONTROL: un cap cu hash-ul schimbat (fara statementHash refacut) -> refuzat');
const id2 = newAgentIdentity(); const { policy: p2, policyHash: h2 } = definePolicy({ agentId: id2.agentId, spend: { amount: '1000', windowSeconds: 3600 }, recipients: ['0xbbbb'] });
const L2 = openLedger({ identity: id2, policy: p2, policyHash: h2, now }); L2.record({ kind: 'payment', to: '0xbbbb', amount: '1' }); L2.record({ kind: 'payment', to: '0xbbbb', amount: '1' });
cer(!headMatchesLedger(cap, L2.export()).ok, '1. CONTROL: capul altui agent nu e al acestui registru');
// un cap cu hash-ul bun dar care numeste alt agent (statementHash refacut): declaratia nu spune adevarul despre registru -> refuzat
const altAgent = clon(cap); altAgent.statement.agentId = id2.agentId; altAgent.statementHash = '0x' + (await import('node:crypto')).createHash('sha256').update(JSON.stringify(altAgent.statement)).digest('hex');
cer(!headMatchesLedger(altAgent, inainte).ok && /another agent/.test(headMatchesLedger(altAgent, inainte).motiv), '1. CONTROL: un cap care numeste alt agent (hash-ul intrarii bun, plicul refacut) -> refuzat');
// ---------------------------------------------------------------- momentul citit din verificator
const f1 = firstSeenFromVerdict(verdict(cap.statementHash));
cer(f1.stare === 'PASSED' && f1.at === F, '2. momentul firstSeen citit din nivelul de finalitate PASSED (ISO si unix, acelasi moment)');
cer(firstSeenFromVerdict(verdict(cap.statementHash, 'PENDING')).stare === 'NEMASURAT', '2. CONTROL: finalitate in asteptare -> NEMASURAT, nu ancora');
const strica = verdict(cap.statementHash); strica.levels[3].detail = strica.levels[3].detail.replace(`(${F})`, `(${F + 60})`);
cer(firstSeenFromVerdict(strica).stare === 'NEMASURAT', '2. CONTROL: ISO si unix care nu spun acelasi moment -> NEMASURAT');
const fara = verdict(cap.statementHash); fara.levels[3].detail = 'post-quantum: recorded';
cer(firstSeenFromVerdict(fara).stare === 'NEMASURAT', '2. CONTROL: un detaliu intr-o forma necunoscuta -> NEMASURAT, nu un moment ghicit');
const cazut = verdict(cap.statementHash); cazut.levels[3].state = 'FAILED';
cer(firstSeenFromVerdict(cazut).stare === 'FAILED', '2. CONTROL: finalitate FAILED -> FAILED');
// ---------------------------------------------------------------- ancorele si verificarea registrului
const r = await sigur(inainte, [notarizat], { verifyProof: 'stub', rpc: 'stub', ruleaza: stub((e) => verdict(e.statementHash)) });
cer(r.stare === 'OK' && r.anchors.length === 1 && r.anchors[0].seq === 1 && r.anchors[0].at === F && r.anchors[0].hash === inainte.entries[1].hash, '3. un cap notarizat, cu finalitate post-cuantica -> ancora {seq 1, hash, at = firstSeen}', JSON.stringify(r));
const rH = await sigur(inainte, [notarizat], { verifyProof: 'stub', rpc: 'stub', ruleaza: stub(() => ({ ...verdict('0x' + '22'.repeat(32)) })) });
cer(rH.stare === 'FAILED' && !rH.anchors.length, '3. CONTROL: verificatorul a judecat alt statementHash -> FAILED, nicio ancora');
const rP = await sigur(inainte, [notarizat], { verifyProof: 'stub', rpc: 'stub', ruleaza: stub((e) => verdict(e.statementHash, 'PENDING')) });
cer(rP.stare === 'NEMASURAT' && !rP.anchors.length, '3. CONTROL: finalitate in asteptare -> NEMASURAT, nicio ancora');
const rN = await sigur(inainte, [notarizat], { verifyProof: 'stub', rpc: 'stub', ruleaza: async () => null });
cer(rN.stare === 'NEMASURAT', '3. CONTROL: verificatorul nu raspunde -> NEMASURAT');
const minte = { ...notarizat, notarization: { ...notarizat.notarization, firstSeen: F - 5000 } };
const rM = await sigur(inainte, [minte], { verifyProof: 'stub', rpc: 'stub', ruleaza: stub((e) => verdict(e.statementHash)) });
cer(rM.stare === 'OK' && rM.anchors[0].at === F, '3. CONTROL: momentul ancorei e cel certificat de verificator, nu cel scris in plic (plicul spune F - 5000)', JSON.stringify(rM.anchors));
// dupa notarizare: o intrare cinstita (la F + 10) si una ANTEDATATA (la T0 + 100, sub F - 300), scrise cu cheia agentului
t = F + 10;
const cinstit = resumeLedger({ identity: id, policy, policyHash, ledger: inainte, now }); cinstit.record({ kind: 'payment', to: '0xbbbb', amount: '10' });
t = T0 + 100;
const antedatat = resumeLedger({ identity: id, policy, policyHash, ledger: inainte, now }); antedatat.record({ kind: 'payment', to: '0xbbbb', amount: '10' });
const mt = F + 1000;
const vC = verifyLedger(cinstit.export(), { policy, maxTime: mt, anchors: r.anchors });
cer(vC.ok && vC.time.lowerBound === 'witnessed', '4. registrul cinstit cu ancora lantului: ok, marginea de jos "witnessed"', JSON.stringify(vC).slice(0, 200));
const vA0 = verifyLedger(antedatat.export(), { policy, maxTime: mt });
cer(vA0.ok, '4. MARTORUL MASURII: fara ancora, intrarea antedatata trece (asta e golul inchis aici)', JSON.stringify(vA0).slice(0, 200));
const vA = verifyLedger(antedatat.export(), { policy, maxTime: mt, anchors: r.anchors });
cer(!vA.ok && /backdated/.test(vA.error || ''), '4. cu ancora lantului, intrarea antedatata e prinsa ("backdated")', JSON.stringify(vA).slice(0, 200));
// alta ramura a aceluiasi agent (aceeasi sesiune): intrarea 1 diferita; capul notarizat al primei ramuri nu e al ei
t = T0; const ramura = openLedger({ identity: id, policy, policyHash, now }); ramura.record({ kind: 'payment', to: '0xbbbb', amount: '10' }); t += 5; ramura.record({ kind: 'payment', to: '0xbbbb', amount: '99' });
const rR = await sigur(ramura.export(), [notarizat], { verifyProof: 'stub', rpc: 'stub', ruleaza: stub((e) => verdict(e.statementHash)) });
cer(rR.stare === 'FAILED' && /another branch/.test(rR.randuri[0].detail), '5. o alta ramura a agentului nu are capul notarizat: FAILED, "another branch"');
cer(!verifyLedger(ramura.export(), { policy, maxTime: mt, anchors: r.anchors }).ok, '5. si verifyLedger refuza ramura cu ancora primei ramuri');
// notarizarea: gardele de dinaintea retelei (un cap atins, alt fel de plic) nu ating reteaua
const atins = clon(cap); atins.statement.seq = 0;
const n1 = await notarizeHead({ envelope: atins, rpc: 'http://127.0.0.1:9', keyFile: 'nu-exista', ethers: null });
cer(!n1.ok && n1.cod === 1 && /modified envelope/.test(n1.motiv), '6. notarizarea refuza un cap atins, inainte de retea');
const n2 = await notarizeHead({ envelope: { ...cap, kind: 'aere-audit-head-attestation' }, rpc: 'x', keyFile: 'x', ethers: null });
cer(!n2.ok && n2.cod === 2, '6. notarizarea refuza alt fel de plic');
// un nod care serveste 2800 (lantul principal): refuz fara confirmare explicita; lantul se citeste de la nod, nu din argument
const eth = (chain, cod) => ({ JsonRpcProvider: class { async getNetwork() { return { chainId: BigInt(chain) }; } async getCode() { return cod; } },
Wallet: class { constructor() { throw new Error('the test never gets this far'); } }, Contract: class {} });
const n3 = await notarizeHead({ envelope: cap, rpc: 'x', keyFile: 'x', ethers: eth(2800, '0x60'), confirmMainnet: false });
cer(!n3.ok && n3.cod === 3 && /mainnet/.test(n3.motiv), '6. un nod al lantului 2800 -> REFUZ fara AERE_CONFIRM_MAINNET=yes (o tranzactie reala)', JSON.stringify(n3));
const n4 = await notarizeHead({ envelope: cap, rpc: 'x', keyFile: 'x', ethers: eth(28001, '0x') });
cer(!n4.ok && n4.cod === 1 && /no contract/.test(n4.motiv), '6. niciun contract la adresa notarului -> REFUZ', JSON.stringify(n4));
// linia de comanda: head scrie exact plicul bibliotecii
const T = fs.mkdtempSync(path.join(os.tmpdir(), 'aere-anc-'));
try {
fs.writeFileSync(path.join(T, 'l.json'), JSON.stringify(inainte));
const c1 = spawnSync(process.execPath, [path.join(AICI, 'agent-ancora.mjs'), 'head', '--ledger', path.join(T, 'l.json'), '--seq', '1', '--out', path.join(T, 'h.json')], { encoding: 'utf8' });
const h = JSON.parse(fs.readFileSync(path.join(T, 'h.json'), 'utf8'));
cer(c1.status === 0 && headMatchesLedger(h, inainte).ok && h.statement.seq === 1, '7. `head` din linia de comanda scrie capul registrului', c1.stderr);
const c2 = spawnSync(process.execPath, [path.join(AICI, 'agent-ancora.mjs'), 'anchors', '--ledger', path.join(T, 'l.json'), '--head', path.join(T, 'h.json'), '--rpc', 'http://127.0.0.1:9'], { encoding: 'utf8', env: { ...process.env, AERE_VERIFY_PROOF: '' } });
cer(c2.status === 2 && /NEMASURAT/.test(c2.stderr), '7. `anchors` fara verificatorul AIP-23 -> NEMASURAT (cod 2), nu ancore', `${c2.status} ${c2.stderr}`);
} finally { fs.rmSync(T, { recursive: true, force: true }); }
console.log(`\nagent-ancora: ${ok}/${ok + rau} cum trebuia`);
process.exitCode = rau ? 1 : 0;