Skip to content

v2: filter verdicts become enforcement-grade (zero over-accept gate before 2.0.0) #567

Closed

Description

@EricAndrechek

Decision (2026-10-07): from ABI v2, filter verdicts are meant to be usable as an enforcement control. That means read-side row-level security and per-record write checks. docs/limitations.md → "Filters are for comparison, not enforcement, for now" stays true until the gate below passes on a published v2 build. Only then is it lifted for v2, and the CHANGELOG says so, as that section already promises.

The contract v2 will publish:

  1. A true is a security claim. A filter answers true only when the pinned server's WHERE would admit the row. An over-accept (a true where the server says false) is a security-severity defect.
  2. Unknown and declined stay fail-closed. Any path that can't be sure declines rather than guessing. Callers enforcing with filters must treat anything but a definite true as "no".
  3. Zero over-accepts is a release criterion. A known over-accept is fixed or declined before the next build ships; it's never carried as a known issue.

The gate before 2.0.0:

  • A filter-vs-server differential in CI across every published ClickHouse line and platform, on every v2 build. It needs zero over-accepts and zero over-rejects, with declines listed rather than counted as agreement. The corpus includes adversarial cases from a downstream consumer that enforces with filters.
  • No open filter divergences on the line. Today there is one, on 26.3: a non-UInt8/Bool filter on a schema that declares a projection. It's approved to become a decline.

Docs (this repo), once the gate passes on a v2 build:

v1 keeps the current wording until a v1 build passes the same gate.

Activity

  1. EricAndrechek commented on Oct 7, 2026

    @EricAndrechek
    MemberAuthor

    Two lines for the contract text when the gate passes. Both are binding-facing, and both already hold:

    • Point 2, spelled out for v2: "anything but a definite true" includes v2's unknown(n) verdict member (spec rule r3), so a caller that maps an unknown verdict to a pass is wrong by contract.
    • The filter handle can't silently become "no filter": a CLOSED filter is never passed to the library as NULL, which would mean "no filter" (spec rule r7). All four bindings run the shared conformance case filter.a_closed_filter_is_never_passed_as_null (Rust by construction), and every released 1.x was measured refusing a closed filter on 2026-10-07.
  2. EricAndrechek commented on Oct 8, 2026

    @EricAndrechek
    MemberAuthor

    For the lift text (ruled 2026-10-08; nothing changes until the lift): the security-grade filter commitment (zero over-accepts, zero over-rejects) covers the Linux artifacts. The macOS (darwin-arm64) artifacts stay a development floor, not an oracle, consistent with docs/limitations.md's existing macOS section: their float parsing diverges by design (the 53-bit long double). The lift's wording must say so and cross-link that section.

  3. EricAndrechek commented on Oct 8, 2026

    @EricAndrechek
    MemberAuthor

    Correction to my note above (2026-10-08): the commitment is NOT "Linux only". New measurements (official macOS ClickHouse binaries) show:

    • the darwin library matches ClickHouse on macOS exactly;
    • on 26.7+, every platform agrees bit for bit;
    • on 26.3, ClickHouse's own float text parse is platform-dependent, Linux amd64 vs arm64 included.

    So the lift's wording is: the security-grade filter commitment (zero over-accepts, zero over-rejects) is the library against a ClickHouse server on the SAME platform. On 26.7+ all platforms agree. On 26.3, Float-literal and Float-parameter filters get a decline (coming from the artifact producer), and the library should run on the server's architecture. Cross-link docs/limitations.md's macOS section, which is corrected in #580.

  4. EricAndrechek commented on Oct 9, 2026

    @EricAndrechek
    MemberAuthor

    One more condition for the lift text (ruled 2026-10-09): the filter guarantee does NOT cover a ClickHouse server configured so that it refuses EVERY query. Documented examples: max_expanded_ast_elements=1 (36), and page=1 on 26.8/26.9 (36). The lift PR will:

    • state this plainly;
    • add a "Settings the server may refuse outright" section to spec/abi-v2/where-settings/README.md, listing the documented pathological values;
    • source that list from the artifact producer's committed list, which its gate counts. The list grows only by sign-off.
  5. EricAndrechek commented on Oct 9, 2026

    @EricAndrechek
    MemberAuthor

    Lifted on v2 by #589 (merge 2877d6cd): filter verdicts are enforcement-grade against a ClickHouse server of the same line, operating system and CPU architecture, for builds that passed the artifact producer's standing filter differential. Artifact build 20261009.074908 (served on the v2-dev channel to SDK 2.0.0-dev.4) is the first; the differential read 12/12 on it as published.

    • Lifted, 11 pairs: 26.3, 26.7, 26.8 and 26.9 on linux-amd64 and linux-arm64; 26.7, 26.8 and 26.9 on darwin-arm64. Each pair has its own CHANGELOG entry in all four bindings.
    • Not covered: 26.3 on darwin-arm64. The macOS 26.3 server refuses deep nesting on its smaller thread stack where the library answers. A follow-up on v2 states it as a documented platform limitation, with the measured band.
    • Outside the guarantee: a server configured to refuse every query (spec/abi-v2/where-settings/documented-pathological.tsv), and the 26.3 float platform requirement.
    • A pair that diverges again gets the gate back, with a fresh entry.
    • v1 is unchanged: on main, filters stay for comparison, not enforcement.

    The section is docs/limitations.md on v2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions