diff --git a/internal/runmgr/material_test.go b/internal/runmgr/material_test.go index ebb3ba1..ad175b1 100644 --- a/internal/runmgr/material_test.go +++ b/internal/runmgr/material_test.go @@ -79,7 +79,23 @@ func TestMaterialIntakeAttachmentOnlyLifecycle(t *testing.T) { } close(hold.release) - waitUntil(t, func() bool { return len(systemTexts(t, c)) >= 1 }) + // 等完成去重门禁本身(CardDone + materialActive 已释放),不要等 notice + // 副作用——deliverNotices 早于 defer materialKeyRelease,systemTexts 先可见会 race。 + key := materialKey(materialDocs()) + waitUntil(t, func() bool { + cards, err := c.mgr.cards.List(c.run.Owner, c.run.ConversationID) + if err != nil || len(cards) != 1 { + return false + } + card := cards[0] + if card.Title != materialCardTitle || card.Status != core.CardDone || card.Tone == "danger" { + return false + } + c.mgr.materialMu.Lock() + active := c.mgr.materialActive != nil && c.mgr.materialActive[string(c.run.ConversationID)][key] + c.mgr.materialMu.Unlock() + return !active + }) // 完成后同批再发:已完成说明,同样不重跑;卡片回投保留材料键。 c3 := secondRunCtx(c, materialDocs(), "")