feat(subscriptions): add AI report context contract - #91428
Conversation
|
Merging to
After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here |
🤖 CI report
|
| File | Size | Δ vs base |
|---|---|---|
posthog-app/src/scenes/AuthenticatedShell.js |
239.6 KiB | 🔺 +25.1 KiB (+11.7%) |
posthog-app/src/scenes/experiments/Experiment.js |
275.1 KiB | 🔺 +5.3 KiB (+2.0%) |
Posted automatically by build-bundle-size-report · uncompressed bytes from dist-report
✅ Eager graph — within budget
How much code each root ships on the eager path — downloaded and parsed before the surface is interactive. Measured from the esbuild output chunks (post-tree-shake, static imports only); lazy import() / React.lazy chunks are not counted.
| Root | Eager (shipped) | Δ vs base | Budget |
|---|---|---|---|
entry (logged-out pages, app bootstrap)src/index.tsx |
1.50 MiB · 22 files | 🟢 -22 B (-0.0%) | ███░░░░░░░ 33.2% of 4.51 MiB |
logged-out boot: index + App + bootApp (preloaded by every page, including /login)src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts |
5.24 MiB · 668 files | 🔺 +199 B (+0.0%) | █████████░ 93.1% of 5.63 MiB |
authenticated shell (every logged-in page)src/scenes/AuthenticatedShell.tsx |
7.66 MiB · 2,677 files | 🟢 -549 B (-0.0%) | █████████░ 87.3% of 8.77 MiB |
🟢 node_modules/monaco-editor/ stays out of src/index.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/index.tsx
🟢 [object Object] stays out of src/index.tsx
🟢 [object Object] stays out of src/index.tsx
🟢 node_modules/monaco-editor/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/layout/navigation-3000/navigationLogic.tsx stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/scenes/dashboard/dashboardLogic.tsx stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 node_modules/monaco-editor/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/scenes/AuthenticatedShell.tsx
🟢 [object Object] stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/scenes/session-recordings/player/sessionRecordingPlayerLogic.ts stays out of src/scenes/AuthenticatedShell.tsx
🟢 [object Object] stays out of src/scenes/AuthenticatedShell.tsx
🟢 [object Object] stays out of src/scenes/AuthenticatedShell.tsx
Largest files eagerly shipped from src/index.tsx
| Size | File |
|---|---|
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 24.6 KiB | ../node_modules/.pnpm/buffer@6.0.3/node_modules/buffer/index.js |
| 6.3 KiB | ../node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react.production.min.js |
| 4.5 KiB | ../node_modules/.pnpm/@jspm+core@2.1.0/node_modules/@jspm/core/nodelibs/browser/process.js |
| 3.9 KiB | ../node_modules/.pnpm/scheduler@0.23.2/node_modules/scheduler/cjs/scheduler.production.min.js |
| 1.4 KiB | ../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js |
| 1.3 KiB | src/RootErrorBoundary.tsx |
| 1.0 KiB | src/index.tsx |
| 912 B | ../node_modules/.pnpm/ieee754@1.2.1/node_modules/ieee754/index.js |
| 854 B | src/scenes/ChunkLoadErrorBoundary.tsx |
Largest files eagerly shipped from src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
| Size | File |
|---|---|
| 281.8 KiB | ../node_modules/.pnpm/posthog-js@1.428.6_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs |
| 267.7 KiB | ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js |
| 255.4 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 104.2 KiB | src/lib/api.ts |
| 79.0 KiB | src/products.tsx |
| 68.8 KiB | src/lib/lemon-ui/icons/icons.tsx |
| 62.8 KiB | src/lib/utils/eventUsageLogic.ts |
| 38.8 KiB | ../node_modules/.pnpm/@dnd-kit+core@6.0.8_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@dnd-kit/core/dist/core.esm.js |
| 33.9 KiB | ../node_modules/.pnpm/kea@4.0.0-pre.6_patch_hash=139b8d1f1304f9d9da452a9a1244c94ea679dbcb85687d8999563146879fb6f5_react@18.3.1/node_modules/kea/lib/index.cjs.js |
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx
| Size | File |
|---|---|
| 281.8 KiB | ../node_modules/.pnpm/posthog-js@1.428.6_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs |
| 267.7 KiB | ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js |
| 255.4 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 153.8 KiB | ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js |
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 104.2 KiB | src/lib/api.ts |
| 95.8 KiB | ../packages/quill/packages/quill/dist/index.js |
| 93.3 KiB | ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js |
| 90.6 KiB | ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js |
| 79.0 KiB | src/products.tsx |
Posted automatically by check-eager-graph · sizes are eager output bytes (shipped, post-tree-shake) from the esbuild metafile · part of #32479
✅ Toolbar bundle — eager 2.29 MiB within budget
What the toolbar ships to customer pages, measured from the esbuild output (minified, post-tree-shake). The eager set is the entry plus everything statically imported from it — fetched before any feature runs; deferred chunks load lazily. The eager guardrail is 5.72 MiB. Each output file must also stay below 10 MB, where CloudFront stops compressing it. The module boundary is enforced separately by check-toolbar-graph.
| Metric | Size | Δ vs base | Budget |
|---|---|---|---|
| Eager (shipped) entry + static imports |
2.29 MiB · 18 files | no change | ████░░░░░░ 40.0% of 5.72 MiB |
| Deferred (lazy) | 2.11 MiB · 45 files | no change | n/a — loads on demand |
Loader dist/toolbar.js |
1.1 KiB | no change | █░░░░░░░░░ 5.8% of 19.5 KiB |
Largest eagerly-shipped chunks
| Size | File |
|---|---|
| 756.4 KiB | dist/toolbar/toolbar-app-LA4JX7FS.css |
| 608.8 KiB | dist/toolbar/chunk-chunk-P3PF5T4P.js |
| 484.7 KiB | dist/toolbar/chunk-chunk-RPV3NYRJ.js |
| 136.6 KiB | dist/toolbar/chunk-chunk-6MQWLXON.js |
| 131.8 KiB | dist/toolbar/chunk-chunk-FDH2IBXT.js |
| 72.2 KiB | dist/toolbar/toolbar-app-VLT4VAGU.js |
| 69.0 KiB | dist/toolbar/chunk-chunk-TSAL54PB.js |
| 35.6 KiB | dist/toolbar/chunk-chunk-DTB5C7AH.js |
| 21.0 KiB | dist/toolbar/chunk-chunk-35CVENAR.js |
| 6.8 KiB | dist/toolbar/chunk-chunk-DV7IWQNF.js |
Posted automatically by check-toolbar-size · sizes are toolbar output bytes (shipped, post-tree-shake) from the esbuild metafile
✅ Dist folder size — 🔺 +222.6 KiB (+0.0%)
Total size of the built frontend/dist folder (all assets), compared against the base branch.
Total: 1458.39 MiB · 🔺 +222.6 KiB (+0.0%)
ℹ️ MCP UI apps size — 33 app(s), 17665.2 KB JS
Built size of each MCP UI app (main.js + styles.css).
| App | JS | CSS |
|---|---|---|
| debug | 600.0 KB | 195.2 KB |
| action | 458.2 KB | 195.2 KB |
| action-list | 564.9 KB | 195.2 KB |
| cohort | 457.2 KB | 195.2 KB |
| cohort-list | 563.8 KB | 195.2 KB |
| email-template | 457.0 KB | 195.2 KB |
| error-details | 472.9 KB | 195.2 KB |
| error-issue | 457.9 KB | 195.2 KB |
| error-issue-list | 564.7 KB | 195.2 KB |
| experiment | 562.0 KB | 195.2 KB |
| experiment-list | 565.6 KB | 195.2 KB |
| experiment-results | 567.1 KB | 195.2 KB |
| feature-flag | 567.6 KB | 195.2 KB |
| feature-flag-list | 571.4 KB | 195.2 KB |
| feature-flag-testing | 461.4 KB | 195.2 KB |
| inline-scan | 457.7 KB | 195.2 KB |
| insight-actors | 563.0 KB | 195.2 KB |
| invite-email-preview | 456.4 KB | 195.2 KB |
| llm-costs | 560.0 KB | 195.2 KB |
| session-recording | 459.0 KB | 195.2 KB |
| survey | 458.8 KB | 195.2 KB |
| survey-global-stats | 562.7 KB | 195.2 KB |
| survey-list | 565.5 KB | 195.2 KB |
| survey-stats | 562.7 KB | 195.2 KB |
| trace-span | 457.6 KB | 195.2 KB |
| trace-span-list | 564.7 KB | 195.2 KB |
| vision-observation-list | 563.9 KB | 195.2 KB |
| workflow | 457.5 KB | 195.2 KB |
| workflow-list | 564.2 KB | 195.2 KB |
| loops-review | 461.9 KB | 195.2 KB |
| query-results | 756.3 KB | 195.2 KB |
| render-ui | 839.5 KB | 195.2 KB |
| visual-review-snapshots | 462.0 KB | 195.2 KB |
⚠️ Backend coverage — 96.0% of changed backend lines covered — 20 uncovered
🧪 Backend test coverage
Patch coverage — changed backend lines (products + core): ███████████████████░ 96.0% (590 / 610)
| File | Patch | Uncovered changed lines |
|---|---|---|
products/exports/backend/models/subscription.py |
58.1% | 52–53, 57–58, 258–259, 583, 585–588, 590–591 |
products/exports/backend/models/subscription_context.py |
81.1% | 29–30, 35–36, 41, 44, 53 |
🤖 Agents: add a test covering the lines above, or note why under "How did you test this code?". Machine-readable gap list: the patch-coverage artifact on this run (gh run download 34262828335 -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 |
warehouse_sources_queue |
██████░░░░░░░░░░░░░░ 29.1% |
92 / 316 |
data_tools |
████████████░░░░░░░░ 62.1% |
90 / 145 |
demo |
████████████░░░░░░░░ 62.1% |
1,658 / 2,671 |
ai_gateway |
███████████████░░░░░ 75.0% |
9 / 12 |
batch_exports |
████████████████░░░░ 79.9% |
19,473 / 24,368 |
apm |
█████████████████░░░ 83.3% |
1,234 / 1,481 |
wizard |
█████████████████░░░ 85.3% |
2,779 / 3,259 |
cdp |
█████████████████░░░ 85.4% |
4,349 / 5,094 |
signals |
█████████████████░░░ 85.5% |
36,471 / 42,645 |
product_tours |
██████████████████░░ 88.0% |
1,312 / 1,491 |
notebooks |
██████████████████░░ 88.5% |
11,879 / 13,429 |
data_warehouse |
██████████████████░░ 88.9% |
12,824 / 14,424 |
business_knowledge |
██████████████████░░ 89.2% |
4,469 / 5,008 |
cohorts |
██████████████████░░ 89.3% |
7,565 / 8,468 |
dashboards |
██████████████████░░ 89.6% |
6,837 / 7,631 |
engineering_analytics |
██████████████████░░ 90.1% |
8,391 / 9,310 |
tasks |
██████████████████░░ 90.3% |
66,287 / 73,399 |
data_modeling |
██████████████████░░ 90.4% |
9,350 / 10,347 |
streamlit_apps |
██████████████████░░ 90.7% |
2,619 / 2,889 |
exports |
██████████████████░░ 90.7% |
9,245 / 10,189 |
managed_warehouse |
██████████████████░░ 90.7% |
9,417 / 10,378 |
alerts |
██████████████████░░ 90.9% |
5,242 / 5,765 |
links |
██████████████████░░ 91.0% |
192 / 211 |
mcp_analytics |
██████████████████░░ 91.2% |
4,411 / 4,837 |
conversations |
██████████████████░░ 91.3% |
21,777 / 23,859 |
canvas |
██████████████████░░ 91.3% |
5,033 / 5,514 |
visual_review |
██████████████████░░ 91.7% |
7,567 / 8,250 |
error_tracking |
██████████████████░░ 92.0% |
13,495 / 14,669 |
notifications |
██████████████████░░ 92.5% |
1,120 / 1,211 |
early_access_features |
███████████████████░ 92.6% |
1,331 / 1,438 |
managed_migrations |
███████████████████░ 92.7% |
1,576 / 1,700 |
slack_app |
███████████████████░ 92.7% |
12,684 / 13,676 |
surveys |
███████████████████░ 93.1% |
6,180 / 6,640 |
mcp_registry |
███████████████████░ 93.2% |
1,471 / 1,578 |
web_analytics |
███████████████████░ 93.3% |
19,324 / 20,706 |
stamphog |
███████████████████░ 93.4% |
6,543 / 7,009 |
context_layer |
███████████████████░ 93.4% |
2,615 / 2,801 |
mcp_store |
███████████████████░ 93.5% |
8,063 / 8,621 |
reminders |
███████████████████░ 93.5% |
477 / 510 |
marketing_analytics |
███████████████████░ 93.5% |
17,452 / 18,657 |
posthog_ai |
███████████████████░ 93.6% |
1,395 / 1,491 |
ai_observability |
███████████████████░ 93.8% |
18,255 / 19,463 |
approvals |
███████████████████░ 93.9% |
3,570 / 3,803 |
billing_alerts |
███████████████████░ 94.1% |
2,079 / 2,210 |
endpoints |
███████████████████░ 94.2% |
9,072 / 9,627 |
review_hog |
███████████████████░ 94.3% |
10,214 / 10,826 |
tracing |
███████████████████░ 94.5% |
2,726 / 2,885 |
legal_documents |
███████████████████░ 94.7% |
2,082 / 2,199 |
workflows |
███████████████████░ 94.7% |
11,801 / 12,455 |
autoresearch |
███████████████████░ 95.0% |
934 / 983 |
customer_analytics |
███████████████████░ 95.1% |
19,308 / 20,303 |
annotations |
███████████████████░ 95.3% |
804 / 844 |
product_analytics |
███████████████████░ 95.3% |
19,340 / 20,292 |
actions |
███████████████████░ 95.4% |
749 / 785 |
replay_vision |
███████████████████░ 95.5% |
22,817 / 23,886 |
skills |
███████████████████░ 95.6% |
5,536 / 5,791 |
experiments |
███████████████████░ 95.6% |
30,259 / 31,643 |
feature_flags |
███████████████████░ 95.7% |
20,361 / 21,270 |
access_control |
███████████████████░ 95.8% |
6,293 / 6,572 |
messaging |
███████████████████░ 95.9% |
3,680 / 3,839 |
growth |
███████████████████░ 96.0% |
7,728 / 8,053 |
logs |
███████████████████░ 96.0% |
13,950 / 14,532 |
revenue_analytics |
███████████████████░ 96.3% |
1,841 / 1,911 |
user_interviews |
███████████████████░ 96.5% |
2,651 / 2,747 |
warehouse_sources |
███████████████████░ 97.2% |
409,791 / 421,671 |
data_quality |
████████████████████ 97.6% |
4,229 / 4,335 |
analytics_platform |
████████████████████ 98.2% |
2,381 / 2,425 |
metrics |
████████████████████ 98.2% |
3,576 / 3,640 |
data_catalog |
████████████████████ 98.4% |
3,268 / 3,322 |
pulse |
████████████████████ 98.4% |
2,028 / 2,060 |
live_debugger |
████████████████████ 99.2% |
621 / 626 |
field_notes |
████████████████████ 99.4% |
167 / 168 |
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.
⚠️ Django migration SQL — 2 new migrations to review
We've detected new migrations on this PR. Review the SQL output for each migration:
products/exports/backend/migrations/0012_subscription_context.py
-- sqlmigrate failed for this migration (see the Validate migrations job log)products/exports/backend/migrations/0013_validate_subscription_context_team_fk.py
-- sqlmigrate failed for this migration (see the Validate migrations job log)Last updated: 2026-09-08 18:29 UTC (4526025)
✅ Django migration risk — migration analysis complete
We've analyzed your migrations for potential risks.
Summary: 0 Safe | 2 Needs Review | 0 Blocked
⚠️ Needs Review
May have performance impact
exports.0012_subscription_context
└─ #1 ⚠️ AddField
Adding NOT NULL field with callable default (list) - verify it's stable
model: subscriptiondelivery, field: context_refs, default: list
└─ #2 ✅ CreateModel
Creating new table is safe
model: SubscriptionContext
└─ #3 ⚠️ AddForeignKeyNotValid: Unknown operation type: AddForeignKeyNotValid
│
└──> ℹ️ INFO:
ℹ️ Skipped operations on newly created tables (empty tables
don't cause lock contention).
exports.0013_validate_subscription_context_team_fk
└─ #1 ⚠️ ValidateForeignKey: Unknown operation type: ValidateForeignKey
Last updated: 2026-09-08 18:29 UTC (4526025)
✅ ClickHouse migration SQL — none
No ClickHouse migrations in the latest push.
|
✅ Visual changes approved by @vdekrijger — baseline updated in 6 new. |
c0fe275 to
733a6d8
Compare
2cc97ae to
7d9c00a
Compare
4ee9f23 to
eb7358a
Compare
eb7358a to
275ce18
Compare
🦔 Hogbox preview · ✅ ready▶ Open the preview
commit |
👀 Auto-assigned reviewersThese soft owners were skipped because they only have minor changes here. Nothing blocks merge, so self-assign if you'd like a look:
Soft owners come from each directory's |
|
🦔 PostHog Review reviewed this pull requestFound 1 must fix, 2 should fix, 2 consider. Published 5 findings (view the review). Resolved comments: 1 fixed, 4 left for you · couldn't handle 1 |
|
PostHog Review alpha 🦔 If you find any issues helpful - please reply "valid", "invalid", etc., for evaluation purposes 🙏 |
The new NOT NULL column had no Postgres default, so a worker still running
the previous image would omit it from its delivery INSERT and hit a
not-null violation until the rollout finished.
db_default lands a real `DEFAULT '{}'` on the column, and sqlmigrate
confirms Django no longer drops it after the ADD COLUMN.
Generated-By: PostHog Desktop
Task-Id: fc7c7475-0a06-4402-bc90-120e90bd5039
PR overviewAll previously flagged issues have been addressed. No open security concerns remain on this pull request. Security reviewNo open security issues remain on this pull request. Fixed/addressed: 1 · PR risk: 0/10 |
The blocked-tile subquery returns one row per tile. That was free while it only fed IN clauses, which semi-join duplicates away, but the new context-ref array repeats a dashboard reference once per blocked tile on it. Adding distinct caps that array at the team's dashboard count. The rows the filter admits are unchanged: IN ignores duplicates, and so does array overlap. Generated-By: PostHog Desktop Task-Id: fc7c7475-0a06-4402-bc90-120e90bd5039
Problem
People creating AI report subscriptions cannot save dashboards or insights as trusted context for later report generation.
This base layer defines the contract. #91787 adds execution, and #91788 adds the UI.
Changes
How did you test this code?
👉 Stay up-to-date with PostHog coding conventions for a smoother review.
Automatic notifications
Docs update
No public docs update. This contract is not user-visible until the final stack layer.
🤖 Agent context
Autonomy: Human-driven (agent-assisted)
/django-migrations,/improving-drf-endpoints,/adopting-generated-api-types,/implementing-mcp-tools,/writing-tests,/running-ci-preflight,/writing-pr-descriptions, and/stacking-prs.