38 lines
3.0 KiB
JavaScript
38 lines
3.0 KiB
JavaScript
// verdict.mjs: the ONE verdict form of the suite. Whatever the artifact (an AIP-23 envelope, a payment receipt, a market timeline,
|
|
// a dataset answer), the verdict says, for each of four levels, PASSED, FAILED or NOT_MEASURED, with the named reason:
|
|
//
|
|
// integrity the artifact is what it says: its hashes bind its content, and the rules it declares (a policy, deadlines, a
|
|
// window, Merkle paths, a payout) hold when recomputed from the evidence supplied
|
|
// authenticity the signature the artifact carries verifies
|
|
// anchoring its statementHash is recorded in the notary contract, under a state root that a post-quantum anchor covers
|
|
// finality that anchor's post-quantum certificate verifies; the finality is the one of the chain it was notarized on
|
|
//
|
|
// A level nobody judged is NOT_MEASURED and says why (`cause`). The verdict is INVALID when a level FAILED; PARTIAL when nothing
|
|
// failed but something the artifact CLAIMS was not measured (a notarization claim not checked offline, a signature scheme the
|
|
// verifier cannot check, a timeline that is not terminal); VALID otherwise, and only with integrity PASSED. `failed` is the sorted
|
|
// list of the rule ids that refused: the suite compares it as an exact set.
|
|
export const LEVELS = ['integrity', 'authenticity', 'anchoring', 'finality'];
|
|
/** Causes that leave a claim of the artifact unmeasured: nothing failed, and the verdict still cannot be VALID. */
|
|
export const CAUZE_PARTIALE = ['claim-not-checked', 'unmeasurable', 'pending', 'incomplete'];
|
|
|
|
export function acumulator() { return Object.fromEntries(LEVELS.map((l) => [l, { failed: [], motive: [], passed: [], nm: [] }])); }
|
|
export const pica = (acc, level, rule, motiv) => { acc[level].failed.push(rule); if (motiv) acc[level].motive.push(motiv); };
|
|
export const trece = (acc, level, ce) => { acc[level].passed.push(ce); };
|
|
export const nemasurat = (acc, level, cause, reason) => { acc[level].nm.push({ cause, reason }); };
|
|
|
|
export function verdictUnic(artifact, acc) {
|
|
const levels = LEVELS.map((l) => {
|
|
const a = acc[l];
|
|
if (a.failed.length) return { level: l, state: 'FAILED', rules: [...new Set(a.failed)].sort(), reason: [...new Set(a.motive)].join('; ') };
|
|
const partial = a.nm.find((x) => CAUZE_PARTIALE.includes(x.cause));
|
|
if (partial) return { level: l, state: 'NOT_MEASURED', rules: [], cause: partial.cause, reason: partial.reason };
|
|
if (a.passed.length) return { level: l, state: 'PASSED', rules: [], reason: a.passed.join('; ') };
|
|
const n = a.nm[0] || { cause: 'not-judged', reason: 'no verifier of this artifact judges this level' };
|
|
return { level: l, state: 'NOT_MEASURED', rules: [], cause: n.cause, reason: n.reason };
|
|
});
|
|
const failed = [...new Set(levels.flatMap((x) => x.rules))].sort();
|
|
const partial = levels.some((x) => x.state === 'NOT_MEASURED' && CAUZE_PARTIALE.includes(x.cause));
|
|
const verdict = failed.length ? 'INVALID' : partial || levels[0].state !== 'PASSED' ? 'PARTIAL' : 'VALID';
|
|
return { v: 1, kind: 'aere-conformance-verdict', artifact, verdict, levels, failed };
|
|
}
|