Repository navigation
refactor(core): simplify system context into a belief model - #34917
Merged
Merged
Conversation
Reconcile never rewrites the baseline; only rebaseline (compaction) and
initialize (first turn) produce baseline text. The durable Applied record
tracks what the model was last told, per source.
- Incompatible stored values re-announce the source baseline as an update
instead of forcing a full replacement
- Sources removed without removal text retain the model's belief silently;
entries self-clean at the next rebaseline
- Rebaseline restates unobservable sources from their last-applied values
instead of blocking; ReplacementBlocked and ReplacementReady are gone
- Rename Snapshot to Applied and Generation to Baseline {text, applied}
One prepare call per turn, before input promotion: it creates the checkpoint when missing, rebaselines after completed compaction, and otherwise narrates drift as a chronological update. The initialize/ prepare two-step and its redundant queries are gone, and context update messages now precede the promoted user message. An undecodable stored applied record heals by treating every source as new instead of failing the drain; ContextSnapshotDecodeError is deleted. Renames: SessionContextEpoch -> SessionContextCheckpoint. The SQL table name and wire event type are unchanged.
Builtins and instruction context become ordinary Location-scoped services exposing load(), the same shape as skill, reference, and MCP guidance. The runner composes all six producers explicitly in loadSystemContext, so the full context roster is readable at one call site. Dynamic registration and scoped deregistration had no consumers.
Copied fork messages keep their parent seqs, but a fresh checkpoint's baseline_seq starts near zero, so nothing folded: forks received a new full baseline plus every stale context-update message from the parent, and copied compaction rows triggered a spurious rebaseline. Inheriting the parent row keeps the fold horizon consistent with the copied transcript. Also asserts the checkpoint reset on committed reverts and deletes the unused SessionStore.runnerContext / SessionHistory.loadForRunner surface.
Pure additions announce only the new entries and pure removals name what is gone, instead of restating the full list on every change. Description or instruction edits still restate the superseding list.
Skill, reference, and MCP guidance shared the same keyed three-way diff mechanics; each keeps only its own changed comparator and phrasing.
The required Provider.Request settings field and tsgo's literal narrowing broke typecheck in llm and core; CI missed it because turbo replayed cached typecheck results for packages whose own sources did not change. - anthropic-messages: lower adaptive thinking display with explicit literal branches so tsgo keeps the union type - runner model: annotate providerOptions with its index-signature return type - tests: construct provider requests with the now-required settings field and copy them mutably for plugin drafts
This was referenced Jul 19, 2026
jinhuang712
pushed a commit
to jinhuang712/opencode
that referenced
this pull request
Sep 26, 2026
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.
Summary
Audit-driven simplification of the V2 system context subsystem (
SystemContextalgebra +SessionContextEpochpersistence). The durable design is unchanged — stable baseline in the system prompt, drift narrated as chronological system messages, seq-based folding — but the implementation now follows one invariant and one mental model:Changes
Algebra (
system-context/index.ts)ReconcileResultnarrows toUnchanged | Updated; reconcile can no longer escalate to a full replacementrebaseline(formerlyreplace) restates unobservable sources from their last-applied values instead of blocking;ReplacementReady/ReplacementBlockedare deleted. Only a session's firstinitializestill blocks on unavailabilitySnapshot→Applied,Generation→Baseline { text, applied }Checkpoint (
session/context-checkpoint.ts, formerlycontext-epoch.ts)prepareentry point per turn, called before input promotion; theinitialize/preparetwo-step and its redundant queries are goneContextSnapshotDecodeErroris deleted fromRunErrorRegistry deleted
load()services; the runner composes all six producers explicitly inloadSystemContext. Dynamic registration/deregistration had no consumersFixes
baseline_seq, so nothing folded: forks got a fresh full baseline plus every stale context-update message, and copied compaction rows triggered a spurious rebaselineSessionStore.runnerContext/SessionHistory.loadForRunnerremovedFeature: delta updates
Compatibility
No migration and no SDK regen: the SQL table (
session_context_epoch), its column names, and thesession.next.context.updatedwire event are unchanged.Testing
packages/core: full suite green (the 6Watcherfailures reproduce identically on unmodifiedv2under load and pass in isolation)bun typecheckclean incore,server,cli,sdk-nextFollow-up
Planned separately:
session_context_epoch→session_context_checkpointtable rename lives there