Audit N-12: goal pushback preamble reaches breakpoint resume via --resume-note
ci / test (push) Failing after 35m34s
ci / test (push) Failing after 35m34s
Goal tasks pushed back by the audit loop lost the packet preamble on the next round: claim-time _apply_audit_loop_packet pasted it into the in-memory prompt/goal, but the next round collided with the existing host task name, fell back to breakpoint goal-resume (no --goal-text), and the host reused the stored goal, discarding the preamble. Fix (minimal, direction (c) trimmed): host goal-resume gains --resume-note, accepted only by the breakpoint branch and prepended to the first turn prompt of this resume only -- never written back to the stored goal, never touching rounds or verification. The worker stashes the same preamble as the memory-only _audit_loop_resume_note at claim time and forwards it on breakpoint resume (Local/Docker goal_resume_task and the popen goal-resume command, each guarded to ignore the note when goal_text is set for a new-goal resume). Accounting untouched: audit 3-round cap, goal_max_rounds/quota, and DB goal columns are unchanged; non-goal pushback is unchanged. Tests: cloud/tests/test_audit_n12.py (9 tests) -- host first-turn-only note + stored-goal/rounds, worker exists-fallback end-to-end with --resume-note, non-goal regression, goal-column accounting, and Local/Docker/popen command shapes. Full cloud suite: 1760 OK (skipped=11), baseline 1751 + 9 new; tests/test_host.py: 62 OK.
This commit is contained in:
1 parent
bc19f09dff
commit
159d7112ae
4 files changed
+421
-11
No files matched your search
+24
-7
@@ -2194,10 +2194,12 @@ class Worker:
|
||||
packet 对 goal 任务同步贴两者),但 goal 任务下一轮
|
||||
实际会撞宿主任务名已存在、经 run_one 的已存在回落走
|
||||
断点续跑(goal-resume 不传 --goal-text,宿主用存储的
|
||||
goal 与 goal_rounds_done+1 继续),所以包前言贴了却
|
||||
不进续跑循环——这是审计推回对 goal 任务的已知效果
|
||||
缺口,不是轮次会计错误,本批不改行为、留待后续批
|
||||
定夺。轮次会计本身有界:审计轮次硬上限 3(MAX_
|
||||
goal 与 goal_rounds_done+1 继续)。N-12 修复:认领贴
|
||||
前言时另存 _audit_loop_resume_note,断点续跑时作
|
||||
--resume-note 传给 host,host 只贴进本次续跑第一轮的
|
||||
prompt,不写回存储的 goal、不改轮次与验收——前言从此
|
||||
到达续跑循环,库内原 goal 与宿主存储的 goal 均不动。
|
||||
轮次会计本身有界:审计轮次硬上限 3(MAX_
|
||||
PUSHBACKS),3 轮后必升级;goal 旧形态总回合数受
|
||||
goal_max_rounds 约束(续跑不重置计数),新形态受配额
|
||||
约束;两组计数器独立、不叠加成无界循环。
|
||||
@@ -2720,7 +2722,10 @@ class Worker:
|
||||
顺序是目录树 → 推回包 → 重跑前言 → 项目上下文 → 原
|
||||
prompt,推回包是最需要 agent 先看到的一段。库里的
|
||||
原 prompt 与包列都不动,包列只在 pass/escalate 时由
|
||||
接线清理、pushback 时由接线覆盖。
|
||||
接线清理、pushback 时由接线覆盖。另存
|
||||
_audit_loop_resume_note(N-12):同一份前言的副本,
|
||||
仅内存键,供断点续跑时作 --resume-note 传给 host;
|
||||
非 goal 任务与开新目标续跑忽略它。
|
||||
"""
|
||||
if task.get("coordinator_parts"):
|
||||
return task
|
||||
@@ -2748,6 +2753,14 @@ class Worker:
|
||||
if task.get("goal_mode") or task.get("verify_command"):
|
||||
new_task["goal"] = preamble + "\n\n" + (
|
||||
task.get("goal") or task.get("prompt") or "")
|
||||
# N-12:前言另存一份作断点续跑备注(仅内存键,不进库)。
|
||||
# goal 任务下一轮撞“已存在”走断点续跑时,host 只用存储
|
||||
# 的原 goal(见 _run_attempt 的 goal_resume 调用),内存
|
||||
# goal 里的前言到不了 agent;_run_attempt 在断点续跑时
|
||||
# 把这份备注作 --resume-note 传给 host,host 只贴进本次
|
||||
# 续跑第一轮的 prompt,不写回存储的 goal。非 goal 任务
|
||||
# 与开新目标续跑忽略此键(sandbox 侧的配对守卫)。
|
||||
new_task["_audit_loop_resume_note"] = preamble
|
||||
new_task["_audit_loop_packet_injected"] = True
|
||||
self._audit(task["project_id"], "worker_audit_loop_packet_injected",
|
||||
task["id"])
|
||||
@@ -5553,7 +5566,9 @@ class Worker:
|
||||
network=tenant_network,
|
||||
extra_env=_merge_env(proxy_env,
|
||||
gateway_env),
|
||||
model_provider=gateway_provider),
|
||||
model_provider=gateway_provider,
|
||||
resume_note=task.get(
|
||||
"_audit_loop_resume_note")),
|
||||
quota_check)
|
||||
else:
|
||||
result = self._docker_call_with_quota_poll(
|
||||
@@ -5620,7 +5635,9 @@ class Worker:
|
||||
result = self.executor.goal_resume_task(
|
||||
task, _resume_text,
|
||||
extra_env=gateway_env,
|
||||
model_provider=gateway_provider)
|
||||
model_provider=gateway_provider,
|
||||
resume_note=task.get(
|
||||
"_audit_loop_resume_note"))
|
||||
elif isinstance(self.executor, LocalExecutor):
|
||||
result = self.executor.goal_task(
|
||||
task, seed_dir=seed_host_dir,
|
||||
|
||||
Reference in new issue
Block a user