From 74905096a7b24d268b06e3c0904a8d89f040d63b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Tue, 16 Jun 2026 17:32:30 +0300 Subject: [PATCH] =?UTF-8?q?feat:=20round-memory=20=D0=B2=D1=8B=D0=B7=D1=8B?= =?UTF-8?q?=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D0=B8=20=D0=BF=D0=B5=D1=80=D0=B5?= =?UTF-8?q?=D0=B4=D0=B0=D1=8E=D1=82=20stage=20=D0=B2=20=D0=BF=D0=BE=D1=82?= =?UTF-8?q?=D0=BE=D0=BB=D0=BA=D0=B8=20SP2c-3b=20=D0=B6=D0=B8=D0=B2=D0=BE?= =?UTF-8?q?=D0=B9=20per-=D1=81=D1=82=D0=B0=D0=B4=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 --- tools/enforce-judge-gate.mjs | 4 +++- tools/enforce-mentor-on-plan-write.mjs | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/tools/enforce-judge-gate.mjs b/tools/enforce-judge-gate.mjs index 21c1ae7..64f9416 100644 --- a/tools/enforce-judge-gate.mjs +++ b/tools/enforce-judge-gate.mjs @@ -492,7 +492,9 @@ async function main() { // Фаза 4: ключ счётчика — task-id (наставник сохранил его в Post-до судьи); sess — fallback. let taskId = null; try { taskId = loadTaskId({ sessionId: (event && event.session_id) || 'unknown', runtimeDir: runtimeDir(), fsImpl: fsDefault }); } catch { taskId = null; } - const n = bumpJudgeNoGo({ taskId, sessionId: (event && event.session_id) || 'unknown', blocked: isNoGo }); + // SP2c-3: потолок per-стадия — stage из функции судьи (gate1=спека, gate2=план). + const stageNoGo = extractGate1Product(event).shouldJudge ? 'spec' : 'plan'; + const n = bumpJudgeNoGo({ taskId, sessionId: (event && event.session_id) || 'unknown', stage: stageNoGo, blocked: isNoGo }); // SP2c-1: дословное замечание судьи на NO-GO в дорожку judge. Best-effort, fail-quiet. if (isNoGo) { try { diff --git a/tools/enforce-mentor-on-plan-write.mjs b/tools/enforce-mentor-on-plan-write.mjs index 38986e1..1e5f950 100644 --- a/tools/enforce-mentor-on-plan-write.mjs +++ b/tools/enforce-mentor-on-plan-write.mjs @@ -241,8 +241,10 @@ async function main() { // вердикт (ok!==true). degraded (wired:false) не считается (escalation L1 не растёт). const verdictDecision = res.verdict && res.verdict.decision; const blocked = res.wired === true && (verdictDecision === 'NO-GO' || res.ok !== true); - // Фаза 4: счётчик на СТЭК (спека+план) одной задачи — ключ task-id (sess — fallback). - const n = bumpMentorNoGo({ taskId: res.taskId, sessionId: sess, blocked }); + // Фаза 4 / SP2c-3: счётчик per-стадия — ключ (task-id + stage). stage из пути события. + const fpStage = String((event.tool_input && event.tool_input.file_path) || ''); + const stageNoGo = SPEC_PATH_RE.test(fpStage) ? 'spec' : (PLAN_PATH_RE.test(fpStage) ? 'plan' : null); + const n = bumpMentorNoGo({ taskId: res.taskId, sessionId: sess, stage: stageNoGo, blocked }); // Фаза 1 (Р2): на NO-GO/degraded — ПОЛНЫЙ текст доходит до контроллера через рабочий // exit-2 канал (подтверждён Фазой 0). На 3-м NO-GO — карточка арбитража. const planContent = String((event.tool_input && event.tool_input.content) ?? '');