Repository navigation
Conversation
🤖 CI report✅ Complexity (TypeScript) — cleanCyclomatic complexity above the limit in changed typescript files (10 for production files, 15 for test files). Warn only: worth simplifying when you next touch these functions. ✅ Bundle size — no changeUncompressed size of every built Total: 76.62 MiB · no change No file changed by more than 1000 B. Posted automatically by build-bundle-size-report · uncompressed bytes from dist-report ✅ Eager graph — within budgetHow 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
🟢 Largest files eagerly shipped from
|
| 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.7 KiB | ../node_modules/.pnpm/@jspm+core@2.1.0/node_modules/@jspm/core/nodelibs/browser/process.js |
| 4.0 KiB | ../node_modules/.pnpm/scheduler@0.23.2/node_modules/scheduler/cjs/scheduler.production.min.js |
| 1.7 KiB | ../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js |
| 1.6 KiB | src/index.tsx |
| 1.3 KiB | src/lib/utils/bootTiming.ts |
| 1.2 KiB | src/RootErrorBoundary.tsx |
| 949 B | src/scenes/ChunkLoadErrorBoundary.tsx |
Largest files eagerly shipped from src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
| Size | File |
|---|---|
| 322.5 KiB | ../node_modules/.pnpm/posthog-js@1.438.21_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs |
| 215.9 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 |
| 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 |
| 99.8 KiB | src/products.tsx |
| 86.2 KiB | src/lib/api.ts |
| 68.2 KiB | src/lib/lemon-ui/icons/icons.tsx |
| 41.9 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 |
| 36.4 KiB | ../node_modules/.pnpm/kea@4.0.0-pre.6_patch_hash=139b8d1f1304f9d9da452a9a1244c94ea679dbcb85687d8999563146879fb6f5_react@18.3.1/node_modules/kea/lib/index.cjs.js |
| 27.0 KiB | ../node_modules/.pnpm/tailwind-merge@2.2.2/node_modules/tailwind-merge/dist/bundle-mjs.mjs |
| 24.6 KiB | ../node_modules/.pnpm/buffer@6.0.3/node_modules/buffer/index.js |
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx
| Size | File |
|---|---|
| 322.5 KiB | ../node_modules/.pnpm/posthog-js@1.438.21_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs |
| 285.9 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 239.8 KiB | ../packages/quill/packages/quill/dist/index.js |
| 215.9 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 |
| 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 |
| 99.8 KiB | src/products.tsx |
| 94.5 KiB | ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js |
| 92.5 KiB | ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js |
| 86.2 KiB | src/lib/api.ts |
Largest files eagerly shipped from src/scenes/dashboard/Dashboard.tsx
| Size | File |
|---|---|
| 322.5 KiB | ../node_modules/.pnpm/posthog-js@1.438.21_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs |
| 285.9 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 239.8 KiB | ../packages/quill/packages/quill/dist/index.js |
| 215.9 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 |
| 153.8 KiB | ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js |
| 144.1 KiB | ../packages/quill/packages/primitives/dist/index.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 |
| 99.8 KiB | src/products.tsx |
| 94.5 KiB | ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js |
| 92.5 KiB | ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js |
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
| Size | File |
|---|---|
| 322.5 KiB | ../node_modules/.pnpm/posthog-js@1.438.21_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs |
| 285.9 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 239.8 KiB | ../packages/quill/packages/quill/dist/index.js |
| 215.9 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 |
| 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 |
| 99.8 KiB | src/products.tsx |
| 94.5 KiB | ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js |
| 92.5 KiB | ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js |
| 86.2 KiB | src/lib/api.ts |
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx
| Size | File |
|---|---|
| 322.5 KiB | ../node_modules/.pnpm/posthog-js@1.438.21_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs |
| 285.9 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 239.8 KiB | ../packages/quill/packages/quill/dist/index.js |
| 215.9 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 |
| 153.8 KiB | ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js |
| 144.1 KiB | ../packages/quill/packages/primitives/dist/index.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 |
| 99.8 KiB | src/products.tsx |
| 94.5 KiB | ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js |
| 92.5 KiB | ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js |
Largest files eagerly shipped from src/scenes/activity/explore/EventsScene.tsx
| Size | File |
|---|---|
| 322.5 KiB | ../node_modules/.pnpm/posthog-js@1.438.21_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs |
| 285.9 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 239.8 KiB | ../packages/quill/packages/quill/dist/index.js |
| 215.9 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 |
| 153.8 KiB | ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js |
| 144.1 KiB | ../packages/quill/packages/primitives/dist/index.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 |
| 99.8 KiB | src/products.tsx |
| 94.5 KiB | ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js |
| 92.5 KiB | ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js |
Largest files eagerly shipped from src/scenes/web-analytics/WebAnalyticsScene.tsx
| Size | File |
|---|---|
| 322.5 KiB | ../node_modules/.pnpm/posthog-js@1.438.21_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs |
| 285.9 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 239.8 KiB | ../packages/quill/packages/quill/dist/index.js |
| 215.9 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 |
| 182.9 KiB | src/queries/validators.js |
| 153.8 KiB | ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js |
| 144.1 KiB | ../packages/quill/packages/primitives/dist/index.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 |
| 99.8 KiB | src/products.tsx |
| 94.5 KiB | ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js |
Largest files eagerly shipped from src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
| Size | File |
|---|---|
| 322.5 KiB | ../node_modules/.pnpm/posthog-js@1.438.21_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs |
| 316.1 KiB | ../node_modules/.pnpm/posthog-js@1.438.21_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/rrweb.js |
| 285.9 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 239.8 KiB | ../packages/quill/packages/quill/dist/index.js |
| 215.9 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 |
| 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 |
| 99.8 KiB | src/products.tsx |
| 94.5 KiB | ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js |
| 92.5 KiB | ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js |
Posted automatically by check-eager-graph · sizes are eager output bytes (shipped, post-tree-shake) from the esbuild metafile · part of PostHog#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 · 40 files | no change | n/a — loads on demand |
Loader dist/toolbar.js |
1.2 KiB | no change | █░░░░░░░░░ 6.0% of 19.5 KiB |
Largest eagerly-shipped chunks
| Size | File |
|---|---|
| 902.2 KiB | dist/toolbar/toolbar-app-PUACMHS6.css |
| 692.2 KiB | dist/toolbar/chunk-chunk-QQQ5YJLC.js |
| 260.7 KiB | dist/toolbar/chunk-chunk-L6XVLVLY.js |
| 131.8 KiB | dist/toolbar/chunk-chunk-FDH2IBXT.js |
| 130.4 KiB | dist/toolbar/chunk-chunk-BIOZUYB7.js |
| 74.8 KiB | dist/toolbar/toolbar-app-3H3VSIEG.js |
| 69.0 KiB | dist/toolbar/chunk-chunk-TSAL54PB.js |
| 35.6 KiB | dist/toolbar/chunk-chunk-EIARHJWB.js |
| 21.7 KiB | dist/toolbar/chunk-chunk-JR4YE4FS.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 — 🔺 +150 B (+0.0%)
Total size of the built frontend/dist folder (all assets), compared against the base branch.
Total: 964.92 MiB · 🔺 +150 B (+0.0%)
ℹ️ MCP UI apps size — 34 app(s), 27969.1 KB JS
Built size of each MCP UI app (main.js + styles.css).
| App | JS | CSS |
|---|---|---|
| debug | 844.3 KB | 209.1 KB |
| action | 767.7 KB | 209.1 KB |
| action-list | 835.3 KB | 209.1 KB |
| cohort | 766.7 KB | 209.1 KB |
| cohort-list | 834.3 KB | 209.1 KB |
| email-template | 766.6 KB | 209.1 KB |
| error-details | 771.6 KB | 209.1 KB |
| error-issue | 768.9 KB | 209.1 KB |
| error-issue-list | 836.7 KB | 209.1 KB |
| experiment | 832.4 KB | 209.1 KB |
| experiment-list | 836.1 KB | 209.1 KB |
| experiment-results | 834.9 KB | 209.1 KB |
| feature-flag | 834.7 KB | 209.1 KB |
| feature-flag-list | 838.4 KB | 209.1 KB |
| feature-flag-testing | 770.0 KB | 209.1 KB |
| inline-scan | 767.2 KB | 209.1 KB |
| insight-actors | 833.8 KB | 209.1 KB |
| llm-costs | 831.1 KB | 209.1 KB |
| session-recording | 768.9 KB | 209.1 KB |
| survey | 768.3 KB | 209.1 KB |
| survey-global-stats | 831.1 KB | 209.1 KB |
| survey-list | 836.0 KB | 209.1 KB |
| survey-stats | 831.1 KB | 209.1 KB |
| trace-span | 767.1 KB | 209.1 KB |
| trace-span-list | 835.2 KB | 209.1 KB |
| vision-observation-list | 834.4 KB | 209.1 KB |
| workflow | 767.0 KB | 209.1 KB |
| workflow-list | 834.7 KB | 209.1 KB |
| workflow-setup-status | 766.7 KB | 209.1 KB |
| query-results | 1086.5 KB | 209.1 KB |
| render-ui | 1162.4 KB | 209.1 KB |
| visual-review-snapshots | 771.6 KB | 209.1 KB |
| workflow-data-suggestions | 769.4 KB | 209.1 KB |
| workflow-sending-rules | 768.0 KB | 209.1 KB |
ℹ️ MCP agent API — agent-facing tool changes
What this PR changes for agents, from the tool schema snapshots and tool definitions.
Tools changed (1):
| Tool | Params | Scopes | Annotations | Schema chars |
|---|---|---|---|---|
workflows-send-email |
description changed |
c4fc6e3 to
c55794e
Compare
a02de53 to
54de7cd
Compare
49cab17 to
24881fa
Compare
54de7cd to
f9c45be
Compare
24881fa to
801bdfc
Compare
e70cb46 to
79e619b
Compare
a5d494f to
1d7fe4c
Compare
79e619b to
ad8792b
Compare
1d7fe4c to
0eeb308
Compare
ad8792b to
c4c5ff0
Compare
0eeb308 to
25f064a
Compare
c4c5ff0 to
67987fd
Compare
25f064a to
0f434a3
Compare
67987fd to
c6e5910
Compare
0f434a3 to
f3b92ce
Compare
c6e5910 to
688eba5
Compare
A code send without `from` now tells cdp-api its sender is the project's default (`from.isDefault`). cdp-api keys an Idempotency-Key retry on the sender the caller chose, so a retry after the default sender changed replays the first send instead of answering that the key was reused. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
f3b92ce to
1c8455d
Compare
688eba5 to
303f239
Compare
…oute-idempotency Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…oute-idempotency Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…oute-idempotency Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…oute-idempotency Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Moved to PostHog#127182. |
Part of the code-first rebuild of the email send stack; replaces parts of PostHog#121867 (one send per idempotency key on
send/email/).Problem
422 idempotency_key_reused, and the first send's answer is lost.Impact
Pays into Grow Workflows through billed
workflows_emailsactions per paying org: a retry with the same key replays instead of failing. In scope: Messaging, email API sends.Merge Danger
Note
🟢 Merge risk: low · two-way door: a revert keys a default-sender send on the resolved sender again
send/email/only, behindworkflows-email-from-code. Template sends keep the template's sender.Changes
fromreplays after the project's default sender changed. Django marks the sender it resolved as the project default (send.from.isDefault), and cdp-api leaves it out of the key.fromkeys on that address, as before.replayedanswer and the422and409refusals are master's, unchanged.How did you test this code?
Test seams:
send/email/through the DRF client, asserting the body posted to cdp-api (test_transactional_email.py).Test rationale: the code-send rows that compare the whole
senddict now expectisDefault: truewithoutfrom, and no marker with one. A marker that is missing, or set on a named sender, fails them.Proofs on this head
1fa81ec(saved withfleet proof):f9abed0, maildev as the sink. 21 requests through the public API. The same Idempotency-Key on a code send answersreplayed: truewith one email.503 delivery_unavailable, nothing reaches maildev, and nothing goes out twice. The node stack deploys first.Earlier live run, 2026-10-31
Live run, 2026-10-31. Django at the top of the stack (
3a30f51c529), cdp-api and both CDP workers at feat(cdp): send a template from the workflow version Django graded #584 (f9abed0841c), mail caught in maildev.fromsender@example.comother@example.com, then resend the same key and bodyreplayed: truewith the same id, one email in totalfromother@example.comreplayed: true, one emailProd shape: a gap until read-only production access exists on 2026-11-02.
CI: the fork has no Depot runners, so those jobs never start.
Semgrep Checks Passfails on every fork PR, because its path filter job runs only for the PostHog owner; semgrep with the repo's rules passes locally on the changed files. The lane check reportscross_lane=false.Release status
Docs update
None.
🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Agent: Claude Code, Claude Opus 5.5 (claude-opus-5-5)
dj3of map Map: send code-managed email templates with one PostHog call #461 onto master's idempotency store, on feat(messaging): point a sender refusal at the from a send names #579 atf3b92ce. One GPT-6.1 Sol review round found nothing.qa-swarm,modernize-pr,tdd,writing-tests,pr-description,writing-pr-descriptions.PIPELINE_REFUSALSdecoderInvolvement: one brief with Michael's shrink decision; one review round (GPT-6.1 Sol) with no findings; QA swarm on 2026-11-01 with one panel round (GPT-6.1 Sol review, Opus 5.5 fresh eyes): 1 finding fixed by running the owed proofs; later changes are merges from below; live, shadow-diff and cross-version proof captured.
🤖 Generated with Claude Code