feat(round-memory): recordArtifact — запись версии + доводов M/J (SP2c-1 helper)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Дмитрий
2026-06-16 16:12:48 +03:00
parent 5d7035875c
commit 8f25ce32e1
2 changed files with 59 additions and 0 deletions
+22
View File
@@ -0,0 +1,22 @@
#!/usr/bin/env node
/** round-memory-record — orchestration-помощник записи памяти кругов (SP2c-1).
* Цель — минимизировать врезки в discipline-source: одна точка пишет снимок версии артефакта
* и доводы контроллера последнего круга «## Переговоры» по дорожкам M/J. Объекция стороны
* (NO-GO) пишется отдельным вызовом recordObjection прямо из стора. Fail-quiet. */
import { recordVersion, recordArg } from './round-memory-store.mjs';
import { parseNegotiationSection } from './negotiation-section.mjs';
/** На запись артефакта: снимок версии + доводы ПОСЛЕДНЕГО круга по дорожкам M/J.
* Пустые доводы не пишутся. Любая ошибка → no-op (false), не кидает. */
export function recordArtifact(taskId, stage, content, baseDir) {
try {
recordVersion(taskId, stage, content, baseDir);
const rounds = parseNegotiationSection(content);
const last = rounds[rounds.length - 1];
if (last) {
if (last.mentor) recordArg(taskId, stage, 'M', last.mentor, baseDir);
if (last.judge) recordArg(taskId, stage, 'J', last.judge, baseDir);
}
return true;
} catch { return false; }
}
+37
View File
@@ -0,0 +1,37 @@
import { describe, it, expect } from 'vitest';
import { mkdtempSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { recordArtifact } from './round-memory-record.mjs';
import { getVersions, getArgs } from './round-memory-store.mjs';
const dir = () => mkdtempSync(join(tmpdir(), 'rmrec-'));
describe('recordArtifact', () => {
it('пишет версию артефакта', () => {
const d = dir();
recordArtifact('t1', 'plan', '# План\nтело', d);
expect(getVersions('t1', 'plan', d)).toEqual(['# План\nтело']);
});
it('пишет доводы последнего круга по дорожкам M/J', () => {
const d = dir();
const content = `# План
## Переговоры
### Круг 1
**Наставнику:** довод M
**Судье:** довод J
## Шаги`;
recordArtifact('t1', 'plan', content, d);
expect(getArgs('t1', 'plan', 'M', d)).toEqual(['довод M']);
expect(getArgs('t1', 'plan', 'J', d)).toEqual(['довод J']);
});
it('нет переговоров → версия есть, доводов нет', () => {
const d = dir();
recordArtifact('t1', 'spec', '# Спека', d);
expect(getVersions('t1', 'spec', d)).toEqual(['# Спека']);
expect(getArgs('t1', 'spec', 'M', d)).toEqual([]);
});
it('fail-quiet на мусоре не кидает', () => {
expect(() => recordArtifact('t1', 'plan', null, '\0bad')).not.toThrow();
});
});