40 lines
2.4 KiB
JavaScript
40 lines
2.4 KiB
JavaScript
|
|
#!/usr/bin/env node
|
|||
|
|
/**
|
|||
|
|
* objection-format — дословные сводки возражений для блок-сообщений (П1).
|
|||
|
|
* Чистые форматтеры (презентация, не логика гейта): судья и наставник.
|
|||
|
|
* Fail-safe: мусор/нет возражений → пустая строка.
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Дословная сводка возражений судьи. Две формы:
|
|||
|
|
* - результат runJudge — блокирующие в `blocking[{anchor:{ref},severity}]` (приоритет);
|
|||
|
|
* - сырой parseJudgeResponse — `objections[{anchor:{ref},severity}]` (fallback).
|
|||
|
|
*/
|
|||
|
|
export function formatJudgeObjection(verdict) {
|
|||
|
|
const blocking = verdict && Array.isArray(verdict.blocking) ? verdict.blocking : null;
|
|||
|
|
const objs = (blocking && blocking.length) ? blocking
|
|||
|
|
: (verdict && Array.isArray(verdict.objections) ? verdict.objections : []);
|
|||
|
|
const lines = objs
|
|||
|
|
.filter((o) => o && o.anchor && o.anchor.ref)
|
|||
|
|
.map((o) => `— [${o.severity || 'light'}] ${o.anchor.ref}`);
|
|||
|
|
return lines.join('\n');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/** Дословная сводка замечания наставника (результат onPlanWrite {ok,wired,reason,verdict}).
|
|||
|
|
* Р7/мерж: NO-GO = decision==='NO-GO' ИЛИ сломанный вердикт (ok!==true). Доносит СУТЬ —
|
|||
|
|
* recommendation (что править) + reasoning (разбор) + plan_points_addressed (по пунктам,
|
|||
|
|
* включая скил-конкретику) + reason сбоя. GO → пустая строка (не заворот). */
|
|||
|
|
export function formatMentorObjection(r) {
|
|||
|
|
if (!r || r.wired !== true) return '';
|
|||
|
|
const v = r.verdict || {};
|
|||
|
|
const isNoGo = v.decision === 'NO-GO' || r.ok !== true;
|
|||
|
|
if (!isNoGo) return '';
|
|||
|
|
const lines = ['Замечание наставника:'];
|
|||
|
|
if (typeof v.recommendation === 'string' && v.recommendation.trim()) lines.push(`Что править: ${v.recommendation.trim()}`);
|
|||
|
|
if (typeof v.reasoning === 'string' && v.reasoning.trim()) lines.push(`Разбор: ${v.reasoning.trim()}`);
|
|||
|
|
const pts = Array.isArray(v.plan_points_addressed) ? v.plan_points_addressed.filter((p) => typeof p === 'string' && p.trim()) : [];
|
|||
|
|
if (pts.length) lines.push('По пунктам:', ...pts.map((p) => `— ${p}`));
|
|||
|
|
if (typeof r.reason === 'string' && r.reason.trim()) lines.push(`(${r.reason.trim()})`);
|
|||
|
|
return lines.length > 1 ? lines.join('\n') : '';
|
|||
|
|
}
|