pstack benny 分诊自动化面向 Slack 问题报告的线程级判定、去重与 Fail-Closed 工单创建【免费下载链接】pluginsCursor plugin specification and official plugins项目地址: https://gitcode.com/GitHub_Trending/plugins125/plugins本文围绕 pstack 插件中 benny 自动化套件的核心操作文件 triage-issue-reports/SKILL.md 展开完整讲解这条“单线程判定thread-only verdict”式问题报告分诊流水线的设计与实现从冻结源线程坐标、读取全量报告证据、原因追踪、五类分类到路由、去重、Fail-Closed 工单创建、单条判定消息与[benny:*]标记契约以及后续跟进窗口。读完本文后你可以理解一套多智能体 Slack 自动化如何在“绝不越权发言、绝不猜单、绝不重复建单”的安全约束下闭环运行并能参照 configuration.example.yaml 与 triage-automation-prompt.md 在自己的仓库中落地同类配置。一、定位一条只读进、单条出的分诊流水线benny 是 pstack 插件位于 pstack/ 目录提供的一组 Cursor 自动化源码包专门处理 Slack 问题报告。整个套件包含两条相互协作的自动化一条负责分诊triage另一条负责复现已确认的 bug 并可能准备小的草稿修复见 benny/README.md 与 benny/FOR_AGENTS.md。分诊这一条的职责边界在 SKILL.md 开篇就写死对一条 Slack 报告做分类并在其源线程里发布一条有用的判定。只有当一个清晰、全新的 bug 时才创建 tracker issue。不在此处复现或修复它。这决定了整条流水线的形态输入是多条 Slack 消息加附件输出恰好是一条线程内回复外加至多一次 tracker 写操作。文件 frontmatter 中的disable-model-invocation: true表明它不是可被模型随意调用的 slash skill而是“仅从已配置好的 Benny 分诊自动化加载”的操作指令文件——这也与 FOR_AGENTS.md 中“SKILL.md文件是直接的自动化指令而非注册的插件技能”的说明一致。硬性安全规则Hard safety rulesSKILL.md 第一节列出 16 条不可违背的规则可归纳为四个层面线程坐标不可变。源频道与根线程坐标是不可变的immutable。永不向源频道发布根消息root message。不向其他频道发消息、不广播回复、不发 DM、不另开替代线程。写操作前必须预检preflight。在任何 tracker 写入之前、以及在判定消息发出之前都要对源父消息做 preflight 校验。如果父消息缺失、被删除、不可访问或状态不确定立即停止不做任何写入。发言权唯一。只发一条有实质内容的判定不做过程播报Do not narrate progress。协调者coordinator是唯一的 Slack 发言者。委派出去的 worker 只能返回发现findings only必须只读且不授予任何 Slack 凭据或写动作每个子任务提示词都必须明令禁止SendSlackMessage、PostToSlack、chat.postMessage以及一切其他 Slack 写操作如果 worker 隔离无法强制这些限制就在协调者内部完成工作。宁缺毋滥地建单。绝不创建无法回链到源线程的 issue。宁可不建单也不建一个靠猜或重复的工单Prefer no ticket over a guessed or duplicate ticket。规则中还显式引用了两条 pstack 原则技能与一个写作技能对源坐标应用 principle-separate-before-serializing-shared-state对最终判定应用 principle-minimize-reader-load 与 unslop。其中前者要求“先消除共享可变状态再谈串行化”——把SOURCE_CHANNEL_ID/SOURCE_THREAD_TS冻结为不可变值正是让所有后续读写只依赖同一份“拥有者状态”、避免多个参与者各自推算线程坐标这一结构性手段后者与 unslop 则保证判定消息短、可读、无 AI 腔。二、第 1 步冻结源坐标在建立工作清单或委派任何 worker 之前必须先完成一次坐标冻结共 7 小步从触发器trigger读取source_channel_id要求它必须等于配置中的源频道否则停止若trigger.thread_ts存在则令SOURCE_THREAD_TS取它否则回退取trigger.ts要求SOURCE_THREAD_TS非空将SOURCE_CHANNEL_ID与SOURCE_THREAD_TS存为不可变值读取线程验证其根消息恰好就是这组坐标抓取一个稳定的源 permalink用于后续去重与工单回链。关键约束是此后所有对源的读取与发布都只能用这两个已存值绝不换成某条回复的时间戳或操作线程operations thread的时间戳。触发器的 JSON 结构在 templates/triage-automation-prompt.md 中给出{ source_channel_id: {{SLACK_CHANNEL_ID}}, message_ts: {{SLACK_MESSAGE_TS}}, thread_ts: {{SLACK_THREAD_TS_OR_EMPTY}} }该模板同时要求“把源频道与根线程时间戳视为不可变。任一缺失或与配置不符时停止且不发布、不写 tracker。”——这正是“fail closed失败即关闭”在入口处的体现。三、第 2 步读完整份报告决策前必须读完根消息和当前所有回复并按清单取证报告人的原话措辞reporter wording产品版本、app build、环境、平台若存在期望行为实际观察到的行为频率与触发条件错误文本或堆栈签名stack signature已有的 issue、commit 或 pull request 链接任何“已有人在修”的明确陈述。附件处理有独立的一节要求“检查每一个相关附件”截图按可用的最大有效分辨率阅读视频要定位出“把正确行为与损坏行为分开的那次状态迁移”日志、trace、崩溃文本要找具体签名媒体需要专家级审查时启用只读 media worker并只问一个狭窄问题worker 仅返回 findings若某个附件读不了就在判定中明说不得臆造其内容。结尾一句是取证总原则在再向报告人追问之前先用线程里已有的证据。四、第 3 步路由之前先做原因追踪选择 owner 或目的地之前先做一次“有界的bounded”源码与历史排查并显式复用 pstack 的两个技能用 how 技能追踪“报告中的动作 → 观察到的结果”这条路径。how定位是回答“X 如何工作”的架构走读简单问题单解释者一趟完成复杂子系统则并行派 2–4 个只读 explorer 再综合当报告像回归regression或涉及防御性代码时用 why 技能。why以“谨慎的调查者”姿态通过 git blame、git log --follow -p、PR 讨论等并行取证设计动机与变更原因。具体五步从报告的动作到观察到的结果识别最可能的代码路径判断可见症状是否属于该代码路径还是属于其下的某个依赖报告疑似回归时检查最近的变更检查是否已有合并的 commit 或开放的 PR 处理了同一症状把确认事实与假设分开。这一遍不要求完整根因只要求“强到足以避免把一个可见症状路由给错误的 owner”。如果仓库读不了则不要猜代码 owner继续做保守分类并说明“原因追踪不可用”。这与 FOR_AGENTS.md 中“两条自动化在频道坐标、tracker 访问、控制适配器或 feature map 缺失/不确定时都 fail closed”的共享规则一致。五、第 4 步五选一分类每条报告只允许落入一个类别类别判据后续动作倾向Bug行为违反预期错误输出、状态损坏、报错、崩溃、挂起、静默 no-op、回归可建单Performance可度量的慢、内存/电量超额、卡顿等资源问题按 bug 处理但必须保留测量值与 profileFeature request当前行为看起来是有意为之报告人想要不同行为或入口不建单Question or feedback询问机制、表达偏好而无具体缺陷、一般性反馈不建单Reroute原因追踪表明另一个已配置的目的地才是归属告知去向不交叉转发边界处理规则明确当 bug 与 feature request 的界限不清时不建单那条唯一的判定可以问一个聚焦问题并使用other标记。六、第 5 步应用配置路由与 owner ping 策略路由图从routing.map_path读取是可选数据。references/routing.example.md 给出了完整示例结构routes数组中每条路由带name、matchproduct_areas/code_paths/error_signatures三类匹配键、destinationSlack 频道与 tracker team、owners与allow_feature_owner_ping外加全局fallback目的地默认为空与ping_policy默认off允许configured-feature-owner与confirmed-regression-author拒绝broad-on-call-group与unverified-owner。该示例强调“triage 技能把它当作数据路由需要来自报告或原因追踪的证据单纯的关键词匹配不够”。匹配与处置规则按确认过的产品区域、代码路径或错误签名匹配当原因追踪指向别处时仅凭可见症状不足以命中路由没有任何路由匹配时明说 owner 不清不猜不交叉发帖cross-post只在源线程里告诉报告人应该把问题带到哪里。Owner ping人默认关闭只有以下四条全部成立才允许路由图里显式点名了该 owner配置允许该类型的 ping该条目是需要 owner 输入的 feature request或最近历史中有强证据指向疑似回归作者owner 不是宽泛的 on-call 组。其他任何情形都不 ping。这一策略与 configuration.example.yaml 中routing.owner_pings_default: false、allow_feature_owner_ping: false、allow_confirmed_regression_author_ping: false三个默认全关的字段一一对应。七、第 6 步issue-tracker 适配器契约文档把 tracker 明确定义为适配器adapter而非指定厂商Linear 只是“一种有效示例”GitHub Issues 或其他 tracker 只要实现同一契约即可。配置契约要求适配器提供七类能力按文本、状态、label、源 URL、日期区间搜索 issue读取单个 issue 及其链接以标题、正文、状态、labels、源 URL 创建 issue更新既有 issue 时不替换无关字段追加源链接与复发recurrence备注若 Slack 交接失败能取消/关闭/删除本次运行所建的 issue补偿动作隐含于 fail-closed 要求任一必需操作不可用时该写操作 fail closed。运行时规则配置的 team、project、status、labels 一律在运行时解析不发明 ID、不新建 label、不指派 owner、不设优先级除非配置显式要求。对应配置段为tracker: type: linear adapter_skill_name: issue-tracker-adapter-placeholder team: team-placeholder project: project-placeholder labels: bug: bug-label-placeholder performance: performance-label-placeholder intake: intake-label-placeholder needs_repro: needs-repro-label-placeholder status: intake-status-placeholder source_link_title: Slack report require_compensation_action: true其中require_compensation_action: true把“补偿动作可用”写成了硬性配置项——这是第 8 步建单前置条件 7 的配置侧对应物。八、第 7 步去重去重有两层。permalink 层无条件执行先检查本条源 permalink 是否已经挂到某个 tracker issue 或某条历史分诊回复上若是既不发布也不建重复单。语义层针对 bug 与 performance用以下维度在 tracker 中搜索——精确错误/崩溃签名、产品区域、触发条件、症状、版本或日期窗口、疑似回归 commit、源 permalink。搜索结果归入四种结论之一Confident duplicate同一签名或同区域同触发同症状或确认的共同原因Possibly related共同原因可能但未证实Weak resemblance相似只是表面No match。处置规则Confident duplicate在既有 issue 上追加源 permalink 与一条简短复发备注除非配置另有说明不重新打开、不改 label、不重新指派Possibly related在判定中作为“不确定”链接给出什么都不创建一个长期关闭的 issue 是“回归线索”不自动等于活跃重复项。九、第 8 步七条件建单门禁只有以下 7 条全部为真才创建 issue分类是 bug 或 performance行为明确是坏的该问题仍然活跃或没有被已知已修复去重没有发现任何“确信”或“疑似”的活跃匹配源父消息与 permalink 已通过 preflighttracker 目标字段已成功解析适配器具备在判定发布失败时的补偿能力。反向清单同样明确feature request、问题、反馈、reroute、疑似重复、确信重复、已修复的 issue一律不建单。新建 issue 必须是自包含的正文包含一个朴素标题点名区域与症状不把猜测的根因写进标题报告人原话引用期望与实际行为版本与环境没有就写unknown触发条件与频率源线程 permalink简短的原因追踪发现且假设必须标注为假设支持时内联截图或代表性视频帧其余产物的链接配置的 intake 状态与 labels。十、第 9 步发布唯一判定与标记契约发布流程先做一次全新的源父消息 preflight然后恰好发布一条回复且必须满足channelSOURCE_CHANNEL_ID、thread_tsSOURCE_THREAD_TS对源频道的任何发布动作若thread_ts为空则永不调用。回复保持短结论先行有 issue 就链接既有或新建的 tracker issue需要时提一句 reroute 或一个缺失事实至多包含一个允许的 owner ping以恰好一行标记marker收尾。标记契约marker contract[benny:bug] [benny:bug] trackerhttps://tracker.example/issue/123 [benny:performance] [benny:performance] trackerhttps://tracker.example/issue/123 [benny:other]约束只使用配置里给出的标记字符串对应 configuration.example.yaml 的verdict_markers段bug、performance、other三个字符串加tracker_attribute: tracker。下游的 repro 自动化只在该标记来自本源线程中已配置的分诊身份时才信任它——这就是两条自动化之间的信任握手协议。发布后的校验与补偿重新读取同一源线程确认判定出现在SOURCE_THREAD_TS之下若没有出现永不改在根消息重试若本次运行建过 tracker issue 而判定没落地就用适配器的补偿动作并验证 issue 已被取消、关闭或删除若补偿无法验证只在自动化运行输出中报告失败不向 Slack 发声。十一、第 10 步单个跟进窗口最后一步是守住一个有界的跟进窗口然后停止只回答指向分诊身份的直接提问在安全时对 tracker issue 做具体更正同一次运行中不发出第二个标记不介入人工协调与闲聊有人要求停止时提前结束窗口最多延长一次新报告应触发新的一次运行。窗口时长由配置budgets.triage_follow_up_minutes示例值 10 分钟与triage_total_minutes30 分钟控制示例预算段如下budgets: poll_seconds: 45 verdict_wait_minutes: 45 triage_follow_up_minutes: 10 triage_total_minutes: 30十二、落地方式配置、提示词与部署配置。分诊运行所需的全部外部值来自 templates/configuration.example.yaml。与分诊直接相关的段有slack源频道 ID、分诊身份triage_identity_user_id、读/线程发布/文件下载等已配置动作、prefer_cursor_actions、可选 bot token 环境变量、allow_source_root_posts: false与allow_worker_slack_writes: false两个默认关闭的开关——后者即“worker 永不持有 Slack 写权”的配置侧落点、tracker见第七节、routing、verdict_markers、status_emoji、budgets、modelstriage/reproduce/code/media_review四个模型槽位。文档要求配置缺失、畸形或不完整时“停止且不发布、不写 tracker”因此这些占位符必须在启用前全部填实。自动化提示词。templates/triage-automation-prompt.md 是供/automate起草自动化时“改写进草稿”的意图模板它要求运行时直接读取并遵循仓库内已提交的.cursor/automations/benny/skills/triage-issue-reports/SKILL.md禁止使用插件缓存路径或拷贝摘录声明触发语义为“配置源 Slack 频道中出现一条新的顶层报告”并重申协调者唯一发言、worker 只读且明确禁写、判定以恰好一个标记收尾、bug/performance 标记可附加trackerURL。部署路径。按 benny/README.md先把 Cursor 指向 FOR_AGENTS.md 并指明目标仓库setup 会把整个目录合并进目标仓库的.cursor/automations/benny/保留目标端独有文件、对冲突走“审阅差异再合并”而非覆盖然后在目标仓库的.cursor/settings.json中启用 pstackplugins: { pstack: { enabled: true } }使how、why、tdd、unslop等共享依赖在项目作用域内可解析。用户自有的配置含routing.md、feature map放在打包目录之外例如.cursor/benny/避免包刷新覆盖。启用前先提交.cursor/settings.json、.cursor/automations/benny/与所有无密钥配置再各建一次自动化草稿并“发一条无害的测试报告验证每条源频道发布都留在原线程内”。具体流程详见 setup-benny/SKILL.md。与 repro 自动化的衔接。分诊只负责判定复现与修复由 reproduce-and-fix-issues/SKILL.md 承接它在同一源线程等待被信任的[benny:bug]/[benny:performance]标记后才进入工作标记里附带的trackerURL即成为复现流程的入口凭据。两条自动化共享同一组不可变坐标与 fail-closed 规则这正是 FOR_AGENTS.md “shared rules”一节描述的架构意图。小结这份 triage SKILL.md 的价值在于把“AI 自动处理用户报障”这一高风险场景的全部危险面逐一压住发言权集中在协调者、线程坐标先冻结后使用、写操作前 preflight、路由与 ping 全部由配置与证据驱动、建单七条件门禁、去重四结论、标记契约作为下游信任锚点、失败时用 tracker 补偿动作回滚。它以纯文本操作指令加 YAML 数据的形式把多智能体协作的隔离边界、失败语义和可验证性写成了可审计、可复现的工程约定是研究 Slack 场景多智能体自动化时一个完整的参考实现。【免费下载链接】pluginsCursor plugin specification and official plugins项目地址: https://gitcode.com/GitHub_Trending/plugins125/plugins创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考