Repository navigation
Conversation
scode
force-pushed
the
hookless/8-drain-fix
branch
from
July 7, 2026 06:18
d0f69f7 to
cc66fd1
Compare
scode
force-pushed
the
hookless/9-self-session
branch
from
July 7, 2026 06:18
ee8e5da to
5ce1a60
Compare
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.
Second find from the live E2E battery, and the worse one: the headless distill child is itself an agent session, so
its transcript — containing the full distill prompt, i.e. every transcript emitted that cycle — lands in the session
store and gets emitted by the next scan. Each cycle's payload embeds the previous cycle's payload; growth is
unbounded. On the test box the fourth cycle hit "Prompt is too long: ~3.7M tokens" and distillation was permanently
wedged. A cron setup on an active box would reach the same wall within days.
The fix marks headless prompts with a fixed first-line sentinel, and the scan records sentinel-classified sessions as
processed without emission — their content is synthetic (leiter's own prompt plus the agent's summary), so nothing is
lost. Two review rounds shaped the details into something considerably more careful than the first cut:
the sentinel — a position injected tool output, quoted docs, or soul-synced block content can never occupy.
Content-anywhere matching would have handed prompt injection a silent suppress-from-learning primitive, and via the
soul-sync channel (sentinel in soul → managed block → every future transcript) a global learning shutdown.
agent_commandofcodex execwrites the child there — the growth loop would have survived that documentedconfiguration untouched), and legacy-log rendering (a still-hooked migrating box's SessionEnd tombstone copies the
child transcript into logs, where an unaccounted copy could re-wedge the exact failure being fixed).
--dry-runelides every sentinel occurrence from its output, so inspecting the prompt cannot mark the inspectingsession; the interactive
leiter soul distillpayload carries no sentinel at all, keeping the invoking sessionlearnable. Excluded session ids are logged, not silently absorbed.
A run whose only changes are child sessions commits their watermarks through the existing empty-only self-commit path
without spawning an agent.
changelog: include