Put the carrier check in the tree instead of a scratchpad, and let the pack name the instrument rather than a remembered number
This commit is contained in:
parent
508384bb48
commit
ac37c8ac59
2 changed files with 99 additions and 4 deletions
|
|
@ -65,10 +65,17 @@
|
|||
внутри — **реестр из 36 сплошно нумерованных живых решений**. Ошибка была в том, что судили по ЗАГОЛОВКУ, не
|
||||
прочитав содержимое. ⇒ **в журнале сделай тот же тест ПРЕЖДЕ выноса.**
|
||||
|
||||
Машинный проход по выносимому (он уже написан контролёром, воспроизводится за секунду): какие `PD-*` и «строки N»
|
||||
упомянуты и все ли разрешаются; и главное — **какие ⛔/⚠⚠-утверждения не ссылаются ни на ряд регистра, ни на строку
|
||||
бэклога, ни на D-ноту**. Замер 06.09 по двум новейшим секциям: **69 таких**, в основном «найдено и починено до
|
||||
сдачи». По норме регистра починенное тоже получает ряд ⇒ **это список на чтение, а не на вынос**.
|
||||
**Прибор — `docs/scripts/carriers.py`** (написан 06.09 ровно под этот заказ; в дереве, не в чьём-то скрэтчпаде):
|
||||
`python3 docs/scripts/carriers.py platform/docs/platform-PROGRESS.md --from N --to M`. Он находит ⛔/⚠⚠-утверждения,
|
||||
не ссылающиеся ни на ряд регистра, ни на строку бэклога, ни на D-ноту, ни на эрратту, и печатает рядом с числом
|
||||
**сколько строк осмотрено** — иначе ноль неотличим от «искал не там».
|
||||
|
||||
⚠ **Число называй ПРИБОРОМ, а не памятью.** На двух новейших секциях (3–2007) он даёт **55**; ручной проход
|
||||
контролёра давал **69**. Расхождение — в определении носителя, не в дереве: это ровно тот случай, из-за которого
|
||||
норма требует называть популяцию. Считай ЭТИМ скриптом и скажи, какой диапазон брал.
|
||||
|
||||
⛔ **И помни, что прибор отвечает на свой вопрос:** он не отличает правило от хроники и не судит о важности.
|
||||
Ноль означает «всё сослалось», а не «выносить безопасно» — читать всё равно надо.
|
||||
|
||||
**Приёмка §4.0:** проход печатает **ноль** утверждений без носителя · вынесено только то, что при чтении оказалось
|
||||
настоящей хроникой · всё, что оказалось правилом или незакрытой находкой, получило ряд регистра или строку бэклога
|
||||
|
|
|
|||
88
docs/scripts/carriers.py
Normal file
88
docs/scripts/carriers.py
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Находки без НОСИТЕЛЯ: утверждения, которые исчезнут при выносе секции в архив.
|
||||
|
||||
Зачем. Смена 06.09 пять раз наткнулась на один класс: находка живёт только в
|
||||
отчёте или в переписке, ряда в регистре и строки в бэклоге у неё нет — и после
|
||||
выноса секции в архив её больше не найти. Отдельно проверено, что и обратное
|
||||
бывает: секция, ВЫГЛЯДЯЩАЯ хроникой по заголовку, оказалась реестром живых
|
||||
решений (`platform/docs/STACK_DECISIONS.md`, решения 1–36). Поэтому перед любым
|
||||
выносом сначала прогоняют это, а решают глазами.
|
||||
|
||||
Что считается носителем: ссылка на ряд регистра (`PD-123`), на строку бэклога
|
||||
(«строка 281», «строки 49 и 161»), на ноту решения (`D39.202`, `D22.6`) или на
|
||||
эрратту («эррата 06.09-в»).
|
||||
|
||||
⚠ Прибор отвечает на СВОЙ вопрос: он не судит, важно ли утверждение, и не умеет
|
||||
отличать правило от рассказа. Ноль здесь означает «всё сослалось», а не «выносить
|
||||
безопасно» — читать всё равно надо.
|
||||
|
||||
Использование:
|
||||
python3 docs/scripts/carriers.py <файл> [--from N] [--to M] [--quiet]
|
||||
|
||||
Код возврата: 0 — находок без носителя нет; 1 — есть (число в последней строке).
|
||||
"""
|
||||
import argparse
|
||||
import re
|
||||
import sys
|
||||
|
||||
# Утверждение, которое автор пометил как важное: именно они переживают вынос
|
||||
# хуже всего, потому что читаются как знание, а не как хроника.
|
||||
MARKED = re.compile(r"⛔|⚠⚠")
|
||||
|
||||
# Носители. `D\d` покрывает и `D22.6`, и `D39.202`; эррата ловится отдельно,
|
||||
# потому что пишется датой, а не номером.
|
||||
CARRIER = re.compile(
|
||||
r"PD-\d+"
|
||||
r"|строк[аиеу]?\s*\d+"
|
||||
r"|строки\s*\d+"
|
||||
r"|\bD\d+(?:\.\d+)*\b"
|
||||
r"|эррат[аеы]\s*\d\d\.\d\d"
|
||||
)
|
||||
|
||||
# Строки, которые несут разметку, а не утверждение.
|
||||
SKIP = re.compile(r"^\s*(\||#{1,6}\s|```|>\s*$)")
|
||||
|
||||
|
||||
def scan(path: str, lo: int, hi: int):
|
||||
out = []
|
||||
with open(path, encoding="utf-8") as fh:
|
||||
for n, raw in enumerate(fh, 1):
|
||||
if n < lo or (hi and n > hi):
|
||||
continue
|
||||
line = raw.rstrip("\n")
|
||||
if SKIP.match(line) or len(line.strip()) < 40:
|
||||
continue
|
||||
if MARKED.search(line) and not CARRIER.search(line):
|
||||
out.append((n, line.strip()))
|
||||
return out
|
||||
|
||||
|
||||
def main() -> int:
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument("path")
|
||||
ap.add_argument("--from", dest="lo", type=int, default=1)
|
||||
ap.add_argument("--to", dest="hi", type=int, default=0)
|
||||
ap.add_argument("--quiet", action="store_true")
|
||||
a = ap.parse_args()
|
||||
|
||||
with open(a.path, encoding="utf-8") as fh:
|
||||
total = sum(1 for _ in fh)
|
||||
hi = a.hi or total
|
||||
found = scan(a.path, a.lo, a.hi)
|
||||
|
||||
if not a.quiet:
|
||||
for n, line in found:
|
||||
print(f" ✗ {a.path}:{n}: {line[:150]}")
|
||||
|
||||
# ⚠ Контрольная величина рядом с нулём — норма CLAUDE.md: «0 находок» и
|
||||
# «искал не там» в выводе неразличимы, поэтому осмотренное печатается всегда.
|
||||
print(f"\ncarriers: {len(found)} помеченных утверждений без носителя")
|
||||
print(f" осмотрено строк: {hi - a.lo + 1} (с {a.lo} по {hi} из {total})")
|
||||
print(" носителем считается: ряд PD · строка бэклога · D-нота · эррата")
|
||||
print(" ⚠ НЕ проверяется: важность утверждения · правило это или хроника —")
|
||||
print(" ноль означает «всё сослалось», а не «выносить безопасно».")
|
||||
return 1 if found else 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Loading…
Add table
Reference in a new issue