From 908fb253d70f3a0366eb244390ce84b737673444 Mon Sep 17 00:00:00 2001 From: weichen Date: Fri, 9 Oct 2026 14:56:34 +0000 Subject: [PATCH] Keep tool-result dumps out of the deliverable gate and cards Why: The live after-run (golden minutes-pm-tool) showed the truncation spill artifact tool-run_shell-.txt entering CheckArtifacts as a .txt deliverable; its non-UTF-8 payload failed the scorer four times in a row. These files exist to keep oversized tool output reachable - they are context relief, not deliverables, and must not occupy delivery cards either. Evidence: SELF - TestLatestDeliverablesKeepsLastPerName extended with a tool-dump ref and asserts exclusion; go test ./internal/... passes; single-task live rerun recorded on the phase02 task card. Impact: latestDeliverables (gate input, verifier refs, reply deliverable list, final artifact_ref cards) skips kind=data tool- prefixed refs. The spill files remain artifacts for context backfill. --- internal/runtime/deliverable_latest_test.go | 6 ++++++ internal/runtime/llm_direct.go | 10 ++++++++++ 2 files changed, 16 insertions(+) diff --git a/internal/runtime/deliverable_latest_test.go b/internal/runtime/deliverable_latest_test.go index 7ff8c24..d5002c5 100644 --- a/internal/runtime/deliverable_latest_test.go +++ b/internal/runtime/deliverable_latest_test.go @@ -14,11 +14,17 @@ func TestLatestDeliverablesKeepsLastPerName(t *testing.T) { {ArtifactID: "art_bbb2", Name: "纪要.docx"}, {ArtifactID: "art_ccc3", Name: "方案.docx"}, {ArtifactID: "art_ddd4", Name: ""}, + {ArtifactID: "art_eee5", Name: "tool-run_shell-call_x1.txt", Kind: "data"}, }} got := st.latestDeliverables() if len(got) != 3 { t.Fatalf("want 3 deliverables, got %d: %+v", len(got), got) } + for _, ref := range got { + if isToolDumpArtifact(ref) { + t.Fatalf("tool result dumps are not deliverables: %+v", ref) + } + } if got[0].ArtifactID != "art_ccc3" || got[0].Name != "方案.docx" { t.Fatalf("方案.docx should resolve to latest: %+v", got[0]) } diff --git a/internal/runtime/llm_direct.go b/internal/runtime/llm_direct.go index b32785e..dc05c05 100644 --- a/internal/runtime/llm_direct.go +++ b/internal/runtime/llm_direct.go @@ -441,6 +441,8 @@ func (st *directRun) demoteLastText() int { // latestDeliverables 同名工件只保留最后登记的版本,顺序不变。 // 修订(同名再登记)后旧版本不再是交付物:不进终轮检查、不重复出现在 // 回复的交付清单里。无名工件互不合并。 +// 超长工具输出的截断转存(runmgr 的 tool-<调用>.txt,kind=data)不是交付物: +// 不进终轮检查、不占交付卡片(实测被评分器当 .txt 交付物误伤,检查连判负)。 func (st *directRun) latestDeliverables() []*core.ArtifactRef { idx := map[string]int{} var out []*core.ArtifactRef @@ -449,6 +451,9 @@ func (st *directRun) latestDeliverables() []*core.ArtifactRef { out = append(out, ref) continue } + if isToolDumpArtifact(ref) { + continue + } if i, ok := idx[ref.Name]; ok { out[i] = ref continue @@ -459,6 +464,11 @@ func (st *directRun) latestDeliverables() []*core.ArtifactRef { return out } +// isToolDumpArtifact 识别「工具结果超长截断转工件」的落盘(上下文救济,非交付物)。 +func isToolDumpArtifact(ref *core.ArtifactRef) bool { + return ref.Kind == "data" && strings.HasPrefix(ref.Name, "tool-") +} + func (st *directRun) addVerifyNote(reason string) { st.addCheck(false, reason) }