mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-29 03:09:36 +00:00
fix: the screenshot witness floor comes from the set, not from survivors
Тот же дефект, что #408 у golden, и в моём же коде из #401. Порог свидетелей считался от числа кадров, уцелевших на диске: rm docs/images/*.png плюс объявить все десять через --expect-change — уцелевших ноль, порог ноль, причины никто не спрашивает, а в манифесте остаётся {"witnesses":0,"floor":0} без единого слова о произошедшем. Щель была описана в комментарии над самой функцией и оставлена открытой. Порог теперь от набора сценариев, свидетели — из тех, с кем есть что сравнить. Разделение принципиальное: удаление кадров лишает доказательств, но не должно снижать планку. Первичная съёмка идёт через --no-witnesses --reason, как теперь и в golden. Отдельного параметра размера, как в golden, здесь не нужно, и это не небрежность: `ids` и есть набор — docs-accept.mjs передаёт DOC_SCREENSHOTS, а verifyDocsCandidate до того отказывает, если набор сцен в кандидате не совпал с ожидаемым. Пустой ids — отказ, а не ноль. Попутно Low из #405: повторная приёмка неизменённого набора затирала acceptance.declared пустым списком. След приёмки отвечает на вопрос «когда эти пиксели приняли и что тогда объявляли», а обновление отпечатка пикселей не меняет — значит и стирать ответ не должно. Прежний след сохраняется и помечается lastWriteWasFingerprintOnly. Заодно отказ по свидетелям теперь возвращает сами числа: вызывающий печатает свой вердикт, и сочинять их заново ему не из чего. Issue: #409 User-Visible: no
This commit is contained in:
@@ -31,18 +31,30 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Порог свидетелей. Формула та же, что у golden (`goldenWitnessFloor`), и это
|
||||
* намеренно: два набора картинок в одном репозитории не должны требовать от
|
||||
* человека помнить два разных правила.
|
||||
* Порог свидетелей — от размера НАБОРА сценариев. Формула та же, что у golden
|
||||
* (`goldenWitnessFloor`), и это намеренно: два набора картинок в одном
|
||||
* репозитории не должны требовать от человека помнить два разных правила.
|
||||
*
|
||||
* Для десяти сцен порог равен одной. Этого достаточно, потому что основную
|
||||
* работу делает не порог, а требование «все необъявленные совпали»: расхождение
|
||||
* среды не бывает точечным. Порог закрывает единственную оставшуюся щель —
|
||||
* попытку объявить изменёнными все кадры разом, когда свидетелей не остаётся
|
||||
* вовсе и подтвердить среду становится нечем.
|
||||
*
|
||||
* Первая редакция (#401) считала порог от числа кадров, УЦЕЛЕВШИХ на диске, и
|
||||
* той самой щелью и обходилась: `rm docs/images/*.png` + объявить все десять
|
||||
* через `--expect-change` — уцелевших ноль, порог ноль, причины никто не
|
||||
* спрашивает, а в манифесте остаётся `{"witnesses":0,"floor":0}` без единого
|
||||
* слова о том, что произошло. Щель была описана в этом самом комментарии
|
||||
* строкой выше и оставлена открытой (#409, близнец golden-дефекта #408).
|
||||
*
|
||||
* Отсутствие закоммиченных кадров — не смягчающее обстоятельство. Свидетелем
|
||||
* такая сцена быть не может, это правда; но невозможность доказать среду не
|
||||
* отменяет требования, а требует сказать это вслух — `--no-witnesses
|
||||
* --reason="…"`, и причина уезжает в манифест.
|
||||
*/
|
||||
export const docsWitnessFloor = (committedCount) => (committedCount > 0
|
||||
? Math.min(10, Math.ceil(committedCount * 0.1))
|
||||
export const docsWitnessFloor = (sceneCount) => (sceneCount > 0
|
||||
? Math.min(10, Math.ceil(sceneCount * 0.1))
|
||||
: 0);
|
||||
|
||||
/** Объявленные имена, которых нет в наборе сценариев. */
|
||||
@@ -104,13 +116,28 @@ export function docsAcceptancePlan({
|
||||
+ ' принимать нельзя: растеризация задевает все кадры с текстом сразу' };
|
||||
}
|
||||
|
||||
// Порог — от набора сценариев, свидетели — из тех, с кем есть что сравнить
|
||||
// (#409). Разделение принципиальное: удаление кадров лишает доказательств, но
|
||||
// не должно снижать планку.
|
||||
//
|
||||
// `ids` здесь и есть набор: `docs-accept.mjs` передаёт DOC_SCREENSHOTS, а
|
||||
// `verifyDocsCandidate` до этого отказывает, если набор сцен в кандидате не
|
||||
// совпал с ожидаемым. Отдельный параметр размера (как в golden, где отчёт
|
||||
// бывает частичным) поэтому не нужен — но пустой `ids` означает, что считать
|
||||
// не от чего, и это отказ, а не ноль.
|
||||
if (!ids.length) {
|
||||
return { ...empty, refusal: 'набор сценариев пуст: порог свидетелей считать не от чего' };
|
||||
}
|
||||
const withCommitted = ids.filter((id) => committed[id]);
|
||||
const floor = docsWitnessFloor(withCommitted.length);
|
||||
const floor = docsWitnessFloor(ids.length);
|
||||
const witnesses = withCommitted.filter((id) => !announced.has(id)
|
||||
&& committed[id] === candidate[id]);
|
||||
if (!skipWitnesses && witnesses.length < floor) {
|
||||
return { ...empty, refusal: 'кадров-свидетелей недостаточно:'
|
||||
+ ` ${witnesses.length} из необходимых ${floor}.`
|
||||
// Числа возвращаются и при отказе: вызывающий печатает свой вердикт, и
|
||||
// сочинять их заново ему не из чего.
|
||||
return { ...empty, witnesses, floor, refusal: 'кадров-свидетелей недостаточно:'
|
||||
+ ` ${witnesses.length} из необходимых ${floor}`
|
||||
+ ` (сцен в наборе ${ids.length}, с закоммиченным кадром ${withCommitted.length}).`
|
||||
+ ' Свидетель — необъявленный кадр, совпавший с закоммиченным байт-в-байт;'
|
||||
+ ' только он доказывает, что среда съёмки та же. Если перерисовка'
|
||||
+ ' действительно тотальная и осознанная — --no-witnesses --reason="…"'
|
||||
|
||||
Reference in New Issue
Block a user