Skip to content

fix(core): a resumed session's /context prices the memory index it carries - #264

Merged
Max17190 merged 6 commits into
mainfrom
context-prices-the-resumed-memory-index
Aug 29, 2026
Merged

fix(core): a resumed session's /context prices the memory index it carries#264
Max17190 merged 6 commits into
mainfrom
context-prices-the-resumed-memory-index

Conversation

@Max17190

@Max17190 Max17190 commented Aug 29, 2026

Copy link
Copy Markdown
Owner

Why

Round-5 ticket T4 (.scratch/selfext-round5/findings.md). PromptBreakdown::from_persisted fills tools and skills from the frozen registry but left memory empty, while the persisted prompt it prices carries the memory section. After a resume that does not refreeze, /context showed zero memory rows for bytes paid on every request.

Summary

  • from_persisted takes the persisted prompt text (it previously took only its length) and parses the memory rows from the prompt's own bytes: the section header (now a shared const, so assembly and parser cannot drift) followed by consecutive - name: description — path lines. Each row is priced as the line length including its newline, the exact accounting the live scan records.
  • Parsing the prompt rather than re-scanning disk is deliberate: a manifest-restored registry holds no memory section, and a fresh scan would price today's selection instead of the lines the prefix actually pays for.

Test Plan

  • a_persisted_breakdown_prices_the_memory_index_it_carries: two memories; the resumed breakdown's rows must equal the live scan's rows exactly (names and byte costs), and a prompt with no section prices none. Red against the previous no-fill behavior (verified).
  • Existing skills half of the accounting test updated to the new signature and still asserts resumed == fresh.
  • Full workspace green (exit 0), clippy zero warnings.

Greptile Summary

Resumed /context accounting now uses the memory-index rows captured when the session prompt was frozen. The manifest preserves those rows across restoration, preventing prompt content from changing the displayed memory costs.

Confidence Score: 5/5

No blocking failure remains.

Focused manifest round-trip and forged-prompt tests passed, confirming that restored accounting retains freeze-time rows and does not interpret prompt bytes.

T-Rex T-Rex Logs

What T-Rex did

  • Validated that the restored-accounting path reads rows from Registry::frozen_memory_rows and that these rows are serialized as RegistryManifest::memory_rows and restored without parsing prompt text.
  • Validated that breakdown.memory is assigned directly from registry.frozen_memory_rows and serialized/restored through RegistryManifest::memory_rows.
  • Observed that both captured commands exited with code 0 and each had one targeted test passing.
  • Noted that the persisted evidence files were saved and checksum-matched their original captured logs.

View all artifacts

T-Rex Ran code and verified through T-Rex

Reviews (6): Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." | Re-trigger Greptile

…rries

PromptBreakdown::from_persisted repopulated tools and skills from the
frozen registry but left memory empty, while the persisted prompt it
prices carries the memory section on every request: after a resume with
no refreeze, /context showed no memory rows for bytes the prefix pays.
A manifest-restored registry holds no memory section and a fresh disk
scan would price today's selection, so the rows are parsed from the
persisted prompt's own bytes (the shared section header, then the index
line shape), reproducing the live scan's accounting exactly.
Comment thread crates/core/src/prompt.rs Outdated
…bytes

The parser took the FIRST heading occurrence, and AGENTS.md is injected
before the generated section, so a user-authored lookalike heading plus a
row-shaped line was priced as the memory index while the real rows were
dropped. The parser takes the LAST occurrence (nothing after the real
section can hold the heading's embedded newlines), and rows are
cross-checked against the manifest's memory identities when the registry
carries them, so an unknown stem is never priced as a memory.
Comment thread crates/core/src/prompt.rs Outdated
…tion

A heading-shaped filename rendered verbatim by the layout section (Linux
filenames may hold newlines) sat after the real section and made the
last-occurrence pick parse the layout and return nothing. Every heading
occurrence now yields a row run, and the LAST run that still holds
identity-passing rows wins: the layout spoof has no row-shaped lines, an
AGENTS.md lookalike filters to zero known stems, and the real section,
frozen with the same identities, always survives.
Comment thread crates/core/src/prompt.rs Outdated
from_manifest clears memory_files on purpose (the resume-delta baseline),
so a restored registry filtered nothing and a resumed prompt carrying an
AGENTS.md lookalike with no genuine section was priced as saved memory.
The freeze's identities now ride a separate frozen channel: set beside
memory_files on a fresh freeze, restored from the manifest (which always
carried them), written back by to_manifest from the frozen channel so a
restored registry re-suspending cannot erase them. The delta baseline
stays reset exactly as before.
Comment thread crates/core/src/prompt.rs Outdated
…parse

Reconstructing /context's memory rows from persisted prompt bytes was an
arms race: filenames and AGENTS.md render into the same prompt, and a
newline-bearing filename can spell the section header AND a row reusing a
genuine stem, defeating any content filter. The freeze now records its
own row accounting (stem, line bytes) in the manifest (MANIFEST_VERSION
4; older manifests read as absent and refreeze, so the channel is Some on
every live path), from_persisted reads only that channel, and the prompt
parser is deleted. The resume-delta baseline stays reset as before.
# Conflicts:
#	crates/core/src/registry.rs
@Max17190
Max17190 merged commit a46f50d into main Aug 29, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant