[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-posthog-signals-scout-flag-debt":3,"mdc--ri5yvv-key":39,"related-org-posthog-signals-scout-flag-debt":514,"related-repo-posthog-signals-scout-flag-debt":696},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":23,"repoUrl":24,"updatedAt":25,"license":26,"forks":27,"topics":28,"repo":34,"sourceUrl":37,"mdContent":38},"signals-scout-flag-debt","identify and remove stale feature flags","Finds feature flags whose decision is over but which are still evaluated in production – terminal rollouts left in place, or keys that no longer appear in any connected repo.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},"posthog","PostHog","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fposthog.png",[12,16,17,20],{"name":13,"slug":14,"type":15},"Observability","observability","tag",{"name":9,"slug":8,"type":15},{"name":18,"slug":19,"type":15},"Feature Flags","feature-flags",{"name":21,"slug":22,"type":15},"Tech Debt","tech-debt",1091,"https:\u002F\u002Fgithub.com\u002FPostHog\u002Fposthog.com","2026-08-10T04:45:50.019808",null,856,[29,30,31,32,8,33],"design","docs","gatsby","handbook","tailwindcss",{"repoUrl":24,"stars":23,"forks":27,"topics":35,"description":36},[29,30,31,32,8,33],"Official docs, website, and handbook for PostHog.","https:\u002F\u002Fgithub.com\u002FPostHog\u002Fposthog.com\u002Ftree\u002FHEAD\u002Fcontents\u002Fpocket-guides\u002Fself-driving\u002Fflag-debt","---\nname: signals-scout-flag-debt\ndescription: >\n  Finds feature flags whose decision is over but which are still evaluated in production –\n  terminal rollouts left in place, or keys that no longer appear in any connected repo.\nallowed_tools:\n  - emit_report\n  - edit_report\n---\n\n# Feature flag debt\n\nFind flags whose decision is over while something is still evaluating them.\n\nNarrower than `signals-scout-feature-flags`, which watches the whole flag surface – evaluation\ncliffs, ghost keys, response-distribution shifts, flag debt – from PostHog data alone. This one\nadds the half that scout cannot see: your repository. Run it if your flags routinely outlive\nyour cleanup PRs. If you want the analysis on demand rather than on a schedule, the\n`cleaning-up-stale-feature-flags` and `finding-deleted-feature-flags` skills already do it, and\n`auditing-experiments-flags` covers experiment-linked flags.\n\nWeekly rather than the daily fleet default: flag debt accumulates over months, so a daily run\nwould re-read the same roster and write nothing six days out of seven.\n\n**Term collision, worth knowing.** The canonical scout uses **ghost flag** for the opposite case\n– code calling a key with no flag behind it, where the SDK silently returns `false`. That is a\ndifferent finding with a different fix. Don't reuse the term here.\n\n## Discriminator\n\nEmit a report when a flag is still emitting `$feature_flag_called` evaluations **and** either\n\n- **(a)** it has been at 100% or 0% with no edits for 60+ days, or\n- **(b)** its key does not appear in any connected repository.\n\nWrite nothing for a flag whose rollout percentage changed recently, or that was edited in the\nlast 30 days – that flag is mid-rollout and doing its job.\n\nThe two cases are not the same finding. **(a)** is cleanup you can do: the code is there and it\ntakes the same branch every time. **(b)** is a question – something is calling that key and it\nisn't in the code you can see. Never treat (b) as a delete candidate on its own.\n\n### Coverage caveat\n\n`$feature_flag_called` fires on explicit evaluation calls. Server SDKs using local evaluation,\nbootstrapped flags, and clients with flag-event capture disabled may not emit it at all, so\n**absence of the event is weak evidence that a flag is unused**. Lean on PostHog's server-side\n`STALE` status, which accounts for `last_called_at`, rather than on raw event absence.\n\n## Explore\n\n1. List flags with recent evaluations, plus their rollout percentage, tags, and last-modified\n   date.\n2. Search every connected repository for each candidate key. Three outcomes, not two:\n   - **A string literal, or a constant that resolves to one** – a definite answer either way.\n   - **Dynamically constructed** – a key assembled at the call site from a variable. A repo\n     search can't resolve these, and they are the main source of false \"the key is gone\"\n     conclusions. Treat a nearby prefix or template match as uncertainty, never as a delete\n     recommendation.\n   - **Not found anywhere** – case (b). Go to step 3 before concluding anything.\n3. For a case (b) flag, work out what is still calling it. The plausible answers are all things\n   this scout can't see: a repo that isn't connected, shipped mobile clients still running old\n   code, or a third-party or SDK consumer. Name the possibilities in the report, and check the\n   `$lib` and `$lib_version` spread on the evaluations – old client versions point at shipped\n   code you can't deploy over.\n4. Before recommending any removal, confirm the flag isn't load-bearing:\n   - **Attached to an experiment**, with a non-empty `experiment_set` – leave it alone entirely;\n     deleting it breaks the experiment and its results.\n   - **Referenced by another flag's release conditions** – flag dependencies exist, and deleting\n     the parent changes what the dependent serves.\n   - **Consumed for its payload** – a flag can sit at 100% and be read only for its payload\n     value, so the key shows up in a config fetch rather than in a branch.\n   - **Tagged as excluded** – see the disqualifiers.\n5. Quantify the reach: evaluations per day and distinct persons. That is what makes the report\n   worth someone's afternoon. It is **not** a billing argument – `$feature_flag_called` is\n   excluded from billable event volume – so don't put a dollar figure on it. The cost here is a\n   code path nobody can reason about, not an invoice.\n6. Bundle the findings into one report rather than filing one per flag, and keep the two cases\n   visibly separate inside it.\n\n## Suggested action\n\nDeleting a flag is not a no-op. Once the flag is gone, evaluation returns `false` or `undefined`\n– not the last value it served. Any live client still evaluating a deleted 100% flag flips to\nthe off path, which is a production behavior change.\n\nSo the order matters, and it isn't one pull request:\n\n1. Remove the call sites, and deploy.\n2. Confirm evaluations stop.\n3. Then delete the flag.\n\nRecommend step 1 – that's the PR an agent can open. Steps 2 and 3 are the follow-up you name in\nthe report, not something to bundle into the same diff.\n\n## Disqualifiers\n\n- The key appears in the repo, even only in tests or config.\n- The key may be dynamically constructed and the search can't rule it out.\n- The flag was edited recently, or its percentage is between 1 and 99.\n- The flag is experiment-linked, has dependent flags, or is read for its payload.\n- The flag carries an exclusion tag. Kill switches and ops toggles look exactly like debt and\n  must never be recommended for removal – but most of them carry no description, so don't try to\n  infer intent from prose. Ask the team to tag them (`keep`, `ops`, `kill-switch`) and read the\n  tag. Record anything you're told to leave alone in your scratchpad so the exclusion survives\n  to the next run. The durable way to stop a scout re-flagging something is to give it somewhere\n  to remember, not to hope for good metadata.\n- Coverage is partial. If any repo that evaluates flags isn't connected, case (b) findings are\n  unsafe – report them as open questions only.\n",{"data":40,"body":44},{"name":4,"description":6,"allowed_tools":41},[42,43],"emit_report","edit_report",{"type":45,"children":46},"root",[47,56,62,100,105,131,138,158,183,188,205,212,245,251,398,404,424,429,447,452,458],{"type":48,"tag":49,"props":50,"children":52},"element","h1",{"id":51},"feature-flag-debt",[53],{"type":54,"value":55},"text","Feature flag debt",{"type":48,"tag":57,"props":58,"children":59},"p",{},[60],{"type":54,"value":61},"Find flags whose decision is over while something is still evaluating them.",{"type":48,"tag":57,"props":63,"children":64},{},[65,67,74,76,82,84,90,92,98],{"type":54,"value":66},"Narrower than ",{"type":48,"tag":68,"props":69,"children":71},"code",{"className":70},[],[72],{"type":54,"value":73},"signals-scout-feature-flags",{"type":54,"value":75},", which watches the whole flag surface – evaluation\ncliffs, ghost keys, response-distribution shifts, flag debt – from PostHog data alone. This one\nadds the half that scout cannot see: your repository. Run it if your flags routinely outlive\nyour cleanup PRs. If you want the analysis on demand rather than on a schedule, the\n",{"type":48,"tag":68,"props":77,"children":79},{"className":78},[],[80],{"type":54,"value":81},"cleaning-up-stale-feature-flags",{"type":54,"value":83}," and ",{"type":48,"tag":68,"props":85,"children":87},{"className":86},[],[88],{"type":54,"value":89},"finding-deleted-feature-flags",{"type":54,"value":91}," skills already do it, and\n",{"type":48,"tag":68,"props":93,"children":95},{"className":94},[],[96],{"type":54,"value":97},"auditing-experiments-flags",{"type":54,"value":99}," covers experiment-linked flags.",{"type":48,"tag":57,"props":101,"children":102},{},[103],{"type":54,"value":104},"Weekly rather than the daily fleet default: flag debt accumulates over months, so a daily run\nwould re-read the same roster and write nothing six days out of seven.",{"type":48,"tag":57,"props":106,"children":107},{},[108,114,116,121,123,129],{"type":48,"tag":109,"props":110,"children":111},"strong",{},[112],{"type":54,"value":113},"Term collision, worth knowing.",{"type":54,"value":115}," The canonical scout uses ",{"type":48,"tag":109,"props":117,"children":118},{},[119],{"type":54,"value":120},"ghost flag",{"type":54,"value":122}," for the opposite case\n– code calling a key with no flag behind it, where the SDK silently returns ",{"type":48,"tag":68,"props":124,"children":126},{"className":125},[],[127],{"type":54,"value":128},"false",{"type":54,"value":130},". That is a\ndifferent finding with a different fix. Don't reuse the term here.",{"type":48,"tag":132,"props":133,"children":135},"h2",{"id":134},"discriminator",[136],{"type":54,"value":137},"Discriminator",{"type":48,"tag":57,"props":139,"children":140},{},[141,143,149,151,156],{"type":54,"value":142},"Emit a report when a flag is still emitting ",{"type":48,"tag":68,"props":144,"children":146},{"className":145},[],[147],{"type":54,"value":148},"$feature_flag_called",{"type":54,"value":150}," evaluations ",{"type":48,"tag":109,"props":152,"children":153},{},[154],{"type":54,"value":155},"and",{"type":54,"value":157}," either",{"type":48,"tag":159,"props":160,"children":161},"ul",{},[162,173],{"type":48,"tag":163,"props":164,"children":165},"li",{},[166,171],{"type":48,"tag":109,"props":167,"children":168},{},[169],{"type":54,"value":170},"(a)",{"type":54,"value":172}," it has been at 100% or 0% with no edits for 60+ days, or",{"type":48,"tag":163,"props":174,"children":175},{},[176,181],{"type":48,"tag":109,"props":177,"children":178},{},[179],{"type":54,"value":180},"(b)",{"type":54,"value":182}," its key does not appear in any connected repository.",{"type":48,"tag":57,"props":184,"children":185},{},[186],{"type":54,"value":187},"Write nothing for a flag whose rollout percentage changed recently, or that was edited in the\nlast 30 days – that flag is mid-rollout and doing its job.",{"type":48,"tag":57,"props":189,"children":190},{},[191,193,197,199,203],{"type":54,"value":192},"The two cases are not the same finding. ",{"type":48,"tag":109,"props":194,"children":195},{},[196],{"type":54,"value":170},{"type":54,"value":198}," is cleanup you can do: the code is there and it\ntakes the same branch every time. ",{"type":48,"tag":109,"props":200,"children":201},{},[202],{"type":54,"value":180},{"type":54,"value":204}," is a question – something is calling that key and it\nisn't in the code you can see. Never treat (b) as a delete candidate on its own.",{"type":48,"tag":206,"props":207,"children":209},"h3",{"id":208},"coverage-caveat",[210],{"type":54,"value":211},"Coverage caveat",{"type":48,"tag":57,"props":213,"children":214},{},[215,220,222,227,229,235,237,243],{"type":48,"tag":68,"props":216,"children":218},{"className":217},[],[219],{"type":54,"value":148},{"type":54,"value":221}," fires on explicit evaluation calls. Server SDKs using local evaluation,\nbootstrapped flags, and clients with flag-event capture disabled may not emit it at all, so\n",{"type":48,"tag":109,"props":223,"children":224},{},[225],{"type":54,"value":226},"absence of the event is weak evidence that a flag is unused",{"type":54,"value":228},". Lean on PostHog's server-side\n",{"type":48,"tag":68,"props":230,"children":232},{"className":231},[],[233],{"type":54,"value":234},"STALE",{"type":54,"value":236}," status, which accounts for ",{"type":48,"tag":68,"props":238,"children":240},{"className":239},[],[241],{"type":54,"value":242},"last_called_at",{"type":54,"value":244},", rather than on raw event absence.",{"type":48,"tag":132,"props":246,"children":248},{"id":247},"explore",[249],{"type":54,"value":250},"Explore",{"type":48,"tag":252,"props":253,"children":254},"ol",{},[255,260,298,318,374,393],{"type":48,"tag":163,"props":256,"children":257},{},[258],{"type":54,"value":259},"List flags with recent evaluations, plus their rollout percentage, tags, and last-modified\ndate.",{"type":48,"tag":163,"props":261,"children":262},{},[263,265],{"type":54,"value":264},"Search every connected repository for each candidate key. Three outcomes, not two:\n",{"type":48,"tag":159,"props":266,"children":267},{},[268,278,288],{"type":48,"tag":163,"props":269,"children":270},{},[271,276],{"type":48,"tag":109,"props":272,"children":273},{},[274],{"type":54,"value":275},"A string literal, or a constant that resolves to one",{"type":54,"value":277}," – a definite answer either way.",{"type":48,"tag":163,"props":279,"children":280},{},[281,286],{"type":48,"tag":109,"props":282,"children":283},{},[284],{"type":54,"value":285},"Dynamically constructed",{"type":54,"value":287}," – a key assembled at the call site from a variable. A repo\nsearch can't resolve these, and they are the main source of false \"the key is gone\"\nconclusions. Treat a nearby prefix or template match as uncertainty, never as a delete\nrecommendation.",{"type":48,"tag":163,"props":289,"children":290},{},[291,296],{"type":48,"tag":109,"props":292,"children":293},{},[294],{"type":54,"value":295},"Not found anywhere",{"type":54,"value":297}," – case (b). Go to step 3 before concluding anything.",{"type":48,"tag":163,"props":299,"children":300},{},[301,303,309,310,316],{"type":54,"value":302},"For a case (b) flag, work out what is still calling it. The plausible answers are all things\nthis scout can't see: a repo that isn't connected, shipped mobile clients still running old\ncode, or a third-party or SDK consumer. Name the possibilities in the report, and check the\n",{"type":48,"tag":68,"props":304,"children":306},{"className":305},[],[307],{"type":54,"value":308},"$lib",{"type":54,"value":83},{"type":48,"tag":68,"props":311,"children":313},{"className":312},[],[314],{"type":54,"value":315},"$lib_version",{"type":54,"value":317}," spread on the evaluations – old client versions point at shipped\ncode you can't deploy over.",{"type":48,"tag":163,"props":319,"children":320},{},[321,323],{"type":54,"value":322},"Before recommending any removal, confirm the flag isn't load-bearing:\n",{"type":48,"tag":159,"props":324,"children":325},{},[326,344,354,364],{"type":48,"tag":163,"props":327,"children":328},{},[329,334,336,342],{"type":48,"tag":109,"props":330,"children":331},{},[332],{"type":54,"value":333},"Attached to an experiment",{"type":54,"value":335},", with a non-empty ",{"type":48,"tag":68,"props":337,"children":339},{"className":338},[],[340],{"type":54,"value":341},"experiment_set",{"type":54,"value":343}," – leave it alone entirely;\ndeleting it breaks the experiment and its results.",{"type":48,"tag":163,"props":345,"children":346},{},[347,352],{"type":48,"tag":109,"props":348,"children":349},{},[350],{"type":54,"value":351},"Referenced by another flag's release conditions",{"type":54,"value":353}," – flag dependencies exist, and deleting\nthe parent changes what the dependent serves.",{"type":48,"tag":163,"props":355,"children":356},{},[357,362],{"type":48,"tag":109,"props":358,"children":359},{},[360],{"type":54,"value":361},"Consumed for its payload",{"type":54,"value":363}," – a flag can sit at 100% and be read only for its payload\nvalue, so the key shows up in a config fetch rather than in a branch.",{"type":48,"tag":163,"props":365,"children":366},{},[367,372],{"type":48,"tag":109,"props":368,"children":369},{},[370],{"type":54,"value":371},"Tagged as excluded",{"type":54,"value":373}," – see the disqualifiers.",{"type":48,"tag":163,"props":375,"children":376},{},[377,379,384,386,391],{"type":54,"value":378},"Quantify the reach: evaluations per day and distinct persons. That is what makes the report\nworth someone's afternoon. It is ",{"type":48,"tag":109,"props":380,"children":381},{},[382],{"type":54,"value":383},"not",{"type":54,"value":385}," a billing argument – ",{"type":48,"tag":68,"props":387,"children":389},{"className":388},[],[390],{"type":54,"value":148},{"type":54,"value":392}," is\nexcluded from billable event volume – so don't put a dollar figure on it. The cost here is a\ncode path nobody can reason about, not an invoice.",{"type":48,"tag":163,"props":394,"children":395},{},[396],{"type":54,"value":397},"Bundle the findings into one report rather than filing one per flag, and keep the two cases\nvisibly separate inside it.",{"type":48,"tag":132,"props":399,"children":401},{"id":400},"suggested-action",[402],{"type":54,"value":403},"Suggested action",{"type":48,"tag":57,"props":405,"children":406},{},[407,409,414,416,422],{"type":54,"value":408},"Deleting a flag is not a no-op. Once the flag is gone, evaluation returns ",{"type":48,"tag":68,"props":410,"children":412},{"className":411},[],[413],{"type":54,"value":128},{"type":54,"value":415}," or ",{"type":48,"tag":68,"props":417,"children":419},{"className":418},[],[420],{"type":54,"value":421},"undefined",{"type":54,"value":423},"\n– not the last value it served. Any live client still evaluating a deleted 100% flag flips to\nthe off path, which is a production behavior change.",{"type":48,"tag":57,"props":425,"children":426},{},[427],{"type":54,"value":428},"So the order matters, and it isn't one pull request:",{"type":48,"tag":252,"props":430,"children":431},{},[432,437,442],{"type":48,"tag":163,"props":433,"children":434},{},[435],{"type":54,"value":436},"Remove the call sites, and deploy.",{"type":48,"tag":163,"props":438,"children":439},{},[440],{"type":54,"value":441},"Confirm evaluations stop.",{"type":48,"tag":163,"props":443,"children":444},{},[445],{"type":54,"value":446},"Then delete the flag.",{"type":48,"tag":57,"props":448,"children":449},{},[450],{"type":54,"value":451},"Recommend step 1 – that's the PR an agent can open. Steps 2 and 3 are the follow-up you name in\nthe report, not something to bundle into the same diff.",{"type":48,"tag":132,"props":453,"children":455},{"id":454},"disqualifiers",[456],{"type":54,"value":457},"Disqualifiers",{"type":48,"tag":159,"props":459,"children":460},{},[461,466,471,476,481,509],{"type":48,"tag":163,"props":462,"children":463},{},[464],{"type":54,"value":465},"The key appears in the repo, even only in tests or config.",{"type":48,"tag":163,"props":467,"children":468},{},[469],{"type":54,"value":470},"The key may be dynamically constructed and the search can't rule it out.",{"type":48,"tag":163,"props":472,"children":473},{},[474],{"type":54,"value":475},"The flag was edited recently, or its percentage is between 1 and 99.",{"type":48,"tag":163,"props":477,"children":478},{},[479],{"type":54,"value":480},"The flag is experiment-linked, has dependent flags, or is read for its payload.",{"type":48,"tag":163,"props":482,"children":483},{},[484,486,492,494,500,501,507],{"type":54,"value":485},"The flag carries an exclusion tag. Kill switches and ops toggles look exactly like debt and\nmust never be recommended for removal – but most of them carry no description, so don't try to\ninfer intent from prose. Ask the team to tag them (",{"type":48,"tag":68,"props":487,"children":489},{"className":488},[],[490],{"type":54,"value":491},"keep",{"type":54,"value":493},", ",{"type":48,"tag":68,"props":495,"children":497},{"className":496},[],[498],{"type":54,"value":499},"ops",{"type":54,"value":493},{"type":48,"tag":68,"props":502,"children":504},{"className":503},[],[505],{"type":54,"value":506},"kill-switch",{"type":54,"value":508},") and read the\ntag. Record anything you're told to leave alone in your scratchpad so the exclusion survives\nto the next run. The durable way to stop a scout re-flagging something is to give it somewhere\nto remember, not to hope for good metadata.",{"type":48,"tag":163,"props":510,"children":511},{},[512],{"type":54,"value":513},"Coverage is partial. If any repo that evaluates flags isn't connected, case (b) findings are\nunsafe – report them as open questions only.",{"items":515,"total":695},[516,533,545,558,571,586,602,618,636,653,668,680],{"slug":517,"name":517,"fn":518,"description":519,"org":520,"tags":521,"stars":530,"repoUrl":531,"updatedAt":532},"analyzing-expensive-users","analyze expensive users in AI observability","Analyze the most expensive users in AI observability and explain why they cost so much. Use when the user asks about top spenders, expensive users, per-user LLM cost, user-level cost drivers, or patterns behind high AI observability spend.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[522,525,528,529],{"name":523,"slug":524,"type":15},"Analytics","analytics",{"name":526,"slug":527,"type":15},"Cost Optimization","cost-optimization",{"name":13,"slug":14,"type":15},{"name":9,"slug":8,"type":15},35568,"https:\u002F\u002Fgithub.com\u002FPostHog\u002Fposthog","2026-08-10T04:16:25.279222",{"slug":534,"name":534,"fn":535,"description":536,"org":537,"tags":538,"stars":530,"repoUrl":531,"updatedAt":544},"auditing-endpoints","audit PostHog project endpoints","Audit every endpoint in a PostHog project for staleness, failed materialisations, and unused materialised versions. Use when the user asks \"what endpoints can I clean up?\", \"are any of my endpoints broken?\", \"which materialised versions are still being called?\", or wants a one-shot cleanup pass over the Endpoints product. Produces a prioritised report grouped by issue type, with recommended actions but does not modify anything without explicit confirmation.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[539,540,543],{"name":523,"slug":524,"type":15},{"name":541,"slug":542,"type":15},"Audit","audit",{"name":9,"slug":8,"type":15},"2026-06-08T08:08:33.693989",{"slug":546,"name":546,"fn":547,"description":548,"org":549,"tags":550,"stars":530,"repoUrl":531,"updatedAt":557},"auditing-warehouse-source-health","audit PostHog data warehouse source health","Audit the health of a PostHog project's data warehouse sources and syncs — find every broken or degraded source connection, sync schema, and webhook channel. Use when the user asks \"why are my imports failing?\", \"what's broken with my sources?\", \"why is my warehouse data stale?\", or wants a one-shot triage of source\u002Fsync health before deciding where to dig in. Produces a prioritized report grouped by severity, with recommended next steps. For materialized-view health use `auditing-warehouse-view-health`; for a single failing sync use `diagnosing-failed-warehouse-syncs`.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[551,552,555,556],{"name":541,"slug":542,"type":15},{"name":553,"slug":554,"type":15},"Data Warehouse","data-warehouse",{"name":13,"slug":14,"type":15},{"name":9,"slug":8,"type":15},"2026-06-18T08:22:57.67984",{"slug":559,"name":559,"fn":560,"description":561,"org":562,"tags":563,"stars":530,"repoUrl":531,"updatedAt":570},"auditing-warehouse-view-health","audit PostHog materialized view health","Audit the health of a PostHog project's materialized views (saved queries) — find every failed materialization and flag unused or stale materialized views that cost storage and compute. Use when the user asks \"which of my views are broken?\", \"why is this materialized view failing?\", \"are any of my views wasting compute?\", or wants a one-shot triage of view health. For source\u002Fsync health use `auditing-warehouse-source-health`.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[564,565,566,569],{"name":541,"slug":542,"type":15},{"name":553,"slug":554,"type":15},{"name":567,"slug":568,"type":15},"Performance","performance",{"name":9,"slug":8,"type":15},"2026-06-18T08:25:10.936787",{"slug":572,"name":572,"fn":573,"description":574,"org":575,"tags":576,"stars":530,"repoUrl":531,"updatedAt":585},"authoring-error-tracking-alerts","author PostHog error tracking alerts","Author error tracking alerts that fire when an issue is created, reopened, or starts spiking. Use when the user asks to set up error notifications, route exceptions to Slack\u002Fwebhook\u002FLinear, or evaluate which error events are worth alerting on. Covers trigger-event selection, integration choice, dedup against existing alerts, and shipping with the canonical message body shape.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[577,580,583,584],{"name":578,"slug":579,"type":15},"Alerting","alerting",{"name":581,"slug":582,"type":15},"Debugging","debugging",{"name":13,"slug":14,"type":15},{"name":9,"slug":8,"type":15},"2026-06-18T08:24:40.318583",{"slug":587,"name":587,"fn":588,"description":589,"org":590,"tags":591,"stars":530,"repoUrl":531,"updatedAt":601},"authoring-log-alerts","author log alerts in PostHog","Author useful, low-noise log alerts on services in a PostHog project. Use when the user asks to set up alerts for their logs, suggest alerts they should add, or evaluate whether a service is worth monitoring. Covers service triage, baseline characterisation, threshold drafting, back-testing via simulate, and shipping with a notification destination.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[592,593,596,597,600],{"name":523,"slug":524,"type":15},{"name":594,"slug":595,"type":15},"Monitoring","monitoring",{"name":13,"slug":14,"type":15},{"name":598,"slug":599,"type":15},"Operations","operations",{"name":9,"slug":8,"type":15},"2026-07-18T05:10:54.430898",{"slug":603,"name":603,"fn":604,"description":605,"org":606,"tags":607,"stars":530,"repoUrl":531,"updatedAt":617},"building-canvases","create and edit PostHog canvases","Create or edit a PostHog canvas — a sandboxed browser application (data board, document, form, small tool, graphics experiment) stored in PostHog and rendered by the desktop\u002Fweb app. Use when a task asks to build, generate, update, or fix a canvas, or when a canvas id is given as the publish target. Covers resolving or creating the target canvas, choosing an implementation approach (React + Quill vs plain HTML\u002Fbrowser APIs), the read → edit → validate → publish → build loop, and which companion canvas skills to load for the details.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[608,611,613,614],{"name":609,"slug":610,"type":15},"Automation","automation",{"name":612,"slug":29,"type":15},"Design",{"name":9,"slug":8,"type":15},{"name":615,"slug":616,"type":15},"Prototyping","prototyping","2026-08-06T06:09:29.946969",{"slug":619,"name":619,"fn":620,"description":621,"org":622,"tags":623,"stars":530,"repoUrl":531,"updatedAt":635},"building-html-canvases","author HTML and CSS PostHog canvases","Author a PostHog canvas with semantic HTML, CSS, and direct browser APIs — documents, articles, generative graphics, 2D canvas and WebGL experiences, and focused experiments where React components add no useful structure. Use after building-canvases has routed a canvas request to a plain-HTML\u002Fbrowser-API implementation. Covers the thin component wrapper the current runtime requires, styling and theming without Quill, drawing surfaces, and animation\u002Fcleanup patterns.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[624,627,628,631,634],{"name":625,"slug":626,"type":15},"CSS","css",{"name":612,"slug":29,"type":15},{"name":629,"slug":630,"type":15},"Graphics","graphics",{"name":632,"slug":633,"type":15},"HTML","html",{"name":9,"slug":8,"type":15},"2026-08-06T06:09:30.313848",{"slug":637,"name":637,"fn":638,"description":639,"org":640,"tags":641,"stars":530,"repoUrl":531,"updatedAt":652},"building-react-quill-canvases","build React and Quill canvases","Author the React + Quill implementation of a PostHog canvas: the single-component contract, the allowed imports, Quill (PostHog's design system) component and composition rules, theme-aware design tokens, loading skeletons, and the in-canvas date picker. Use after building-canvases has routed a canvas request to a React implementation — dashboards, data boards, forms, tools, or any canvas that should look native to PostHog.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[642,643,646,649],{"name":612,"slug":29,"type":15},{"name":644,"slug":645,"type":15},"Frontend","frontend",{"name":647,"slug":648,"type":15},"React","react",{"name":650,"slug":651,"type":15},"UI Components","ui-components","2026-08-06T06:09:18.633724",{"slug":654,"name":654,"fn":655,"description":656,"org":657,"tags":658,"stars":530,"repoUrl":531,"updatedAt":667},"building-workflows","build and edit PostHog workflows","Build, edit, test, enable, and monitor PostHog workflows over MCP. Author the action\u002Fedge graph so it runs and opens cleanly in the visual editor, then change drafts surgically with patch operations. Use when asked to build, set up, automate, change, fix, or debug a workflow, campaign, broadcast, drip sequence, or event-triggered automation in the workflows product.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[659,660,663,664],{"name":609,"slug":610,"type":15},{"name":661,"slug":662,"type":15},"MCP","mcp",{"name":9,"slug":8,"type":15},{"name":665,"slug":666,"type":15},"Workflow Automation","workflow-automation","2026-08-10T04:16:26.294119",{"slug":669,"name":669,"fn":670,"description":671,"org":672,"tags":673,"stars":530,"repoUrl":531,"updatedAt":679},"check-posthog-loading","inspect PostHog SDK loading across URLs","Inspect how the PostHog JavaScript SDK is loaded across a list of URLs. Use to confirm consistent installation across pages, find pages missing the snippet, detect mismatched API keys or hosts between pages, and verify the load method (head snippet vs deferred vs array.js).\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[674,675,676,677,678],{"name":523,"slug":524,"type":15},{"name":581,"slug":582,"type":15},{"name":644,"slug":645,"type":15},{"name":13,"slug":14,"type":15},{"name":9,"slug":8,"type":15},"2026-05-07T05:56:19.828048",{"slug":681,"name":681,"fn":682,"description":683,"org":684,"tags":685,"stars":530,"repoUrl":531,"updatedAt":694},"consuming-endpoints-from-client-code","integrate PostHog endpoints into client applications","Wire a PostHog endpoint into a client app or SDK. Covers fetching the OpenAPI spec, generating a typed client with openapi-generator or @hey-api\u002Fopenapi-ts, sending the right auth header, shaping the variables payload (HogQL code_name vs insight breakdown property), handling rate-limit and materialised-endpoint error responses. Use when the user says \"how do I call my endpoint\", \"generate a client for this\", or \"what auth header do I use\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[686,689,690,691],{"name":687,"slug":688,"type":15},"API Development","api-development",{"name":644,"slug":645,"type":15},{"name":9,"slug":8,"type":15},{"name":692,"slug":693,"type":15},"SDK","sdk","2026-06-08T08:08:34.929454",248,{"items":697,"total":741},[698,712,719,730],{"slug":699,"name":699,"fn":700,"description":701,"org":702,"tags":703,"stars":23,"repoUrl":24,"updatedAt":711},"signals-scout-ai-cost","monitor AI feature costs and performance","Watches cost per conversation for AI features and reports when it breaks from its recent norm while volume holds steady, attributing the change to a model, prompt, cache, or retry cause.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[704,705,708,709,710],{"name":526,"slug":527,"type":15},{"name":706,"slug":707,"type":15},"LLM","llm",{"name":594,"slug":595,"type":15},{"name":13,"slug":14,"type":15},{"name":9,"slug":8,"type":15},"2026-08-10T04:45:48.936016",{"slug":4,"name":4,"fn":5,"description":6,"org":713,"tags":714,"stars":23,"repoUrl":24,"updatedAt":25},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[715,716,717,718],{"name":18,"slug":19,"type":15},{"name":13,"slug":14,"type":15},{"name":9,"slug":8,"type":15},{"name":21,"slug":22,"type":15},{"slug":720,"name":720,"fn":721,"description":722,"org":723,"tags":724,"stars":23,"repoUrl":24,"updatedAt":729},"signals-scout-silent-failure","detect and diagnose silent application failures","Watches the completion rate of one named core action for breaks from its own norm, and reports the likely cause – with swallowed exceptions as the first thing it looks for.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[725,726,727,728],{"name":581,"slug":582,"type":15},{"name":594,"slug":595,"type":15},{"name":13,"slug":14,"type":15},{"name":9,"slug":8,"type":15},"2026-08-10T04:45:56.482808",{"slug":731,"name":731,"fn":732,"description":733,"org":734,"tags":735,"stars":23,"repoUrl":24,"updatedAt":740},"signals-scout-your-scout","configure PostHog signal scouts","What this scout watches and the condition under which it files a report.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[736,737,738,739],{"name":609,"slug":610,"type":15},{"name":594,"slug":595,"type":15},{"name":13,"slug":14,"type":15},{"name":9,"slug":8,"type":15},"2026-08-10T04:45:49.295902",4]