Files
portal/tools/judge-goal-anchor.mjs
T

27 lines
1.3 KiB
JavaScript

#!/usr/bin/env node
/**
* judge-goal-anchor (§11 #2 — цель приколочена) — исходная цель пинится НЕИЗМЕННЫМ
* якорем (frozen + хеш); судья меряет против неё на каждом гейте. Анти-дрейф
* «цель → мой пересказ»: если на гейт подали перефразированную цель, хеш не сойдётся
* → дрейф → флаг. Судья опирается на pinned.goal, не на возможно-искажённую текущую.
*/
import { createHash } from 'node:crypto';
import { canonicalJson } from './receipt-sign.mjs';
function goalHash(goal) {
return createHash('sha256').update(canonicalJson(String(goal ?? ''))).digest('hex');
}
/** Приколотить цель: неизменная запись {goal, goal_hash}. */
export function pinGoal(goal) {
return Object.freeze({ goal: String(goal ?? ''), goal_hash: goalHash(goal) });
}
/** Сверить текущую цель с приколоченной. Хеш не сошёлся → дрейф (флаг). */
export function checkGoalIntegrity(pinned, currentGoal) {
const actual = goalHash(currentGoal);
const expected = pinned && pinned.goal_hash;
const drifted = actual !== expected;
return { ok: !drifted, drifted, expected, actual };
}