Repository navigation
feat(context-reuse): explain invalidation with bounded internal attribution - #2586
Conversation
There was a problem hiding this comment.
Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.
An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.
|
CI note: the failing jobs look unrelated to this change.
I can't re-run jobs here. Could a maintainer re-run |
hireview001
left a comment
There was a problem hiding this comment.
- CI failed: CI result (failure).
- CI failed: dsh-package (failure).
- CI failed: Main (failure). Failed steps: dsh-package / Test built plugin in the real DSH runtime; CI result / Require successful selected checks.
…bution Revalidation of a prepared-context binding now attaches a content-free explanation to every context-reuse-source-changed it raises, readable by in-process callers of ScopedContextApplication.validate_reuse as ContextReuseError.invalidation. Error codes, exception types, check_context and HTTP output, the binding format and the 64/8 bounds are unchanged. - A bound root that is no longer its active head is named with revised, forgotten, merged or retired from the same authorized read; validation still stops at the first failing root, so the explanation is partial. - A changed snapshot is compared node by node; only nodes that are bound roots are named, ancestors and Sources are reported by subject only. - Changed or no-longer-indexable cited files are reported without paths. - Explanations hold at most 16 changes and 4096 UTF-8 bytes of canonical JSON, truncate deterministically, and fall back to unavailable if they cannot be built, leaving the original rejection intact. RFC 2086 (en/zh) documents the explanation, disclosure rules and bounds. Refs oceanbase#2522 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
e5355e0 to
86d3c84
Compare
There was a problem hiding this comment.
Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.
An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.
Which issue or RFC does this PR close?
Closes #2522.
Design contract: RFC 2086 (
docs/en/rfcs/2086-core-inference-gates-and-optional-gateway.md), section "Stable context reuse and model cache integration" and the new "Explaining a rejected reuse in process".Rationale for this change
When a prepared-context binding stops being reusable, revalidation raised the same generic
context-reuse-source-changedfor a revised root, a forgotten/merged/retired root, a changed ancestor or Source, and a changed cited file, with no indication of which bound evidence changed. An in-process caller could not tell, for example, which of two roots was revised.This PR adds a bounded, content-free explanation for in-process callers while keeping every existing decision, error code, authorization check and public output unchanged. It does not repair, re-prepare, extend the binding or follow a new head.
What changes are included in this PR?
ScopedContextApplication.validate_reusefailures now carryContextReuseError.invalidation(aContextReuseInvalidationwithattribution, orderedchangesandtruncated) on everycontext-reuse-source-changedraised by revalidation, and on nothing else. Preparation never explains.read_dependency_snapshot): the root that is no longer its active head is named withrevised,forgotten,mergedorretired. The lifecycle state outranks a revision written by the same operation, and an active root at a newer revision (including a restore) isrevised. Validation still stops at the first failing root, so the explanation ispartialand never mentions unexamined roots.changed,addedorremoved. Only a node that is itself a bound root is named; ancestors and Sources are reported by subject only, because the binding records no root-to-dependency map. The explanation iscompleteonly when no code was cited, since code is compared afterwards.codechangedorremoved, never with its path.context-reuse-code-unavailablecarries no explanation.to_json), ordered roots, ancestors, Sources, with deterministic prefix truncation. Any failure while building an explanation yieldsunavailableand the original rejection is raised unchanged.Unchanged:
check_contextstill returnscontext-refresh-required; HTTP still maps these errors to the generic 422 without details; the binding format, encrypted envelope, five-minute retention, identity binding and 64/8 dependency bounds are untouched.Are there any user-facing changes?
No public HTTP, OpenAPI, MCP or Receipt change, and no breaking change. The only new surface is the internal
ContextReuseError.invalidationattribute (plus theContextReuseInvalidation/ContextReuseChangetypes inpowercontext.builtin.runtime.context_reuse) for embedded callers. Remote hosts receive no new reasons.How was this change tested?
New and updated tests:
tests/builtin/runtime/test_context_reuse.pyvalidate_reuseentry on SQLite;unavailable.tests/builtin/runtime/test_code_context_reuse.py: changed, removed and unavailable cited files against a real Git repository and code index.git archiveexport of the base commit showed all four root changes raising the same code with no explanation.Commands:
Not covered by execution: artifact-level read denial for a principal that can read the Scope is not constructible with the built-in RBAC/Casbin roles (every role with
SCOPE_READgrants childARTIFACT_READ); AuthZEN was not checked. The final-comparison branch is exercised with a replaced dependency snapshot because a real store fails the early root check first. No OceanBase or real-host acceptance was run.AI usage statement
Implemented with Claude Code (Claude Opus 5.5). One agent context designed and wrote the change; a separate read-only Claude verification context independently reviewed the design and slice 1, the final snapshot, and the post-review edits against the issue contract, returning CONTINUE each time. The human owner made the disclosure and scope decisions.
🤖 Generated with Claude Code