67fecd7149
- secretary-reconcile.mjs: buildReconcilePrompt (весь протокол+обмен), parseReconcileResponse, reconcileGuard (ни одна старая строка не пропала), buildGuardRemark (обоснованный возврат), stampProvenance (turn+session по тексту), reconcileTurn (вызов->сторож->до 2 возвратов) - stop-хук: вместо applyExtraction вызывает reconcileTurn; мотор инъектируется - renderProtocol: зачёркивание во ВСЕХ разделах (закрытые вопросы видны ~~struck~~) - ретайр: applyExtraction/buildExtractionPrompt/parseExtractionResponse (secretary-extract удалён) - Слой 1, провенанс @session, флажок по сессии, оглавление — без изменений - спека + план reconcile в docs/superpowers 33 теста green (мотор замокан, без сети). Модель для prod — Sonnet. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
33 lines
1.6 KiB
JavaScript
33 lines
1.6 KiB
JavaScript
// Структура и сверка короткого протокола (§D5/§D7). Отменённое зачёркивается, не удаляется.
|
|
export function EMPTY_PROTOCOL() {
|
|
return { subject: '', decisions: [], will: [], open: [], doneNext: [], history: [] };
|
|
}
|
|
|
|
function prov(turns) {
|
|
return Array.isArray(turns) && turns.length ? ` [${turns.map((t) => `→${t}`).join(', ')}]` : '';
|
|
}
|
|
|
|
// Навигация в Слой 1: метка сессии рядом с [→N] → искать raw/<session>.log, "=== ХОД turn=N ===".
|
|
function src(entry) {
|
|
return entry && entry.session ? ` @${String(entry.session).slice(0, 8)}` : '';
|
|
}
|
|
|
|
export function renderProtocol(protocol) {
|
|
const L = [];
|
|
L.push('## Решения');
|
|
for (const d of protocol.decisions) {
|
|
const body = d.struck ? `~~${d.text}~~` : d.text;
|
|
const why = d.why ? ` — ${d.why}` : '';
|
|
L.push(`- ${body}${why}${prov(d.turns)}${src(d)}`);
|
|
}
|
|
L.push('', '## Твоя воля / запреты');
|
|
for (const w of protocol.will) L.push(`- ${w.struck ? `~~${w.text}~~` : w.text}${prov(w.turns)}${src(w)}`);
|
|
L.push('', '## Открытые вопросы');
|
|
for (const o of protocol.open) L.push(`- ${o.struck ? `~~${o.text}~~` : o.text}${prov(o.turns)}${src(o)}`);
|
|
L.push('', '## Сделано / дальше');
|
|
for (const s of protocol.doneNext) L.push(`- [${s.done ? 'x' : ' '}] ${s.struck ? `~~${s.text}~~` : s.text}${prov(s.turns)}${src(s)}`);
|
|
L.push('', '## История (заменено, не стёрто)');
|
|
for (const h of protocol.history) L.push(`- ~~${h.oldText}~~ → ${h.newText}${prov(h.turns)}`);
|
|
return L.join('\n');
|
|
}
|