Подтверждение плановой рассылки
Запуск Навыка
При явном вызове или однозначном смысловом совпадении применяйте навык сразу. Перед первым шагом покажите ровно одну короткую контекстную строку (не более 30 слов) и продолжайте работу в том же ответе, не ожидая реакции:
Применяю экспериментальный навык «Подтверждение плановой рассылки» (обратная связь — @kir-kopylov): <кратко назовите конкретную пользу для текущего запроса>; продолжаю без ожидания.
Не включайте в строку внутреннее имя папки или пересказ всего запроса. Не спрашивайте, применять ли навык.
Строка запуска не является самостоятельным ответом. В том же сообщении сразу начните проверку: при переданном пакете назовите первый проверяемый элемент цепочки, а при его отсутствии — перечислите минимально недостающие запись запуска, отправки, ответ провайдера и полученную копию. Не заканчивайте ответ одной строкой запуска.
Если одновременно подходят совместимые навыки, выберите минимальный набор и покажите одну общую строку. Если подходы ведут к несовместимым результатам и запрос не позволяет выбрать, спросите только о желаемом результате, не о разрешении применить навык.
Запуск навыка не расширяет полномочия. Выполните всю безопасную и уже разрешённую часть; запросите подтверждение только непосредственно перед ещё не разрешённым внешним или изменяющим действием. Не запрашивайте повторно уже данное разрешение и не дублируйте системное окно подтверждения.
Задача
Этот навык доказывает статус одного заранее подготовленного выпуска. Он не исследует новости, не меняет содержание письма, не создаёт Gmail-черновик, не отправляет письмо и не меняет расписание.
Время запуска рядом со временем полученного письма — слабое совпадение, а не доказательство. Для PASS нужна цепочка: запланированный запуск → конкретный вызов отправки → ответ почтового провайдера → полученная копия того же письма.
Нужный Вход
Соберите один нормализованный пакет доказательств:
- ожидаемый выпуск:
run_id,artifact_sha256, получатели, тема, текст, HTML при наличии, дедлайн; - запись планировщика с
run_id, идентификатором его запуска и временем старта; - запись конкретной отправки с тем же идентификатором запуска, временем отправки, отпечатком выпуска и ответом провайдера с
message_idи временем принятия; - полученная копия с тем же
message_idи полями письма; - явная область поиска дублей: ящик, начало и конец интервала, запрос и правило, что считать копией;
- полная read-only история использованных
run_idдля проверки повторного запуска; - прежняя сохранённая квитанция, если она уже есть.
Не создавайте доказательство задним числом. Если поле не было записано в момент отправки, пометьте его как отсутствующее.
Как Проверять
- Сначала сохраните старое. Если передана прежняя квитанция, оцените её отдельно до свежего поиска. Новый недоступный поиск не стирает уже сохранённое доказательство.
- Проверьте происхождение.
run_idу ожидаемого выпуска и планировщика совпадает; идентификатор запуска планировщика совпадает с конкретной отправкой;message_idотправки совпадает с полученной копией. - Проверьте содержание. Сравните отпечаток исходящего пакета, получателей, тему, текст и HTML, если HTML ожидался. Нельзя зачесть красивый текст с чужим HTML или неверной темой.
- Проверьте порядок и срок. Время старта ≤ отправка ≤ ответ провайдера ≤ получение; полученная копия лежит внутри объявленного интервала и не позже дедлайна. Если часы или часовые зоны не позволяют сравнить — это не успех.
- Проверьте дубли и повтор запуска. Поиск должен быть полным для указанного ящика, интервала, запроса и правила копии. История не должна содержать текущий
run_id. Итог «дублей нет» всегда ограничен этой областью, а не всем интернетом или всеми ящиками.
Итоговые Статусы
| Статус | Значение |
|---|---|
PASS |
Полная цепочка существует; содержание совпало; выпуск получен в срок; в объявленной области найдена ровно одна копия. |
FAIL |
Наблюдается положительное нарушение: другой текст/HTML/тема/получатель, дубль, опоздание или разорванная подтверждённая цепочка. |
UNPROVEN |
Не хватает цепочки, поиск неполный, время несопоставимо или данные недоступны. Это не означает «не отправлено». |
Верните не общий «всё хорошо», а короткую квитанцию:
Статус: PASS / FAIL / UNPROVEN.
Получение: [что подтверждено отдельно от зачёта планового запуска].
Происхождение: [цепочка либо её пробел].
Содержание: [текст/HTML/тема/получатели].
Срок: [результат сравнения].
Дубли: [результат только для ящика, интервала и правила].
Прежняя квитанция: [сохранена / не передана].
Следующее безопасное действие: [одно действие].
Локальный Проверяющий Модуль
Для пакета без секретов можно запустить:
python3 scripts/verify_receipt.py receipt-packet.json
Модуль только читает JSON и возвращает PASS, FAIL или UNPROVEN с причинами. Он не обращается к Gmail, не создаёт историю и не отправляет письма. Его PASS ограничен теми записями и областью поиска, которые вошли во входной пакет.
Первая версия поддерживает только выпуск без CC, BCC и вложений. Непустые дополнительные получатели или вложения не игнорируются: пакет не может получить PASS без отдельного расширения контракта.
Границы
- Не отправляйте или повторно не отправляйте письмо ради проверки.
- Не называйте отсутствие письма в неполном поиске доказательством сбоя.
- Не называйте одну найденную копию доказательством отсутствия дублей вне объявленной области.
- Не стирайте старую квитанцию из-за новой ошибки чтения или пустого поиска.
- Не считайте
isinstance(prior_receipt, dict)доказательством: прежняя квитанция должна содержатьrun_id,message_id, отпечаток и время записи. - Не обещайте mathematically exact-once: почтовый провайдер и область наблюдения дают только доказанный практический вывод.
Definition Of Done
Проверка готова, когда результат имеет один из трёх статусов, не сильнее входной цепочки, и явно называет границу проверки дублей. При неопределённости завершайте UNPROVEN, а не догадкой о доставке или недоставке.
Опрос После Использования
Опрос задаётся один раз — после квитанции или честного стопа, не посреди восстановления. Если пользователь уже ответил «пропустить» в этой сессии, не переспрашивайте.
Опрос по skill:
1. Что в работе подтверждения плановой рассылки было полезно?
2. Что стоит доработать в процедуре или формате ответа?
Можно ответить коротко или написать "пропустить".
Если пользователь ответил, сохраните санированную карточку в ~/.codex/skill-runs/podtverzhdenie-planovoy-rassylki/usage-feedback.jsonl — лучше через bundled script:
python3 scripts/log_usage_feedback.py --liked "..." --improve "..." --outcome "..."
Script перед записью редактирует приватные пути, контакты и token-like строки и сохраняет в JSONL redaction_applied и redaction_types. Если запись невозможна из-за sandbox, прав или отсутствия tools, не делайте вид, что лог сохранён: скажите об этом и покажите короткую JSONL-карточку для ручного сохранения. Raw-ответы, контакты, пути и секреты не коммитить.
Логирование Сбоев
Перед выполнением прочитайте локальный known-exceptions.yaml как список уже известных случаев и применяйте подходящее do_next_time без нового поиска.
Если пользователь поправил skill, поиск оказался уже заявленной области, отсутствовала связь планировщика с отправкой или квитанция была потеряна в интерпретации, запишите приватную карточку в ~/.codex/skill-runs/podtverzhdenie-planovoy-rassylki/exception-log.jsonl.
Пишите факты: какой выпуск проверялся, какая запись отсутствовала или противоречила, как ограничена область поиска и что сделать в следующий раз. Если поле неизвестно, пишите unknown. Raw logs не коммитить.