Skip to content

fix(signals): let the scout suggestion activity check answer for quiet projects - #115038

Merged
trunk-io[bot] merged 1 commit into
masterfrom
posthog-self-driving/fixsignals-make-the-quiet-project-7c3132
Oct 11, 2026
Merged

trunk-io[bot] merged 1 commit into
masterfrom
posthog-self-driving/fixsignals-make-the-quiet-project-7c3132

Conversation

@posthog

@posthog posthog Bot commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

Problem

  • Quiet projects still get scheduled scout-suggestion scans that end empty, because the low-activity gate almost never skips them.
  • The activity read caps ClickHouse at max_rows_to_read = 100_000, which counts rows read, not rows that match the filter.
  • ClickHouse reads whole granules. A quiet project's 14-day window touches about one granule per part, and other teams' rows mostly fill those granules.
  • So a quiet project reads several hundred thousand rows, trips the guard with code 158, and the gate treats the capped read as active.
  • Nothing showed this, because a capped read and an answered read look the same downstream.

Closes #115035

Origin

  • Scout: a custom scout
  • First signal: 2026-10-11
  • Inbox report: open
  • Task started by: auto-start, after the report was rated P2 and ready to fix

Changes

  • The ClickHouse rows-read guard is now its own constant, ACTIVITY_READ_MAX_ROWS_READ = 5_000_000. Quiet projects finish the read and get exact numbers.
  • Busy projects still trip the guard and count as active. read_overflow_mode: throw and the capped-means-active rule stay.
  • ACTIVITY_READ_MAX_ROWS keeps only its role as the high bound for min_events_in_window.
  • Each planning tick now counts answered, capped and failed reads. The plan output, the coordinator output and the tick log carry the counts.
  • The tick log goes to warning level when more than half of the reads hit the guard.
  • The bounded inner LIMIT alternative from the issue was not used. It truncates the day spread and keeps the same expected-exception shape for busy projects.
- "max_rows_to_read": ACTIVITY_READ_MAX_ROWS,          # 100_000
+ "max_rows_to_read": ACTIVITY_READ_MAX_ROWS_READ,     # 5_000_000

Note

More quiet projects now get low_activity stamps instead of scans. That is the designed behavior from #104535. The thresholds (100 events, 3 active days) do not change.

How did you test this code?

Ran products/signals/backend/test/test_scout_suggestions.py locally against Postgres and ClickHouse, plus ruff and mypy on the two changed modules.

Test rationale:

  • Extended test_the_read_is_bounded_and_kept_off_the_interactive_cluster: fails if the guard goes back to the threshold constant. The existing capped-read cases already cover the code 158 path.
  • Added an events_clamped case to test_activity_knobs: fails if min_events_in_window clamps to the new guard instead of ACTIVITY_READ_MAX_ROWS.
  • Added test_each_read_outcome_is_counted: fails if a capped or failed read is counted as answered, which hides the original bug again. No existing test checks the counts.
  • Not checked: the production effect. A test database holds one small part, so no unit test reproduces the granule spread. After deploy, SignalsScoutSuggestionsActivityCheck reads in system.query_log should mostly end QueryFinish, and the tick logs should show mostly answered reads.

Release status

  • No feature flag controls this change

Docs update

None.

🤖 Agent context

Autonomy: Fully autonomous

Agent: PostHog Desktop (Claude Code), claude-opus-5-5

  • Skills invoked: /writing-tests, /writing-pr-descriptions.
  • Duplicate search found no open PR for this issue.
  • The work draws only on the public issue. No session material is in the diff.

🤖 Generated with Claude Code

Created with PostHog Desktop from this inbox report.

…t projects

Split the event-threshold clamp from the ClickHouse rows-read guard. The guard now sits at 5M rows read, because a quiet project's 14-day read touches shared granules in many parts and tripped the old 100K guard, so the gate treated it as active.

Count answered, capped and failed activity reads on each planning tick, log them, and log at warning level when most reads hit the guard.

Refs #115035

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Generated-By: PostHog Desktop
Task-Id: a13837de-1464-41e0-900b-0ee315911d7c
@posthog posthog Bot added the self-driving label Oct 11, 2026
@posthog
posthog Bot marked this pull request as ready for review October 11, 2026 11:51
@trunk-io

trunk-io Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

😎 Merged successfully - details.

@posthog

posthog Bot commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor Author

PostHog Review · Deep · reviewed fd86184

Nothing to post.

Step Status Result
Prepare the diff done 2 files, 1 chunk
Pick perspectives done 3 perspectives
Run review passes done 0 issues
Merge overlapping findings done 0 → 0
Validate findings done
Publish done Nothing to post

A happy dog on a sunny path

@parameterai

parameterai Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

Risk: No findings

This change raises the ClickHouse rows-read guard on the internal scout-suggestion activity check from 100k to 5M (so quiet projects get exact counts instead of tripping the guard), and adds per-outcome read counters to the selection result, Temporal plan/coordinator outputs, and tick log. The check's security posture is unchanged: the query stays parameterized and team-scoped, capped reads still count as active, and the per-read wall-clock cap remains. No security issues found.

Sentinel reviewed fd86184 · Review settings

@github-actions

github-actions Bot commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

🤖 CI report

⚠️ Trunk lane — backend Python lane

This PR is assigned to the backend Python lane. It runs backend Python tests and may merge in parallel with PRs in other lanes.

✅ Duplication (Python) — clean

New Python code duplication introduced by this branch. Fails at 70+ tokens in app code, or 150+ tokens when both copies live in test files. Advisory while the gate proves itself: extract a shared helper instead of copying.

✅ Duplication (TypeScript) — clean

New TypeScript code duplication introduced by this branch. Fails at 70+ tokens in app code, or 150+ tokens when both copies live in test files. Advisory while the gate proves itself: extract a shared helper instead of copying.

🚨 Comment density — 20% of added code lines are comments (15 of 75)

This section warns when comments are more than 3% of the code lines a PR adds, and alerts above 6%. Before agent-assisted PRs, the typical share was about 2%. Only full-line comments count. Docstrings, generated files, snapshots, migrations, and workflow files are left out.

Comments that restate the code, record how the change came about, or narrate the next line add noise for the next reader. Keep the comments that explain a reason the code cannot show, and remove the rest. See .agents/skills/writing-code-comments/SKILL.md for the house rules.

Files with the most added comment lines:

File Comment lines Added lines
products/signals/backend/scout_harness/suggestions.py 13 32
products/signals/backend/temporal/agentic/scout_suggestions.py 2 20

This check does not block merging. It updates on every push and clears when the share drops.

⚠️ Backend coverage — 90.0% of changed backend lines covered — 3 uncovered

🧪 Backend test coverage

Patch coverage — changed backend lines (products + core): ██████████████████░░ 90.0% (28 / 31)

File Patch Uncovered changed lines
products/signals/backend/temporal/agentic/scout_suggestions.py 66.7% 158, 161–162

🤖 Agents: add a test only if an uncovered line exposes a realistic regression that existing tests miss. Otherwise explain why no new test is needed under "How did you test this code?". Gap list: the patch-coverage artifact on this run (gh run download 121951255874275 -n patch-coverage), or the coverage-data block at the end of this comment.

Per-product line coverage (touched products)
Product Coverage Lines
platform_features ██░░░░░░░░░░░░░░░░░░ 12.1% 7 / 58
demo ███████████░░░░░░░░░ 55.9% 1,508 / 2,700
data_tools ████████████░░░░░░░░ 61.2% 90 / 147
warehouse_sources_queue █████████████░░░░░░░ 66.8% 1,921 / 2,875
aeo ███████████████░░░░░ 76.3% 617 / 809
batch_exports ████████████████░░░░ 80.1% 21,382 / 26,689
apm █████████████████░░░ 84.1% 1,306 / 1,553
mcp_analytics █████████████████░░░ 85.7% 4,844 / 5,651
ml_inference █████████████████░░░ 86.3% 524 / 607
warehouse_suggestions █████████████████░░░ 87.3% 2,252 / 2,580
posthog_ai ██████████████████░░ 87.7% 4,226 / 4,817
notebooks ██████████████████░░ 88.4% 15,201 / 17,196
today ██████████████████░░ 88.6% 2,866 / 3,233
cdp ██████████████████░░ 88.7% 5,081 / 5,729
mcp_registry ██████████████████░░ 89.0% 1,596 / 1,794
product_tours ██████████████████░░ 89.1% 1,337 / 1,500
dashboards ██████████████████░░ 89.5% 7,205 / 8,050
webmcp ██████████████████░░ 89.6% 240 / 268
cohorts ██████████████████░░ 89.6% 8,458 / 9,438
signals ██████████████████░░ 89.9% 68,515 / 76,200
data_modeling ██████████████████░░ 90.1% 10,856 / 12,043
ai_training ██████████████████░░ 90.4% 349 / 386
tasks ██████████████████░░ 90.6% 80,623 / 89,013
visual_review ██████████████████░░ 90.7% 9,842 / 10,856
data_warehouse ██████████████████░░ 90.8% 14,831 / 16,339
canvas ██████████████████░░ 90.9% 7,748 / 8,522
exports ██████████████████░░ 91.0% 9,698 / 10,663
business_knowledge ██████████████████░░ 91.0% 8,791 / 9,656
autoresearch ██████████████████░░ 91.1% 10,243 / 11,245
managed_warehouse ██████████████████░░ 91.2% 11,053 / 12,114
error_tracking ██████████████████░░ 91.6% 16,797 / 18,328
wizard ██████████████████░░ 91.8% 6,008 / 6,548
streamlit_apps ██████████████████░░ 91.8% 3,087 / 3,362
stamphog ██████████████████░░ 92.0% 8,243 / 8,964
conversations ██████████████████░░ 92.0% 29,714 / 32,284
managed_migrations ██████████████████░░ 92.5% 1,600 / 1,730
early_access_features ███████████████████░ 92.6% 1,339 / 1,446
alerts ███████████████████░ 92.9% 7,246 / 7,797
review_hog ███████████████████░ 93.0% 15,717 / 16,904
surveys ███████████████████░ 93.1% 6,626 / 7,118
web_analytics ███████████████████░ 93.1% 24,096 / 25,877
notifications ███████████████████░ 93.2% 1,152 / 1,236
approvals ███████████████████░ 93.4% 4,526 / 4,848
cross_project_dashboards ███████████████████░ 93.4% 880 / 942
slack_app ███████████████████░ 93.5% 14,854 / 15,882
context_layer ███████████████████░ 93.7% 3,409 / 3,640
marketing_analytics ███████████████████░ 93.8% 20,074 / 21,402
messaging ███████████████████░ 93.8% 4,468 / 4,762
billing_alerts ███████████████████░ 93.9% 2,090 / 2,226
customer_analytics ███████████████████░ 93.9% 26,079 / 27,773
mcp_store ███████████████████░ 93.9% 9,008 / 9,593
experiments ███████████████████░ 94.2% 33,676 / 35,760
ai_observability ███████████████████░ 94.2% 26,434 / 28,069
replay_vision ███████████████████░ 94.3% 29,048 / 30,807
legal_documents ███████████████████░ 94.3% 2,289 / 2,427
logs ███████████████████░ 94.5% 15,850 / 16,770
actions ███████████████████░ 94.6% 973 / 1,029
reminders ███████████████████░ 94.8% 760 / 802
endpoints ███████████████████░ 94.8% 9,333 / 9,847
growth ███████████████████░ 94.8% 11,268 / 11,880
skills ███████████████████░ 94.9% 7,049 / 7,431
annotations ███████████████████░ 95.0% 816 / 859
tracing ███████████████████░ 95.2% 3,631 / 3,815
data_catalog ███████████████████░ 95.5% 4,419 / 4,628
access_control ███████████████████░ 95.5% 7,779 / 8,143
product_analytics ███████████████████░ 95.7% 28,676 / 29,952
alerts_platform ███████████████████░ 95.8% 5,013 / 5,234
revenue_analytics ███████████████████░ 95.9% 1,878 / 1,959
data_quality ███████████████████░ 95.9% 8,569 / 8,933
feature_flags ███████████████████░ 96.2% 26,870 / 27,935
warehouse_sources ███████████████████░ 96.4% 453,908 / 470,920
security ███████████████████░ 96.7% 1,452 / 1,501
pulse ███████████████████░ 97.4% 2,023 / 2,078
metrics ████████████████████ 97.7% 4,406 / 4,509
analytics_platform ████████████████████ 98.0% 2,775 / 2,833
field_notes ████████████████████ 99.4% 172 / 173

Report-only. Patch coverage = changed backend lines covered vs origin/master. Sorted lowest first.
Known gaps: lines covered only by Temporal tests show as uncovered; core line numbers may drift if master changed the same file.

@pr-assigner-resolver-posthog
pr-assigner-resolver-posthog Bot requested a review from a team October 11, 2026 11:52

@stamphog stamphog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved.

Contained, reversible change with targeted tests and no open substantive review concerns. The read remains bounded on the offline workload; the verified Inbox provenance exempts the machine author from the bot-author rule.

Gate mechanics and policy version
Gate Result
prerequisites ✓ all clear
deny-list ✓ no deny categories matched
size ✓ 63L, 2F substantive, 90L/3F incl. docs/generated/snapshots — within ceiling
tier ✓ T1-agent / T1b-small (90L, 3F, single-area, fix)
stamphog 2.4.1 .stamphog/policy.yml @ fd86184 · reviewed head fd86184

@andrewm4894

Copy link
Copy Markdown
Member

/trunk merge

@trunk-io

trunk-io Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

Static Badge   Static Badge   Static Badge

View Full Report ↗︎ ⋅ Docs

@trunk-io
trunk-io Bot merged commit 00a19a8 into master Oct 11, 2026
@trunk-io
trunk-io Bot deleted the posthog-self-driving/fixsignals-make-the-quiet-project-7c3132 branch October 11, 2026 12:38
@deployment-status-posthog

deployment-status-posthog Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

Deploy status

Environment Status Deployed At Workflow
dev ✅ Deployed 2026-10-11 12:56 UTC Run
prod-us ✅ Deployed 2026-10-11 13:07 UTC Run
prod-eu ✅ Deployed 2026-10-11 13:09 UTC Run

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(signals): let the scout suggestion activity check answer for quiet projects

1 participant