
PostHog 产品告警工程指南为产品添加告警与扩展共享告警平台【免费下载链接】posthog:hedgehog: PostHog is the leading platform for building self-driving products. Our developer tools – AI observability, analytics, session replay, flags, experiments, error tracking, logs, and more – capture all the context agents need to diagnose problems, uncover opportunities, and ship fixes. Steer it all from Slack, web, desktop, or the MCP.项目地址: https://gitcode.com/GitHub_Trending/po/posthog本篇基于 PostHog 仓库内的工程技能文档 .agents/skills/adding-product-alerting/SKILL.md 及其四份参考文档整理。核心主题是当某个 PostHog 产品需要接入告警能力时如何组合已有的生命周期状态机、目的地destination、投递、调度、邮件与前端原语完成接入Adopt当某项能力可跨产品复用时又该如何按平台契约扩展Extend共享告警基础设施。读完本文你将掌握路由决策方法、十条平台不变量、products/alerts/backend/各模块的公开契约以及端到端验证告警链路的标准做法。先做路由决策需求应该走哪条路径原文档开篇即要求路由优先Route first任何与告警相关的工程请求先按下表确定路径再阅读对应参考文档避免在错误的层动手。需求路径阅读文档给一个产品添加告警能力Adopt接入adopting-platform-alerting.md构建/扩展产品告警编辑器、目的地 UI、高级选项、评估历史Frontendfrontend-alerting.md添加生命周期规则、目的地类型、投递行为、调度原语、邮件能力、向导选项或共享评估特性Extend扩展extending-platform-alerting.md只改某一个已有产品的行为Adopt first先接入保持产品自持除非该行为可复用且有真实的第二个用例理解归属或选择正确的层Architecturearchitecture.md配置/撰写已有的 logs 或 error tracking 告警Out of scope使用authoring-log-alerts或authoring-error-tracking-alerts技能添加实时应用内通知Out of scope使用sending-notifications技能两条路径都服务于同一目的共享告警平台既是积木也是契约。文档强调在创建产品本地告警框架之前必须先从本技能出发。十条平台不变量Platform invariants无论走哪条路径以下规则必须保持评估保持领域专属。产品自己决定数据是否越限共享生命周期消费的是归一化的CheckInput。只有一个生命周期状态机。复用 state_machine.py产品间的真实差异通过AlertPolicy表达而不是分叉fork代码。只有一个产品 mutator。所有对持久化的state或consecutive_failures的写入都必须经过产品适配器的apply_outcome。派发与持久化必须一致。对 HogFunction 通知在内事件生产者确认acknowledge事件之前不得持久化任何依赖通知的状态迁移若生产失败恢复 check 前的结果。注意该确认只证明事件进入了内事件传输层不证明下游目的地执行。目的地是白名单制。共享支持某个目的地类型并不会自动让它在每个产品中都可见可选。调度数学是共享的到期资格判定是产品自持的。固定节奏、日历锚点、时区与调度限制辅助函数来自 scheduling.py模型专属的到期谓词与持久化留在接入方。共享代码里没有产品分支。生命周期模块保持纯 Python可复用的 Django 行为放在products/alerts/backend/的其他位置。前端数据在产品边界归一化。共享编辑器组件渲染归一化后的定义、目的地、高级选项、调度与历史产品 API 调用、payload 与评估专属字段留在产品适配器。默认值保持向后兼容。新的平台选项必须让既有接入方显式选择后才能改变行为。配置、路由与投递是一个契约。受支持的目的地必须能被持久化、可见、在告警触发时被选中、并到达投递 worker。不能只测其中一步。架构分层代码应该放在哪里architecture.md 给出的分层地图如下编辑代码前先用它决定归属层位置职责纯生命周期决策products/alerts/backend/state_machine.py状态迁移、策略决策、通知动作共享告警基础设施products/alerts/backend/调度数学、目的地配置与持久化、内事件投递、邮件传输、insight 告警模型/API 与 insight 评估产品适配器products/name/backend/领域评估、模型快照、单一 mutator、事件 payload、允许的目的地、到期查询、历史与编排共享告警创建 UIfrontend/src/lib/components/Alerting/AlertWizard/可复用的 HogFunction 目的地、触发器与配置流程共享产品告警 UIproducts/alerts/frontend/components/与容器无关的编辑器布局、定义原语、高级选项、目的地编辑器、调度展示与评估图表产品 UIproducts/name/frontend/或frontend/src/scenes/name/表单逻辑、API 调用、产品字段、归一化适配器、入口、详情表与向导配置两个参考接入方reference adopters是理解整个平台的钥匙products/logs固定节奏调度、HogFunction 目的地、投递回滚、产品自持的 Temporal 编排以及共享产品告警编辑器组件的参考实现Insight 告警日历锚点、周末跳过与邮件投递的参考实现。两者都使用共享的静默时段quiet hours调度限制。每个产品保留自己的模型、到期查询与调度持久化。evaluation包在 insight 查询种类之间共享但不是给无关产品用的通用评估器。生命周期契约CheckInput 进AlertCheckOutcome 出state_machine.py 的模块文档注释明确它遵循 Prometheus/Alertmanager 的拆分思路——评估留在各领域产品生命周期决策集中在这一处契约就是进一个CheckInput出一个AlertCheckOutcome。模块是纯 Python无任何 Django 或产品模型导入。核心类型与函数AlertStateNOT_FIRING、FIRING、PENDING_RESOLVE仅输入态、ERRORED、SNOOZED、BROKENCheckInput归一化一次产品评估字段为threshold_breached、is_inconclusive、error_message、is_transient_errorAlertSnapshot机器做决策所需的最小字段集——state、cooldown、last_notified_at、snooze_until、consecutive_failures以及 N-of-M 滑窗字段evaluation_periods、datapoints_to_alarm、recent_events_breached1-of-1 即任何越限即触发evaluate_alert_check(...)/evaluate_alert_failure(...)返回AlertCheckOutcome含new_state、notification、consecutive_failures、update_last_notified_at、error_message、disable不做任何持久化控制面辅助函数apply_enable、apply_disable、apply_snooze、apply_threshold_change等返回ControlPlaneOutcome与AlertCheckOutcome共享new_state consecutive_failures从而能统一流经产品本地的apply_outcomeNotificationActionNONE/FIRE/RESOLVE/ERROR/BROKEN告诉产品该投递哪种事件。产品差异通过AlertPolicyfrozen dataclass表达源码中的注释非常克制每个标志都编码一个真实观测到的产品差异——不要投机地加标志也不要未经核查所有接入方就改默认值。仓库中可以看到两套现成策略LOGS_ALERT_POLICY AlertPolicy() # 默认即 logs 行为 BILLING_ALERT_POLICY AlertPolicy( broken_is_terminalFalse, # BROKEN 可被一次成功检查重新评估 transient_errors_count_toward_brokenTrue, notify_error_on_every_failureTrue, cooldown_gates_initial_fireFalse, cooldown_gates_resolveFalse, renotify_while_firingTrue, # 持续越限时每冷却窗重复通知 clear_check_ends_snoozeTrue, # 清除检查即解除 snooze disable_when_brokenTrue, # 达到 BROKEN 同时禁用告警 )关键参数还包括max_consecutive_failures默认MAX_CONSECUTIVE_FAILURES 5设为None则失败永不升级为 BROKEN、errors_set_errored_state是否把评估失败暴露为可见的 ERRORED 状态、notify_resolve是否发送恢复通知等。错误行为是承重的error behavior is load-bearing文档特别列出五条语义失败的检查不清除已在 firing 的告警inconclusive 检查保持状态与失败计数不变瞬态错误默认静默除非策略显式选择计数错误通知通常只发生在进入错误态的第一个失败边缘投递失败不得消耗本应重试的生命周期或失败计数边缘。源码中对应实现很直观evaluate_alert_failure对瞬态错误直接返回_stay式的原状态结果注释解释了集群抖动会同时命中整批告警广播会制造噪音失败计数用于向 BROKEN 升级而错误通知基于snapshot.consecutive_failures 0判断每条错误链只通知一次。产品接入时还需扩展 semgrep 规则.semgrep/rules/security/alert-state-must-go-through-state-machine.yaml用静态检查强制state 写入必须走状态机。相关决策测试见 test_state_machine.py 与 test_insight_alert_state_machine.py。目的地契约EventKindSpec 与 DESTINATION_SPECS 注册表产品面向的目的地设置统一从products.alerts.backend.facade.api导出见 facade/api.py 的__all__validate_destination_databuild_alert_destination_configcreate_alert_destination_hog_functionssoft_delete_alert_destinationssoft_delete_all_alert_destinationssend_alert_email从 destination_configs.py 的实现可以看到契约的具体形状DestinationType枚举定义了共享支持的目的地slack、discord、webhook、teamsMicrosoft TeamsEventKindSpecfrozen dataclass描述一种事件的目的地无关内容event_id、display_kind、header、details、主操作 URL/标签、webhook body、product_label等共享 builder 依据DESTINATION_SPECS注册表把它转换成 HogFunction payload。每个目的地类型在该注册表中拥有自己的模板 ID、必填字段、input 构建、回读read-back与读取脱敏redaction——添加一个目的地类型就是在那里加一条注册项产品自己拥有事件 ID、事件属性、措辞、动作以及允许的目的地列表。删除是 fail-closed 的必须始终用team_id、alert_id和产品允许的事件 ID 三重限定。create_alert_destination_hog_functions会拒绝创建该告警已有的目的地因此文档要求锁住告警行再调用。目的地相关测试分布在 test_destination_configs.py 与 test_destinations.py。投递契约把生产、flush、确认当成三个阶段HogFunction 通知 worker 直接使用products.alerts.backend.destinations文档给出严格的四步序列produce_alert_internal_event(...)返回ProduceResult或Noneflush_alert_internal_events(...)刷新共享生产者——批处理 worker 每产生一批只 flush 一次alert_internal_event_delivered(...)检查 flush 之后生产者是否确认了每条内事件产品只为已确认acknowledged的内事件持久化依赖通知的生命周期变更。语义边界很重要生产者确认只证明内事件传输层收到了事件不证明下游 HogFunction 执行更不证明最终 Slack/Discord/webhook/Teams 投递成功。helper 负责记录与捕获生产者失败回滚、重试时机、调度推进与检查历史语义归产品所有。文档以 logs 为参考内事件未确认时在该告警下一次节奏上重新评估。邮件侧则要求调用方通过 facade 的send_alert_email(...)发起并自持收件人、授权、主题、模板、上下文、错误处理以及一个稳定的campaign_key——它承担必需的邮件重试与去重语义不能在 helper 内部生成不稳定的 key。调度契约分片、网格对齐与日历锚点scheduling.py 同样是纯 Python拥有可复用的调度数学compute_shard_offset_seconds(alert_id, check_interval_minutes, ...)用alert_id.int % shard_count确定性地把 UUID 键控的告警分配到调度器 tick 上避免同一时刻全量告警同时触发。源码注释给了具体例子60 秒调度间隔、5 分钟节奏下告警分布在[0, 60, 120, 180, 240]秒的 5 个桶上并说明用alert_id.int而非进程内hash()是因为它跨 Pod 重启稳定且 UUIDv7 低位是随机段、取模均匀。advance_next_check_at(...)从上一次计划推进跳过错过的间隔把时间戳 snap 到以午夜为锚的节奏网格上再应用分片偏移。注释解释了原因调度器 cron 每分钟触发一次若返回的next_check_at带亚分钟偏移如 12:05:30cron 会等待而浪费整个 tick网格对齐让同节奏告警落在同一规范网格上已漂移的告警在下一次运行时惰性自愈。CalendarInterval/to_calendar_interval(...)面向产品的间隔契约real_time、every_15_minutes、hourly、daily、weekly、monthly镜像posthog.schema.AlertCalculationInterval。next_calendar_check_time(...)计算固定节奏或团队本地时区的每日/每周/每月锚点并在使用pytz本地化时显式处理AmbiguousTimeError取 is_dstTrue与NonExistentTimeError取 is_dstFalse 再 normalize保证 DST 切换下墙钟行为不变。validate_and_normalize_schedule_restriction(...)与parse_blocked_windows_tuples(...)校验产品 payload 并产出纯阻断窗口契约。scan_next_unblocked_utc(...)、is_utc_datetime_blocked(...)、is_weekend(...)时区感知地应用限制且全程不导入 Django 模型。文档特别强调两条实践纪律计算分片时用调度器真实间隔创建、更新、推进告警时使用同一个分片函数保证稳态节奏稳定。产品负责把自己存储的枚举与 payload 翻译成共享契约到期资格、调度持久化、重试与编排保留在产品侧。调度测试见 test_scheduling.py 与 test_grid_scheduling.py。前端契约两条共享路径数据在产品边界归一化frontend-alerting.md 与 architecture.md 共同定义前端归属。共享产品告警 UI 位于products/alerts/frontend/components/它是表现层基础设施不是前端产品注册表AlertEditor、AlertEditorFormDetails、AlertEditorSection与容器无关的表单外壳对应 AlertEditor.tsxAlertDefinition*系列组件定义、调度、下次评估与时区的可组合展示原语AlertAdvancedOptions共享的折叠与启用计数行为见 AlertAdvancedOptions.tsxQuietHoursFields从归一化的限制、节奏与项目时区渲染静默时段输入见 QuietHoursFields.tsxAlertNotificationDestinationEditor渲染归一化的已保存/待定目的地见 AlertNotificationDestinationEditor.tsxAlertEvaluationHistoryChart渲染归一化的评估点与当前阈值见 AlertEvaluationHistoryChart.tsx。产品自持的部分包括keyed kea logic、API 调用、表单 schema、源/过滤控件、支持的目的地类型、HogFunction payload、阈值转换、启用计数计算与历史表格modal、场景宽度与内嵌节尺寸也留在产品侧。AlertWizard保留为共享的 HogFunction 创建流程。接入方通过带 key 的alertWizardLogicprops 提供支持的子模板 ID、WizardTrigger[]、WizardDestination[]及可选的 URL/preset 行为。后端支持某目的地并不代表向导里就有这个选项——向导兼容性由 HogFunction 子模板决定。前端规则还包括业务逻辑放 keyed kea logic 而非 React hooks持久化表单用kea-forms网络操作必须有 loading 与防重复提交AlertEvaluationHistoryChart的AlertEvaluationHistoryPointlabel/value/firedAtTime要区分当时已触发与按当前配置会触发不得仅凭当前阈值推断历史 firingStorybook 用真实背景 tokenbg-bg-primary等bg-default是遗留文本色别名在浅色模式下会画出深色背景。路径一给产品添加平台告警Adopt九步adopting-platform-alerting.md 给出接入清单核心原则是先组合现有平台再考虑新增共享抽象1. 定义产品契约。编码前写下产品专属输入评估什么数据、什么构成 breached/clear/inconclusive/transient error/permanent error哪些生命周期状态与控制面动作对用户可见固定节奏还是日历对齐有哪些通知事件种类firing/resolved/errored/broken允许哪些目的地类型需要 HogFunction、邮件还是两者检查历史与详情页有哪些字段。文档警告不要因为产品将来可能需要就新增AlertPolicy选项——先确认现有策略确实表达不了且该差异是有意的。2. 添加产品持久化与隔离。产品拥有自己的告警配置与检查历史模型所有租户数据模型需要team_id与 fail-closed 作用域存储构造AlertSnapshot所需字段加上产品评估与调度字段必须保持一致的写入放进窄transaction.atomic()块不要在事务内做通知投递。3. 构建生命周期适配器。建一个产品状态机模块参照products/logs/backend/alert_state_machine.py选定或定义产品的AlertPolicy→ 把模型与近期历史转成共享快照 → 把领域评估转成CheckInput→ 调用evaluate_alert_check(...)或evaluate_alert_failure(...)→ 所有共享结果经由唯一一个产品自持的apply_outcome应用 → 控制面动作走共享 helper 并汇入同一 mutator → 扩展 alert-state semgrep 规则覆盖产品后端。除此之外任何地方都不得修改state或consecutive_failures。4. 定义通知内容与目的地。建一个薄产品模块参照products/logs/backend/alert_destinations.py每个通知动作定义一个EventKindSpec事件 ID 与属性保持稳定HogFunction 靠它们过滤与渲染内事件 payload 必须包含模板用到的全部属性显式声明产品允许的DestinationType值校验/构建/创建/删除一律走products.alerts.backend.facade.api删除用 team、alert ID 与允许事件 ID 限定。再次强调共享支持某目的地不等于产品自动接入。5. 让投递与生命周期状态事务化。HogFunction 目的地的六步序列评估并保留每个 check 前的快照/结果用于回滚 → 生产内事件并保留每个ProduceResult→ 批内只 flush 一次 → 用alert_internal_event_delivered(...)逐个检查确认 → 持久化之前为未确认结果恢复依赖投递的结果 → 按产品契约持久化已确认结果、检查历史与调度。邮件路径则显式决定邮件失败是阻断生命周期迁移还是单独记录。6. 添加调度与到期选择。直接从实现模块导入产品面向的调度契约from products.alerts.backend.scheduling import ( CalendarInterval, advance_next_check_at, compute_shard_offset_seconds, is_utc_datetime_blocked, is_weekend, next_calendar_check_time, parse_blocked_windows_tuples, scan_next_unblocked_utc, to_calendar_interval, validate_and_normalize_schedule_restriction, )固定分钟检查复用compute_shard_offset_seconds(...)与advance_next_check_at(...)若产品调度器间隔不同于共享默认值DEFAULT_SCHEDULE_INTERVAL_SECONDS 60就包一层分片函数创建/更新/评估路径保持同一稳定分片计算自持实现并测试到期谓词含 team 作用域、enabled、broken、snooze 与next_check_at行为。日历对齐检查to_calendar_interval(...)转换产品间隔值next_calendar_check_time(...)配合团队 IANA 时区静默时段用validate_and_normalize_schedule_restriction(...)校验、parse_blocked_windows_tuples(...)解析绝不重写时区/DST 逻辑。模型访问、API 错误翻译、有界重试日志与next_check_at持久化留在产品适配器。7. 添加产品编排。评估器、历史、到期查询、批处理、Temporal/Celery 编排、重试与指标都归产品。避免大 Temporal payload——只传 alert ID 与引用在 activity 内加载数据通知派发不进数据库事务。8. 添加前端。按上一条前端契约选择AlertWizard或共享产品告警组件或两者兼用每个网络动作都要有 loading 与防重复提交保护。9. 验证边界。补最低层级的测试覆盖真实回归共享状态机决策用例、产品快照与单一 mutator 行为、目的地校验/生成配置/归属安全删除/事件属性完整性、投递成功/入队失败/flush 失败/保存前回滚、到期谓词与节奏/分片行为、API schema 与租户隔离、向导逻辑与产品入口。路径二扩展共享告警平台Extendextending-platform-alerting.md 的总原则只有当可复用能力、选项或高级行为属于共享基础设施时才走这条路若只有一个产品需要、共享契约会变成投机就保持产品本地。扩展分类先找到单一事实来源能力主要事实来源同时检查生命周期状态、通知动作、控制面迁移、策略选项products/alerts/backend/state_machine.py共享决策测试、每个接入方策略与适配器、semgrep 规则固定节奏、日历、时区或调度限制行为products/alerts/backend/scheduling.py产品包装、创建/更新路径、到期查询、调度器间隔、DST 边界目的地类型或目的地级选项products/alerts/backend/destination_configs.pyHogFunction 模板/子模板、facade 导出、产品白名单、AlertWizardHogFunction 持久化或投递语义products/alerts/backend/destinations.pyworker 批处理、回滚、投递指标、目的地测试邮件传输能力products/alerts/backend/email_notifications.pyfacade 导出、campaign key 语义、接入方模板与测试共享 insight 查询评估products/alerts/backend/evaluation/告警配置 schema、API 校验、查询种类门控、生成的 API 类型共享告警模型或 API 选项products/alerts/backend/models/与products/alerts/backend/api/迁移、OpenAPI、前端逻辑、MCP schema向导触发器、目的地或高级创建选项frontend/src/lib/components/Alerting/AlertWizard/HogFunction 子模板兼容性、接入方 props、kea 测试变更若跨多行必须逐行有意更新不能把跨层契约藏在一个产品适配器里。生命周期扩展规则保持state_machine.py无 Django 与产品模型导入只针对观测到的语义差异添加策略字段并给出保留所有现有接入方行为的默认值优先新增纯迁移 helper 而非直接改模型更新受影响的 firing/resolving/snoozing/erroring/breaking/cooldown 决策表审计投递回滚确保新的通知动作不能在投递成功前消耗边缘。调度扩展规则辅助函数保持纯 Python固定网格与日历契约保持显式不要按产品名分支调度器间隔假设必须显式化保持确定性 UUID 分片与稳定稳态节奏DST 下保持本地墙钟锚点静默时段在团队时区中评估测试覆盖错过间隔、漂移自愈、节奏变更、DST 转换、跨夜窗口与边界时刻到期资格留在产品侧除非存在真实的跨产品模型契约。添加一个新目的地类型的七步在products/alerts/backend/destination_configs.py添加枚举值、HogFunction 模板 ID 与必填字段扩展校验与build_alert_destination_config(...)且不改变既有 payload添加或更新posthog/cdp/templates/destination/template_destination.py传输模板及其相邻测试在frontend/src/scenes/hog-functions/sub-templates/sub-templates.ts添加告警专属的模板兼容性决定哪些产品显式允许该目的地并更新其目的地编辑器或展示逻辑仅在相关子模板支持时把选项加入AlertWizard覆盖校验、生成 payload、归属安全删除、CDP 模板行为、产品渲染与向导兼容性的测试。对已有目的地的高级选项需先判断它是传输级transport-wide还是产品专属传输级进共享的类型化目的地数据与共享 builder产品专属的措辞、事件属性与事件种类行为留在EventKindSpec与产品适配器。其他扩展领域投递把事件创建、生产者 flush、生产者确认当三个阶段绝不把生产者确认描述为最终目的地投递批 flush 保持高效有界helper 只在调用方能凭返回值做显式回滚决策时才可非抛出为新的派发阶段加指标与结构化失败上下文验证部分批次生产失败只回滚受影响的告警。邮件send_alert_email(...)保持传输 helper 定位不做产品策略引擎调用方拥有收件人、模板、上下文与 campaign key只有多种告警类型需要同一传输行为时才加共享选项。共享 insight 评估evaluation/包在 insight 告警内部是种类无关的。扩展契约的顺序是定义告警配置 schema 与校验 → 添加产出ExtractionResult的 extractor → 比较与越限格式尽量独立于查询执行 → 按查询种类注册 dispatch 且不在无关 extractor 里分支 → create/update/simulate 路径一致地门控不支持或 feature-flag 的种类 → serializer/schema 变更后重新生成 OpenAPI 与前端类型。不要因为包名叫evaluation就把无关产品的评估器路由进来。共享产品告警前端只有当第二个接入方有相同的表现契约时才扩展products/alerts/frontend/components/。组件保持与容器无关、无产品名分支接受归一化的定义行、目的地视图模型、评估点、阈值、调度状态与启用计数API 调用、表单 schema、kea logic、payload 构建、产品过滤器、检测器配置、仿真与历史表格留在产品适配器优先小而可组合的定义原语而不是一个带满可选 props 的大组件改动共享契约时要同时验证至少一条 insight 路径与一条 logs 路径。AlertWizard业务逻辑进 keyed kea logic触发器/目的地兼容性从 HogFunction 子模板推导只有后端输入契约共享时才加可复用 UI 选项保留 URL 恢复、已有告警检测、测试、loading 与防重复提交行为。Facade 导出即兼容性承诺产品面向的 Django helper 通过products.alerts.backend.facade.api导出worker 专属的投递原语需要详细结果类型时留在products.alerts.backend.destinations。要更新类型标注与 help text让 OpenAPI 与 MCP schema 保持有用当归属边界、公开 helper 集合或接入流程变化时更新技能文档本身。不要仅为方便而暴露内部 helper——一个 facade 导出就是一份兼容性承诺对照 facade/api.py 中snooze_alert_from_slack的注释可见该承诺如何体现Slack webhook 无 team 上下文授权必须全部从告警行重新推导且用select_for_update()行锁做权威复查。拒绝错误的抽象出现以下任一情况就停下把变更留在产品侧不存在第二个用例选项会把产品模型字段泄漏进共享状态机通用 helper 需要产品名分支某目的地选项只改变一种事件种类的内容共享到期查询需要某个产品的状态名或租户模型向导选项没有共享的 HogFunction 输入契约。平台应该从已验证的接入方需求中生长而不是从猜测的未来灵活性中生长。把告警当作端到端系统对待原文档Current limits之外的另一核心章节指出告警跨越多条边界——目的地可能在 UI 里合法、被 API 拒绝、保存后不可见、或保存后永不被调用单条边界上的单元测试不能证明下一条边界工作。对每个受支持的告警来源与目的地类型必须经由公共接口测通这条路径通过每种受支持的管理 API 创建或更新目的地读回告警确认目的地可见触发告警确认路由选中了该目的地确认投递 worker 接受了通知或记录了清晰的失败。最后一步用测试传输或 mock 外部端点完成不依赖真实客户目的地。每当共享过滤器、白名单、事件 ID、模板 ID 或归属规则变化时添加聚焦测试。配套要求还包括维护一份显式的兼容性矩阵受支持的来源、事件、目的地与管理路径组合尽量让单一事实来源驱动相关白名单若必须用多个白名单就要命名受支持组合并测试——永远不要把空匹配当作成功而不记录原因。在每个边界埋点配置接受/拒绝、目的地选中、事件产生、worker 匹配、投递尝试、投递结果带关联 ID 与稳定的来源/目的地维度对相邻阶段的持续失配告警——这样才能发现各组件都不报错的静默丢件。部署后与定期运行隔离的合成检查且合成检查必须证明整条路径而不只是生产者接受了事件。把共享变更当作一个告警系统来评审当变更触及共享告警时评审所有可能消费它的契约而不只是动机产品。从参考接入方出发检查受影响维度生命周期产品适配器、控制面动作、持久化状态、通知边缘投递与目的地事件生产者/消费者、确认与回滚、模板、产品与通用管理 API调度创建/更新路径、到期资格、重试、节奏、静默时段、时区行为授权目的地创建、管理与派发时的产品/项目/组织边界前端与 API 契约生成的客户端、待定目的地重试、已有目的地可见性、所有使用共享数据的 UI分类与资格所有对事件/模板/目的地/告警类型做分类的生产者与消费者——一个新限制可能在一条路径上阻断创建在另一条路径上阻断投递。对事件、目的地、查询或授权变更要按精确事件 ID、模板 ID、模型类型、通用 API、UI 以及正则/前缀匹配映射出所有匹配的产品与客户端注意一个新产品可以自持目的地生命周期而另一个产品仍有意使用通用 HogFunction 路径这种混合状态。当通用访问违反归属或授权边界时立即收紧只为显式安全、受支持的路径保留通用访问并有意识地将其迁移到产品自持 API为新归属边界与每一条仍受支持的路径添加公共接口测试并包含证明未授权用户不能跨产品/项目/组织边界列举、读取、创建、更新、删除或派发目的地的负向测试。当前局限不要发明平行的框架文档最后给出明确的现状边界目前没有通用告警基类模型、产品注册表、push 模式的submit_check(...)、通用调度器 runner也没有通用 Temporal harness。不要围绕这些缺失的拼图发明平行框架。对非 insight 产品在共享契约落地之前评估、持久化、到期查询、历史与编排都保留在产品内。这既是约束也是路线图PostHog 的告警平台由 logs 与 insight 两个参考接入方反推生长——共享层只沉淀被两个以上产品真实验证过的契约状态机、调度数学、目的地注册表、投递确认、邮件传输、归一化前端原语而模型、到期谓词、编排与领域评估始终留在产品侧。理解这一点是读完本文后最重要的收获。【免费下载链接】posthog:hedgehog: PostHog is the leading platform for building self-driving products. Our developer tools – AI observability, analytics, session replay, flags, experiments, error tracking, logs, and more – capture all the context agents need to diagnose problems, uncover opportunities, and ship fixes. Steer it all from Slack, web, desktop, or the MCP.项目地址: https://gitcode.com/GitHub_Trending/po/posthog创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考