Files
brain/tools/post-seal.mjs
T

47 lines
2.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env node
/**
* post-seal (фикс дедлока) — печать плана в PostToolUse наставника. Берёт СВЕЖИЙ вердикт
* наставника (для текущего плана) + сохранённый судьёй GO (judge-go) → binding нах.F4 сходится,
* stale-вердикт исчезает. Переиспользует sealOnWiredGo (плановую ветку). Все I/O инъектируемы.
*/
import { sealOnWiredGo } from './enforce-judge-gate.mjs';
import { loadJudgeGo, judgeGoValidFor } from './judge-go-store.mjs';
import { freezeGate } from './freeze-gate.mjs';
import { sealPlan } from './seal-orchestration.mjs';
import { loadFrozenArtifact, saveFrozenPlan } from './plan-lock.mjs';
import { parseVerifiedContext } from './plan-verified-context.mjs';
import { artifactHasUnresolvedExtracted } from './context-verity.mjs';
import fsDefault from 'node:fs';
import { resolve as pathResolve } from 'node:path';
/**
* Запечатать план по свежему вердикту наставника + сохранённому GO судьи.
* Нет валидного GO (нет файла / чужой plan_hash / битая подпись) → {sealed:false, reason}.
* Иначе — sealOnWiredGo с freeze-gate на СВЕЖЕМ вердикте (mentorVerdict).
*/
export function postSealPlan({ event, mentorVerdict, planHash, sessionId, runtimeDir, repoRoot, key, deps = {} }) {
const judgeGo = (deps.loadJudgeGo || loadJudgeGo)({ sessionId, runtimeDir });
if (!judgeGoValidFor(judgeGo, { planHash, key })) {
return { sealed: false, reason: 'нет валидного GO судьи для этого плана (binding/подпись)' };
}
const fsImpl = deps.fsImpl || fsDefault;
return (deps.sealOnWiredGo || sealOnWiredGo)({
event,
verdict: { wired: true, decision: 'GO', judged_hash: judgeGo.judged_hash },
judgeMode: judgeGo.judge_mode,
deps: {
key,
sealPlan: deps.sealPlan || sealPlan,
loadCurrentArtifact: deps.loadCurrentArtifact || (() => loadFrozenArtifact({ sessionId, runtimeDir })),
persistPlan: deps.persistPlan || ((seal) => saveFrozenPlan({ plan: seal, sessionId, runtimeDir })),
mentorGate: deps.mentorGate || (({ content }) => freezeGate({
mentorVerdict,
mentorWired: true,
planHash,
verifiedContextArtifact: parseVerifiedContext(content),
hasUnresolvedExtractedImpl: (art) => artifactHasUnresolvedExtracted(art, (f) => fsImpl.readFileSync(pathResolve(repoRoot, f), 'utf8')),
})),
},
});
}