Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ae357a20f7 | ||
|
|
c6ef6820e4 | ||
|
|
175c612d35 |
@@ -0,0 +1,2 @@
|
||||
blank_issues_enabled: true
|
||||
contact_links: []
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
name: 新技能提案
|
||||
about: 提新技能或技能改动前先过 SCOPE.md 门槛(默认拒绝,能组合就不新增)
|
||||
title: "[技能] "
|
||||
labels: skill
|
||||
---
|
||||
|
||||
## 1. 真实失败(必填)
|
||||
|
||||
在哪个真实任务/会话里出了问题?跑了什么、期望什么、实际什么。
|
||||
|
||||
> 假设性的「这样会更好」不算。说不清就说明还不到提的时候。
|
||||
|
||||
## 2. 为什么组合不出来(必填)
|
||||
|
||||
用现有哪个技能组合试过?为什么做不到?
|
||||
|
||||
> 能组合出来的,改现有技能,不新增。
|
||||
|
||||
## 3. 是否重复提案
|
||||
|
||||
- [ ] 已读 `.out-of-scope/` 三份拒绝档案,不是重复提案
|
||||
|
||||
## 4. 分桶与调用模式
|
||||
|
||||
- 初始分桶:`beta`(新技能一律先 beta)
|
||||
- 调用模式:`model-invoked` / `user-invoked`
|
||||
- 判定:这件事是不是「人下命令才开始」?是 → `user-invoked`(同时写 `disable-model-invocation: true`)
|
||||
|
||||
## 5. 最低交付
|
||||
|
||||
- [ ] `evals/evals.json` 3 条:正常路径 / 边界 / 失败恢复
|
||||
- [ ] `docs/skills/<name>.md` 四段式:What it does / When to reach for it / Common questions / It's working if
|
||||
- [ ] `docs/skill-routing.md` 已回改
|
||||
- [ ] `catalog.json` 已 regenerate
|
||||
- [ ] `CHANGELOG.md` + `plugin.json` 版本号
|
||||
@@ -0,0 +1,24 @@
|
||||
## 这个 PR 做了什么
|
||||
|
||||
<!-- 一句话,说明改的是哪个技能 / 哪套流程 -->
|
||||
|
||||
## SCOPE 门槛
|
||||
|
||||
- [ ] 真实失败:说清了在哪个真实任务里出的问题
|
||||
- [ ] 组合不出来:说明用现有技能组合为什么做不到
|
||||
- [ ] 已查 `.out-of-scope/`,不是重复提案
|
||||
|
||||
## 改动检查
|
||||
|
||||
- [ ] 分桶正确(新技能一律 `beta`;`promoted` 需要真实使用记录 + evals 通过)
|
||||
- [ ] 调用模式正确(`user-invoked` 必须写 `disable-model-invocation: true`)
|
||||
- [ ] `evals/evals.json` 3 条(正常 / 边界 / 失败恢复)
|
||||
- [ ] `docs/skills/<name>.md` 四段式
|
||||
- [ ] `docs/skill-routing.md` 已回改
|
||||
- [ ] `catalog.json` 已 regenerate(`python3 scripts/generate-catalog.py`)
|
||||
- [ ] `CHANGELOG.md` + `plugin.json` 版本号已更新
|
||||
- [ ] 四道门禁通过:`validate-skills.py --strict`、`scan-skill.sh`、`generate-catalog.py --check`、`tests/install-skills.test.sh`
|
||||
|
||||
## 人工拍板项(有则写明)
|
||||
|
||||
<!-- deprecated 删除、路由变更、promoted 晋升,需要人确认 -->
|
||||
@@ -25,3 +25,9 @@ __pycache__/
|
||||
|
||||
# Node
|
||||
node_modules/
|
||||
|
||||
# 定时任务产出(本机运行产物,不回写仓库;evals 结果报告除外)
|
||||
reports/skill-health/
|
||||
reports/monthly/
|
||||
reports/_scheduler/
|
||||
reports/evals/queue-*.md
|
||||
|
||||
@@ -58,5 +58,13 @@
|
||||
|
||||
- 新增 beta 技能 `diagnosing-bugs`(难查 bug 诊断纪律:先建红循环再推理),补齐 evals 与四段式文档;路由表同步。
|
||||
- 新增 `scripts/monthly-review.sh`:一条命令跑月度审阅(覆盖率 / 扫描 / 第三方 / catalog / description 异常)。
|
||||
|
||||
### 治理落地:定时任务与提案入口(2026-11-01)
|
||||
|
||||
- 新增 `scripts/scheduled-task.sh`:`daily` / `weekly` / `monthly` 三个确定性任务,只跑门禁、扫漂移、生成队列;需要模型判断的部分(真跑 evals、审阅 routing)生成 queue 文件交 agent。
|
||||
- 新增 `scripts/install-schedulers.sh`:把节拍装成 macOS 用户级 launchd(`com.pipexerp.ai-proj-skill-{daily,weekly,monthly}`),不再依赖会话提醒;支持 `--status` / `--run` / `--uninstall`。
|
||||
- 新增 `.gitea/issue_template/new-skill.md`、`.gitea/issue_template/config.yaml`、`.gitea/pull_request_template.md`:提案与 PR 走同一套 SCOPE 门槛问题。
|
||||
- `README.md` 一键部署从 2 步改为 4 步(补 git hooks 与定时任务);`MAINTENANCE.md` 增加「定时任务」一节,写明脚本只做确定性动作的边界。
|
||||
- `.gitignore` 排除定时任务产出(`reports/skill-health/`、`reports/monthly/`、`reports/_scheduler/`、`reports/evals/queue-*.md`)。
|
||||
- 新增 `scripts/evals-status.py` 与 `reports/evals/TEMPLATE.md`:evals 覆盖率与回归报告模板。
|
||||
- `skill-creator` 实战记录 #1:用标准流程新建 `diagnosing-bugs`(beta,待观察后晋升)。
|
||||
|
||||
@@ -45,6 +45,27 @@
|
||||
- 复核覆盖率:`--coverage` 的两项缺口是否按路线图收敛。
|
||||
- 更新本文件与 `CHANGELOG.md`。
|
||||
|
||||
## 定时任务(launchd,2026-11-01 起)
|
||||
|
||||
节拍不再挂在「会话提醒」上(会话一断就失效),改成宿主级 launchd:
|
||||
|
||||
```bash
|
||||
./scripts/install-schedulers.sh # 安装(幂等;换机器重跑一次即可复现)
|
||||
./scripts/install-schedulers.sh --status # 看状态与最近产出
|
||||
./scripts/install-schedulers.sh --run daily # 立刻跑一次(调试)
|
||||
./scripts/install-schedulers.sh --uninstall
|
||||
```
|
||||
|
||||
| 任务 | 时间 | 脚本做什么 | 产出 |
|
||||
| --- | --- | --- | --- |
|
||||
| `daily` | 每天 07:20 | 漂移 audit + 入库安全扫描 + 覆盖率 | `reports/skill-health/daily-YYYY-MM-DD.md`(`latest.md` 供 7:30 日报直接读) |
|
||||
| `weekly` | 每周一 10:00 | 算上周改动技能 + 3 个高风险项,生成 evals 抽样队列 | `reports/evals/queue-YYYY-MM-DD.md` |
|
||||
| `monthly` | 每月 1 日 10:00 | 一条命令跑完月度审阅;1/4/7/10 月附季度治理清单 | `reports/monthly/review-YYYY-MM.md`、`quarterly-YYYY-Qn.md` |
|
||||
|
||||
**边界**:脚本只做确定性动作。真跑 evals、审阅 routing 这类需要模型判断的部分,脚本只生成队列文件,由项目经理 Bot 在 7:30 日报里接手执行——分工不写在脚本里就会漏。
|
||||
|
||||
日志:`reports/_scheduler/<job>.log`。
|
||||
|
||||
## 责任分工
|
||||
|
||||
- 项目经理 Bot:执行节奏、出周/月报、盯漂移与门禁。
|
||||
|
||||
@@ -69,7 +69,7 @@ PRD 文档存储在思源笔记中,可以导出发送到飞书群,通过飞
|
||||
- **Codex**([Skills 文档](https://developers.openai.com/codex/skills))或 **Claude Code** 已安装
|
||||
- **ai-proj 账号 + MCP API Key**:联系管理员获取(Key 格式: `aiproj_pk_xxx`)
|
||||
|
||||
### 一键部署(2 步搞定)
|
||||
### 一键部署(4 步搞定)
|
||||
|
||||
```bash
|
||||
# 1. 克隆仓库
|
||||
@@ -78,8 +78,16 @@ cd ai-proj-helper
|
||||
|
||||
# 2. 默认安装到 Codex 的用户级标准目录 ~/.agents/skills
|
||||
./install-skills.sh
|
||||
|
||||
# 3. 装本地门禁(Gitea Actions 无 runner,commit/push 靠 git hook 兜底)
|
||||
./scripts/install-git-hooks.sh
|
||||
|
||||
# 4. 装技能治理定时任务(macOS launchd:每日漂移检查 / 每周 evals 队列 / 每月审阅)
|
||||
./scripts/install-schedulers.sh
|
||||
```
|
||||
|
||||
第 3、4 步只对「本仓库的维护者」需要——只装技能给别人用的,跑完第 2 步就可以停。
|
||||
|
||||
安装器会复制完整技能目录,包括 `SKILL.md`、references、scripts 和 assets。Codex 会自动发现 `~/.agents/skills` 中的技能;若没有出现,重启 Codex。
|
||||
|
||||
Claude Code 用户显式选择 Claude 目标;需要同时配置 MCP 和 marketplace 时运行 `init.sh`:
|
||||
|
||||
Executable
+143
@@ -0,0 +1,143 @@
|
||||
#!/usr/bin/env bash
|
||||
# 安装 / 卸载 / 查看技能治理的定时任务(macOS 用户级 launchd)
|
||||
#
|
||||
# 为什么用 launchd 而不是会话提醒:会话提醒随会话消失,节拍就断了;
|
||||
# launchd 是宿主级,跟仓库绑定,换机器重跑一次即可复现。
|
||||
#
|
||||
# 用法:
|
||||
# ./scripts/install-schedulers.sh 安装(幂等,会先卸载再装)
|
||||
# ./scripts/install-schedulers.sh --status 看三个任务的加载状态
|
||||
# ./scripts/install-schedulers.sh --run daily 立刻跑一次(调试用)
|
||||
# ./scripts/install-schedulers.sh --uninstall 卸载
|
||||
set -uo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
TASK="$ROOT/scripts/scheduled-task.sh"
|
||||
AGENTS="$HOME/Library/LaunchAgents"
|
||||
LOGDIR="$ROOT/reports/_scheduler"
|
||||
PREFIX="com.pipexerp.ai-proj-skill"
|
||||
UID_N="$(id -u)"
|
||||
JOBS="daily weekly monthly"
|
||||
|
||||
SCHED_PATH="/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
|
||||
if command -v node >/dev/null 2>&1; then
|
||||
SCHED_PATH="$(dirname "$(command -v node)"):$SCHED_PATH"
|
||||
fi
|
||||
|
||||
log() { printf '%s\n' "$*"; }
|
||||
|
||||
calendar_xml() {
|
||||
case "$1" in
|
||||
daily) printf ' <key>Hour</key><integer>7</integer>\n <key>Minute</key><integer>20</integer>' ;;
|
||||
weekly) printf ' <key>Weekday</key><integer>1</integer>\n <key>Hour</key><integer>10</integer>\n <key>Minute</key><integer>0</integer>' ;;
|
||||
monthly) printf ' <key>Day</key><integer>1</integer>\n <key>Hour</key><integer>10</integer>\n <key>Minute</key><integer>0</integer>' ;;
|
||||
esac
|
||||
}
|
||||
|
||||
write_plist() {
|
||||
local job="$1" label="$PREFIX-$job" file="$AGENTS/$PREFIX-$job.plist" cal
|
||||
cal="$(calendar_xml "$job")"
|
||||
cat > "$file" <<PLIST
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key><string>$label</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/bin/bash</string>
|
||||
<string>$TASK</string>
|
||||
<string>$job</string>
|
||||
</array>
|
||||
<key>WorkingDirectory</key><string>$ROOT</string>
|
||||
<key>EnvironmentVariables</key>
|
||||
<dict>
|
||||
<key>HOME</key><string>$HOME</string>
|
||||
<key>PATH</key><string>$SCHED_PATH</string>
|
||||
</dict>
|
||||
<key>StandardOutPath</key><string>$LOGDIR/$job.log</string>
|
||||
<key>StandardErrorPath</key><string>$LOGDIR/$job.err.log</string>
|
||||
<key>RunAtLoad</key><false/>
|
||||
<key>StartCalendarInterval</key>
|
||||
<dict>
|
||||
$cal
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
PLIST
|
||||
}
|
||||
|
||||
unload_one() {
|
||||
local label="$PREFIX-$1"
|
||||
launchctl bootout "gui/$UID_N/$label" >/dev/null 2>&1 || launchctl unload "$AGENTS/$label.plist" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
install() {
|
||||
mkdir -p "$AGENTS" "$LOGDIR"
|
||||
chmod +x "$TASK" 2>/dev/null
|
||||
local job label
|
||||
for job in $JOBS; do
|
||||
label="$PREFIX-$job"
|
||||
write_plist "$job"
|
||||
unload_one "$job"
|
||||
if launchctl bootstrap "gui/$UID_N" "$AGENTS/$label.plist" 2>/dev/null; then
|
||||
log "已加载 $label"
|
||||
elif launchctl load -w "$AGENTS/$label.plist" 2>/dev/null; then
|
||||
log "已加载(load) $label"
|
||||
else
|
||||
log "加载失败 $label(检查 plist: $AGENTS/$label.plist)"
|
||||
fi
|
||||
done
|
||||
log ""
|
||||
log "触发时间:daily 每天 07:20 / weekly 每周一 10:00 / monthly 每月 1 日 10:00(1/4/7/10 月附季度清单)"
|
||||
log "日志:${LOGDIR#$ROOT/}/<job>.log"
|
||||
log "产出:reports/skill-health/、reports/evals/queue-*.md、reports/monthly/"
|
||||
}
|
||||
|
||||
status() {
|
||||
local job label
|
||||
for job in $JOBS; do
|
||||
label="$PREFIX-$job"
|
||||
if launchctl print "gui/$UID_N/$label" >/dev/null 2>&1; then
|
||||
printf '%-8s 已加载 %s\n' "$job" \
|
||||
"$(launchctl print "gui/$UID_N/$label" 2>/dev/null | grep -E 'state =|last exit code' | tr -d '\t' | tr '\n' ' ')"
|
||||
else
|
||||
printf '%-8s 未加载\n' "$job"
|
||||
fi
|
||||
done
|
||||
log ""
|
||||
log "日志目录:${LOGDIR#$ROOT/}"
|
||||
log "最近产出:"
|
||||
ls -1t "$ROOT/reports/skill-health"/daily-*.md "$ROOT/reports/evals"/queue-*.md "$ROOT/reports/monthly"/review-*.md 2>/dev/null | head -3 | sed "s#^$ROOT/# - #"
|
||||
}
|
||||
|
||||
run_now() {
|
||||
local job="${1:-}"
|
||||
case "$job" in daily|weekly|monthly) ;; *) log "用法: $0 --run daily|weekly|monthly"; exit 2 ;; esac
|
||||
mkdir -p "$LOGDIR"
|
||||
local label="$PREFIX-$job"
|
||||
if launchctl print "gui/$UID_N/$label" >/dev/null 2>&1; then
|
||||
launchctl kickstart -k "gui/$UID_N/$label" && log "已触发 $job(看 ${LOGDIR#$ROOT/}/$job.log)"
|
||||
else
|
||||
log "任务未加载,直接前台执行"
|
||||
/bin/bash "$TASK" "$job"
|
||||
fi
|
||||
}
|
||||
|
||||
uninstall() {
|
||||
local job label
|
||||
for job in $JOBS; do
|
||||
label="$PREFIX-$job"
|
||||
unload_one "$job"
|
||||
rm -f "$AGENTS/$label.plist"
|
||||
log "已卸载 $label"
|
||||
done
|
||||
}
|
||||
|
||||
case "${1:-install}" in
|
||||
install|--install) install ;;
|
||||
--status|status) status ;;
|
||||
--run) run_now "${2:-}" ;;
|
||||
--uninstall|uninstall) uninstall ;;
|
||||
*) log "用法: $0 [install|--status|--run daily|weekly|monthly|--uninstall]"; exit 2 ;;
|
||||
esac
|
||||
Executable
+162
@@ -0,0 +1,162 @@
|
||||
#!/usr/bin/env bash
|
||||
# 技能治理定时任务入口(由 launchd 调用,见 scripts/install-schedulers.sh)
|
||||
#
|
||||
# 设计原则:脚本只做「确定性」的事——跑门禁、扫漂移、生成清单。
|
||||
# 需要模型判断的部分(真跑 evals、人工审阅 routing)不在脚本里做,只生成 queue 文件,
|
||||
# 由项目经理 Bot 在 7:30 项目日报里接手执行。这样节拍不依赖任何会话的记忆。
|
||||
#
|
||||
# 用法:
|
||||
# ./scripts/scheduled-task.sh daily # 每天 07:20,先于 7:30 项目日报
|
||||
# ./scripts/scheduled-task.sh weekly # 每周一 10:00
|
||||
# ./scripts/scheduled-task.sh monthly # 每月 1 日 10:00(1/4/7/10 月附带季度清单)
|
||||
set -uo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
cd "$ROOT" || exit 1
|
||||
|
||||
JOB="${1:-daily}"
|
||||
DAY="$(date '+%F')"
|
||||
HEALTH_DIR="$ROOT/reports/skill-health"
|
||||
EVALS_DIR="$ROOT/reports/evals"
|
||||
MONTHLY_DIR="$ROOT/reports/monthly"
|
||||
mkdir -p "$HEALTH_DIR" "$EVALS_DIR" "$MONTHLY_DIR"
|
||||
|
||||
log() { printf '[%s] %s\n' "$(date '+%H:%M:%S')" "$*"; }
|
||||
|
||||
# ---------- 公共采集:漂移 / 入库扫描 / 覆盖率 / 第三方 ----------
|
||||
DRIFT_LINE=""; SCAN_LINE=""; COV_LINE=""; THIRD_LINE=""
|
||||
DRIFT_N="0"; HIGH_N="0"
|
||||
collect_health() {
|
||||
local audit
|
||||
audit="$(./install-skills.sh --audit 2>&1)"
|
||||
DRIFT_LINE="$(printf '%s\n' "$audit" | grep -E '[0-9]+ 个漂移' | tail -1)"
|
||||
SCAN_LINE="$(./scripts/scan-skill.sh 2>&1 | grep '扫描完成' | tail -1)"
|
||||
COV_LINE="$(/usr/bin/python3 scripts/validate-skills.py --coverage 2>&1 | grep '覆盖率' | tail -1)"
|
||||
THIRD_LINE="$(./scripts/scan-installed.sh 2>&1 | grep '扫描完成' | tail -1)"
|
||||
DRIFT_N="$(printf '%s' "$DRIFT_LINE" | grep -oE '[0-9]+ 个漂移' | grep -oE '^[0-9]+' || true)"
|
||||
HIGH_N="$(printf '%s' "$SCAN_LINE" | grep -oE '[0-9]+ 个高危' | grep -oE '^[0-9]+' || true)"
|
||||
DRIFT_N="${DRIFT_N:-0}"
|
||||
HIGH_N="${HIGH_N:-0}"
|
||||
AUDIT_OUT="$audit"
|
||||
}
|
||||
|
||||
# ---------- 每日:漂移 + 入库扫描,写一份可被日报直接读的健康快照 ----------
|
||||
run_daily() {
|
||||
local md="$HEALTH_DIR/daily-$DAY.md" todo=0
|
||||
collect_health
|
||||
{
|
||||
echo "# 技能健康 $DAY"
|
||||
echo
|
||||
echo "- 漂移:${DRIFT_LINE:-未采集}"
|
||||
echo "- 入库扫描:${SCAN_LINE:-未采集}"
|
||||
echo "- 覆盖率:${COV_LINE:-未采集}"
|
||||
echo "- 第三方技能:${THIRD_LINE:-未采集}"
|
||||
echo
|
||||
echo "## 需要处理"
|
||||
if [ "$DRIFT_N" != "0" ]; then
|
||||
echo "- 漂移 ${DRIFT_N} 个(未安装 / 版本落后),按 MAINTENANCE「每日」处理"
|
||||
todo=1
|
||||
fi
|
||||
if [ "$HIGH_N" != "0" ]; then
|
||||
echo "- 入库扫描高危 ${HIGH_N} 个,立即处理,不等日报"
|
||||
todo=1
|
||||
fi
|
||||
[ "$todo" = "0" ] && echo "无"
|
||||
echo
|
||||
echo "## 原始输出(audit 尾部)"
|
||||
echo '```'
|
||||
printf '%s\n' "$AUDIT_OUT" | tail -15
|
||||
echo '```'
|
||||
} > "$md"
|
||||
cp "$md" "$HEALTH_DIR/latest.md"
|
||||
log "daily -> ${md#$ROOT/}"
|
||||
log "漂移 ${DRIFT_N} / 高危 ${HIGH_N} / ${SCAN_LINE:-扫描未采集}"
|
||||
}
|
||||
|
||||
# ---------- 每周:生成 evals 抽样队列(执行仍需模型,见 MAINTENANCE「每周一」)----------
|
||||
run_weekly() {
|
||||
local md="$EVALS_DIR/queue-$DAY.md"
|
||||
local changed changed_total highrisk reports
|
||||
changed_total="$(git log --since='7 days ago' --name-only --pretty=format: 2>/dev/null \
|
||||
| grep -oE '^skills-[a-z]+/[^/]+-plugin/' | sort -u | wc -l | tr -d ' ')"
|
||||
changed="$(git log --since='7 days ago' --name-only --pretty=format: 2>/dev/null \
|
||||
| grep -oE '^skills-[a-z]+/[^/]+-plugin/' \
|
||||
| sed -E 's#^skills-[a-z]+/##; s#-plugin/$##' \
|
||||
| sort | uniq -c | sort -rn | head -5 | awk '{print $2}' | tr '\n' ' ')"
|
||||
highrisk="dev-coding dev-review req-design"
|
||||
reports="$(ls "$EVALS_DIR"/*.md 2>/dev/null | grep -vE 'TEMPLATE|queue-' | wc -l | tr -d ' ')"
|
||||
{
|
||||
echo "# 本周 evals 抽样队列 $DAY"
|
||||
echo
|
||||
echo "现有回归报告:${reports:-0} 份(目标:每周至少 +1 份)"
|
||||
echo
|
||||
echo "## 范围"
|
||||
echo
|
||||
echo "- 上周改动技能共 ${changed_total:-0} 个,按改动次数取前 5:${changed:-(无)}"
|
||||
echo "- 高风险固定项:$highrisk"
|
||||
echo
|
||||
echo "## 做法(每个技能)"
|
||||
echo
|
||||
echo "1. 取 1 条关键用例,跑「有技能 / 无技能」两遍;"
|
||||
echo "2. 按 rubric 打分,写增量;"
|
||||
echo "3. 结果写入 \`reports/evals/$DAY-<技能名>.md\`(模板 \`reports/evals/TEMPLATE.md\`)。"
|
||||
echo
|
||||
echo "## 判读"
|
||||
echo
|
||||
echo "- 连续两次无增量 → 按 \`SCOPE.md\` 评估降级。"
|
||||
echo "- 全量只在治理大改时做,不做每周全量。"
|
||||
echo
|
||||
echo "> 本文件由 launchd 每周一 10:00 自动生成;脚本不调模型,执行由 agent 接手。"
|
||||
} > "$md"
|
||||
log "weekly -> ${md#$ROOT/}(报告现有 ${reports:-0} 份)"
|
||||
}
|
||||
|
||||
# ---------- 每月:一条命令出齐审阅项;季度月附治理清单 ----------
|
||||
run_monthly() {
|
||||
local mo md mon q
|
||||
mo="$(date '+%Y-%m')"
|
||||
mon="$(date '+%m')"
|
||||
md="$MONTHLY_DIR/review-$mo.md"
|
||||
{
|
||||
echo "# 技能月度审阅 $mo"
|
||||
echo
|
||||
./scripts/monthly-review.sh 2>&1
|
||||
} > "$md"
|
||||
collect_health
|
||||
{
|
||||
echo
|
||||
echo "## 补充:漂移与第三方"
|
||||
echo
|
||||
echo "- ${DRIFT_LINE:-漂移未采集}"
|
||||
echo "- ${THIRD_LINE:-第三方未采集}"
|
||||
} >> "$md"
|
||||
log "monthly -> ${md#$ROOT/}"
|
||||
case "$mon" in
|
||||
01|04|07|10)
|
||||
q="$(date '+%Y')-Q$(( (10#$mon - 1) / 3 + 1 ))"
|
||||
local mq="$MONTHLY_DIR/quarterly-$q.md"
|
||||
{
|
||||
echo "# 季度治理复核 $q"
|
||||
echo
|
||||
echo "按 MAINTENANCE「每季度首月 1 日 10:30」逐项打勾:"
|
||||
echo
|
||||
echo "- [ ] 过一遍 \`docs/skill-routing.md\`:删掉不再用的引用、补上新技能"
|
||||
echo "- [ ] 清理 \`deprecated\`:满 3 个月且无回滚需求 → 删除插件目录"
|
||||
echo "- [ ] 复核分桶与调用模式:还有没有命令型技能占着 \`model-invoked\`"
|
||||
echo "- [ ] 复核覆盖率:\`--coverage\` 两项缺口是否按路线图收敛"
|
||||
echo "- [ ] 更新 \`MAINTENANCE.md\` 与 \`CHANGELOG.md\`"
|
||||
} > "$mq"
|
||||
log "quarterly -> ${mq#$ROOT/}"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
case "$JOB" in
|
||||
daily) run_daily ;;
|
||||
weekly) run_weekly ;;
|
||||
monthly) run_monthly ;;
|
||||
*)
|
||||
echo "用法: $0 daily|weekly|monthly" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
Reference in New Issue
Block a user