docs(adr): ADR 009 keeps the window out of a pushed filter and names query pushdown sources (improvise-felo.4)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
This commit is contained in:
Claude (adr9-steward)
2026-10-09 22:31:45 -07:00
committed by Edward Langley
parent 81f1b5e13a
commit b8a0b6a846
+8 -2
View File
@@ -51,6 +51,10 @@ formula result at a key, and the raw fold of the cells that match a partial key.
incremental backend implements it in a seam crate, `improvise-incremental`, which
depends on `zset` and improvise-core. improvise-core never depends on `zset`.
A live source (ADR 003) that reports its changes feeds cell deltas like `DataStore`. A
source that answers aggregate queries but reports no changes implements the derived-value
operator directly, by query pushdown, with no change feed.
The circuit decides *which* formula cells to re-evaluate. The one existing evaluator
computes each value, so formulas are never compiled into operators.
@@ -316,8 +320,10 @@ notice carries:
**A client receives only what it needs.** Filtering is part of the DBSP graph, not a
separate mechanism. A client either pulls just the state it needs, or pushes a filter to
the host's side of its connection: a filter operator on its shape key and window, written
in the query language, through which its notices pass. A pushed filter belongs to the open
the host's side of its connection: a filter operator on its shape's query, written in the
query language, through which its notices pass. The filter never names the window, which
stays the client's: the client intersects the moved keys of a notice or correction with
its own window. A pushed filter belongs to the open
connection, like that connection's timeout, and is released with it. On a sequence of
requests the client sends it with each request, so the host keeps no per-client state
beyond an open connection. While a connection's filter is open, it counts as a request