HarperFast / HarperFast/harper
sourcedFrom cache only populates from origin via PK get(); search()/GraphQL/relationship reads silently miss uncached keys
- Dominant language
- JavaScript
- Stars
- 89
- Forks
- 10
- Avg merge
- 2d 2h
- Merged PRs (30d)
- 205
Description
## Summary
On a `sourcedFrom` cache table, a **cold-cache** read populates from origin on exactly one surface — an explicit REST PK GET (`GET /Node/11`). Every other read surface returns null/empty with **zero** origin fetches:
| Surface | Fetches | Populated? |
|---|---|---|
| REST PK GET (`/Node/11`) | 1 | **yes** |
| REST query by pk (`/Node/?id=12`) | 0 | no |
| REST query by attr | 0 | no |
| GraphQL root single (`Node(id:"21")`) | 0 | no |
| GraphQL list/filter | 0 | no |
| GraphQL `parent` edge (target uncached) | 0 | no (even though `parentId` was known) |
| GraphQL `children` edge | 0 | no |
So the gap is **`get()` vs `search()`**, not GraphQL-vs-REST.
## Root cause (source-confirmed)
`getFromSource` (the origin fetch) lives only in the `get()` path (`resources/Table.ts:4225`, guarded by `hasSourceGet`). GraphQL routes all top-level fields through `resource.search()` (`server/graphqlQuerying.ts:323`), and REST conditions also hit `search()`. `search()` index-scans the **local** store; its only source hook (`transformEntryForSelect` → `ensure_loaded`/`checkLoaded`, `Table.ts:2739`) only fully-loads entries the scan already found locally — it never fetches a pk the local index lacked. Cold ids are invisible to every search surface.
## Decision / intended behavior
Per maintainer (Kris): GraphQL/search reads **should** populate a sourcedFrom cache on miss, like the REST PK path. So this is a defect, not just a doc gap. The targeted fix: resolve singular PK / `parent` (and root `Type(id:)`) lookups via `get()` so they trigger origin population; for set-valued `search()`/list/filter, define and document the intended behavior (a query can't enumerate which uncached keys to pull, so at minimum the singular-key surfaces should populate).
## Notes (working correctly)
Single-flight stampede dedup and SWR refresh both work; the missing depth limit (#1291) does **not** amplify origin load on a cached graph (cache-miss children simply don't appear).
## Repro
`integrationTests/qa-scratch/sourced-graph.test.ts` (first sighting); `integrationTests/qa-scratch/sourced-parity.test.ts` (full parity matrix).
---
_Found via the exploratory QA campaign (qa-explorer), scenarios QA-043 + QA-046. Harper `001bf7b9c` (v5.1.0, main)._
Contributor guide
Assessment
This issue has not been assessed yet.