Suppression query runs on every category-scoped call; needs a batch-aware skip #35
Closed
opened 2026-08-05 08:23:27 -04:00 by jared
·
1 comment
No Branch/Tag Specified
main
ci/mirror-canonical-tags
chore/release-47-badges-mirror-pr
docs/readme-perf-remeasure-56
feat/pagination-search-balances-57
feat/duckdb-threads-60
feat/cohort-predicates-58
fix/windows-backslash-paths
ci/mirror-to-github
ci/github-actions-matrix
feat/public-release-0.3.0
chore/fixture-sb203
ci/apt-https
fix/pushdown-pagination
feat/all-categories-37
fix/partial-coverage-signposting-9
fix/schema-v7
fix/cog-categories-balance-subtype
feat/cog-balances-25
feat/revenue-concepts-12
feat/expenditure-concepts-11
feat/coverage-disclosure-13
feat/complete-argument-18
fix/kodor-batch-14-15-16
fix/all-scoped-series-breaks-19
fix/regen-fixture-corpus-18
test/walkthrough-findings
feat/expenditure-concept
fix/3-url-trailing-slash
feat/phase-r3-signposting
fix/fixture-option-b-aggregates
feat/phase-r2-harmonization
feat/phase-r1-forward
feat/cog-gov-search-basket-mode
v0.4.0
Labels
Clear labels
kodor
kodor/feature-proposal
kodor/fix
kodor/needs-review
kodor/triaged
madison-walkthrough
severity/high
severity/low
severity/medium
south-guide
verdict/defect
verdict/definitional
kodor
kodor/feature-proposal
kodor/fix
kodor/needs-review
kodor/triaged
Kodor should process this issue
Kodor has written a feature proposal
Kodor should implement a fix (assigned to Kodor)
Kodor's work or failure needs Jared's review
Kodor has already triaged this issue (skip)
Surfaced while building the client-facing Southern API guide
needs
human
Cannot move without a person -- a decision, a check an agent cannot make, something outside the repo
origin
client
Came from a client ask
origin
obligation
Created by a change elsewhere
origin
review
Came from human review
origin
roborev
Promoted from a roborev finding
type
chore
Maintenance with no behaviour change
type
debt
Owed work -- docs, tests, cleanup a change obligated
type
decision
Needs a decision before work can proceed
type
defect
Something is wrong
type
feature
New capability
ws
api
Query verbs and results
ws
corpus
Corpus, mirror, provenance
ws
docs
Vignettes and guides
Assign a task to kodor
Kodor thinks this needs a feature.
Kodor should fix this
Kodor thinks the user is ready to review this.
Kodor is done with this issue.
No labels
Milestone
No items
No Milestone
Projects
Clear projects
No projects
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: Civilytics/uscogdata#35
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Deferred finding I3(b) from the uscogdata#9 final review (PR #32). A first attempt shipped and was reverted after measurement — read this before trying again.
The cost
.build_suggestions()calls.suppressed_components()unconditionally whenever a category-scoped,basis = "harmonized"query has candidate recipes. Before #9 a healthy category query returned after one cheap candidate query; now it always pays for the anti-join. That includes the shapecog_geographic_rollup()andcog_peer_compare()issue with large govid lists, and cog-api may read the corpus over HTTP.#9 did land the bigger half of this: the
NOT EXISTSsubquery now restates its year/govid literals, so it prunes to the requested year partitions instead of scanning all of them (Scanning Files: 1/4on the fixture, against ~57 partitions on the live corpus). That fix stands and is not in question here.What was tried and why it was reverted
A
.needs_suppression_query()in-memory pre-check: skip the round trip when every flow-scoped component of every candidate recipe already appears in the result'scodes_included. It was correct — a scoped re-review measured 260 (gov x year x category) combinations and found 0 unsound skips — but it did not pay for itself:comp_rowsmetadata query (~1.65 ms/call) to save an expected ~0.34 ms (the real query is ~12.45 ms at a 2.7% hit rate) — net slower on the fixtureThe structural reason it cannot work in that form: it requires every sibling component present for every requested (govid, year).
Public Welfare— the motivating category of #9 itself — has flow-scoped components {E67, E68}, neither of which ever appears in a modern year'scodes_included, so it runs the full round trip on every call regardless. Ordinary reporting variance defeats the condition almost always.It also left an untested exactness invariant: the gate's soundness rests on
codes_includedand the anti-join sharing the harmonizeditem_codespace (inst/sql/22-spending_long_harmonized.sql'sREPLACE (harmonized_code AS item_code)). If that ever changed, signposting would silently stop firing — the exact silent-failure class #9 exists to prevent.Reverted in
7707462; a comment at the call site inR/suggestions.Rrecords the attempt.What a real fix probably needs
codes_includedcoupling, ship a fixture property test asserting "gate says skip => the real query returns 0 rows" alongside it.Closing: measured, and the premise no longer holds
This is the "absorb or kill" call that #56 step 3 asked for. Killing it.
This issue assumes the suppression round trip is a cost worth engineering around. The
profiling in #56 says otherwise, and the evidence is now specific rather than intuitive:
suggestion and suppression machinery — sums to tens of milliseconds against a
local corpus. The same
cog_spending()call measured 66 ms local vs 3.9 s remote.small slice of an already-cheap pipeline. There is no configuration in which fixing it
changes what a user experiences.
The stronger argument is the one already recorded here: a first attempt shipped and was
reverted after measurement.
.needs_suppression_query()was correct (0 unsound skipsacross 260 gov × year × category combinations) and still net-negative — it skipped 7/260
candidate-bearing queries, 0/5 of the multi-govid batch shape that motivated the finding,
and added an unconditional ~1.65 ms metadata query to save an expected ~0.34 ms.
That failure was structural, not an implementation detail: the skip condition needs every
sibling component present for every requested (govid, year), and
Public Welfare— thecategory that motivated #9 in the first place — has flow-scoped components {E67, E68},
neither of which appears in a modern year's
codes_included. Ordinary reporting variancedefeats the condition. A second attempt would have to beat both the measurement and that
structure.
The half of this that mattered already landed in #9: the
NOT EXISTSsubquery restatesits year/govid literals, so it prunes to the requested partitions instead of scanning all
~57. That fix stands and is not what is being closed here.
Where the leverage actually is, from the same profiling: remote HTTP round-trips, the
corpus's parquet row-group layout (fixed in pipeline #93, published 2026-08-09), and
partition-level caching. Not the R pipeline.
Method and raw numbers: the profiling comment on #56, and
docs/benchmarks/inCivilytics/cog-api(2026-08-baseline.md,2026-08-phase3-replicas.md,2026-08-final.md), reproducible viascripts/bench.shthere.Reopen if a future measurement puts the R pipeline back on the critical path — but it
should start from a number, not from the intuition that a per-call query must be worth
removing.