全技能树相对路径审计+路径引用规范固化(P0)
- 审计 V1.0 全树(主技能+references+全部subskills及嵌套)Windows/Unix 绝对路径与 md 断链
- 豁免判定: 环境判别锚点/路径配置表/示例路径保留; browser-harness/envs 由 gitignore 兜底不随分发
- 修复: SKILL.md 七节越级引用 ../../../失误与规避记录.md 改语义说明(仅开发机维护场景); mcn-dou-analysis 内嵌 nuwa-skill-main 断链(多语言/社区/评分卡/示例 LICENSE)改官方 GitHub URL(源+dsh 副本同步)
- 新增 references/规则/路径引用规范.md(相对路径铁律: 允许项~占位/__file__推导/URL + 禁令盘符/Unix/越级 + 豁免 + 自检), 模板同步 V1.0+4 自有 subskills+dsh 4 副本
- 5 源 SKILL.md + 4 dsh SKILL.md 挂 🔴 路径引用引用行
- 自有内容 md 断链复验=0; 临时审计脚本已清理
This commit is contained in:
1 parent
ca009c095e
commit
061bbb64fb
21 files changed
+437
-23
No files matched your search
@@ -0,0 +1,104 @@
|
||||
# 自动化任务清理规范(09-03 定稿)
|
||||
|
||||
> **用途**:后台自动化任务(一次性任务)积攒过多时,安全清理**过期 / 执行失败**的任务。
|
||||
> **适用环境**:WorkBuddy 全环境通用(开发机 / dsh 部署环境 / 用户环境)——automations 表是 WorkBuddy 宿主自带(`~/.workbuddy/workbuddy.db`),不依赖 MCN 工作台,任何装了本技能的 WorkBuddy 都能执行。
|
||||
> **红线(用户明确)**:**只能清理「过期」或「错误/失败」的任务**,禁止清理未来任务 / 周期任务 / 运行中任务。
|
||||
|
||||
## 一、触发场景
|
||||
|
||||
用户表达以下任一意图时,按本文档执行(不需要走创作流程):
|
||||
- 「后台在执行什么任务?」
|
||||
- 「没用的任务可以清空吗 / 清一下后台任务 / 把过期任务删掉」
|
||||
- 「清理自动化任务 / 任务太多了」
|
||||
|
||||
执行前先**只读盘点 → 列出清单 → 用户确认 → 再删**,禁止未经确认批量删除。
|
||||
|
||||
## 二、判定标准(只清这两类)
|
||||
|
||||
自动化任务表 `automations` 存储任务定义,运行记录在 `automation_runs`,运行状态在 `automation_runtime_state`。
|
||||
|
||||
| 类别 | 可清理条件(全部满足) | 典型 |
|
||||
|---|---|---|
|
||||
| 🟢 **过期历史任务** | `schedule_type='once'`(一次性)且计划时间已过,且**已跑完**(有 run 记录且终态 ACCEPTED、`result_success=1`) | 工作台批量创作/复盘跑完后的任务定义 |
|
||||
| 🔴 **错误/失败任务** | `schedule_type='once'` 且已终结但**未成功**:run 终态 PENDING_REVIEW / `result_success=0` / runtime_state 有 `last_error`(如 user_cancel 中断) | 被用户取消的导入、出错的复盘 |
|
||||
| ⚪ **死任务**(可选,需用户点头) | `schedule_type='once'` 且**从未运行**(无 run 记录)且计划时间已过期(如 >24h 前),确认不会被调度器补跑 | 旧版重复任务、被新版取代的任务 |
|
||||
|
||||
### 禁止清理(硬性)
|
||||
|
||||
| 情形 | 原因 |
|
||||
|---|---|
|
||||
| `schedule_type='recurring'`(周期任务) | 未来还会按 rrule 触发 |
|
||||
| 计划时间在**未来**(`scheduled_at` / `next_run_at` 未到) | 还没执行 |
|
||||
| `automation_runtime_state.running=1` | 正在执行 |
|
||||
| run 状态 QUEUED / IN_PROGRESS(排队/进行中) | 尚未终结 |
|
||||
| `deleted_at` 已非空 | 已删过,无需处理 |
|
||||
|
||||
## 三、执行步骤
|
||||
|
||||
### 第 1 步:只读盘点(SQL 查询,只读不改)
|
||||
|
||||
数据库:`~/.workbuddy/workbuddy.db`(Windows: `C:\Users\<用户名>\.workbuddy\workbuddy.db`;macOS/Linux: `~/.workbuddy/workbuddy.db`)。**只用只读模式打开**(SQLite URI `mode=ro`),任务表可能被宿主进程占用,只读查询不受影响。
|
||||
|
||||
```bash
|
||||
# 审计三表:automations(任务定义)/ automation_runs(运行历史)/ automation_runtime_state(运行状态)
|
||||
python3 -c "
|
||||
import sqlite3, os, datetime, json
|
||||
db = os.path.expanduser('~/.workbuddy/workbuddy.db')
|
||||
con = sqlite3.connect(f'file:{db}?mode=ro', uri=True)
|
||||
con.row_factory = sqlite3.Row
|
||||
cur = con.cursor()
|
||||
def ts(v):
|
||||
if v is None: return None
|
||||
try: return datetime.datetime.fromtimestamp(int(v)/1000).strftime('%m-%d %H:%M')
|
||||
except: return v
|
||||
|
||||
print('=== 1) 真正在跑(running=1,禁止清理)===')
|
||||
for r in cur.execute('SELECT automation_id, running, last_error FROM automation_runtime_state WHERE running=1').fetchall():
|
||||
print(dict(r))
|
||||
|
||||
print()
|
||||
print('=== 2) 每个任务:类型/计划时间/是否已跑/是否成功 ===')
|
||||
rows = cur.execute('''
|
||||
SELECT a.id, a.name, a.status, a.schedule_type, a.scheduled_at, a.next_run_at, a.last_run_at,
|
||||
COUNT(r.automation_id) AS run_cnt,
|
||||
SUM(CASE WHEN r.result_success=1 THEN 1 ELSE 0 END) AS ok_cnt,
|
||||
MAX(CASE WHEN r.status IN ('QUEUED','IN_PROGRESS') THEN 1 ELSE 0 END) AS active_run
|
||||
FROM automations a LEFT JOIN automation_runs r ON r.automation_id = a.id
|
||||
WHERE a.deleted_at IS NULL
|
||||
GROUP BY a.id ORDER BY a.created_at
|
||||
''').fetchall()
|
||||
for r in rows:
|
||||
d = dict(r)
|
||||
d['scheduled_at'] = ts(d['scheduled_at']); d['next_run_at'] = ts(d['next_run_at']); d['last_run_at'] = ts(d['last_run_at'])
|
||||
print(json.dumps(d, ensure_ascii=False))
|
||||
"
|
||||
```
|
||||
|
||||
### 第 2 步:按判定标准归档
|
||||
|
||||
对上面输出逐条归档到三类:**🟢 过期已完成** / **🔴 错误失败** / **⚪ 从未运行的死任务**(这三类之外的:未来任务 / recurring / running / QUEUED / IN_PROGRESS → 一律保留)。
|
||||
|
||||
### 第 3 步:列清单给用户确认
|
||||
|
||||
用表格呈现:`任务名 | ID | 计划时间 | 归档类别 | 建议动作(删除/保留)`,等用户明确同意后再删。
|
||||
|
||||
### 第 4 步:删除(走宿主工具,禁止直改数据库)
|
||||
|
||||
删除必须通过 WorkBuddy 宿主自动化工具逐条执行(`automation_update`,mode=delete),**严禁**用 SQL `DELETE` / `UPDATE` 直写 automations 表(宿主可能正持有连接;且工具删除是受支持的软删,会正确置 `deleted_at`)。
|
||||
|
||||
> 工具删除幂等安全:对已删除任务重复删会返回 `already deleted or does not exist`(success:true),不会报错。
|
||||
|
||||
### 第 5 步:复核
|
||||
|
||||
```python
|
||||
# 只读复核:有效任务应为 0 或仅剩应保留项
|
||||
SELECT COUNT(*) FROM automations WHERE deleted_at IS NULL;
|
||||
SELECT COUNT(*) FROM automation_runtime_state WHERE running=1; -- 应为 0
|
||||
```
|
||||
|
||||
## 四、补充事实(实测,便于判断)
|
||||
|
||||
- **宿主不会自动清理**:一次性任务跑完(ACCEPTED)后任务定义保留、状态仍 ACTIVE,调度器只扫未来时间,不会再触发——但也不会自动删除 → 需人工/按本规范清理
|
||||
- **删除不影响任何产物**:已生成的脚本/复盘/会话历史在 `automation_runs`(保留),删任务定义只移除调度入口,不影响历史记录与产出文件
|
||||
- 工具删除为**软删**(置 `deleted_at`),表行物理保留,逻辑上不可见
|
||||
- 命名线索:`创作指令`/`复盘指令`/`重写-xxx(videoID)`/`修复-videoID`/`解析视频-xxx` 均为一次性任务;带明确未来重复意图(周报/日报)才会是 recurring
|
||||
Reference in new issue
Block a user