From 829d6227190b0b9a28e0a4fcb423478a5632f0cc Mon Sep 17 00:00:00 2001 From: Aere Network Date: Mon, 12 Oct 2026 06:11:12 +0300 Subject: [PATCH] Citations: CITATIONS-UNRESOLVED.md generated from the published files; the top README cites the tests on their real paths under tools/proof-of-software/test/; the Cloud client file brought to the published SDK copy (O-017, 2026-10-12) --- CITATIONS-UNRESOLVED.md | 19 +++++++++++++++ README.md | 18 +++++++------- sdk/index.mjs | 53 +++++++++++++++++++++++++++++++++++++---- sdk/package.json | 2 +- 4 files changed, 78 insertions(+), 14 deletions(-) create mode 100644 CITATIONS-UNRESOLVED.md diff --git a/CITATIONS-UNRESOLVED.md b/CITATIONS-UNRESOLVED.md new file mode 100644 index 0000000..bd6544d --- /dev/null +++ b/CITATIONS-UNRESOLVED.md @@ -0,0 +1,19 @@ +# Citations in this repository that you cannot open + +This file is generated by the publication stager of this repository (scripts/legaturi-declaratie.cjs in the Aere working +tree) and enforced by legaturi.cjs. It is the complete list, measured on 2026-10-12, of every path cited in this +repository that does not resolve to a published file. + +A citation is a promise that a claim is checkable. Where the target is not published, or names a file the reader creates +while using the tool, the claim is traceable but **not independently verifiable by you**, and it should be read as our +assertion. Nothing was deleted to produce this list: every path below is still cited in the text exactly as our authors +wrote it. + +Paths that DO resolve are written relative to a side-by-side checkout of the Aere repositories, so they begin with a +repository name, for example `aere-contracts/contracts/pqc/AereCryptoRegistry.sol`. + +Unresolvable distinct paths in this repository: **3**. + +- `attestation.json` cited in: aere-proof-of-software/tools/proof-of-software/README.md +- `config.json` cited in: aere-proof-of-software/tools/proof-of-software/README.md +- `gradle/verification-metadata.xml` cited in: aere-proof-of-software/tools/proof-of-software/README.md diff --git a/README.md b/README.md index 9e29fd8..edc8bb8 100644 --- a/README.md +++ b/README.md @@ -25,15 +25,15 @@ Node.js 22 or later, and git. Results measured on 2026-09-30 (Node.js 24.14.1, W | test | result | negative control | |---|---|---| -| attestation and verification | 16/16 (`test/pos.test.mjs`) | inside the test | -| ML-BOM of a model directory | 8/8 (`test/model.test.mjs`) | `test/model-control-negativ.mjs` edits `pos.mjs` in place and restores it; not run for this table | -| developer credential | 12/12 (`test/credential.test.mjs`) | 7/7 (`test/credential-control-negativ.mjs`) | -| who signed (`--signer`) | 7/7 (`test/semnatar.test.mjs`) | 4/4 (`test/semnatar-control-negativ.mjs`) | -| npm SBOM from the committed lockfile | 11/11 (`test/sbom.test.mjs`) | 5/5 (`test/sbom-control-negativ.mjs`) | -| Go SBOM from the committed go.sum | 14/14 (`test/sbom-go.test.mjs`) | 8/8 (`test/sbom-go-control-negativ.mjs`) | -| .NET and Gradle SBOMs from the committed lock files | 27/27 (`test/sbom-nuget-gradle.test.mjs`) | 20/20 (`test/sbom-nuget-gradle-control-negativ.mjs`) | +| attestation and verification | 16/16 (`tools/proof-of-software/test/pos.test.mjs`) | inside the test | +| ML-BOM of a model directory | 8/8 (`tools/proof-of-software/test/model.test.mjs`) | `tools/proof-of-software/test/model-control-negativ.mjs` edits `pos.mjs` in place and restores it; not run for this table | +| developer credential | 12/12 (`tools/proof-of-software/test/credential.test.mjs`) | 7/7 (`tools/proof-of-software/test/credential-control-negativ.mjs`) | +| who signed (`--signer`) | 7/7 (`tools/proof-of-software/test/semnatar.test.mjs`) | 4/4 (`tools/proof-of-software/test/semnatar-control-negativ.mjs`) | +| npm SBOM from the committed lockfile | 11/11 (`tools/proof-of-software/test/sbom.test.mjs`) | 5/5 (`tools/proof-of-software/test/sbom-control-negativ.mjs`) | +| Go SBOM from the committed go.sum | 14/14 (`tools/proof-of-software/test/sbom-go.test.mjs`) | 8/8 (`tools/proof-of-software/test/sbom-go-control-negativ.mjs`) | +| .NET and Gradle SBOMs from the committed lock files | 27/27 (`tools/proof-of-software/test/sbom-nuget-gradle.test.mjs`) | 20/20 (`tools/proof-of-software/test/sbom-nuget-gradle-control-negativ.mjs`) | | hybrid signature library | 34/34 (`sdk-pq-sign/test/pq-sign.test.mjs`); its check of the ML-DSA half on chain is skipped without a Cloud key | inside the test | -| GitHub Action | `test/action.test.mjs` (long; installs pinned dependencies from the npm registry) | not measured for this publication | +| GitHub Action | `tools/proof-of-software/test/action.test.mjs` (long; installs pinned dependencies from the npm registry) | not measured for this publication | The GitHub Action is in this repository, which lives on git.aere.network; GitHub runs actions only from GitHub repositories, so to use it, copy these three folders into a GitHub repository you control and point `uses:` at it, pinned to a full commit SHA @@ -44,4 +44,4 @@ the documentation are in English. No third party has reviewed this code. ## Licence -MIT, see [LICENSE](LICENSE). Files: 48 (tools/proof-of-software 37, sdk-pq-sign 6, sdk 3). +MIT, see [LICENSE](LICENSE). Files: 49 (tools/proof-of-software 37, sdk-pq-sign 6, sdk 3). diff --git a/sdk/index.mjs b/sdk/index.mjs index c421c4f..69768a7 100644 --- a/sdk/index.mjs +++ b/sdk/index.mjs @@ -75,12 +75,57 @@ export class AereCloud { return this._req('POST', '/verify' + (chain ? `?chain=${encodeURIComponent(chain)}` : ''), { body: envelope }); } + /** + * identity verification (1.7.0): an AERE Identity presentation judged by the published command line -> VALID / PARTIAL / INVALID with every + * row, the claims shown and the subject when no row failed, and the command (with the moment) that reproduces the verdict. Read `verdict`: + * PARTIAL means some rows could not be judged (no trusted issuers, no status list). Needs a gateway that serves POST /v1/identity/verify. + * @param {{presentation:object, audience:string, nonce:string, trustedIssuers?:(string|object)[], statusLists?:object[], revocations?:object[], maxAgeSeconds?:number}} request + * @returns {Promise<{verdict:'VALID'|'PARTIAL'|'INVALID', notJudged:number, subject:object|null, claims:object|null, rows:object[], judgedAt:string, verifier:object, reproduce:string}>} + */ + identityVerify(request) { return this._req('POST', '/identity/verify', { body: request }); } + + /** + * compliance check (1.7.0): your policy judged on an AERE Identity presentation -> COMPLIANT / NOT_COMPLIANT with the reasons, and with + * `record: true` the record of the decision as an AIP-23 envelope without personal data (notarize it with notarize()). No claims come back. + * @param {{presentation:object, policy:object, audience:string, nonce:string, statusLists?:object[], revocations?:object[], record?:boolean}} request + * @returns {Promise<{verdict:'COMPLIANT'|'NOT_COMPLIANT', compliant:boolean, reasons:string[], policyId:string, policyHash:string, presentationHash:string, record?:object, judgedAt:string, verifier:object, reproduce:string}>} + */ + complianceCheck(request) { return this._req('POST', '/compliance/check', { body: request }); } + + /** + * payments, the risk step (1.8.0): one payment by a person or a company judged under YOUR declared policy by the published module + * (payments/risc.mjs) -> ALLOW / REFUSE with the reasons, what was measured and what was NOT (named in `unmeasured`, never simulated: + * no sanctions list, no identity tier), and the hashes (policyHash, inputsHash, verdictHash) from which anyone reproduces the verdict. + * A refusal is a verdict (HTTP 200, `verdict: 'REFUSE'`), not an error. Needs a gateway that serves POST /v1/payments/risk. + * @param {{policy:object, inputs:object}} request inputs: { chainId, payer, payee, asset, amount, rate:{usdPerUnit, source, at}, history, now } + * @returns {Promise<{verdict:'ALLOW'|'REFUSE', reasons:string[], unmeasured:string[], measured:object, policyHash:string, inputsHash:string, verdictHash:string, verifier:object, reproduce:string}>} + */ + paymentsRisk(request) { return this._req('POST', '/payments/risk', { body: request }); } + + /** + * payments, the receipt (1.8.0): for a payment ALREADY on the chain the gateway serves. The verdict is reproduced and must be ALLOW, + * the transaction must be the payment judged, and the receipt (an instruction and its AIP-23 settlement envelope) comes back notarized. + * Throws AereCloudError 409 (risk_refused, tx_mismatch, chain_mismatch), 404 (tx_not_found) or 502 (notarization_failed, with the + * receipt built but without a time). The amount in USD is exact at the rate YOU declare in the inputs; it is not a market price. + * @param {{policy:object, inputs:object, txHash:string, purpose?:string}} request + * @returns {Promise<{receipt:{instruction:object, envelope:object}, verdict:object, verifier:object, reproduce:string}>} + */ + paymentsReceipt(request) { return this._req('POST', '/payments/receipt', { body: request }); } + + /** + * payments, verify a receipt (1.8.0): the rules of the published module against the policy, the inputs and the chain, and the + * envelope judged by the reference verifier -> VALID / INVALID / PARTIAL (PARTIAL: the notarization is not under a certified anchor yet). + * @param {{receipt:{instruction:object, envelope:object}, policy:object, inputs:object}} request + * @returns {Promise<{verdict:'VALID'|'INVALID'|'PARTIAL', reasons:string[], rules:object, envelope:object|null, amountUsd:string, verifier:object, reproduce:string}>} + */ + paymentsVerify(request) { return this._req('POST', '/payments/verify', { body: request }); } + // ---- chain data ---- dataHead() { return this._req('GET', '/data/head'); } validators() { return this._req('GET', '/data/validators'); } anchors(limit = 10) { return this._req('GET', `/data/anchors?limit=${encodeURIComponent(limit)}`); } anchor(height) { return this._req('GET', `/data/anchors/${encodeURIComponent(height)}`); } - // 2026-09-26: the post-quantum finality point (finalized/safe = the parent of the last certified anchor), the tag nodes do not serve yet + // 2026-09-26: the post-quantum certified point (finalized/safe = the parent of the last certified anchor; evidence that its signers sealed it, not by itself that it was decided, AIP-22 erratum 2026-10-01); the tags nodes did not serve then finality() { return this._req('GET', '/data/finality'); } transfers(address, limit = 50) { return this._req('GET', `/data/transfers?address=${encodeURIComponent(address)}&limit=${encodeURIComponent(limit)}`); @@ -90,7 +135,7 @@ export class AereCloud { /** Notarizeaza un digest de 32 de octeti (0x + 64 hex); noi platim gazul. */ notarize(hash) { return this._req('POST', '/notarize', { body: { hash } }); } proofOf(hash) { return this._req('GET', `/notarize/${encodeURIComponent(hash)}`); } - // 2026-09-17: the proof with its post-quantum finality (first appearance, covering anchor, verdict, verification steps) + // 2026-09-17: the proof under a post-quantum certificate (first appearance, covering anchor, verdict, verification steps) proof(hash) { return this._req('GET', `/proof/${encodeURIComponent(hash)}`); } // quantum readiness scan of a domain's public TLS edge: free without a key; { attest: true } notarizes the report digest @@ -108,8 +153,8 @@ export class AereCloud { return this._req('POST', '/pq/readiness/perimeter', { body }); } - // AIP-21 (2026-09-18): the per-block post-quantum finality record (seals heard by a validator, re-verified, quorum - // verdict). Free, no key. Testnet 28001 first; `network` is reserved for chain 2800 once the method reaches its validators. + // AIP-21 (2026-09-18): the per-block post-quantum seal record (seals heard by a validator, re-verified, quorum + // verdict: evidence of participation, not by itself of the decision, AIP-21 erratum 2026-10-01). Free, no key. Testnet 28001 first; `network` is reserved for chain 2800 once the method reaches its validators. // `client`: 'besu' (default), 'nethermind', or 'both' (two independent implementations, with `agreement` computed by the gateway). pqFinality(block = 'latest', network = 'testnet', client = 'besu') { return this._req('GET', `/pq/finality/${encodeURIComponent(block)}?network=${encodeURIComponent(network)}&client=${encodeURIComponent(client)}`, { auth: false }); diff --git a/sdk/package.json b/sdk/package.json index 507d980..1850e44 100644 --- a/sdk/package.json +++ b/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@aere/cloud", - "version": "1.6.0", + "version": "1.8.0", "description": "Official client for the Aere Cloud API: keyed RPC, post-quantum verification, chain data, notarization, webhooks and gas sponsorship on Aere Network (chain 2800).", "type": "module", "main": "index.mjs",