textmachine/docs/archive/prompts/BACKEND_PACK18_DEBTS_SESSION_PROMPT.md

13 KiB
Raw Blame History

Промт бэкенд-сессии: ПАК-18 «долги контракта» (согласие на пере-оплату · семантика escalation_model · два нита общности)

Статус: ПАК ОТРАБОТАН И ЗАКРЫТ (D39.31, 25.07) — промт архивный, исполнять из него нечего. Итог: --accept-rebill построен на снапшотной гранулярности · escalation_model = авторитетная модель (санкционированный пере-капчер golden, новый baseline 211c9013…) · два нита общности отложены ПО ЗАМЕРУ (сняты позже D39.35 → едут ШАГОМ 0 мини-прогона). Отчёт с ревью-шапкой: archive/reports/PACK18_DEBTS_REPORT_2026-07-25.md.

Статус выдачи: 25.07.2026, оркестратор №8. Пак-17 закрыт целиком (D39.26 дизайн · D39.27 стройка · D39.28 дельта allow). Этот пак берёт три ратифицированных, но не построенных долга. Почему сейчас: это единственная работа, которая не ждёт никого — полигон параллельно добывает факты ToS под accepts_labels, подписи владельца не требуется, платных вызовов ноль.

Первый деливерабл — эхо-блок (≤10 строк): скоуп / инварианты / чего не делать. ДО работы.

Общие инварианты пака — «РОВНО ТАК»

  • Деньги durable: reserve→settle+чекпойнт одной транзакцией; $0-резюм внутри снапшота; resnapshot = переоплата ОДНА. Ничего из этого пак не меняет.
  • Golden: байт-идентичен ВЕЗДЕ, кроме санкционированного пере-капчера пункта 2 (условия — там же). Парити EXACT · -race · сэндбокс-репродукции через настоящий драйвер (норма 11: мок-провайдер, сквозные сценарии) · дифф ^func Test ИСПОЛНЕНИЕМ, не памятью · заявление = команда (приёмка ре-ранит манифест).
  • Общность §0: Go не ветвится по паре/книге; пар-данные — в данные. Ревью-вопрос по умолчанию: «заработает ли на паре, которой в репо ещё НЕТ, без правки Go?»
  • Сессия НЕ коммитит, git mv декларировать. Отчёт: docs/archive/reports/PACK18_DEBTS_REPORT_<дата>.md.
  • Канал вопросов: непонятно / промт конфликтует с кодом или доками → пинг оркестратору через владельца, НЕ тихая интерпретация. Аддендумы доезжают только релеем — подтверди получение строкой в отчёте.

ПУНКТ 1 — --accept-rebill[=usd]: согласие на пере-оплату (D20.2-Q2, ратифицирован 10.07, в коде ОТСУТСТВУЕТ)

Что ратифицировано (D20.2-Q2, спека backend/docs/D15.2-content-addressed-resume-spec.md §7): порог согласия rebill_consent_usd = min($0.50, 5%×ProjectedBookUSD) с fallback-флором $0.50 при ProjectedBookUSD = 0; флаг --accept-rebill[=usd] с ОПЦИОНАЛЬНЫМ потолком суммы — форма Р6 «согласие на КОНКРЕТНУЮ трату»: голый флаг принимает проецируемую сумму целиком, --accept-rebill=1.50 принимает её только если проекция ≤ $1.50, иначе отказ.

Граница скоупа — РАТИФИЦИРУЮ ЗДЕСЬ (проверено мной по коду перед выдачей): пер-чанковой проекции §7 в движке не существуетguard_hash отсутствует в коде полностью, дрейф сегодня булев (ConfigDrift/SnapshotDrift, export.go/status.go). Поэтому:

  • Строим согласие на ТОЙ гранулярности, на которой движок реально пере-оплачивает — снапшотной. Смена снапшота промахивает все чекпойнты книги, то есть проекция честно считается как «единицы, уже оплаченные под старым снапшотом, будут оплачены заново; сумма их хранимых chunk_status.cost_usd = $X» (для единиц без хранимой цены — оценка ledger.EstimateUSD над их текущими msgs; так и предписывает спека).
  • guard_hash и пер-чанковый dry-run §7 в этом паке НЕ строим. Они едут с content-addressed resume v3, когда он понадобится.
  • Оговорка спеки «каскад §7.1-бис ложится ПЕРЕД семантикой флага» на этой гранулярности вырождена (пере-оплачивается всё, каскаду нечего добавлять) — это не нарушение ратифицированного порядка, а его неприменимость. Зафиксируй строкой в отчёте.
  • Согласие обязано стоять ДО денег: ни одной резервации, пока порог превышен и согласие не дано. Отказ — громкий, с суммой и числом единиц, и он НЕ должен убивать read-only пути ($0-контракт status/report/export, D20.4).

«РЕШИ САМ И АРГУМЕНТИРУЙ»: где живёт вычисление проекции (прайор: рядом со status-проекцией, она уже считает ProjectedBookUSDstatus.go:485) · форма сообщения об отказе · как флаг ложится на translate и redrive (у обоих сегодня есть --resnapshot, main.go:90,201) · что делать, когда проекция ниже порога (прайор: молча продолжать — согласие требуется только сверх порога).

Развилка → ПИНГ, не решение молча: если при чтении кода окажется, что снапшотной гранулярности недостаточно для честной суммы (например, часть единиц не пере-оплачивается) — принеси развилку с цифрами, не строй мини-версию guard_hash.


ПУНКТ 2 — escalation_model = модель, чей выход АВТОРИТЕТЕН (сегодня пишется ПОПРОБОВАННАЯ)

Факт (вынесен из пака-17 как вердикт-изменение, D39.26 §14.6.1): stagerun.go пишет в chunk_status.escalation_model модель, которую ПОПРОБОВАЛИ, а не ту, что ответила; golden пинит esc_model="fake-fallback" на хопе, который ОТКАЗАЛ (testdata/golden/capture.golden), и маскировка это не скрывает.

«РОВНО ТАК»:

  1. Пере-капчер golden САНКЦИОНИРОВАН — ровно под этот дифф и ни подо что больше. Дисциплина приёмки: маскированный структурный дифф обязан показать ТОЛЬКО колонки esc_model; любая другая сдвинувшаяся строка = стоп и пинг, а не «заодно».
  2. Ни одна ось RequestHash/снапшота не двигается — это телеметрия, а не вход вызова: пере-оплаты быть не должно (докажи исполнением: снапшоты обеих волн до/после совпадают).
  3. Миграции нет, старые durable-строки не переписываются. Смешанная семантика в исторических данных допустима; скажи об этом явно в отчёте (и, если считаешь нужным, отметь в самом отчёте report).
  4. Прайор семантики (опровергается аргументом): поле держит модель, чей выход стал АВТОРИТЕТНЫМ; если авторитетного выхода хопа не было (хоп тоже отказал) — поле пустое, а факт попытки уже несёт escalated=true, и путь хопов выводится из durable-чекпойнтов (прецедент пака-16: счётчики из чекпойнтов, миграция отменена). Если считаешь, что терять идентичность отказавшего хопа нельзя — принеси аргумент и альтернативу, это ровно тот случай, где сессия компетентнее.

ПУНКТ 3 — два нита общности (владелец 25.07; УСЛОВНЫЕ — берутся только байт-нейтрально)

Оба — про утечку языка/пары в generic-код:

  • множитель expectedHours := n * 2 (internal/checks/checkers.go:174) — правило «1 时辰 = 2 часа» вшито в Go;
  • Detail-строки чекеров (internal/checks/repair.go:103,138 и соседи) — статический 时辰-текст в generic-файле: на второй паре он соврёт.

«РОВНО ТАК» — условие включения: берутся ТОЛЬКО в байт-нейтральной форме, с доказательством ИСПОЛНЕНИЕМ (выход чекеров байт-идентичен до/после над корпусом; CheapGateVersion и pack.Version() не двигаются; golden не трогается). Причина жёсткости: CheapGateVersion фолдится в оба волновых снапшота безусловно, а pack.Version() присутствует у СТЕНДОВЫХ книг — любой сдвиг убивает $0-резюм драфта, на котором поедет замер остатка пака-16. Молча бампить версию нельзя; молча НЕ бампить, поменяв версионируемое правило, — тоже. Если байт-нейтральной формы не выходит — отложи и скажи явно с причиной; это принятый исход, а не провал пака.

«РЕШИ САМ»: где живут данные (кандидаты — langpack internal/lang+configs/langpacks/ либо пар-слой configs/pairs/<пара>у обоих есть version-фолды, проверь какие именно) · форма шаблонов Detail-строк (цитаты/подстановки из данных, без англ. диагностики в теле) · как гарантировать, что дефолт остаётся байт-идентичным сегодняшнему поведению.


НЕ делать

ru-target долг (isRuTarget/TokenizeCyrillic/санитайзер — слой 7, D39.24 §15.3): он архитектурный и получит СВОЙ дизайн-пак, сюда не тащить · guard_hash/пер-чанковый dry-run · заполнение accepts_labels (зона полигона, ждём фактов ToS) · L3 · live 18+ · расширение скоупа без пинга.

Мандат самопроверки (обязателен, решение владельца 12.07)

Ревью ИСПОЛНЕНИЕМ своего кода и своих результатов: сквозные сценарии через настоящий драйвер (согласие сверх порога и под ним; отказ без флага; --accept-rebill=<сумма> ниже проекции; хоп ответил / хоп отказал), мутации на каждую новую ветку (мутация возвращает дефект → тест краснеет), ценз тестов исполнением. Уроки паков 14/15/16: две завышенные тест-заявки подряд и девять дефектов, прошедших чтение, — ловит только исполнение.