From 56074a04305091b0570e86fb84931d54af68f7df 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:48:13 +0300 Subject: [PATCH] =?UTF-8?q?feat:=20round-memory=20arbitrationRequested=20?= =?UTF-8?q?=D0=B4=D0=B5=D1=82=D0=B5=D0=BA=D1=82=D0=BE=D1=80=20=D0=BC=D0=B0?= =?UTF-8?q?=D1=80=D0=BA=D0=B5=D1=80=D0=B0=20=D0=B0=D1=80=D0=B1=D0=B8=D1=82?= =?UTF-8?q?=D1=80=D0=B0=D0=B6=D0=B0=20SP2d-a?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 --- tools/negotiation-section.mjs | 10 ++++++++++ tools/negotiation-section.test.mjs | 17 ++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/tools/negotiation-section.mjs b/tools/negotiation-section.mjs index 082e9f5..80fdf95 100644 --- a/tools/negotiation-section.mjs +++ b/tools/negotiation-section.mjs @@ -33,3 +33,13 @@ function extractAddressee(body, label) { const mm = String(body || '').match(re); return mm ? mm[1].trim() : ''; } + +/** SP2d: контроллер просит арбитраж на ЛЮБОМ круге — маркер `**Арбитраж:** <причина>` в + * артефакте (раздел «Переговоры»). Возвращает причину (truthy) или '' если маркера нет. + * Карточка арбитража показывается при этом маркере независимо от круга (потолок ≤3 остаётся). */ +export function arbitrationRequested(md) { + const text = typeof md === 'string' ? md : ''; + const m = text.match(/\*\*Арбитраж:\*\*\s*([^\n]*)/i); + if (!m) return ''; + return m[1].trim() || 'арбитраж запрошен контроллером'; +} diff --git a/tools/negotiation-section.test.mjs b/tools/negotiation-section.test.mjs index 0773764..202c58b 100644 --- a/tools/negotiation-section.test.mjs +++ b/tools/negotiation-section.test.mjs @@ -1,5 +1,5 @@ import { describe, it, expect } from 'vitest'; -import { parseNegotiationSection } from './negotiation-section.mjs'; +import { parseNegotiationSection, arbitrationRequested } from './negotiation-section.mjs'; const PLAN = `# План ## Цель @@ -41,3 +41,18 @@ describe('parseNegotiationSection', () => { expect(parseNegotiationSection(null)).toEqual([]); }); }); + +describe('arbitrationRequested (SP2d)', () => { + it('нет маркера → пусто', () => { + expect(arbitrationRequested('# План\n## Переговоры\n### Круг 1\n**Судье:** x')).toBe(''); + }); + it('маркер с причиной → причина', () => { + expect(arbitrationRequested('## Переговоры\n**Арбитраж:** тупик по §4')).toBe('тупик по §4'); + }); + it('маркер без причины → truthy (дефолт)', () => { + expect(arbitrationRequested('**Арбитраж:**')).toBeTruthy(); + }); + it('не строка → пусто', () => { + expect(arbitrationRequested(null)).toBe(''); + }); +});