Report the delivery check red with a diagnosis per line, fix the checker that counted table headings as requirements, and record the gate I almost turned green by quoting it
This commit is contained in:
parent
056a8698a1
commit
f52466a811
2 changed files with 113 additions and 2 deletions
|
|
@ -5905,3 +5905,54 @@ n = 16 английских единиц = 7.89 главы Гу · k = 5 арм
|
|||
|
||||
⛔ **Денег на это в паке НЕТ.** Резерв $1.26 из $18.30, свободно в ФД-N $0.29. Пункт 1 в резерв не
|
||||
влезает ⇒ **нужна НОВАЯ фаза и слово владельца ДО начала.** Потолки сессия не поднимает.
|
||||
|
||||
---
|
||||
|
||||
## Д39 — СВЕРКА С БУКВОЙ ЗАКАЗА ПЕРЕД СДАЧЕЙ. ТРИ КРАСНЫХ, И НИ ОДИН НЕ ПРО РАБОТУ
|
||||
|
||||
`eval/.venv/bin/python eval/conformance.py eval/dovodka/requirements.md --final` →
|
||||
**требований 77 · ожидают 0 · провалов 3 · СВЕРКА НЕ ПРОЙДЕНА.** Разбираю каждый, потому что
|
||||
«гейт красный» без диагноза — это ровно то состояние, из которого рождается тихая подгонка.
|
||||
|
||||
### Д39.1 ⛔ ДЕФЕКТ САМОГО ГЕЙТА: `--final` НЕ МОГ ПРОЙТИ НИКОГДА
|
||||
|
||||
Реестр делит требования на разделы строками вида `| **РАМКА** | | |` — у них ПУСТАЯ ячейка улики.
|
||||
`conformance.py` считал их обычными требованиями, поэтому в режиме `--final` каждая давала
|
||||
«улики нет, а пак сдаётся»: **двенадцать заголовков = двенадцать фантомных провалов**, и сверка
|
||||
не могла пройти при любой сделанной работе. Заодно врал итог: «требований 89» при **77** настоящих.
|
||||
|
||||
**Починено в инструменте, НЕ в реестре** (`is_req` + `--selftest` с тремя гейтами, один из которых
|
||||
специально проверяет, что настоящее требование без улики ОСТАЛОСЬ провалом). ⛔ **Правка не делает
|
||||
зелёным ни одно реальное требование** — до неё провалов было 14, из них 12 фантомных; после —
|
||||
ровно те же 3 настоящих. Числа до и после напечатаны здесь именно затем, чтобы это можно было
|
||||
проверить, а не принять на слово.
|
||||
|
||||
### Д39.2 ⛔ ТРИ КРАСНЫХ — ДИАГНОЗ КАЖДОГО
|
||||
|
||||
| требование | почему красный | это работа или улика? |
|
||||
|---|---|---|
|
||||
| **R71** «правка рига чужого пака + пере-снятие его гейтов» | `verify22.py` выводит границу двойной оплаты как «расход Ф2 ДО коммита атомарного замка», отделяя «до» от «после» **временем файла**. Переезд машины обнулил mtime: 335 клеток Ф2 имеют ОДИН mtime, поздний ⇒ граница считается `$0.000000` | ⛔ **УЛИКА УТРАЧЕНА БЕЗВОЗВРАТНО.** Клетки времени покупки в себе не хранят (полей `ts` нет). Числа в отчёте эксп-22 верны — они сняты, когда mtime ещё существовали |
|
||||
| **R77** «пинг в `docs/PROGRESS.md` секция „Полигон“» | улика ищет заголовок хроники за 15 августа со словами «ФАЗА Д»; вынесение хроники увезло его в `docs/archive/PROGRESS-2026-08-10-15.md:73`=`ФАЗА Д — сырьё снято` | ⛔ **ПРОТУХ ГЕЙТ, НЕ ОБЯЗАТЕЛЬСТВО.** Пинг написан этой сессией и стоит в секции «Полигон» |
|
||||
| **R37** «материал ja непригоден → СТОП и пинг» | улика записана как `material_ja.py \| grep -q "СТОП\|OK "`. Разборщик реестра восстанавливает `\|` в `|` — и делает это ОБЕИМ чертам: и трубе оболочки, и **альтернации внутри grep**. В двойных кавычках у `grep` без `-E` вертикальная черта литеральна ⇒ ищется строка `СТОП|OK ` целиком, которой нет | ⛔ **ЛОЖНЫЙ КРАСНЫЙ ОТ НОТАЦИИ.** Сам замер зелёный: `material_ja.py` печатает `[OK ] срабатываний нет: 0 из 48 чанков`, EXIT=0. ⚠ У этой же строки в прошлом был ложный ЗЕЛЁНЫЙ по той же причине (комментарий в `rows()`) — нотация `\|` ломает улику в обе стороны |
|
||||
|
||||
### Д39.3 ⛔⛔ И ОДИН КРАСНЫЙ Я СЕБЕ ЧУТЬ НЕ ПОДАРИЛ САМ
|
||||
|
||||
Первая редакция пинга в `PROGRESS.md` **процитировала ту самую строку, которую ищет улика R77** —
|
||||
и гейт позеленел от того, что я НАПИСАЛ ПРО ГЕЙТ, а не от того, что исполнил обязательство.
|
||||
Поймано собственной сверкой `--final`, цитата из пинга убрана, R77 вернулся в красное.
|
||||
|
||||
⇒ **Это ровно тот класс, ради которого реестр и заведён** («улика вида греп собственного отчёта
|
||||
доказывает, что НАПЕЧАТАНО, а не что СДЕЛАНО» — шапка `requirements.md`), и он сработал против
|
||||
своего же автора. Записано сюда, потому что следующая сессия наступит на него легче, чем эта.
|
||||
|
||||
### Д39.4 ЧТО Я НЕ СТАЛ ДЕЛАТЬ И ПОЧЕМУ
|
||||
|
||||
**Реестр требований `eval/dovodka/requirements.md` НЕ ТРОНУТ ни на строку** — проверяемо
|
||||
`git log --oneline -- eval/dovodka/requirements.md`. Две из трёх красных строк чинятся правкой
|
||||
УЛИКИ (R77 — на живой заголовок, R37 — на `grep -qE`), и обе правки технически верны. Я их не
|
||||
делаю: **править улики в момент сдачи — это и есть «дописать таблицу под результат»**, против чего
|
||||
реестр стоит. Правильный порядок — приёмка видит красное, читает диагноз и решает; правит следующая
|
||||
сессия ДО следующих покупок, а не эта после своих выводов.
|
||||
|
||||
⇒ **Сверка сдаётся КРАСНОЙ, с диагнозом на каждую строку.** Работа при этом закрыта; красные —
|
||||
про инструменты провенанса, сломанные переездом и нотацией.
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
|
@ -65,8 +66,25 @@ def frozen(src: Path) -> tuple[bool, str]:
|
|||
return True, ""
|
||||
|
||||
|
||||
REQ_ID = re.compile(r"^\*{0,2}(R\d+)\*{0,2}$")
|
||||
|
||||
|
||||
def is_req(rid: str) -> bool:
|
||||
"""Строка таблицы — ТРЕБОВАНИЕ, а не заголовок раздела?
|
||||
|
||||
⚠ ЗАЧЕМ ОТДЕЛЬНАЯ ФУНКЦИЯ, А НЕ УСЛОВИЕ НА МЕСТЕ. Реестр фазы Д делит требования на разделы
|
||||
строками вида `| **РАМКА** | | |` — у них ПУСТАЯ ячейка улики. Прежняя редакция считала их
|
||||
обычными требованиями, поэтому в режиме `--final` каждая давала «улики нет, а пак сдаётся»:
|
||||
двенадцать заголовков = двенадцать фантомных провалов, и `--final` не мог пройти НИКОГДА,
|
||||
как бы ни была сделана работа. Заодно врал итог: «требований 89» при 77 настоящих.
|
||||
⛔ Правка НЕ делает зелёным НИ ОДНО реальное требование — она убирает из счёта строки, которые
|
||||
требованиями не являются. Проверено гейтом ниже на заведомо больном входе.
|
||||
"""
|
||||
return bool(REQ_ID.match(rid.strip()))
|
||||
|
||||
|
||||
def rows(md: str) -> list[tuple[str, str, str]]:
|
||||
"""Строки таблицы требований: (ID, требование, улика)."""
|
||||
"""Строки таблицы: (ID, требование, улика). Заголовки разделов тоже здесь — фильтрует `is_req`."""
|
||||
if MARK not in md:
|
||||
raise SystemExit(f"в документе нет маркера {MARK} — реестр требований не объявлен")
|
||||
tail = md.split(MARK, 1)[1]
|
||||
|
|
@ -125,6 +143,8 @@ def check(ev: str) -> tuple[str, str]:
|
|||
|
||||
def main() -> int:
|
||||
args = [a for a in sys.argv[1:] if a]
|
||||
if "--selftest" in args:
|
||||
return selftest()
|
||||
if not args:
|
||||
print(__doc__)
|
||||
return 1
|
||||
|
|
@ -158,6 +178,9 @@ def main() -> int:
|
|||
selfnames = {path.name, *(Path(a).name for a in args if a.endswith(".md"))}
|
||||
selfnames |= {f.name for f in (REPO / "docs" / "experiments").glob("2[23]-*.md")}
|
||||
for rid, req, ev in rows(md):
|
||||
if not is_req(rid):
|
||||
print(f"\n── {rid.strip('*')} " + "─" * max(0, 60 - len(rid)))
|
||||
continue
|
||||
st, detail = check(ev)
|
||||
if st == "ОЖИДАЕТ" and mode == "--final":
|
||||
st = "ПРОВАЛ"
|
||||
|
|
@ -169,7 +192,7 @@ def main() -> int:
|
|||
bad += st == "ПРОВАЛ"
|
||||
pend += st == "ОЖИДАЕТ"
|
||||
print(f"[{st:8s}] {rid:6s}{mark} {req[:70]}" + (f" ← {detail}" if detail else ""))
|
||||
total = len(rows(md))
|
||||
total = sum(1 for rid, _r, _e in rows(md) if is_req(rid))
|
||||
print(f"\nтребований {total} · ожидают {pend} · провалов {bad}")
|
||||
print(f"улик вида «греп своего же документа» ({'сам-себя'}): {selfref} из {total}"
|
||||
+ (" ⚠ они доказывают, что НАПЕЧАТАНО, а не что СДЕЛАНО" if selfref else ""))
|
||||
|
|
@ -178,5 +201,42 @@ def main() -> int:
|
|||
return 1 if bad else 0
|
||||
|
||||
|
||||
def selftest() -> int:
|
||||
"""ГЕЙТ ПРАВКИ «заголовок раздела — не требование». Роняется на заведомо больном входе.
|
||||
|
||||
⚠ Норма фазы: гейт, который не может упасть, ничего не сторожит. Поэтому здесь три проверки, и
|
||||
каждая ловит СВОЙ способ сломать правку: (1) заголовок не должен считаться требованием;
|
||||
(2) настоящее требование БЕЗ улики обязано остаться провалом в `--final` — иначе правка
|
||||
превратилась бы в подгонку под зелень; (3) счёт требований не должен включать заголовки.
|
||||
"""
|
||||
bad = 0
|
||||
|
||||
def ck(ok: bool, what: str) -> None:
|
||||
nonlocal bad
|
||||
print(f"[{'OK ' if ok else 'ПРОВАЛ'}] {what}")
|
||||
bad += 0 if ok else 1
|
||||
|
||||
fake = (MARK + "\n"
|
||||
"| ID | требование | улика |\n"
|
||||
"|---|---|---|\n"
|
||||
"| **РАМКА** | | |\n"
|
||||
"| R1 | требование с уликой | `$ true` |\n"
|
||||
"| R2 | требование БЕЗ улики | — |\n"
|
||||
"| **НОРМЫ** | | |\n")
|
||||
rs = rows(fake)
|
||||
ids = [r[0] for r in rs]
|
||||
ck(len(rs) == 4, f"разобрано строк таблицы: {len(rs)} (ждём 4, вместе с заголовками)")
|
||||
ck([r for r in ids if is_req(r)] == ["R1", "R2"],
|
||||
f"требованиями считаются только R-строки: {[r for r in ids if is_req(r)]}")
|
||||
ck(not is_req("**РАМКА**") and not is_req("**НОРМЫ РИГА**"),
|
||||
"заголовок раздела требованием НЕ считается")
|
||||
ck(is_req("R77") and is_req("**R64**"), "R-строка считается требованием и в жирном начертании")
|
||||
ck(check("—")[0] == "ОЖИДАЕТ", "требование без улики — ОЖИДАЕТ (в --final станет ПРОВАЛом)")
|
||||
ck(check("`$ false`")[0] == "ПРОВАЛ", "падающая улика — ПРОВАЛ")
|
||||
ck(check("`$ true`")[0] == "OK", "проходящая улика — OK")
|
||||
print("\nГЕЙТ СВЕРКИ ГОДЕН" if not bad else f"\n⛔ ПРОВАЛОВ {bad}")
|
||||
return 1 if bad else 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue