P1 security batch: quota execution checks, cost accounting, goal/coordinator semantics, PR channel, orphan signature, control-plane and console hardening

- Docker quota watchdog + fail-closed quota checks, system tasks need real owner
- max_cost_usd actually accumulated, cancel records cost, estimated rows excluded from unpriced cap, cache_write declared non-billed
- goal-resume keeps original verify on breakpoint resume, goal retry falls back to resume, goal_max_rounds capped at 100 at create and execution
- coordinator children inherit parent model/effort, orphans marked interrupted with audit
- PR jobs on docker workers return explicit needs_local_worker instead of silent empty
- worker code signature covers 6 files and is checked before claim, fail-closed
- sub2api lazy provisioning with rotation, backup whitelist + 0600, push SSRF block, repos/workers desensitized, key/project audits and limits, console buttons/quota/status wording, coordinator/automation quota reserve
This commit is contained in:
host committed 2026-10-27 16:27:50 +00:00
1 parent d254240d84
commit 1402dc67fd
20 files changed
+2616 -179

No files matched your search

+22 -3
View File
@@ -2164,9 +2164,11 @@ def main():
p = sub.add_parser("goal-resume")
p.add_argument("--task", required=True)
p.add_argument("--goal-text", default=None,
help="新目标文本:旧任务接续 goal 模式时用——跳过状态与"
help="新目标文本:仅开新目标时用——跳过状态与"
"goal 记录守卫,在旧线程上从第 1 轮开新目标循环"
"(新语义:无验收、不传 --max-rounds 时不限轮次)")
"(新语义:无验收、不传 --max-rounds 时不限轮次)。"
"断点续跑绝不能传它(不传时沿用原 goal+原验收命令),"
"传了会把原验收命令覆盖成 None")
p.add_argument("--max-rounds", type=int, default=None,
help="不传时沿用原任务的 goal_max_rounds;传了则覆盖总轮次")
p.add_argument("--verify-timeout", type=int, default=600,
@@ -2811,12 +2813,23 @@ def main():
verify_timeout=args.verify_timeout)
elif args.cmd == "goal-resume":
t = state["tasks"][args.task]
# P1 goal-resume 契约(与 cloud/sandbox.py、cloud/worker.py
# 三处一致,绝不能混用):
# - 开新目标:调用方传 --goal-text 时走下面分支,在旧线程
# 上从第 1 轮开新循环(verify=None,新语义)。这个分支
# 只能由“开新目标”的调用方用,断点续跑绝不能传 --goal-text
# ——传了就会把原 verify_command 覆盖成 None。
# - 断点续跑:调用方不传 --goal-text 时走下面守卫分支,
# 沿用原 goal + 原 verify_command + 原 goal_max_rounds,
# 从 goal_rounds_done 的下一轮续跑,verify 原样传回
# run_goal_loop(run_goal_loop 会把它再写回同一值,
# 不是覆盖成 None)。
if args.goal_text:
# 旧任务接续 goal 模式(云端 /continue 带 goal_mode=1
# 时走这里):旧任务已终局、没有 goal 记录是正常情况,
# 不能按断点续跑的守卫拒绝。只要线程还在,就在旧线程
# 上从第 1 轮开新目标循环(新语义:无验收、不传轮次
# 时不限轮次,模型宣告完成才结束)。
# 时不限轮次,模型宣告完成才结束,上界是云端配额)。
if not t.get("thread_id"):
print(f"goal-resume 拒绝:{args.task} 没有会话线程,"
f"不能接续")
@@ -2851,6 +2864,12 @@ def main():
max_rounds = t["goal_max_rounds"]
else:
max_rounds = 3
# P1:断点续跑时旧验收形态的 0 轮次(脏数据,0 在旧形态
# 里表示不限轮次)不按不限轮次跑,钳制到 100 轮(与云端
# GOAL_MAX_ROUNDS_CAP 同值);新形态(verify 为空)的 0
# 保持不限轮次,上界是云端配额。
if max_rounds == 0 and t.get("verify_command"):
max_rounds = 100
srv.resume_thread(t["thread_id"])
last_turn = (t.get("turns") or [{}])[-1]
last_result = last_turn.get("result") or {}