From ac37c8ac594d01636936bd8c1d8464720742e678 Mon Sep 17 00:00:00 2001 From: heaven Date: Sun, 6 Sep 2026 17:20:19 +0300 Subject: [PATCH] Put the carrier check in the tree instead of a scratchpad, and let the pack name the instrument rather than a remembered number --- docs/PLATFORM_MONEY_TRUTH_SESSION_PROMPT.md | 15 +++- docs/scripts/carriers.py | 88 +++++++++++++++++++++ 2 files changed, 99 insertions(+), 4 deletions(-) create mode 100644 docs/scripts/carriers.py diff --git a/docs/PLATFORM_MONEY_TRUTH_SESSION_PROMPT.md b/docs/PLATFORM_MONEY_TRUTH_SESSION_PROMPT.md index cb2453bc..734a43b8 100644 --- a/docs/PLATFORM_MONEY_TRUTH_SESSION_PROMPT.md +++ b/docs/PLATFORM_MONEY_TRUTH_SESSION_PROMPT.md @@ -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:** проход печатает **ноль** утверждений без носителя · вынесено только то, что при чтении оказалось настоящей хроникой · всё, что оказалось правилом или незакрытой находкой, получило ряд регистра или строку бэклога diff --git a/docs/scripts/carriers.py b/docs/scripts/carriers.py new file mode 100644 index 00000000..edc7ac64 --- /dev/null +++ b/docs/scripts/carriers.py @@ -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())