mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-30 11:49:16 +00:00
Сверка PROCESS.md, ролевых выжимок, AGENTS.md, TESTING.md, CONTRIBUTING.md и скриптов по 26 найденным расхождениям (D1–D26): трейлеры по классам изменений, gate:small как единственный источник состава, пороги ревью, путь реестра мутантов, golden по ci:golden, порядок чтения промпта ревью. - scripts/change-classes.mjs: классы A/B/C/D — один модуль для process-gate и проверки трейлеров. - commit-msg: коммит только с файлами класса C (документация) трейлеров не требует; указанные трейлеры по-прежнему проверяются. - Маршрут автора без docs/STATUS.md: 5345 → 4703 слова. - Промпт ревью читает SCOPE → AGENTS → REVIEWER, как ROUTES.reviewer. Issue: #701 User-Visible: no Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
57 lines
3.4 KiB
JavaScript
57 lines
3.4 KiB
JavaScript
// #634: цена входа агента измерима и ограничена (AC1: автор ≤ 12 000 слов).
|
|
import assert from 'node:assert/strict';
|
|
import { readFileSync } from 'node:fs';
|
|
import test from 'node:test';
|
|
import { ROUTES, countWords, measureAll, measureRoute } from '../scripts/entry-cost.mjs';
|
|
|
|
const read = (rel) => readFileSync(new URL(`../${rel}`, import.meta.url), 'utf8');
|
|
|
|
test('#634 entry-cost: вход автора и ревьюера в бюджете (AC1)', () => {
|
|
const results = measureAll();
|
|
assert.equal(ROUTES.author.budget, 12000, 'бюджет автора — AC1 #634');
|
|
for (const [name, result] of Object.entries(results)) {
|
|
if (result.budget == null) continue;
|
|
assert.equal(result.over, false, `${name}: ${result.total} слов > бюджета ${result.budget}`);
|
|
assert.ok(result.total <= result.budget);
|
|
}
|
|
// Маршрут автора не содержит полного канона — иначе бюджет держится случайно.
|
|
assert.ok(!ROUTES.author.files.includes('PROCESS.md'));
|
|
assert.ok(ROUTES.author.files.includes('docs/process/AUTHOR.md'));
|
|
assert.ok(ROUTES.reviewer.files.includes('docs/process/REVIEWER.md'));
|
|
});
|
|
|
|
test('#634 entry-cost: превышение бюджета краснит замер', () => {
|
|
const files = { 'a.md': 'one two three', 'b.md': 'четыре пять\nшесть\t семь' };
|
|
const reader = (rel) => files[rel];
|
|
assert.equal(countWords(files['b.md']), 4);
|
|
const within = measureRoute({ budget: 7, files: ['a.md', 'b.md'] }, reader);
|
|
assert.deepEqual([within.total, within.over], [7, false]);
|
|
const over = measureRoute({ budget: 6, files: ['a.md', 'b.md'] }, reader);
|
|
assert.deepEqual([over.total, over.over], [7, true]);
|
|
assert.equal(measureRoute({ budget: null, files: ['a.md'] }, reader).over, false);
|
|
});
|
|
|
|
test('#634 entry-cost: AGENTS.md называет те же маршруты в том же порядке', () => {
|
|
const agents = read('AGENTS.md');
|
|
const section = agents.slice(agents.indexOf('**Reading order by role**'), agents.indexOf('The two digests'));
|
|
assert.ok(section.length > 0, 'раздел порядка чтения в AGENTS.md');
|
|
const route = (prefix) => {
|
|
const item = section.split('\n- ').find((chunk) => chunk.startsWith(prefix));
|
|
assert.ok(item, `AGENTS.md: нет пункта «${prefix}»`);
|
|
return [...item.matchAll(/`([^`]+\.md)`/g)].map((match) => match[1]);
|
|
};
|
|
assert.deepEqual(route('author'), ROUTES.author.files);
|
|
assert.deepEqual(route('reviewer'), ROUTES.reviewer.files);
|
|
assert.deepEqual(route('changing the pipeline'), ROUTES.canon.files);
|
|
});
|
|
|
|
test('#701 D14: промпт ревьюера читает маршрут reviewer в том же порядке, что AGENTS.md', async () => {
|
|
const { readFileSync } = await import('node:fs');
|
|
const { ROUTES } = await import('../scripts/entry-cost.mjs');
|
|
const workflow = readFileSync(new URL('../.github/workflows/_process.yml', import.meta.url), 'utf8');
|
|
const start = workflow.indexOf('Прочитай в этом порядке, прежде чем судить:');
|
|
assert.ok(start > 0, 'нумерованный порядок чтения в промпте найден');
|
|
const items = [...workflow.slice(start, start + 3000).matchAll(/^\s+(\d)\. (\S+)/gm)].slice(0, 3).map((m) => m[2]);
|
|
assert.deepEqual(items, ROUTES.reviewer.files);
|
|
});
|