fix(loops): accept event.action shorthand and show trigger events - #73094
Conversation
🦔 Hogbox preview · ✅ ready▶ Open the preview
commit |
|
😎 This pull request was merged. |
🤖 CI report✅ Bundle size — no changeUncompressed size of every built Total: 64.66 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.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 |
| 912 B | ../node_modules/.pnpm/ieee754@1.2.1/node_modules/ieee754/index.js |
| 789 B | src/scenes/ChunkLoadErrorBoundary.tsx |
| 762 B | src/index.tsx |
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx
| Size | File |
|---|---|
| 281.5 KiB | ../node_modules/.pnpm/posthog-js@1.407.1/node_modules/posthog-js/dist/rrweb.js |
| 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 |
| 236.0 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 226.1 KiB | ../node_modules/.pnpm/posthog-js@1.407.1/node_modules/posthog-js/dist/module.js |
| 167.1 KiB | src/queries/validators.js |
| 154.3 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 |
| 105.8 KiB | src/lib/api.ts |
| 94.0 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 |
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.18 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.18 MiB · 17 files | no change | ████░░░░░░ 38.1% of 5.72 MiB |
| Deferred (lazy) | 2.07 MiB · 33 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 |
|---|---|
| 713.8 KiB | dist/toolbar/toolbar-app-HY7HJI4V.css |
| 545.0 KiB | dist/toolbar/chunk-chunk-RQ4FN27S.js |
| 484.2 KiB | dist/toolbar/chunk-chunk-QS5AHYGW.js |
| 133.6 KiB | dist/toolbar/chunk-chunk-SYFILNLU.js |
| 131.8 KiB | dist/toolbar/chunk-chunk-T5KY5WYR.js |
| 71.0 KiB | dist/toolbar/toolbar-app-IWQPCR2K.js |
| 69.0 KiB | dist/toolbar/chunk-chunk-27JL52RE.js |
| 35.6 KiB | dist/toolbar/chunk-chunk-ZOYUTNIC.js |
| 20.9 KiB | dist/toolbar/chunk-chunk-IIQH4XLX.js |
| 12.2 KiB | dist/toolbar/chunk-chunk-PIK3PADE.js |
Posted automatically by check-toolbar-size · sizes are toolbar output bytes (shipped, post-tree-shake) from the esbuild metafile
✅ Dist folder size — 🔺 +717 B (+0.0%)
Total size of the built frontend/dist folder (all assets), compared against the base branch.
Total: 1357.64 MiB · 🔺 +717 B (+0.0%)
ℹ️ MCP UI apps size — 32 app(s), 17065.5 KB JS
Built size of each MCP UI app (main.js + styles.css).
| App | JS | CSS |
|---|---|---|
| debug | 599.5 KB | 187.7 KB |
| action | 457.8 KB | 187.7 KB |
| action-list | 564.3 KB | 187.7 KB |
| cohort | 456.8 KB | 187.7 KB |
| cohort-list | 563.3 KB | 187.7 KB |
| email-template | 456.6 KB | 187.7 KB |
| error-details | 472.4 KB | 187.7 KB |
| error-issue | 457.5 KB | 187.7 KB |
| error-issue-list | 564.2 KB | 187.7 KB |
| experiment | 561.5 KB | 187.7 KB |
| experiment-list | 565.1 KB | 187.7 KB |
| experiment-results | 563.2 KB | 187.7 KB |
| feature-flag | 567.1 KB | 187.7 KB |
| feature-flag-list | 570.9 KB | 187.7 KB |
| feature-flag-testing | 461.0 KB | 187.7 KB |
| insight-actors | 562.1 KB | 187.7 KB |
| invite-email-preview | 456.0 KB | 187.7 KB |
| llm-costs | 559.5 KB | 187.7 KB |
| session-recording | 458.6 KB | 187.7 KB |
| session-summary | 463.9 KB | 187.7 KB |
| survey | 458.4 KB | 187.7 KB |
| survey-global-stats | 562.2 KB | 187.7 KB |
| survey-list | 565.0 KB | 187.7 KB |
| survey-stats | 562.2 KB | 187.7 KB |
| trace-span | 457.2 KB | 187.7 KB |
| trace-span-list | 564.2 KB | 187.7 KB |
| workflow | 457.1 KB | 187.7 KB |
| workflow-list | 563.7 KB | 187.7 KB |
| loops-review | 461.2 KB | 187.7 KB |
| query-results | 745.5 KB | 187.7 KB |
| render-ui | 826.2 KB | 187.7 KB |
| visual-review-snapshots | 461.6 KB | 187.7 KB |
ℹ️ MCP snapshots — skipped stale run for 8b4d0d5
Skipped the snapshot commit because the branch advanced to 7ad67f3 while the workflow was testing 8b4d0d5.
The new commit will trigger its own snapshot update workflow. If a fresh run does not start, merge master or push an empty commit.
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 |
Prompt To Fix All With AIFix the following 1 code review issue. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 1
products/tasks/backend/presentation/serializers_loops.py:207-210
**Event-action associations are lost**
When a trigger contains shorthand for multiple event types, such as `issues.opened` and `pull_request.synchronize`, normalization merges both actions into one trigger-wide filter. This also accepts `issues.synchronize` and `pull_request.opened`, causing the loop to fire for webhook combinations that were not requested.
Reviews (1): Last reviewed commit: "show github trigger events in loop revie..." | Re-trigger Greptile |
There was a problem hiding this comment.
The fix correctly restricts the event.action shorthand to a single event per trigger, resolving the exact cross-event action-leak bug all three bot reviewers flagged; tests cover both the folding and the rejection cases, and the author (STRONG familiarity, owning team) plus three independent bot reviews provide assurance over this security-relevant trigger-matching logic.
- Author wrote 100% of the modified lines and has 10 merged PRs in these paths (familiarity STRONG).
- 👍 on the PR from greptile-apps[bot], hex-security-app[bot].
Gate mechanics and policy version
| Gate | Result | |
|---|---|---|
| prerequisites | ✓ | all clear |
| deny-list | ✓ | no deny categories matched |
| size | ✓ | 123L, 3F substantive, 963L/15F incl. docs/generated/snapshots — within ceiling |
| tier | ✓ | T1-agent / T1d-complex (963L, 15F, two-areas, fix) |
| stamphog 2.0.0b3 | .stamphog/policy.yml @ 24c0565 · reviewed head 873c3e8 |
Problem
Agents creating loops through MCP keep writing GitHub triggers as
events: ["issues.opened"], the GitHub Actions shorthand. The API only accepts bare webhook events with the action expressed as a filter, so creation fails with a validation error surfaced in the review card. Nothing in the tool schema told the agent which events are allowed, and the review card's Runs line only showed the repository, not which events fire the loop.Changes
event.actionshorthand into the bare event plus anactionsfilter, matching its existing tolerance for singular filter keys. Shorthand is limited to a single event per trigger and cannot mix with bare events: the foldedactionsfilter applies to every event in the trigger, so anything broader would fire event/action pairs nobody asked for.confighelp text now enumerates the allowed events and documents the shorthand. Regenerated the OpenAPI-derived schemas and MCP tool snapshots so the tool descriptions carry this.GitHub (posthog/code: issues opened)instead ofGitHub (posthog/code), including action, branch and label filters. No screenshot since the card renders inside MCP agent hosts; the output strings are asserted in the jest suite.products/tasks/docs/LOOPS*.md) from the repo.How did you test this code?
filters.actions, the singularactionalias) and for the rejections (unknown events, empty action suffix, shorthand mixed with bare events, shorthand spanning multiple events). The github trigger config validation had no API test coverage before. Fulltest_loops_api.pypasses locally on a fresh test database.tsgo --noEmitin services/mcp, are all clean.Automatic notifications
Docs update
N/A. The internal loops docs are removed from the repo in this PR.
🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Authored with Claude Code from a bug report of a failed loop creation. Normalizing at save time was chosen over only teaching the agent the right shape, because agents will keep reaching for GitHub's own
issues.openednotation. Review bots (veria, Greptile, Graphite) correctly flagged that the first cut flattened shorthand actions across different events, which would over-fire a credentialed loop; the follow-up commit restricts shorthand to one event per trigger instead of preserving per-event pairs, keeping the stored filter shape unchanged. The docs removal commit is by Charles directly.