#657 added ?instinct= to GET /api/v1/state/observations. instinct_ref is a hot-only column — it is not a bare column on archive_observation — so the implementation sets hotOnlyFilters and skips the cold tier entirely whenever that filter is present.
Correct today: all 5,904 observations on the live tenant are hot-tier, so nothing is missed.
The problem is what it looks like later. Once observations age into cold.db, an instinct's panel will show only its hot observations and present that as the full count. Under-reporting how often a pattern has been seen is not a neutral error — the observation count feeds how much discretion an instinct earns, and the page is where you judge whether to grant it autonomy.
coldRead.ts's own header warns about exactly this: a query whose window reaches past the cutoff "must read both tiers or it silently" under-reports. This change adds a new path that does so deliberately.
The response cannot currently distinguish the two cases. tiers comes back as ["hot"] both when cold was out of scope and when cold was deliberately skipped because of a hot-only filter. A caller cannot tell "there is nothing older" from "I did not look".
Options, roughly in order of appeal:
- Add
instinct_ref as a real column on archive_observation so the filter works across both tiers. Needs a migration (phase0).
- Have the response distinguish the cases — e.g.
tiers_skipped: ["cold"] — so a consumer can disclose the limit rather than silently truncate.
- Decompress and filter cold bodies. O(n) and unattractive.
Not urgent. Filed so the daily-cadence workaround is not mistaken for a design decision, and so the first person to see a suspiciously low observation count has something to find.
Related: #584.
#657 added
?instinct=toGET /api/v1/state/observations.instinct_refis a hot-only column — it is not a bare column onarchive_observation— so the implementation setshotOnlyFiltersand skips the cold tier entirely whenever that filter is present.Correct today: all 5,904 observations on the live tenant are hot-tier, so nothing is missed.
The problem is what it looks like later. Once observations age into
cold.db, an instinct's panel will show only its hot observations and present that as the full count. Under-reporting how often a pattern has been seen is not a neutral error — the observation count feeds how much discretion an instinct earns, and the page is where you judge whether to grant it autonomy.coldRead.ts's own header warns about exactly this: a query whose window reaches past the cutoff "must read both tiers or it silently" under-reports. This change adds a new path that does so deliberately.The response cannot currently distinguish the two cases.
tierscomes back as["hot"]both when cold was out of scope and when cold was deliberately skipped because of a hot-only filter. A caller cannot tell "there is nothing older" from "I did not look".Options, roughly in order of appeal:
instinct_refas a real column onarchive_observationso the filter works across both tiers. Needs a migration (phase0).tiers_skipped: ["cold"]— so a consumer can disclose the limit rather than silently truncate.Not urgent. Filed so the daily-cadence workaround is not mistaken for a design decision, and so the first person to see a suspiciously low observation count has something to find.
Related: #584.