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
+19
-2
@@ -687,7 +687,8 @@ class LocalExecutor(Executor):
|
||||
task["id"], self.runner(cmd))
|
||||
|
||||
def goal_resume_task(self, task, goal_text=None, extra_env=None,
|
||||
model_provider=None, max_rounds=None) -> dict:
|
||||
model_provider=None, max_rounds=None,
|
||||
resume_note=None) -> dict:
|
||||
"""调 host.py goal-resume,分两种调用(P1,与 worker、
|
||||
host 三处一致,绝不能混用):
|
||||
- 断点续跑:goal_text=None(worker 的 _resume_kind=
|
||||
@@ -699,6 +700,10 @@ class LocalExecutor(Executor):
|
||||
- 开新目标:goal_text 为新目标文本(云端 /continue 带
|
||||
goal_mode=1 时走这里)。命令带 --goal-text 与
|
||||
--max-rounds(默认 0,新语义不限轮次,上界是配额)。
|
||||
resume_note(N-12):仅断点续跑时用,作 --resume-note
|
||||
传给 host,host 只贴进本次续跑第一轮的 prompt,不写回
|
||||
存储的 goal、不改轮次与验收;goal_text 非空(开新目标)
|
||||
时忽略它(新目标自带 goal_text,不需要断点备注)。
|
||||
不传 --repo:goal-resume 操作已有 host 任务,不新建
|
||||
worktree。结论解析与 goal_task 同款。
|
||||
"""
|
||||
@@ -715,6 +720,8 @@ class LocalExecutor(Executor):
|
||||
str(max_rounds if max_rounds is not None else 0)]
|
||||
elif max_rounds is not None:
|
||||
cmd += ["--max-rounds", str(max_rounds)]
|
||||
if goal_text is None and resume_note:
|
||||
cmd += ["--resume-note", resume_note]
|
||||
return self._goal_result_from_runner(
|
||||
task["id"], self._run_local(cmd, extra_env))
|
||||
|
||||
@@ -863,10 +870,15 @@ class LocalExecutor(Executor):
|
||||
# 沿用原 goal+verify 断点续跑,绝不能用续跑消息覆盖
|
||||
# 原 verify);其它情况(开新目标)才用 task["prompt"]
|
||||
#(worker 已换成续跑消息)当 --goal-text,--max-rounds 0。
|
||||
# N-12:断点续跑且任务带审计推回备注时,另传
|
||||
# --resume-note(只贴第一轮 prompt,不写回存储的 goal)。
|
||||
cmd += ["goal-resume", "--task", self._host_name(task)]
|
||||
if task.get("_resume_kind") != "breakpoint":
|
||||
cmd += ["--goal-text", task["prompt"],
|
||||
"--max-rounds", "0"]
|
||||
elif task.get("_audit_loop_resume_note"):
|
||||
cmd += ["--resume-note",
|
||||
task["_audit_loop_resume_note"]]
|
||||
else:
|
||||
cmd += ["dispatch", "--name", self._host_name(task),
|
||||
"--task", task["prompt"]]
|
||||
@@ -1634,11 +1646,14 @@ class DockerExecutor(Executor):
|
||||
def goal_resume_task(self, task, goal_text=None, timeout=None,
|
||||
extra_mounts=None, network=None,
|
||||
extra_env=None, model_provider=None,
|
||||
max_rounds=None) -> dict:
|
||||
max_rounds=None, resume_note=None) -> dict:
|
||||
"""容器内调 host.py goal-resume,分两种调用(P1,与 Local
|
||||
goal_resume_task 同款契约):断点续跑传 goal_text=None
|
||||
(不带 --goal-text,host 沿用原 goal+verify+轮次),开新
|
||||
目标才传 goal_text(带 --goal-text 与 --max-rounds,默认 0)。
|
||||
resume_note(N-12):仅断点续跑时作 --resume-note 传给
|
||||
host(Local 同款语义:只贴第一轮 prompt,不写回存储的
|
||||
goal);goal_text 非空时忽略它。
|
||||
解析与 goal_task 同款(完整 stdout 结论、存库截尾),但
|
||||
没有“已存在”分支:goal-resume 本来就是操作已有 host 任务,
|
||||
不存在 dispatch 撞名问题;returncode 非 0 时:有结论仍
|
||||
@@ -1654,6 +1669,8 @@ class DockerExecutor(Executor):
|
||||
if max_rounds is not None else 0)]
|
||||
elif max_rounds is not None:
|
||||
_resume_args += ["--max-rounds", str(max_rounds)]
|
||||
if goal_text is None and resume_note:
|
||||
_resume_args += ["--resume-note", resume_note]
|
||||
inner = self._inner_host_command(
|
||||
*_resume_args,
|
||||
model=task.get("model"), effort=task.get("effort"),
|
||||
|
||||
Reference in new issue
Block a user