gitlink-cli/skills/gitlink-stale/references/gitlink-stale-exempt.md

11 KiB
Raw Blame History

gitlink-stale — 白名单豁免规则

本文档详述"哪些 Issue/PR 永不被 stale skill 处理"的完整规则。 豁免规则在 Stage B 执行,先于 AI 判断(节省 API 调用)。

1. 豁免原则

核心思想:宁可放过,不可误关。

任何满足"长期重要"或"主动声明保留"信号的 Issue 都应被豁免。

原则 说明
保守 不确定时,豁免(不处理)
多信号 任一豁免信号触发即可
可追溯 豁免原因必须记录在报告中
可配置 用户可自定义豁免规则

2. 豁免信号全集

2.1 标签豁免(最强信号)

标签名(中/英) 豁免原因 默认权重
pinned / 置顶 显式标记永久保留 必豁免
security / 安全 安全相关,永不自动关闭 必豁免
roadmap / 路线图 长期规划 必豁免
epic / 里程碑 大型任务父节点 必豁免
keep-open / 保留 显式声明 必豁免
in-progress / 进行中 正在处理 必豁免
under-review / 审查中 等待审查 必豁免
help-wanted 等社区认领 必豁免
good-first-issue 等新手认领 必豁免
p0 / p1 高优先级 必豁免

2.2 Tracker 类型豁免

GitLink 的 tracker_id 映射(参考 issue-triage skill

tracker_id 名称 默认豁免
1 bug 不豁免(仍可能 stale
2 feature 不豁免
3 support 不豁免(最易 stale
4 doc 不豁免
5 test 不豁免
6 duplicate 直接关闭(特殊处理)
7 question 不豁免
自定义 roadmap 豁免
自定义 epic 豁免

2.3 优先级豁免

priority_id 等级 默认豁免
1 low 不豁免
2 normal 不豁免
3 high ⚠️ 仅在 confidence >= 0.9 时处理
4 urgent 豁免

2.4 标题模式豁免

匹配以下正则的标题豁免:

keep_open_title_patterns:
  - "\\[WIP\\]"
  - "\\[Pinned\\]"
  - "\\[Keep.?Open\\]"
  - "\\[RFC\\]"
  - "^Roadmap:"
  - "^路线图"
  - "^讨论"
  - "^提案"
  - "长期"
  - "permanent"

匹配以下模式的标题强制关闭(反向豁免):

force_close_title_patterns:
  - "^测试$"           # 仅"测试"两字
  - "^test$"           # 仅"test"
  - "\\[占位\\]"
  - "\\[已过期\\]"
  - "^ignore$"
  - "deprecated"

2.5 作者豁免

作者类型 豁免规则
仓库 owner 豁免(信任 owner 会跟进)
仓库 member 豁免
资深贡献者(≥ 10 PR merged ⚠️ confidence >= 0.85 才处理
普通用户 不豁免
路过用户(仅 1 Issue 不豁免(更倾向清理)

2.6 时间豁免

时间条件 豁免规则
创建时间 < 7 天 豁免(给新 Issue 缓冲期)
最后活动 < 60 天 豁免(未达 stale 阈值)
已 milestone 锁定 豁免

2.7 关联豁免

关联条件 豁免规则
有 linked PR标题含"fixed in #N" 豁免(等 PR 合并)
有子任务(被 epic 引用) 豁免
duplicate of 已 closed 直接关闭(特殊处理)

3. 豁免执行算法

def check_exempt(issue, repo_meta, user_meta):
    """
    返回 (is_exempt, reason) 或 (False, None)
    
    顺序:从最强信号到弱信号,任一触发即返回
    """
    
    # 1. 标签豁免(最强)
    EXEMPT_LABELS = {
        "pinned", "置顶",
        "security", "安全",
        "roadmap", "路线图",
        "epic", "里程碑",
        "keep-open", "保留",
        "in-progress", "进行中",
        "under-review", "审查中",
        "help-wanted",
        "good-first-issue",
        "p0", "p1",
    }
    
    for label in get_labels(issue):
        if label.lower() in EXEMPT_LABELS:
            return True, f"含豁免标签: {label}"
    
    # 2. 标题强信号
    import re
    for pattern in KEEP_OPEN_TITLE_PATTERNS:
        if re.search(pattern, issue.subject, re.IGNORECASE):
            return True, f"标题匹配保留模式: {pattern}"
    
    # 3. 优先级豁免
    if issue.priority_id == 4:  # urgent
        return True, "urgent 优先级"
    
    # 4. tracker 豁免
    if issue.tracker_id in [ROADMAP, EPIC]:
        return True, "tracker 是 roadmap/epic"
    
    # 5. 作者豁免
    if issue.author.login == repo_meta.owner:
        return True, "作者是仓库 owner"
    if issue.author.login in repo_meta.members:
        return True, "作者是仓库 member"
    
    # 6. 时间豁免(创建 < 7 天)
    days_since_created = (now() - parse(issue.created_at)).days
    if days_since_created < 7:
        return True, f"创建仅 {days_since_created} 天,在缓冲期内"
    
    # 7. 高优先级的特殊处理
    if issue.priority_id == 3:  # high
        # 不直接豁免,但需要 confidence >= 0.9
        return False, None  # 走正常流程
    
    return False, None


def check_force_close(issue):
    """
    反向豁免:强制关闭
    """
    import re
    for pattern in FORCE_CLOSE_TITLE_PATTERNS:
        if re.search(pattern, issue.subject, re.IGNORECASE):
            return True, f"标题匹配强制关闭模式: {pattern}"
    return False, None

4. 豁免决策流程图

       ┌─────────────────────────────┐
       │ Issue 候选(已通过时间过滤)   │
       └────────────┬────────────────┘
                    ▼
       ┌─────────────────────────────┐
       │ 1. 强制关闭模式匹配?         │─── 是 ──→ force_close
       └────────────┬────────────────┘
                    │ 否
                    ▼
       ┌─────────────────────────────┐
       │ 2. 含豁免标签?              │─── 是 ──→ exempt
       └────────────┬────────────────┘
                    │ 否
                    ▼
       ┌─────────────────────────────┐
       │ 3. 标题匹配保留模式?         │─── 是 ──→ exempt
       └────────────┬────────────────┘
                    │ 否
                    ▼
       ┌─────────────────────────────┐
       │ 4. priority == urgent      │─── 是 ──→ exempt
       └────────────┬────────────────┘
                    │ 否
                    ▼
       ┌─────────────────────────────┐
       │ 5. tracker == roadmap/epic │─── 是 ──→ exempt
       └────────────┬────────────────┘
                    │ 否
                    ▼
       ┌─────────────────────────────┐
       │ 6. 作者是 owner/member     │─── 是 ──→ exempt
       └────────────┬────────────────┘
                    │ 否
                    ▼
       ┌─────────────────────────────┐
       │ 7. 创建 < 7 天?             │─── 是 ──→ exempt
       └────────────┬────────────────┘
                    │ 否
                    ▼
              进入 AI 判断

5. 自定义豁免规则

用户可在仓库根目录创建 .gitlink-stale.yml 自定义:

# .gitlink-stale.yml
version: 1.0

# 阈值
thresholds:
  stale_days: 60
  close_days: 74
  grace_days: 14

# 豁免标签(追加到默认列表)
exempt_labels:
  - "客户合同"
  - "VIP 用户反馈"

# 豁免标题模式(追加)
exempt_title_patterns:
  - "^\\[长期讨论\\]"

# 强制关闭模式(追加)
force_close_title_patterns:
  - "^spam"

# 豁免用户
exempt_authors:
  - "trusted-contributor"

# 自定义 priority 豁免
exempt_priorities:
  - 4  # urgent
  - 3  # high比默认更严格

# 自定义 tracker 豁免
exempt_trackers:
  - 8  # 自定义的"内部任务"

💡 Skill 在执行前自动加载此文件(如果存在),与默认规则合并。详见 SKILL.md §4.3


6. 豁免审计

报告中必须列出所有被豁免的 Issue便于人工复核

{
  "summary": {
    "exempt": 15,
    "exempt_breakdown": {
      "label_pinned": 3,
      "label_security": 2,
      "label_roadmap": 5,
      "priority_urgent": 2,
      "author_owner": 2,
      "title_pattern": 1
    }
  },
  "exempt_items": [
    {
      "number": 88,
      "title": "[Pinned] 项目长期路线图",
      "exempt_reason": "含豁免标签: pinned",
      "exempt_signal": "label_pinned"
    },
    {
      "number": 92,
      "title": "线上数据库故障",
      "exempt_reason": "urgent 优先级",
      "exempt_signal": "priority_urgent"
    }
  ]
}

7. 边界情况

情况 处理
同一 Issue 含豁免标签和强制关闭模式 豁免优先(保守原则)
标签名大小写不同(Pinned vs pinned 大小写不敏感
标签名含空格(keep open 标准化(去空格、转小写)后比较
标签是 emoji📌 当前不支持,建议搭配文字标签
作者 ID 已注销(login == null 不豁免(可能就是僵尸)
用户自定义规则与默认冲突 用户规则优先(追加而非覆盖)

8. 推荐的标签配置

为了让 Skill 发挥最佳效果,强烈推荐仓库具备以下标签:

标签名 用途
pinned 显式标记永久保留的 Issue
security 安全相关
roadmap 路线图
stale 已被本 Skill 标记
duplicate 重复 Issue
wontfix 决定不修复(但保留记录)

如果仓库缺少这些标签Skill 在执行前会提示用户创建(不会自动创建,避免越权)。