13 KiB
Промт бэкенд-сессии: ПАК-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-проекцией, она уже считает ProjectedBookUSD — status.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), и маскировка это не скрывает.
«РОВНО ТАК»:
- Пере-капчер golden САНКЦИОНИРОВАН — ровно под этот дифф и ни подо что больше. Дисциплина приёмки: маскированный структурный дифф обязан показать ТОЛЬКО колонки
esc_model; любая другая сдвинувшаяся строка = стоп и пинг, а не «заодно». - Ни одна ось
RequestHash/снапшота не двигается — это телеметрия, а не вход вызова: пере-оплаты быть не должно (докажи исполнением: снапшоты обеих волн до/после совпадают). - Миграции нет, старые durable-строки не переписываются. Смешанная семантика в исторических данных допустима; скажи об этом явно в отчёте (и, если считаешь нужным, отметь в самом отчёте
report). - Прайор семантики (опровергается аргументом): поле держит модель, чей выход стал АВТОРИТЕТНЫМ; если авторитетного выхода хопа не было (хоп тоже отказал) — поле пустое, а факт попытки уже несёт
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: две завышенные тест-заявки подряд и девять дефектов, прошедших чтение, — ловит только исполнение.