handoff: читатель раньше чистки + хвост живёт в своей session-заметке (v1.2.11 + v1.2.12) - #34
Merged
Merged
Conversation
…риаж handoff (v1.2.11) Continuity получила автоматического ЧИТАТЕЛЯ, которого у неё не было. Замер на живом vault 2026-07-25: handoff 805 KiB, 185 блоков, 863 открытых пункта. Тело втягивалось ради continuity в 6% сессий — потому что прочитать его нечем: Read отказывается на 256 KB / 25000 токенов, а Bash режет вывод до превью. Инструкция «при старте прочитать handoff» была неисполнима, и docs/session.md обещал путь чтения, которого в коде нет. Добавлено: - hot-scan.py — собирает незакрытые хвосты из pending-секций свежих session-заметок; внутри pending-секции голый «- буллет» тоже хвост (класс v1.1.10: живое ≠ всегда чекбокс, на живом vault таких 90); все лимиты в БАЙТАХ (len(str) занижает кириллицу на 34%) - инжект дайджеста в mnemo-context.sh рядом с нуджем: project-scoped (метка проекта = basename git common dir, чтобы воркти отдавал имя проекта, а не своё), байтовый cap, деградация до нуджа при любом сбое, обязательная строка про протухшую премису - handoff-resolver.py + health Step 7.6 — офлайн report-only триаж: потолок выигрыша, классы блоков по payoff, пункты с внешним якорем. Инвариант keep-hot ИМПОРТИРУЕТСЯ из vault-write.py, а не копируется. Свои якоря пункта отделены от унаследованных из заголовка блока: смешение раздувает «резолвимость» с 27.6% до 60.6% Исправлено: - docs/session.md обещал чтение handoff при старте — такого пути не было - «token bomb read every session» как обоснование потолка: реальная цена раздутого handoff — нечитаемость, а не токены - session/SKILL.md теперь честно называет предел гварда: один открытый «- [ ]» пришпиливает блок, поэтому архиватор законно бывает no-op при превышении потолка в 20 раз Тесты: test-hot-scan.py (20), test-context-hook.py (11, CLI obsidian замокан), test-handoff-resolver.py (15). Мутант-килл пройден на двух инвариантах: подмена байтов символами и игнор плоских буллетов роняют сюиту. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…строку-указатель (v1.2.12) Замер, который переопределил реформу: свежие открытые пункты handoff присутствуют в своих session-заметках лишь в 9% случаев (старые — 34%). То есть handoff стал ЕДИНСТВЕННЫМ домом forward-state — отсюда и 805 KiB, и невозможность ни прочитать его, ни сжать. Схлопывать блоки в строки нельзя: потерялись бы 257 живых хвостов. Настоящий фикс — не формат блока, а ДОМ хвоста. - session Step 5 + depth-contract: незакрытая нить пишется в свою session-заметку, handoff получает указатель. Строка-указатель ограничена ЧИСЛОМ СЕССИЙ, скопированный хвост — ничем. - vault-write: action handoff-index-upsert, идемпотентный по ссылке на session-заметку (чекпоинт обновляет свою строку, а не плодит близнеца). Попутно чинит уже сломанный контракт: Step 5 требовал «точную старую секцию из read», но большой handoff читается превью, где целой секции нет. Лимиты в БАЙТАХ; при обрезке жертвуем меткой проекта, но не ссылкой. Блочный путь (archive-handoff) не тронут, его регресс-сюита цела. - migrate-handoff-to-index.py — одноразовая миграция, dry-run по умолчанию. Блоки переносятся ДОСЛОВНО И ЦЕЛИКОМ (не извлечением чекбоксов: 90 плоских буллетов и ~200 строк прозы держат живое без «- [ ]»), session-заметки не трогаются, ничего не удаляется, .bak до записи, проверка дословного присутствия после. Живой замер: 826916 B → 35910 B. - restore-handoff-from-bak.py — откат написан и отрепетирован ДО миграции (vault без git). На копии живого файла: migrate → restore возвращает байт-в-байт, md5 совпал. - split-handoff-archive.py — архив по месяцам + компактный хаб. Холодный файл не безобиден: 717 KiB не открывается (лимит чтения 256 KB), при этом попадает почти в любой поиск. Крупные месяцы дробятся: июнь = 425 KB. 43 новых теста. Мутант-килл: счёт символов вместо байтов и снятый hard cap роняют сюиту. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Поймано живым повторным запуском на уже мигрированном handoff: скрипт не выходил рано при нуле блоков, а честно проходил весь путь и дописывал в хаб архива маркер «сюда перенесены 0 блоков (0 B)» плюс пару пустых строк в конец handoff. Данные не страдали (0 блоков — нечего переносить, бэкапы писались впустую), но повторный прогон обязан быть неотличим от несделанного. Теперь при отсутствии датированных блоков скрипт печатает «handoff уже в индекс-формате — мигрировать нечего» и выходит, не создавая ни бэкапов, ни правок. Два теста пинят это: повторный прогон не меняет ни один из двух файлов и не плодит лишний .bak. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Личные permission-разрешения в публичном плагине выдали бы каждому, кто клонирует репо, заранее одобренный путь к скриптам, которые необратимо переписывают vault. Файл нужен локально, в репозитории ему не место. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Jul 26, 2026
jojoprison
added a commit
that referenced
this pull request
Jul 26, 2026
… взят из main (1.2.11 слит в 1.2.12), код — из ветки
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Зачем
Meta — Session Handoffдорос до 805 KiB и перестал работать как «тонкий живой индекс», которым объявлен собственным контрактом. Разбор показал, что чинить надо не то, что казалось.Три замера, которые переопределили решение
docs/session.mdобещал путь чтения, которого в коде не существовало.- [ ].Что сделано
v1.2.11 — читатель, которого не было
hot-scan.pyсобирает открытые хвосты из pending-секций session-заметок; внутри pending-секции голый- буллеттоже хвост (класс v1.1.10 — живое ≠ всегда чекбокс, на живом vault таких 90)hooks.hotDigest): project-scoped, байтовый cap, деградация до нуджа при любом сбое, обязательная строка про протухшую премисуhandoff-resolver.py+healthStep 7.6 — офлайн report-only триаж; инвариант keep-hot импортируется изvault-write.py, а не копируется; свои якоря пункта отделены от унаследованных из заголовка (смешение раздувает «резолвимость» с 27,6% до 60,6%)v1.2.12 — смена дома хвоста
sessionStep 5 +depth-contract.md: незакрытая нить пишется в свою session-заметку, handoff получает указатель. Строка-указатель ограничена числом сессий; скопированный хвост — ничемhandoff-index-upsertвvault-write.py, идемпотентный по ссылке на заметку. Попутно чинит уже сломанный контракт: Step 5 требовал «точную старую секцию из read», но большой handoff читается превью, где целой секции нет ни однойmigrate-handoff-to-index.py/restore-handoff-from-bak.py/split-handoff-archive.py— все с--dry-runпо умолчанию и.bakдо записиДоказательства, а не обещания
Что осталось за рамками диффа
Миграция самого vault (
--apply) — отдельное осознанное действие владельца: vault без версионирования, поэтому команда запускается вручную, после dry-run.🤖 Generated with Claude Code