You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
The adopted-source fingerprint does not cover @@ includes — a change to an included-only snippet is invisible to staleness detection #2948
Split out of #2813 rather than folded into it, because it is a pre-existing gap with a real cost to close, and burying it in the fix would have made the fix's coverage look larger than it is.
What is not covered
NodeTypeSourceFingerprint.Compute (added in #2947) hashes the compile input as NodeCompileShaping.CollectCompileSources yields it: the deduplicated, non-executable, non-blank
Code nodes a source/test query matched, reduced to (node path, SHA-256 of the code text).
An @@Path/To/Snippet include pulls a Code node that no source query matches. It reaches the
emitted assembly — NodeSetCompiler.ResolveInputs resolves includes after the fold — but it is
absent from the fold, so:
editing an included-only snippet does not move AdoptedSourceFingerprint / CurrentSourceFingerprint, and
a prebuilt assembly built before that edit still adopts as AdoptedVerified.
BakeEquivalenceTest already pins this shape explicitly: Widget/Snippets/Greeting is asserted
absent from sourceVersions while Greeting is asserted present in the emitted surface.
Why it is not a regression
It is the same setNodeTypeDefinition.CompiledSources records, so IsDirty has always had
this hole too — an included-only edit never dirtied the type and never triggered a recompile. #2947
does not widen the gap; it just makes it worth naming, because the fingerprint now carries a verified claim where before there was only an unverified one.
What closing it would take
Both sides must resolve includes before hashing:
the bake already does (NodeSetCompiler.ResolveInputs → NodeCompileShaping.ResolveCodeIncludes
against the tree's NodeSet, a dictionary lookup);
the live side does not. InstallSourcesWatcher holds only the query-matched nodes, and
resolving includes there means a mesh read per include, on a path that runs at every hub
activation and every source edit. That is a real cost and a real reactive-composition change
(the watcher's Update lambda is pure and synchronous today), which is why it is not smuggled
into a data-loss fix.
An alternative worth weighing first: fold the include-resolved text in only where it is already
computed — i.e. have the compile stamp the resolved set — so the live half never has to do the
mesh reads.
Acceptance
A test in the shape of AdoptedBuildSourceStampTest: a type whose only change is to an
included-only snippet, whose bundle was baked before that change, must be refused, not adopted
as verified.
Related: #2813 (the fingerprint), #2947 (the PR that made it reachable), #2820 (the execute-time
interlock that consumes BuildProvenance).
Activity