diff --git a/tools/enforce-judge-gate.mjs b/tools/enforce-judge-gate.mjs index bd88587..9f3a072 100644 --- a/tools/enforce-judge-gate.mjs +++ b/tools/enforce-judge-gate.mjs @@ -24,7 +24,7 @@ import { CLASSIFIER_MODEL, HEAVY_LLM_TIMEOUT_MS } from './router-config.mjs'; import fsDefault from 'node:fs'; import { join } from 'node:path'; // Task 5 (sealed-plan production): печать на реальном wired GO. -import { sealArtifact, sealPlan, sealablePlan, sealableArtifact, judgedHashOf, decideSeal, ownerSealAction } from './seal-orchestration.mjs'; +import { sealArtifact, sealPlan, sealablePlan, sealableArtifact, judgedHashOf, decideSeal, ownerSealAction, ownerSealActionForContent } from './seal-orchestration.mjs'; // SP3-b owner-seal: escape-грант владельца над owner-seal:<хеш тела> (читается в sealTurnProd, sync). import { escapeGrantOpen, loadFloorEscapes, loadConsumed } from './escape-grant.mjs'; import { resolveReceiptKey } from './receipt-key-config.mjs'; @@ -61,6 +61,8 @@ export function buildJudgeArbitrationMessage(verdict, planContent, n) { side: 'judge', level: 'L2', round: n, objectionVerbatim: formatJudgeObjection(verdict) || '(судья не дал текста возражения)', controllerPositionVerbatim: position, + // SP3-c: owner-seal-метка (тот же хеш, что sealTurnProd) → владельцу есть откуда взять escape. + sealAction: ownerSealActionForContent(planContent), }); const opts = card.options.map((o) => `• ${o.label}: ${o.whatChanges}`).join('\n'); return [ diff --git a/tools/enforce-mentor-on-plan-write.mjs b/tools/enforce-mentor-on-plan-write.mjs index c443b8e..2a6b348 100644 --- a/tools/enforce-mentor-on-plan-write.mjs +++ b/tools/enforce-mentor-on-plan-write.mjs @@ -9,7 +9,7 @@ import { readStdin, parseEventJson, exitDecision, runtimeDir } from './enforce-hook-helpers.mjs'; import { mentorSeamActive, resolveMentorLlmKey } from './mentor-gate-config.mjs'; import { PLAN_PATH_RE, SPEC_PATH_RE } from './enforce-judge-gate.mjs'; -import { sealablePlan, sealableArtifact, judgedHashOf } from './seal-orchestration.mjs'; +import { sealablePlan, sealableArtifact, judgedHashOf, ownerSealActionForContent } from './seal-orchestration.mjs'; import { planId } from './plan-lock.mjs'; import { onPlanWrite, onSpecWrite } from './on-plan-write.mjs'; import { parseVerifiedContext } from './plan-verified-context.mjs'; @@ -50,6 +50,8 @@ export function buildMentorArbitrationMessage(res, planContent, n) { side: 'mentor', level: 'L1', round: n, objectionVerbatim: formatMentorObjection(res) || '(нет текста замечания)', controllerPositionVerbatim: position, + // SP3-c: owner-seal-метка (тот же хеш, что sealTurnProd) → владельцу есть откуда взять escape. + sealAction: ownerSealActionForContent(planContent), }); const opts = card.options.map((o) => `• ${o.label}: ${o.whatChanges}`).join('\n'); return [