Skip to content

Re-scoping a cache-reloaded snapshot keeps typedefs that scoping the fresh extraction drops

Index: Known gaps — closed

Status (2026-10-31): CLOSED. Root cause identified and fixed: the attribution scoping reads for the flat constants/typedefs/typedefs_qualified maps lives in a runtime-only HeaderAttributedMap, which the snapshot codec deliberately does not persist (a loaded baseline must not license its own attribution). A reloaded snapshot therefore carried plain dicts, and flat_map_dependency_scope._kept_keys kept every entry. The dump cache now stores the attribution in a cache-private sidecar (workflows/dump/cache/declaring_headers.py) and re-attaches it on read; a header-derived entry missing its sidecar is a miss. Reproduced on libssl.so.3 with -H openssl/ssl.h (fresh scope 652 typedefs, reloaded 821) before the fix; equal after. Tests: tests/test_dump_cache_rescope_roundtrip.py.

Original status (2026-10-22): OPEN. Found while adding the finished-snapshot dump-cache tier (PR #1726).

scope_snapshot_excluding_dependencies applied to a snapshot reloaded from the raw dump cache is not equal to the same call on the freshly extracted snapshot: on libssl.so.3 with -H openssl/ssl.h the reloaded side keeps typedefs such as ASN1_ENCODING (and their semantic_ir / typedef-id entries) that the fresh side drops. So before #1726 a warm run could differ from a cold one.

The finished tier is written only from a fresh extraction, and a finished-tier miss re-extracts rather than re-scoping the raw cache entry, so warm runs through resolve_input reproduce cold output (a cache populated before #1726 pays one extra extraction per operand, once). The asymmetry itself remains for any other caller that scopes a deserialized snapshot. Root cause (which state the serialization round-trip loses or adds that scoping reads) is not yet identified.