The release where every line deja gives an agent was read off a real store
rather than a fixture, and the same question asked of each one: is this about
what was asked. The answers were bad. 42% of the conclusions in a recall answer
were about work the query never mentioned; of 63 lines calling something a
file's prior decision, none named the file or its package; a third of excerpts
opened inside a word and nearly two thirds closed inside one; the mark for an
abandoned approach sat on million-word sessions where something was dropped
somewhere by definition. The other half of the release is the compaction. A
summary keeps the conclusions and drops the task, the files and the commands
they rest on, which costs a median of 28 actions before the next edit against 10
from a cold start — deja now captures the working context as the compaction
starts and hands it back once, with what each command did and what was left
open. Rebuilds take 30s instead of 51, a recall answer 0.9s instead of 2.3, and
deja how 96ms instead of 286.
Added
- Working context survives a compaction. The pre-compact hook stores the task, the decision, the files, the commands and what is left open; the next session-start, prompt or tool call gets it back once, within a 4 KB budget, with the commands marked passed or failed and a line saying whether the repository moved since. (#3436, #3490)
deja wip: what the last session in this directory was doing, derived from the transcript rather than from a note someone remembered to write. (#3454)- A program this machine does not have is named before the command runs, with the same command that ran without the wrapper beside it — nine of the ten sessions told about a missing command at session start ran it anyway. (#3449, #3487, #3488)
- Xcode Coding Assistant sessions are indexed under the provider that ran them, Claude Code or Codex. (#3467)
deja frictionrecognises the walls an agent actually hits: a shell's position marker is itself the error signal, and timeouts, the harness's own tool errors and the Python traceback tails join the phrase list. (#3446)- The point-of-action hooks record the text they injected, so what deja said before an edit or a command can be read back and audited. 507 injections on a real machine carried none of it. (#3455)
- The recall benchmark asks in Russian too: 100 queries, half Cyrillic, one session per query, with recall@1 pinned at 1.00 as the regression gate. (#3481, #3482, #3483)
Changed
- Index format version 38, on-disk layout 2. A record's role moved out of its compressed body, which is the layout change; 36 and 37 changed what deja derives from a transcript and left every byte's meaning alone. (#3446, #3458, #3464)
- A store whose content rules are stale still answers, instead of telling the agent to ask again later. 8 of 56 recalls an agent really made on a real machine came back during a rebuild, and an agent does not ask again; three of the last four bumps changed no layout. (#3472)
- A rebuild takes 30s instead of 51: the four sidecar passes run together, fix mining and the neighbour map run per session on all cores, and the multilingual redaction alternation only runs on text holding its own words. (#3462, #3463, #3465)
- A recall answer takes 0.9s instead of 2.3 and repeats 219 fewer bytes: ranking and hit-building run on all cores, the ranker stops building every message's token set to test five words, and the block explains itself once per session. (#3461)
deja howtakes 96ms instead of 286ms on a 2,721-session store, because scanning for one kind of record no longer inflates all 280,000 of them. (#3464)- The session-start block leads with what was settled instead of with the newest sessions: it served six, four of which had settled nothing. Context-bench coverage 0.00 to 0.50. (#3468)
- The recall answer line picks the session's outcome, not its first reply, and reads decisions in either language — 59 of 60 decision lines on a Russian store went unseen. (#3473)
- The conclusions a recall answer lists are the ones about the query; an unrelated conclusion is offered as such rather than under a label claiming it answered the question. (#3476, #3484)
- The files line names the files the question is about and keeps them relative to the repository, where one stray
/private/tmppath used to make all four absolute. Ten real lines: 2258 bytes to 1808, and words of the question present in 4 lines instead of 1. (#3479, #3480) - A
deja blamerow names a few touched files instead of forty, and quotes a piece of evidence once across forks of the same session. Six real paths went from 20 sessions to 38 at the same byte cost. (#3456, #3469) - Excerpts and the width cut end on whole words: of 400 real messages, 35% of excerpts opened inside a word and 62% closed inside one, now 2% and 30%; lines shortened to the terminal width split the last word in 56% of cases, now 11%. (#3475, #3477)
deja fixanswers a failing test with an edit's worth of evidence, not a command that merely followed it, and a repaired remedy carries the failing command it corrects. The repair rule compares programs instead of the shell prompt a harness stored, so a missingtimeoutwrapper is transparent. (#3458)- The prompt and recall benchmarks refuse to measure a corpus an ignore rule hides, rather than printing zeros: run from a tree under
~/.claude/jobsthe prompt bench read 0 of 13 questions and 13 of 13 beside it. (#3460) - The off-topic benchmark arms ask through the hook, so a gate at the hook level is measured by them. (#3485)
Fixed
- The pre-tool block no longer claims a file has a prior decision when the line is about something else: none of 63 such lines on a real store named the file or its package, a review agent's hold on another change was offered months later as that file's position, a promoted note about the repository description arrived in front of
main.go, and one incident diagnosis was offered for five differentmain.go— two files of one name are two files now, where one name in five pooled several real paths. (#3451) - A standing decision is one fact rather than one line per file, and a sentence already seen is not news under another session's id: replaying a real session's 2,805 edits, the agent received 17 lines where 3 were distinct. (#3451)
- An announcement of intent is not a decision: 13% of the lines read as decisions were plans, and a block leading with one reads as having no decision at all. (#3470)
- The weak-match pointer names what was asked about instead of the session's title, where "how is the block" came back as an unrelated task note. (#3471)
- The mark for an abandoned approach is dropped on sessions too long to scan — 23 of 60 search hits and 32 marks across sixteen recall answers were on million-word sessions. (#3474, #3478)
- A quoted excerpt is what someone said, not what the harness or deja said: over twelve queries, 6% of 77 quoted lines were a teammate-message envelope and 6% deja's own credit sentence coming round again. (#3457)
- A compaction summary does not fill
recall_context: it names everything a session did, so it matched any question and was 95% of three of eight answers, 44% of the bytes served. (#3459) - The command warning names the project the failure happened in, so a command shape that travels between checkouts stops reporting another repository's test failure as this one's. (#3486)
- VS Code Copilot Chat: a turn the editor raised itself is not the person's words. A background-completion notification carried a command's stdout under the user role, and a confirmation click was indexed as a typed sentence; the turn still times the session and its work records are unchanged. (#3452)
Changelog
Features
- feat(bench): the recall corpus asks in Russian too (#3483)
- feat(hook): a program this machine does not have is named before the command runs (#3449)
- feat(hook): the environment block says the command ran without the wrapper (#3488)
- feat(hook): the missing-program line says the command ran without it (#3487)
- feat: recover working context automatically after compaction (#3436) (@chrisgeo)
Fixes
- fix(bench): a recall query names the occasion, so one session answers it (#3482)
- fix(bench): each recall query names one session (#3481)
- fix(bench): refuse to measure a corpus the ignore rule hides (#3460)
- fix(blame): a piece of evidence is quoted once (#3456)
- fix(blame): a row names a few touched files, not forty (#3469)
- fix(compaction): the packet names the instruction, what is left, and how each command went (#3490)
- fix(copilot-chat): a turn VS Code raised itself is not the person's words (#3452) (@Sora-bluesky)
- fix(ctx): a compaction summary does not fill the context window (#3459)
- fix(digest): an announcement of intent is not a decision (#3470)
- fix(hook): the command warning names the project the failure happened in (#3486)
- fix(hook): the start block leads with what was settled (#3468)
- fix(hook): the weak-match pointer names what was asked about (#3471)
- fix(log): the point of action keeps what it said (#3455)
- fix(mcp): a stale content version still answers (#3472)
- fix(recall): an excerpt is what someone said, not what the harness or deja said (#3457)
- fix(recall): an unrelated conclusion is offered, not claimed (#3484)
- fix(recall): one stray path no longer makes the files line absolute (#3480)
- fix(recall): the answer line picks the outcome, not the first reply (#3473)
- fix(recall): the answer marks an abandoned approach only where it can be found (#3478)
- fix(recall): the conclusions list leaves out the session's other work (#3476)
- fix(recall): the files line names the ones the question is about (#3479)
- fix(search): drop the abandonment mark on sessions too long to scan (#3474)
- fix(search): excerpts start and end on whole words (#3475)
- fix(search): the width cut ends on a whole word (#3477)
- fix: the failure path says what it knows (#3458)
Performance
- perf(index): a rebuild takes 30s instead of 51s (#3463)
- perf(index): a record's role sits outside its compressed body (#3464)
- perf(index): the neighbour map is mined on all cores (#3465)
- perf(redact): the multilingual pattern runs on its own words (#3462)
- perf: a recall answer takes 0.9s instead of 2.3s, and repeats 219 fewer bytes (#3461)
Other
- Xcode Coding Assistant sessions join their provider's history (#3467) (@anupamchugh)
- chore: pin the manifests to 0.19.5 (#3447)
- ci: the test job cap is 90m, not 60 (#3495)
- ci: the windows test timeout is 25m, not 12 (#3494)
- deja wip: what the last session here was doing, derived (#3454)
- release: 0.20.0 (#3492)
- test(bench): the off-topic arms ask through the hook (#3485)
- what counts as a wall, and what counts as a remedy (#3446)
- what deja says at the moment of action, audited against a real store (#3451)
Install
curl -fsSL https://raw.githubusercontent.com/vshulcz/deja-vu/main/install.sh | sh
go install github.com/vshulcz/deja-vu/cmd/deja@v0.20.0
brew install deja-vu