mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-04 13:48:57 +00:00
Rule 8 skipped the status check for any range without class A files, so a task in S3-spec or S4-spec-review could push a branch of tests, demo or scripts with only a warning. §11.8 forbids exactly that: before S5 neither class A commits nor the branch itself is pushed, because the spec-review step takes the freshest origin/issue/<NN>-* as its material and lays the SPEC-REVIEW document there, putting code in front of a spec reviewer who must not read it (§2.4). The #562 entry was written for a task before its first S status. The decision is now made per issue in checkIssueStatuses: the status stays optional only when the range is infrastructural and the issue carries neither S3-spec nor S4-spec-review. Such an issue gets a rule 8 refusal naming its status and §11.8; the range-wide #562 warning is still printed. No status, S1-new/S2-analysis (reviewer-filed infra issues) and S5-S8 keep their old outcome; closed, blocked and fail-closed checks are untouched; rule 10 is still called only for ranges with class A. PROCESS.md §10.2 gets the one-sentence exception, the mutation registry a mutant that drops the S3/S4 condition. Issue: #753 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:
@@ -411,6 +411,12 @@ export function commitsUnderRuleOne(commits) {
|
||||
// поставить продуктовой задаче и увести продуктовый коммит от проверки статуса,
|
||||
// а перестать трогать класс A, не перестав быть инфраструктурной задачей,
|
||||
// нельзя. Существование issue, его открытость и `blocked` проверяются всё равно.
|
||||
//
|
||||
// Признак диапазона не знает, где задача. Задача в маршруте ТЗ (`S3-spec`,
|
||||
// `S4-spec-review`: `track:ask`, повышенный show после `reclassify` #726, ручной
|
||||
// возврат) уже не «до первого S-статуса»: её ветка до `S5` не пушится вовсе
|
||||
// (§11.8), иначе ревью ТЗ получает её материалом. Поэтому исключение снимается
|
||||
// по каждому issue в `checkIssueStatuses`, а не по диапазону (#753).
|
||||
export function isInfrastructureRange(commits) {
|
||||
if (!commits.length) return false;
|
||||
return !commits.some((c) => c.classes.has('A'));
|
||||
@@ -450,6 +456,12 @@ export function commitsNeedingIssueStatus(
|
||||
return underRuleOne.filter((commit) => !isPublishedPrereleaseCommit(commit.sha));
|
||||
}
|
||||
|
||||
// Статусы маршрута ТЗ, для которых инфраструктурный вход #562 не действует
|
||||
// (#753). `S1-new` и `S2-analysis` в него не входят: инфраструктурные issue,
|
||||
// заведённые ревьюером, приходят с `S1-new`, а ветка до `S4` материалом ревью
|
||||
// ТЗ не становится.
|
||||
export const SPEC_ROUTE_STATUS = ['S3-spec', 'S4-spec-review'];
|
||||
|
||||
// 8. статус issue. Fail closed: недоступный или закрытый issue — отказ, а не
|
||||
// пропуск. Гейт, который молчит при недоступном источнике правды, бесполезен.
|
||||
export function checkIssueStatuses(
|
||||
@@ -484,11 +496,15 @@ export function checkIssueStatuses(
|
||||
continue;
|
||||
}
|
||||
const names = (issue.labels ?? []).map((l) => (typeof l === 'string' ? l : l.name));
|
||||
if (!statusOptional && !names.some((n) => allowed.includes(n))) {
|
||||
const specRoute = names.filter((n) => SPEC_ROUTE_STATUS.includes(n));
|
||||
const optional = statusOptional && specRoute.length === 0;
|
||||
if (!optional && !names.some((n) => allowed.includes(n))) {
|
||||
const status = names.filter((n) => /^S\d-/.test(n));
|
||||
out.push({
|
||||
level: 'fail', rule: 8, sha: '-',
|
||||
msg: `issue #${nn}: статус ${status.length ? status.join(',') : 'не проставлен'}, а нужен один из ${allowed.join(' / ')}`,
|
||||
msg: statusOptional
|
||||
? `issue #${nn} в ${specRoute.join(',')}: ветка задачи до «Готово к разработке» не пушится (§11.8); инфраструктурный вход (#562) — не для задачи в маршруте ТЗ`
|
||||
: `issue #${nn}: статус ${status.length ? status.join(',') : 'не проставлен'}, а нужен один из ${allowed.join(' / ')}`,
|
||||
});
|
||||
}
|
||||
if (names.includes('blocked')) {
|
||||
|
||||
Reference in New Issue
Block a user