From 5c115e900ee9ffdc22a05bf64b93d83853fcc4d9 Mon Sep 17 00:00:00 2001 From: Mengz <2567587994@qq.com> Date: Sun, 26 Jul 2026 10:40:37 +0800 Subject: [PATCH] =?UTF-8?q?feat(skills):=20=E5=BC=BA=E5=8C=96=E7=8B=AC?= =?UTF-8?q?=E7=AB=8B=E7=BB=B4=E6=8A=A4=E8=80=85=E9=9B=B7=E8=BE=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- skills/gitlink-maintainer-radar/SKILL.md | 114 +++++++++++++++++- .../agents/openai.yaml | 2 +- .../examples/executive-duty-board.md | 29 +++++ .../scripts/validate_radar_report.py | 60 +++++++++ 4 files changed, 202 insertions(+), 3 deletions(-) create mode 100644 skills/gitlink-maintainer-radar/examples/executive-duty-board.md create mode 100644 skills/gitlink-maintainer-radar/scripts/validate_radar_report.py diff --git a/skills/gitlink-maintainer-radar/SKILL.md b/skills/gitlink-maintainer-radar/SKILL.md index 7f34682..a2d5ea8 100644 --- a/skills/gitlink-maintainer-radar/SKILL.md +++ b/skills/gitlink-maintainer-radar/SKILL.md @@ -1,14 +1,68 @@ --- name: gitlink-maintainer-radar -description: "维护者雷达:面向 GitLink 仓库维护者,联合扫描 open Pull Request、open Issue、消息提醒、review 分配和等待时长,识别响应超时、review 负载失衡、负责人长期停滞等协作瓶颈,生成按优先级排序的处置清单、催办建议和责任调整建议。用于用户需要值班巡检待办、判断哪些事项被晾着了、找出 reviewer 瓶颈、发现有负责人但无进展的条目,或生成维护者今日工作面板时。" +description: "GitLink 维护者队列专项雷达:扫描 open PR、open Issue、Review 分配和等待时长,识别响应超时、reviewer 负载失衡、责任停滞与安全事项运营优先级,生成带 MR 编号、明确等待方和证据的只读 Markdown 待办。用户只需点名 gitlink-maintainer-radar 并提供仓库;默认不调用其他 Skill、不修改远端。" --- +## 已合并功能的增量证据 + +配套 PR #430 的队列差异可作为本 Skill 的增量输入;#430 未合并时只使用当前队列,不得虚构变化。值班扫描优先展示 `new`、`priority_changed`、`risk_changed` 和 `resolved`,把未变化项压缩为数量;需要深入某个 PR 时,可在 PR #429 可用后用证据包补齐 Review、提交和 CI 状态: + +```bash +gitlink-cli workflow +review-queue --owner --repo --previous queue-previous.json --format json +gitlink-cli workflow +review-context --owner --repo --number --include-ci=true --format json +``` + +本 Skill 只负责 SLA、Reviewer 负载、责任停滞和今日待办;`risk_changed` 是提醒信号,不直接宣称代码存在漏洞或阻断合并。 + +队列项优先消费 `age_hours`、`waiting_hours`、`stale`、`review_state`、`reviewer_count` 和 `waiting_on`。同一 PR 的超 SLA、review 负载和责任停滞合并为一个 `MR-` 动作;`waiting_on=author` 才生成作者跟进,状态为空时只报告“责任未知”,不得误催 reviewer。`changes` 中的稳定项只保留计数,首屏最多列出 5 个动作。 + # gitlink-maintainer-radar **CRITICAL - 先阅读 [`../gitlink-shared/SKILL.md`](../gitlink-shared/SKILL.md),按其中的认证、全局参数和安全规则执行。** **CRITICAL - 所有 GitLink 操作只使用 `gitlink-cli`,不要改用 `gh`、`glab` 或网页猜测数据。** **CRITICAL - 默认只读分析。只有在用户明确要求时才回写评论、标签或成员分配。** +## 默认调用契约 + +用户只需说“使用 `gitlink-maintainer-radar` 扫描 `/`”;也可以给出 PR/Issue 编号限制范围。默认扫描当前 open 队列,除非仓库无法确定,不要求用户重复说明 SLA、输出格式或报告路径。 + +点名后默认自动执行: + +- 只分析响应时效、reviewer 负载、责任停滞、等待方和维护优先级,不调用其他 Skill,不判断代码漏洞、CLI 契约或合并就绪度。 +- 只读运行,不评论、不催办、不标记已读、不改标签、不分配、不关闭、不修改远端。 +- 使用 `MR-001` 起的稳定编号,记录对象、等待方、超时证据、紧迫度、影响、置信度和建议动作。 +- 首屏先显示今天直接能执行的最多 5 项动作;HOT、高风险和安全运营事项使用颜色和粗体。 +- 聊天和报告首屏按 PR 分节;响应 SLA、等待方、Reviewer 负载、责任停滞、安全运营优先级、维护动作分别使用结论前置判断卡,后接解释、`依据:` 和影响/下一步。 +- 一次运行只生成一份 UTF-8 Markdown,保存到 `reports/skill-runs/gitlink-maintainer-radar/---.md`;完整队列与负载明细放同一文件附录。 +- 报告文件是完成条件,不是可选附件。必须先确定本轮唯一绝对路径、写入完整报告并通过 `validate_radar_report.py`,之后才能发送聊天结论。 + +最终回复按 PR 复用报告首屏六方面判断卡,再给报告绝对路径;不得把多个 PR 或多个治理方面压成一段。正常可写工作区中不得以“已在聊天输出”为由跳过落盘,也不得返回上一轮旧报告路径。写入失败时先创建父目录并使用明确 UTF-8;只有文件系统确实不可写时才允许输出完整 Markdown 并标记“未落盘”。 + +首屏固定先使用: + +```markdown +# 维护者值班摘要 + +**队列事实:** 扫描 open PR 条,目标 PR 条,数据完整性 。 +**判定依据:** 固定 `as_of`、当前状态、活动时间和分配关系;详细结论按 PR 展示。 + +## PR #123 +**响应 SLA:** 已超时 24 小时 **[hot]**:等待 review 共 96 小时;依据:创建时间、最近活动和 72 小时阈值;影响:进入今日优先队列。 +**等待方:** 当前等待 reviewer **[action_required]**:作者已经更新且没有新 Review;依据:最后提交、Review 状态和分配关系;下一步:提醒或转派 reviewer。 +**Reviewer 负载:** 当前 reviewer 过载 **[high]**:名下积压 5 条待审 PR;依据:同一快照的 reviewer 待办计数;影响:建议释放容量。 +**责任停滞:** 责任明确但长期无动作 **[hot]**:分配后 4 天没有推进;依据:assignee/reviewer 与最后活动时间;下一步:确认接单或转派。 +**安全运营优先级:** 需要优先安排安全复看 **[high]**:改动触及权限路径;依据:文件范围和已有安全标记,不代表漏洞成立;影响:优先匹配安全 reviewer。 +**维护动作:** 今天完成转派并启动复看 **[action_required]**:该 PR 同时超 SLA 且责任停滞;依据:MR-001 与上述时间/负载证据;下一步:维护者确认 reviewer。 + +## 先做这 3 件事 + +1. [MR-001][blocking] 转派 PR #123 安全复查;等待:reviewer。 +2. [MR-002][high] 回复 Issue #87;首响超 24 小时。 +3. [MR-003][high] 复看 PR #118;等待:maintainer。 +``` + +指定多个 PR 时重复 `## PR #` 和六张卡。队列级计数仅作为范围元数据,不能代替逐 PR 判断。 + 这个 skill 不再做“把通知列表抄一遍”的弱摘要,而是把三类真正影响维护者效率的治理信号合在一起: 1. **响应时效雷达**:找出超出响应 SLA 的 Issue 和 PR。 @@ -17,6 +71,52 @@ description: "维护者雷达:面向 GitLink 仓库维护者,联合扫描 op 把它当作“维护者值班面板”来用,而不是通知中心。 +## 效率版值班面板 + +首屏只给维护者今天可以执行的队列: + +每次运行记录扫描时间、范围、默认分支、分页结果、字段缺口和数据新鲜度;默认只读,不自动提醒、分配、评论、关闭或修改远端对象。 + +- 先显示 HOT 数量、最早超时对象、安全事项、reviewer 瓶颈和本轮扫描时间。 +- 最多输出 5 项动作,并明确等待方:`author`、`reviewer`、`maintainer` 或 `platform`。 +- 同一 PR 的 SLA、review 负载和责任停滞信号合并为一项,避免重复催办。 +- 普通消息、点赞和已明确归属且未超时的条目只计数,不展开正文。 + +## 待办生成与误催防护 + +每个待办先计算 `urgency`、`impact`、`confidence` 三项,再合并成一个 `MR-` 动作: + +- `urgency`:首响超时、review 等待时长、超 SLA 程度和最近一次活动时间。 +- `impact`:安全热点、阻塞关系、PR 风险和受影响范围;只引用其他 Skill 的事实,不重新宣称漏洞。 +- `confidence`:是否有明确时间、reviewer/assignee、当前 head 和证据来源;未知责任或缺失快照必须降低置信度。 + +`waiting_on=author` 才生成作者跟进,`waiting_on=reviewer` 才生成 reviewer 跟进,`waiting_on=maintainer` 才生成维护者收口动作,空值只报告“责任未知”。同一 PR 的多个超时信号合并为一项;每日重复运行若运行键和证据未变化,只更新计数,不重复评论。 + +自动回写仅允许发布低风险、可撤销的事实提醒,且必须经过运行协议的幂等和证据条件;不得自动关闭 Issue/PR、强制分配 reviewer 或将超时升级为合并阻断。 + +报告首屏必须带 `as_of`、扫描范围、队列快照来源和数据完整性;每项 `MR-` 动作引用一个主证据和一个责任方,无法确认责任方时明确写“责任未知”。 + +对涉及凭据、权限、命令、路径、webhook、依赖和敏感数据的 PR 提升为安全 HOT;但仅凭标题或标签不能认定存在漏洞,必须标记证据状态,并优先收集 diff、测试和 Review 事实。 + +首屏格式: + +```markdown +# 维护者值班摘要 +## PR #123 +**响应 SLA:** 已超过 Review SLA **[hot]**:等待 96 小时;依据:固定扫描时间与最后活动;影响:今天处理。 +**等待方:** 等待 reviewer **[action_required]**:作者已更新;依据:提交和 Review 状态;下一步:安排复看。 +**Reviewer 负载:** 分配存在瓶颈 **[high]**:当前 reviewer 积压较多;依据:同一快照待审计数;下一步:考虑转派。 +**责任停滞:** 已分配但无推进 **[hot]**:责任关系存在但四天无动作;依据:分配与活动时间;下一步:确认接单。 +**安全运营优先级:** 需要安全复看 **[high]**:涉及权限路径;依据:改动文件与风险标签;影响:匹配专项 reviewer。 +**维护动作:** 今天转派并复看 **[action_required]**:同时命中超时和停滞;依据:MR-001;下一步:维护者执行分派。 +``` + +如果没有 open PR 或 open Issue,明确报告“没有可分析的 open PR/Issue”;如果消息接口失败,不得用通知列表代替协作队列,也不得伪造 SLA。 + +## 职责边界与组合协同 + +独立运行时,本 Skill 只分析响应时效、reviewer 负载、责任停滞和队列变化,不判断代码是否有漏洞、不评价 CLI 契约,也不决定 PR 是否可合并。组合运行时读取 `CR-xxx`、`CG-xxx`、`TP-xxx` 和 `IN-xxx` 的状态,只将它们转换为维护动作 `MR-xxx`;一个安全发现只提升优先级,不在本 Skill 中重新宣称漏洞成立。 + ## 核心能力 ### 1. 响应时效雷达 @@ -137,7 +237,7 @@ gitlink-cli pr +version-diff --owner --repo -i --format - review 结论是否已经形成,但没有后续动作 - 是否存在 reviewer 过载导致的人工瓶颈 -如果用户需要深入判断代码可行性,切换到 `gitlink-pr-assessor`。如果用户要判断是否适合集成主线,切换到 `gitlink-pr-integrator`。 +如果发现需要代码可行性或集成判断,只写入“超出本次范围”和建议后续检查,不自动调用其他 Skill。 ### Step 4:为停滞 Issue 建立责任视图 @@ -170,6 +270,16 @@ gitlink-cli pr +version-diff --owner --repo -i --format 4. 今天建议先做的动作 5. 可延后的背景项 +保存后必须运行: + +```bash +python -X utf8 skills/gitlink-maintainer-radar/scripts/validate_radar_report.py \ + --report + +``` + +随后严格按 UTF-8 重读报告,确认每个目标 PR 都有“响应 SLA、等待方、Reviewer 负载、责任停滞、安全运营优先级、维护动作”六方面结论前置判断卡。失败时必须补写或修复报告并重新校验,不能直接结束任务。 + 推荐输出模板: ```markdown diff --git a/skills/gitlink-maintainer-radar/agents/openai.yaml b/skills/gitlink-maintainer-radar/agents/openai.yaml index a68ddc2..7ead41d 100644 --- a/skills/gitlink-maintainer-radar/agents/openai.yaml +++ b/skills/gitlink-maintainer-radar/agents/openai.yaml @@ -1,4 +1,4 @@ interface: display_name: "维护者雷达" short_description: "识别响应超时、review 失衡和责任停滞,生成维护者处置面板。" - default_prompt: "Use $gitlink-maintainer-radar 扫描这个 GitLink 仓库当前的响应 SLA、review 负载和责任停滞情况,输出按优先级排序的处置清单和建议动作。" + default_prompt: "使用 $gitlink-maintainer-radar 扫描指定 GitLink 仓库或 PR;聊天和 Markdown 均按 PR 分节,将响应 SLA、等待方、Reviewer 负载、责任停滞、安全运营优先级、维护动作分别做成结论前置判断卡,后接依据与影响;保存并校验 UTF-8 报告,全程只读。" diff --git a/skills/gitlink-maintainer-radar/examples/executive-duty-board.md b/skills/gitlink-maintainer-radar/examples/executive-duty-board.md new file mode 100644 index 0000000..4601b32 --- /dev/null +++ b/skills/gitlink-maintainer-radar/examples/executive-duty-board.md @@ -0,0 +1,29 @@ +# 轻量维护者值班示例 + +```bash +gitlink-cli pr +list --owner Gitlink --repo gitlink-cli --state open --format json +gitlink-cli issue +list --owner Gitlink --repo gitlink-cli --state open --format json +gitlink-cli api GET users//messages.json --query "status=1&limit=40" --format json +``` + +```markdown +# 维护者值班摘要 + +**队列事实:** 扫描 open PR 12 条、open Issue 8 条,时间基线为 `2026-07-23T08:00:00Z`。 +**判定依据:** 当前状态、创建和最后活动时间、Review、reviewer/assignee 与配置 SLA。 + +## PR #123 +**响应 SLA:** Review 已超时 **[hot]**:等待 reviewer 96 小时,超过 72 小时阈值;依据:固定扫描时间和最后有效活动;影响:进入今日优先队列。 +**等待方:** 当前等待 reviewer **[action_required]**:作者已提交修复但尚无复看结论;依据:最后提交晚于最后 Review;下一步:提醒或转派 reviewer。 +**Reviewer 负载:** 现有分配形成瓶颈 **[high]**:当前 reviewer 同时积压 5 条待审 PR;依据:同一快照内的待审计数;影响:继续等待风险较高。 +**责任停滞:** 责任明确但长期无推进 **[hot]**:分配后 4 天没有动作;依据:reviewer 分配时间与活动时间线;下一步:确认接单或释放责任。 +**安全运营优先级:** 需要优先安排安全复看 **[high]**:改动触及认证路径但不代表漏洞成立;依据:文件范围和已有安全标记;影响:应匹配安全 reviewer。 +**维护动作:** 今天完成转派并启动复看 **[action_required]**:超 SLA、负载瓶颈和安全关注同时存在;依据:MR-001 至 MR-003;下一步:维护者指定可用 reviewer。 + +## 先做这 3 件事 +1. **[MR-001][blocking] 转派** PR #123 的安全复查,当前等待 reviewer(责任:维护者)。 +2. **[MR-002][high] 回复** Issue #87,首响已超时(责任:维护者)。 +3. **[MR-003][high] 复看** 作者已更新的 PR #118(责任:reviewer)。 +``` + +只展开会改变本轮行动的条目。普通通知只计数;接口失败、空队列和未配置 SLA 都要原样标出。 diff --git a/skills/gitlink-maintainer-radar/scripts/validate_radar_report.py b/skills/gitlink-maintainer-radar/scripts/validate_radar_report.py new file mode 100644 index 0000000..1e44f3b --- /dev/null +++ b/skills/gitlink-maintainer-radar/scripts/validate_radar_report.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python3 +"""Validate that maintainer-radar saves a usable UTF-8 Markdown report.""" + +from __future__ import annotations + +import argparse +import re +import sys +from pathlib import Path + + +REQUIRED_MARKERS = ( + "# 维护者值班摘要", + "**队列事实:**", + "**判定依据:**", + "## PR #", + "**响应 SLA:**", + "**等待方:**", + "**Reviewer 负载:**", + "**责任停滞:**", + "**安全运营优先级:**", + "**维护动作:**", + "MR-", +) + + +def validate_report(text: str) -> list[str]: + errors: list[str] = [] + if "\ufffd" in text or "\x00" in text or "\x1b" in text: + errors.append("report contains invalid encoding or ANSI control characters") + for marker in REQUIRED_MARKERS: + if marker not in text: + errors.append(f"missing radar report marker: {marker}") + cjk_count = len(re.findall(r"[\u3400-\u9fff]", text)) + if cjk_count < 60: + errors.append(f"radar narrative is incomplete: found {cjk_count} CJK characters, need at least 60") + return errors + + +def main() -> int: + parser = argparse.ArgumentParser(description="Validate a saved maintainer-radar report.") + parser.add_argument("--report", required=True, type=Path) + args = parser.parse_args() + try: + text = args.report.read_text(encoding="utf-8", errors="strict") + except (OSError, UnicodeError) as exc: + print(f"radar report validation failed: {exc}", file=sys.stderr) + return 2 + errors = validate_report(text) + if errors: + print("radar report validation failed:", file=sys.stderr) + for error in errors: + print(f"- {error}", file=sys.stderr) + return 1 + print(f"radar report validation passed: {args.report.resolve()}") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main())