Repository navigation
feat(automation): add durable monitoring and structured diagnostics - #115
Merged
Merged
Conversation
Qiyuanqiii
marked this pull request as ready for review
August 20, 2026 07:16
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
摘要
scheduled-job.v1:支持一次性/周期计划、IANA 时区元数据、稳定 UTC occurrence、deadline、停止条件、轮次/模型/elapsed 预算、retry/backoff、misfire、通知与显式 Run owner。run_once|skip收敛。loop-monitor数据面。无新证据时不调用模型;approved_repair只有在精确 Code/Deliver、operator-confirmed permission snapshot 和逐 Job 确认同时成立时才可进入 executor handoff。当前生产 wiring 不安装 repair/model executor,缺失 adapter 时明确 fail closed。doctor-snapshot.v1、debug-query.v1与diagnostic-bundle.v1:提供 readiness 原因、Run/Provider/Harness/Workspace/Sandbox/Browser/Network/Tool 投影、跨组件 correlation、单调时间线、cursor、时间窗、扫描/返回上限和字段级脱敏;原始 event payload、Prompt、终端输入与命令输入不可查询。mainbe5e481(PR feat(ui-evidence): add source-bound real-browser verification #113 UI Evidence 与 PR feat(extensions): MCP Client、Plugin 包与受限生命周期 Hooks #114 Extension Runtime),冲突已全部解决;最终 schema 分配为 v119 UI Evidence、v120 MCP Client、v121 Plugin/Hook、v122 Scheduled Diagnostics。Closes #105.
Durable Job 协议与状态语义
scheduled-job.v1的 immutable spec 绑定:once|periodic、IANA timezone、UTC anchor、interval 和run_once|skipmisfire policy;stop_on_target_terminal、最大轮次、最大模型调用和最大 elapsed;all|failures|silentnotification;read_only|approved_repairexecution mode。Job 状态固定为
active|paused|completed|failed|cancelled|exhausted。每次 mutation 都要求scheduled-job-control.v1、显式 idempotency key、request fingerprint、Run owner、expected revision 和 requester;相同 key/相同意图返回原结果,不同意图复用 key 冲突。pause/resume/cancel 通过 revision CAS,不能静默覆盖并发控制操作。Schema v122 新增:
scheduled_jobs:spec、next wake、pending occurrence、预算、水位、最后结果、terminal reason 与公开 lease projection;scheduled_job_authorizations:逐 Job、不可变、带 snapshot ID/revision 和 expiry 的 repair 授权;scheduled_job_operations:不可变幂等控制账本;scheduled_job_rounds:以(job_id, occurrence_at)为身份的 attempt/generation/fence/结果账本;scheduled_job_notifications:按稳定 dedup digest 去重的有界通知。authorization、operation、notification 使用 immutable trigger;FK、CHECK、digest、UTF-8/identity/时间/状态不变量在 domain、store 和 schema 多层校验。
Scheduler、lease、恢复与水位
Worker 默认关闭,只有显式
--enable-scheduled-job-worker才启动;API/Desktop 还要求 scheduled control capability 与独立 control token。worker process-local 并发固定为 1,跨进程权威由 store transaction 决定:周期身份由 immutable UTC anchor + elapsed seconds 推导,DST gap/fold 不会复制或删除 occurrence。长时间 sleep 后,
run_once收敛为一个 catch-up round,skip记录明确 skipped round,不会无界 replay。观察每轮最多读取 100 个 envelope。最终实现保证:
truncated=true保留 overflow 事实,但未读 tail 不会被永久跳过;scheduled_job.*新证据才算 changed,单纯截断/自身审计事件不消耗模型。权限与安全边界
时间到达只授予“尝试 claim 并重新检查”的权利,不授予 execution、network、approval 或 capability bypass。
read_onlyloop-monitor 要求当前 Plan phase;任何 tool fact 都会被拒绝,且tool_called=true必须同时有 model handoff。approved_repair创建时必须满足:Code/Deliver;approval|full_access且operator_confirmed=true;confirm_repair=true;execution_bypass=false、network_bypass=false、approval_bypass=false。Store 在 claim transaction 中重读 mode/permission;Application 在 executor handoff 前再次重读并逐字段比较。后续真实命令/修复 sink 仍必须复用普通 command/Job lifecycle 的 policy、approval、lease、operation-key 和 cancellation 门禁。本 PR 不实现任意 cron shell,也不因“监控”自动提权。
HTTP read bearer 与 control bearer 严格分离且启动时必须不同。scheduled mutation 使用 control bearer、POST、严格 JSON、bounded body、重复 key 拒绝、unknown field 拒绝、Run URL ownership 与 idempotency key;GET 使用 read bearer。listener 继续只允许 loopback。
结构化 doctor/debug/Bundle
doctor-snapshot.v1是只读快照,不主动修改配置、安装依赖、放宽权限或执行网络/进程探测。它提供 build/schema、Provider/model route、Harness readiness、Run/Mission/profile、Workspace/root、surface/phase/permission、network mode/allow-target count、sandbox/browser/plugin/tool readiness 与明确 detail code/evidence level。debug-query.v1:after_sequencecursor;observed_at并标记 adjustment;withheld。公开 Type/Source/Subject ID 在输出前经过 UTF-8、长度、NUL/control-character 检查和 Secret redaction。Prompt、模型内容、Provider 原始错误、Tool 参数/输出、终端输入、命令输入、credential、fence token 和 operation fingerprint 均不进入公开 timeline 或 bundle。
CLI、HTTP、Desktop 与 Skill
CLI 新增:
HTTP/OpenAPI 新增:
Desktop control plane 负责 worker start/cancel/wait/store-close 顺序,并向 renderer 投影精确 capability 与 worker health。React Scheduled Tasks 支持 read-only 创建、列表/详情、revision-bound pause/resume/cancel、recent round/notification、next wake 与显式诊断包下载;客户端 capability 只影响 UI,server-side authorization 始终权威。
内置
doctor、debug升级到 1.1.0;新增loop-monitor@1.0.0,保持 root、explicit-only、non-model-invocable、无隐式 tool dependency。README 中英文、usage、HTTP API、独立 scheduled-jobs/diagnostics 指南、Project Status 和 ADR 0121 同步描述保证、失败语义与残余边界。主线兼容性与冲突处理
最终 head
898f37b已包含最新mainbe5e481:v122 → v121 → v120 → v119 → v118收敛,migration plan 连续到 v122。第一次同步 PR #113 解决 14 个冲突;第二次同步 PR #114 解决 9 个冲突,重点覆盖迁移版本、README ledger、OpenAPI 和 TypeScript parser/type 并集。两次均从合并后的 Go schema 重新生成 OpenAPI/TS,没有覆盖或降级 UI Evidence、MCP、Plugin/Hook 或 Scheduled Diagnostics。
最终 OpenAPI 为 139 paths / 155 operations / 389 schemas:
e3621910dc3bf1b6bc6f18b40fd413603e6b32d246170a4731eca0762bcacaef762d6431b16f6a8e05cee451327c1fe40df8881e96551ef7455cb9d1beb67c3e验收条件对应
>100backlog 和真实短周期 smoke 已覆盖。本地验证
在第一次主线同步后的完整矩阵:
go test ./internal/store -count=1 -timeout 30m:通过,695.010s;覆盖当时完整 migration/recovery、claim/fence/retry/notification/budget/stop 矩阵。同步最新 PR #114 后重新验证最终组合树:
go test -run '^$' ./...全仓编译通过。go test -tags "desktop,wv2runtime.error" -count=1 ./cmd/cyberagent-desktop ./internal/desktop ./internal/webui,全部通过。go vet ./...、go mod verify、go mod tidy -diff、git diff --check通过。npm run typecheck、完整npm test(63 files / 274 tests)、npm run build、npm run check:api通过。npm audit --audit-level=high:0 vulnerabilities。once_completed,1 round、0 model calls;doctor/debug/bundle 均可读取。原始 Scheduled Diagnostics 受影响包的
staticcheck -checks='SA*,S1*,QF*'已通过。同步 PR #114 后的扩大扫描只命中internal/plugins/package.go使用archive/tar.Header.SetModTime的SA1019,该行来自最新main、不在本 PR 相对main的 diff 中;本 PR 不把它误写成自身零告警结论。govulncheck ./...在本机 Go 1.26.5 如实报告 5 项可达标准库 advisory:GO-2026-6218、GO-2026-6090、GO-2026-6089、GO-2026-5972、GO-2026-5026,均标记由 Go 1.26.6 修复。本 PR 未新增 Go module 依赖;远端固定 Go 1.25 当前补丁版的结果由 CI 给出,不能把本机结果写成 zero finding。安全审计
9fc824c..2c9200a:60/60 review rows,3 个候选全部完成 validation/attack-path 收敛,0 reportable finding;scan ID08dc9192-a84b-46a9-9125-d840e5c43ee4。>100回归。not_applicable,不是被遗漏。2c9200a..baa7fd2:2/2 文件、0 candidate / 0 reportable finding;scan ID3b096ab7-6ab5-4400-8de5-a8b18e7a33ca。9fc824c..baa7fd2;随后两次主线集成通过逐冲突审阅、迁移定向/race、Go 集成和前端生成验证。这里不把原始 sealed range 扩大成未扫描的新范围。非目标与残余边界
CI 状态与超时说明
旧 Go check 的失败是
go test -timeout 20m -count=1 ./...在 migration-heavy Store 套件达到 20 分钟后被测试框架终止,并非测试断言失败。最新main已由 PR #114 独立把完整套件保留为无缓存执行并将有界 deadline 调整到 30 分钟,因此本 PR 的最终树不再额外修改 CI workflow,也没有通过跳过 Store、启用 cache 或删除测试来“变绿”。最终 head
898f37b的 GitHub Actions run32349073450已成功:完整无缓存 Go suite 用时 19m35s,随后go vet与 pinnedgovulncheck通过;TypeScript、Rust、macOS Desktop、Windows Desktop、Real Edge UI evidence 也全部成功。Desktop release 的 dependency/license 与可复现 ZIP 检查成功,PR 上的发布步骤按设计 skipped。PR 当前为MERGEABLE / CLEAN。Audit