Compare commits

...

1 Commits

Author SHA1 Message Date
Mengz 5c115e900e feat(skills): 强化独立维护者雷达 2026-07-26 10:40:37 +08:00
4 changed files with 202 additions and 3 deletions

View File

@ -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 <owner> --repo <repo> --previous queue-previous.json --format json
gitlink-cli workflow +review-context --owner <owner> --repo <repo> --number <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` 扫描 `<owner>/<repo>`”;也可以给出 PR/Issue 编号限制范围。默认扫描当前 open 队列,除非仓库无法确定,不要求用户重复说明 SLA、输出格式或报告路径。
点名后默认自动执行:
- 只分析响应时效、reviewer 负载、责任停滞、等待方和维护优先级,不调用其他 Skill不判断代码漏洞、CLI 契约或合并就绪度。
- 只读运行,不评论、不催办、不标记已读、不改标签、不分配、不关闭、不修改远端。
- 使用 `MR-001` 起的稳定编号,记录对象、等待方、超时证据、紧迫度、影响、置信度和建议动作。
- 首屏先显示今天直接能执行的最多 5 项动作HOT、高风险和安全运营事项使用颜色和粗体。
- 聊天和报告首屏按 PR 分节;响应 SLA、等待方、Reviewer 负载、责任停滞、安全运营优先级、维护动作分别使用结论前置判断卡,后接解释、`依据:` 和影响/下一步。
- 一次运行只生成一份 UTF-8 Markdown保存到 `reports/skill-runs/gitlink-maintainer-radar/<owner>-<repo>-<scope>-<yyyyMMdd-HHmmssZ>.md`;完整队列与负载明细放同一文件附录。
- 报告文件是完成条件,不是可选附件。必须先确定本轮唯一绝对路径、写入完整报告并通过 `validate_radar_report.py`,之后才能发送聊天结论。
最终回复按 PR 复用报告首屏六方面判断卡,再给报告绝对路径;不得把多个 PR 或多个治理方面压成一段。正常可写工作区中不得以“已在聊天输出”为由跳过落盘,也不得返回上一轮旧报告路径。写入失败时先创建父目录并使用明确 UTF-8只有文件系统确实不可写时才允许输出完整 Markdown 并标记“未落盘”。
首屏固定先使用:
```markdown
# 维护者值班摘要
**队列事实:** 扫描 open PR <n> 条,目标 PR <n> 条,数据完整性 <status>
**判定依据:** 固定 `as_of`、当前状态、活动时间和分配关系;详细结论按 PR 展示。
## PR #123
**响应 SLA** <span style="color:#B42318"><strong>已超时 24 小时</strong></span> **[hot]**:等待 review 共 96 小时;依据:创建时间、最近活动和 72 小时阈值;影响:进入今日优先队列。
**等待方:** <span style="color:#B54708"><strong>当前等待 reviewer</strong></span> **[action_required]**:作者已经更新且没有新 Review依据最后提交、Review 状态和分配关系;下一步:提醒或转派 reviewer。
**Reviewer 负载:** <span style="color:#B54708"><strong>当前 reviewer 过载</strong></span> **[high]**:名下积压 5 条待审 PR依据同一快照的 reviewer 待办计数;影响:建议释放容量。
**责任停滞:** <span style="color:#B42318"><strong>责任明确但长期无动作</strong></span> **[hot]**:分配后 4 天没有推进依据assignee/reviewer 与最后活动时间;下一步:确认接单或转派。
**安全运营优先级:** <span style="color:#B42318"><strong>需要优先安排安全复看</strong></span> **[high]**:改动触及权限路径;依据:文件范围和已有安全标记,不代表漏洞成立;影响:优先匹配安全 reviewer。
**维护动作:** <span style="color:#B42318"><strong>今天完成转派并启动复看</strong></span> **[action_required]**:该 PR 同时超 SLA 且责任停滞依据MR-001 与上述时间/负载证据;下一步:维护者确认 reviewer。
## 先做这 3 件事
1. <span style="color:#B42318"><strong>[MR-001][blocking] 转派</strong></span> PR #123 安全复查等待reviewer。
2. <span style="color:#B54708"><strong>[MR-002][high] 回复</strong></span> Issue #87;首响超 24 小时。
3. <span style="color:#B54708"><strong>[MR-003][high] 复看</strong></span> PR #118等待maintainer。
```
指定多个 PR 时重复 `## PR #<number>` 和六张卡。队列级计数仅作为范围元数据,不能代替逐 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** <span style="color:#B42318"><strong>已超过 Review SLA</strong></span> **[hot]**:等待 96 小时;依据:固定扫描时间与最后活动;影响:今天处理。
**等待方:** <span style="color:#B54708"><strong>等待 reviewer</strong></span> **[action_required]**:作者已更新;依据:提交和 Review 状态;下一步:安排复看。
**Reviewer 负载:** <span style="color:#B54708"><strong>分配存在瓶颈</strong></span> **[high]**:当前 reviewer 积压较多;依据:同一快照待审计数;下一步:考虑转派。
**责任停滞:** <span style="color:#B42318"><strong>已分配但无推进</strong></span> **[hot]**:责任关系存在但四天无动作;依据:分配与活动时间;下一步:确认接单。
**安全运营优先级:** <span style="color:#B54708"><strong>需要安全复看</strong></span> **[high]**:涉及权限路径;依据:改动文件与风险标签;影响:匹配专项 reviewer。
**维护动作:** <span style="color:#B42318"><strong>今天转派并复看</strong></span> **[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 <owner> --repo <repo> -i <number> --format
- review 结论是否已经形成,但没有后续动作
- 是否存在 reviewer 过载导致的人工瓶颈
如果用户需要深入判断代码可行性,切换到 `gitlink-pr-assessor`。如果用户要判断是否适合集成主线,切换到 `gitlink-pr-integrator`
如果发现需要代码可行性或集成判断,只写入“超出本次范围”和建议后续检查,不自动调用其他 Skill
### Step 4为停滞 Issue 建立责任视图
@ -170,6 +270,16 @@ gitlink-cli pr +version-diff --owner <owner> --repo <repo> -i <number> --format
4. 今天建议先做的动作
5. 可延后的背景项
保存后必须运行:
```bash
python -X utf8 skills/gitlink-maintainer-radar/scripts/validate_radar_report.py \
--report <absolute-report-path>
```
随后严格按 UTF-8 重读报告,确认每个目标 PR 都有“响应 SLA、等待方、Reviewer 负载、责任停滞、安全运营优先级、维护动作”六方面结论前置判断卡。失败时必须补写或修复报告并重新校验,不能直接结束任务。
推荐输出模板:
```markdown

View File

@ -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 报告,全程只读。"

View File

@ -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/<login>/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** <span style="color:#B42318"><strong>Review 已超时</strong></span> **[hot]**:等待 reviewer 96 小时,超过 72 小时阈值;依据:固定扫描时间和最后有效活动;影响:进入今日优先队列。
**等待方:** <span style="color:#B54708"><strong>当前等待 reviewer</strong></span> **[action_required]**:作者已提交修复但尚无复看结论;依据:最后提交晚于最后 Review下一步提醒或转派 reviewer。
**Reviewer 负载:** <span style="color:#B54708"><strong>现有分配形成瓶颈</strong></span> **[high]**:当前 reviewer 同时积压 5 条待审 PR依据同一快照内的待审计数影响继续等待风险较高。
**责任停滞:** <span style="color:#B42318"><strong>责任明确但长期无推进</strong></span> **[hot]**:分配后 4 天没有动作依据reviewer 分配时间与活动时间线;下一步:确认接单或释放责任。
**安全运营优先级:** <span style="color:#B42318"><strong>需要优先安排安全复看</strong></span> **[high]**:改动触及认证路径但不代表漏洞成立;依据:文件范围和已有安全标记;影响:应匹配安全 reviewer。
**维护动作:** <span style="color:#B42318"><strong>今天完成转派并启动复看</strong></span> **[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 都要原样标出。

View File

@ -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())