Ingestion cache contract: stale node identity vs content-stable reuse after regenerated chunk IDs
Context
PR #23003 fixes the document-level identity collision from #23002, but its follow-up discussion exposed a broader cache-contract choice that appears worth deciding separately rather than burying in that focused fix.
The current generic transformation cache stores and returns the entire transformed BaseNode list. At the same time, the revised key in #23003 can intentionally omit an intermediate node's current id_ when a SOURCE relationship exists, in order to keep downstream cache reuse stable when an upstream splitter regenerates random chunk IDs.
The PR author confirmed the remaining case: two sibling chunks can have the same source id + same content but different current chunk ids, and a cache hit can return output carrying identity from the earlier run. The author also explicitly deferred the generic semantic choice to maintainers and offered to follow up once a direction is chosen.
Minimal decision case
A regression that makes the contract visible:
run 1:
source S -> splitter emits chunk id A, content X
-> downstream transform records/depends on input id A
-> cache stores downstream output
expire only the splitter-stage cache
run 2:
source S -> splitter emits chunk id B, same content X
-> downstream cache key is unchanged
-> cache hit returns output derived from A
For a generic TransformComponent, that is observably stale if the transform is allowed to depend on id_, relationships, or other non-content node state.
Contract options
I see two coherent directions:
- Full-node transformation cache — if arbitrary transforms may depend on full
BaseNodesemantics and the cache returns transformed nodes wholesale, include every node field that is semantically allowed to affect the transform in the key. Regenerated random IDs may legitimately cause misses. - Content-stable payload cache — if the intended optimization is reuse across regenerated chunk IDs, cache only content-derived payloads (for example embeddings) and apply them to the current node instead of returning a stale cached node object wholesale.
The risky middle ground is declaring current node identity irrelevant in the key while still returning cached values whose identity/relationships may depend on it.
Acceptance test for whichever contract is chosen
Please keep one regression where the downstream transform records the input node id (or another non-content field), regenerate the upstream chunk id while keeping source+content constant, and assert the second result follows the documented contract:
- full-node contract: downstream transform re-runs for B and result records B; or
- payload-reuse contract: payload is reused but attached to/currently represented by B, never A.
This issue is not asking #23003 to expand scope; it is intended to give the maintainer-level semantic decision a dedicated surface so the focused PR can remain focused.
Source: run-llama/llama_index