zfl-automation-port —— 便携自动化(随技能包迁移 + 双机镜像)
为什么需要它
WorkBuddy 自动化(定时/周期任务)存在 ~/.workbuddy/workbuddy.db,默认不随技能包(zip)走:
- 打包技能 → 另一台机合并 → 自动化不在包里,仍在源机 db 生效。
- 手拷配置过去时,
cwds/prompt 常烤死本机路径(某盘工作区、C 盘用户目录下的 .workbuddy),换机路径不存在 → 静默失败。
本技能把自动化变成可搬运的普通文件(跟技能包或独立 bundle 走),换机后解析占位符、生成计划,再由 agent 调 automation_update 重建。
两条路线
| 路线 | 适用 | 模型 |
|---|---|---|
| A. 随技能迁移 | 自动化服务于某技能,换机后重建 | spec 存进所属技能 automations/,随包走 |
| B. 双机镜像合并 | 整机全部定时任务跨机重建 + 两机合并 + 后续增量同步 | 整机 bundle → merge/错峰 → ledger 增量对账 |
两条路线共用占位符规范,且都只产出计划,create/update 由 agent 经 automation_update 执行。
占位符规范
| 占位符 | 含义 | 导入时解析为 |
|---|---|---|
{{WB_HOME}} |
WorkBuddy 主目录 | os.path.expanduser("~/.workbuddy") |
{{WORKSPACE}} |
自动化工作区(cwd/落盘) | --workspace(路线 A)或 workspace-map(路线 B) |
误报豁免(同 zfl-skill-syncer Check 4b):占位符本身、%USERPROFILE%、环境变量形、\Users\Default 不计硬编码。
文件布局
- 路线 A spec:
<所属技能>/automations/<语义名>.automation.json。 - 路线 B bundle:独立
automations-bundle.json(带machine_tag),不绑技能。 scripts/helper(纯 Python,不碰 db,只做占位符转换/计划产出):- A:
template_spec.py(导出单条)、resolve_spec.py(解析+校验)、reimport_all.py(批量扫描技能导入)。 - B:
export_bundle.py(整机导出)、rrule_offset.py(错峰纯函数)、merge_mirror.py(双机合并)、diff_sync.py(ledger 增量对账)。 - 共用:
json_io.py(JSON 读入护栏:文件缺失/畸形/形态错误一律给[ERROR]+ 下一步,不抛栈)。 scripts/tests/:test_rrule_offset.py、test_mirror_smoke.py、test_io_guard.py。
路线 A:随技能迁移
- 源机:agent
automation_update view取配置 →template_spec.py模板化 → 写入所属技能automations/(命令见references/implementation-details.md)。spec 随技能发布/打包自动带上(两条通道均含,已实测)。 - 目标机:合并技能包后对 agent 说「导入 zfl-automation-port 管理的便携自动化,工作区用 <目标路径>」→ agent 跑
reimport_all.py→ 逐条automation_update重建。注意:spec 仅"跟着技能走",不会自动变成运行任务,必须走 resolve→create。
路线 B:双机镜像合并 + 增量同步
> 完整工作流、命令与设计决策见 references/mirror-workflow.md。要点:
- 匹配键 = name(内容指纹
_prompt_hash仅判"修改");同名不同 prompt → 记conflicts,不静默覆盖。 - 错峰:
--primary机保持基准时刻,另台 matched 任务 rrule+offset-minutes(默认 30);仅 recurring 且含 BYHOUR/BYMINUTE 可偏移,一次性scheduledAt不偏移。 - workspace 双映射:
machine_workspace_map.json把{{WORKSPACE}}解析为目标机路径。 - 增量对账(两阶段):ledger 按 name 维度记账(不依赖机器本地 id);
diff_sync.py的 diff 模式只读不写账、产出 create/update/delete,agent 执行成功后用--commit <plan>记账 ⇒ 失败项下轮仍重报、不静默丢失;delete 默认仅报告(--apply-deletes才删)。 - 自维护:导入
automations/sync-mirror.automation.json,每天定时"拉对端 bundle→diff→对齐"。
安全底线
- 解析后若有残留
{{...}}或未模板化机器路径 → 报错/告警并拒绝输出(H9 零硬编码同纪律)。 - 重建前必须显式给
--workspace/--workspace-map,不用猜的路径静默创建。 - 冲突(同名不同 prompt)不自动覆盖;删除不自动执行。
与既有护栏的关系
- H9/H10:技能源文件与自动化 spec/bundle 均零硬编码机器路径。
- zfl-skill-syncer Check 4b、zfl-sync-suite:打包扫描天然 0 WARN;合并后提示"导入便携自动化"。
> helper 只做占位符转换与计划产出,不直连 workbuddy.db;create/update/delete 由 agent 经 automation_update 完成。
版本变更
见 references/CHANGELOG.md。