Repository navigation
fix(core): retire instruction notices after revert resync - #62028
yyytttwww888-beep wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
Looks correct. I reproduced #62027 on the base with the PR's runner scenarios: the real runner with the simulated model still sent the old "Changed target" / "Changed context" notices after the undo. With this change they're gone. The rebuilt baseline is used, and instruction updates made after the revert still reach the model. Projector and runner tests (292), instruction-state and session-instructions tests (19) and tsc -b for packages/core pass.
rewind runs while the revert event is being applied, after the rows from the boundary onward are deleted. So marking every instruction notice in the session only affects the ones that survive, and rebuilding the session from its events sets the marker again.
Public API: no SDK, HTTP, plugin, config or CLI changes. Instruction notice messages may now carry metadata.instructionSuperseded: true in their free-form metadata, which is backwards compatible. #61551 uses the same marker for forks, so the two PRs should agree on its shape and on where it's filtered in history.ts.
No blocking concerns.
Related: #61550
|
One thing this leaves in place: after the undo, the baseline is rebuilt from the current values, so the system prompt changes and the next request writes the whole conversation to the prompt cache again. An alternative that fixes the same contradiction and keeps the cache: when the undo removes an update but keeps the epoch start, reset the fold to its baseline instead of deleting it. The surviving notices stay valid, the next step restates what changed since, and the cached prefix is still read. The same idea covers forks (#61550). The change is here: dev...swf-cmd:opencode-upstream:fork-instruction-baseline I can't open it as a PR right now because I'm at the repository's open-PR limit, but I'm happy to once maintainers say which direction they prefer. |
|
@swf-cmd Thanks, I agree that preserving the baseline can improve prefix reuse. I tested your alternative at
I added the A → B → A case and the checkpoint case in To retain the notices safely, the tracked state needs to reflect the surviving history and its instruction epoch before calculating the current update. Resetting it to the baseline alone leaves these cases inconsistent. AI-assisted testing and analysis. |
There was a problem hiding this comment.
The new commit only adds tests: one reverts after instructions return to their original value, the other reverts to a point before a native compaction checkpoint. Both are short and clear. They fail on the base and pass here. The source is unchanged since my last review. The issue's reproduction script fails on the base and passes with this branch. Runner and projector tests (294) and tsc -b for packages/core pass.
Public API: unchanged, apart from the backwards-compatible metadata.instructionSuperseded: true on instruction notice messages noted before.
No new concerns.
|
Right on both, thanks for testing it. Resetting to the baseline forgets what the surviving B notice told the model. And once the revert goes past a checkpoint, my version just clears the state the way Keeping the prefix would need the state rebuilt from the surviving notices on their epoch's baseline, which |
Issue for this PR
Closes #62027
Type of change
What does this PR do?
Undoing an instruction update rebuilt the current baseline while replaying older notices that contradicted it. When the revert actually clears the instruction fold, mark surviving instruction notices as superseded and omit them from model context. Keep their rows and IDs for transcript reads and later revert boundaries. Reverts that preserve the fold still replay their valid updates.
No feature flag: this fixes existing revert behavior. The free-form metadata gains
instructionSuperseded: trueon affected notices. Earlier committed reverts are not backfilled. Related: #61551 uses the same marker for copied fork notices; this PR handles revert and can land independently.How did you verify your code works?
bun run check(35 tasks) andgit diff --checkpass.Visual
Screenshots / recordings
Not applicable; session history behavior.
Checklist
Added by the opencode bot (AI-generated).
Related: #61550