process: derived artifacts are accepted on dev once per beta (#697)

The screenshot fingerprint and golden baselines stop being a tax on every
task branch:

- Task branches no longer commit docs/images/** or golden baselines. On a
  branch the screenshot freshness stays a preflight warning; the review
  prompt, REVIEWER.md and AUTHOR.md drop check-docs as a per-task gate.
- beta-derived.yml refreshes them on dev in one bot commit before the beta
  candidate: canonical docs capture + docs:accept --reviewed, golden from
  the golden-images artifact of a completed Validate on dev +
  golden:accept --reviewed. A changed frame or scene is accepted only when
  named in the inputs; undeclared differences refuse. Baseline commits carry
  Release: and Baseline-Reviewed:; the subject is not a candidate subject.
- classify-changes: the Release: trailer on an issue/* branch no longer
  switches on the heavy set. ci:full / ci:golden do: process-track emits
  full=true, the review gate dispatches Validate with full=true and does not
  accept a light proof.

Canon: PROCESS.md §3 п.13, §5.1, §8, §11.4; CONTRIBUTING.md.

Issue: #697
User-Visible: no
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
This commit is contained in:
Claude
2026-09-28 23:38:50 +03:00
parent c716bb0f63
commit 2a62ad5b95
15 changed files with 490 additions and 63 deletions
+13 -1
View File
@@ -88,13 +88,23 @@ export function classifyAll() {
* - `workflow_dispatch` с `full=true` — ночной прогон (nightly.yml) и ручной;
* - pull_request — там Validate единственный сигнал.
*/
export function heavyGatesRequested({ eventName, headMessage, fullInput } = {}) {
export function heavyGatesRequested({ eventName, headMessage, fullInput, refName } = {}) {
if (eventName === 'pull_request') return true;
if (eventName === 'workflow_dispatch') return String(fullInput) === 'true';
if (eventName === 'schedule') return true;
// #697: на ветке задачи трейлер `Release:` тяжёлый набор больше не включает.
// Его там носит только приёмка эталонов, а golden на ветке задачи — по метке
// `ci:golden`: конвейер ревью диспатчит Validate с `full=true` сам. Кандидат
// беты и релиза собирается на `dev` — там трейлер работает как прежде.
if (isTaskBranch(refName)) return false;
return hasReleaseTrailer(headMessage);
}
/** Ветка задачи — `issue/<NN>-…` (PROCESS §3). */
export function isTaskBranch(refName) {
return /^issue\//.test(String(refName || '').replace(/^refs\/heads\//, ''));
}
/**
* Нужны ли мутанты по диффу (#510, сужено в #601). За 08–09.09 они съели 86 %
* job-минут Validate, потому что бежали на каждом промежуточном пуше и
@@ -159,6 +169,7 @@ if (invokedDirectly) {
eventName: process.env.EVENT_NAME,
headMessage: process.env.HEAD_MESSAGE,
fullInput: process.env.FULL_INPUT,
refName: process.env.REF_NAME,
})}\n`);
} else if (process.argv.includes('--heavy')) {
// Отдельный вызов: у `heavy` другие входы (событие, сообщение head-коммита),
@@ -167,6 +178,7 @@ if (invokedDirectly) {
eventName: process.env.EVENT_NAME,
headMessage: process.env.HEAD_MESSAGE,
fullInput: process.env.FULL_INPUT,
refName: process.env.REF_NAME,
});
process.stdout.write(`heavy=${heavy ? 'true' : 'false'}\n`);
const mutants = mutantsRequested({