Why: Authentic quotes do not establish an unstated approval, and the evaluation wrapper must honor tighter production output limits. Evidence: Approval-overstatement and 780-token-cap regressions failed first; complete Backend suite and fixture cap checks now pass. Impact: Render material records from trusted labels and validated quotations, reserve interpretation for explicit finding kinds, bump recipe identity and cap the fixture without overriding smaller limits. Refs: Approved R05; independent model assessment; original failed samples preserved
182 lines
6.6 KiB
Go
182 lines
6.6 KiB
Go
package runmgr
|
|
|
|
import (
|
|
"agent-system-backend/internal/cardsvc"
|
|
core "agent-system-core"
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func checkpointEnvironment(t *testing.T) *runCtx {
|
|
st := openRecoveryStore(t)
|
|
m := newRecoveryManager(t, st)
|
|
m.SetInstanceID("A")
|
|
m.SetCards(cardsvc.New(st, nil))
|
|
conv := recoveryConversation(t, st)
|
|
parent := recoveryRun(t, st, conv, core.RunRunning)
|
|
data := []byte("上线六月")
|
|
a := core.Artifact{Owner: conv.Owner, ProjectID: conv.ProjectID, Name: "决定.txt"}
|
|
if e := st.CreateArtifact(&a, data); e != nil {
|
|
t.Fatal(e)
|
|
}
|
|
sum := sha256.Sum256(data)
|
|
docs := []core.ParsedDocument{{Meta: core.DocMeta{Filename: a.Name, Origin: &core.DocumentOrigin{ArtifactID: a.ID, ContentHash: hex.EncodeToString(sum[:]), ParserRevision: "txt.v1"}}, Blocks: []core.DocBlock{{Type: core.BlockPara, Text: string(data)}}}}
|
|
b, _, e := m.registerBackgroundTask(parent, bgSpawnOpts{name: "整理", material: true, documents: docs})
|
|
if e != nil {
|
|
t.Fatal(e)
|
|
}
|
|
if e = m.startTaskProjection(b, "run_material"); e != nil {
|
|
t.Fatal(e)
|
|
}
|
|
return &runCtx{mgr: m, run: core.Run{ID: "run_material", Kind: core.RunSubagent, Owner: conv.Owner, ConversationID: conv.ID, ProjectID: conv.ProjectID}, subAgent: materialSubagentID, task: b, sources: materialSources(docs, 48000)}
|
|
}
|
|
func validCheckpoint(c *runCtx, id string) core.WorkCheckpointCandidate {
|
|
var src core.TaskSourceRef
|
|
for _, s := range c.sources {
|
|
src = s.Ref
|
|
break
|
|
}
|
|
return core.WorkCheckpointCandidate{CheckpointID: id, PhaseID: "crosscheck", Focus: "核对决定", Remaining: "尚在核对", NextStep: "继续整理", Findings: []core.WorkFindingCandidate{{FindingKey: "date", Text: "材料记载上线六月", Kind: "material_record", Impact: "安排交付需要采用该日期", Sources: []core.TaskSourceQuote{{SourceID: src.ID, BlockIndex: src.BlockIndex, Quote: "上线六月"}}}}}
|
|
}
|
|
|
|
func TestMaterialRecordCannotAddAnUnstatedApproval(t *testing.T) {
|
|
c := checkpointEnvironment(t)
|
|
cp := validCheckpoint(c, "approval")
|
|
cp.Findings[0].Text = "上线六月已经批准,无需再次确认"
|
|
cp.Findings[0].Impact = "批准状态已经明确"
|
|
cp.Findings[0].Assumptions = "审批已完成"
|
|
if err := c.PublishWorkCheckpoint(cp); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
card, err := c.mgr.st.GetCard(c.run.Owner, c.task.cardID)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
f := card.Task.Findings[0]
|
|
if strings.Contains(f.Text, "批准") || f.Impact != "" || f.Assumptions != "" || !strings.Contains(f.Text, "上线六月") {
|
|
t.Fatalf("model interpretation was published as a material record: %+v", f)
|
|
}
|
|
}
|
|
func TestTaskCheckpointPersistentIdempotentAndCorrected(t *testing.T) {
|
|
c := checkpointEnvironment(t)
|
|
cp := validCheckpoint(c, "1")
|
|
if e := c.PublishWorkCheckpoint(cp); e != nil {
|
|
t.Fatal(e)
|
|
}
|
|
card, _ := c.mgr.st.GetCard(c.run.Owner, c.task.cardID)
|
|
revision := card.Task.Revision
|
|
if len(card.Task.Findings) != 1 || !strings.HasPrefix(card.Task.Findings[0].ID, "finding_") {
|
|
t.Fatal("checkpoint absent", card.Task)
|
|
}
|
|
if e := c.PublishWorkCheckpoint(cp); e != nil {
|
|
t.Fatal(e)
|
|
}
|
|
card, _ = c.mgr.st.GetCard(c.run.Owner, c.task.cardID)
|
|
if card.Task.Revision != revision {
|
|
t.Fatal("retransmission advanced revision")
|
|
}
|
|
cp.Findings[0].Text = "different"
|
|
if e := c.PublishWorkCheckpoint(cp); e == nil {
|
|
t.Fatal("same id different payload accepted")
|
|
}
|
|
cp = validCheckpoint(c, "2")
|
|
cp.Findings[0].Text = "日期需要进一步核对"
|
|
cp.Findings[0].Corrects = "date"
|
|
if e := c.PublishWorkCheckpoint(cp); e != nil {
|
|
t.Fatal(e)
|
|
}
|
|
card, _ = c.mgr.st.GetCard(c.run.Owner, c.task.cardID)
|
|
if len(card.Task.Findings) != 2 || card.Task.Findings[0].Status != "corrected" {
|
|
t.Fatal("correction erased history", card.Task.Findings)
|
|
}
|
|
}
|
|
func TestTaskCheckpointRejectsFalseSourcesAndLateWrites(t *testing.T) {
|
|
c := checkpointEnvironment(t)
|
|
cp := validCheckpoint(c, "1")
|
|
cp.Findings[0].Sources[0].Quote = "不存在的七月"
|
|
if e := c.PublishWorkCheckpoint(cp); e == nil {
|
|
t.Fatal("invented quotation accepted")
|
|
}
|
|
cp = validCheckpoint(c, "2")
|
|
cp.Findings[0].Kind = "verified"
|
|
if e := c.PublishWorkCheckpoint(cp); e == nil {
|
|
t.Fatal("verification privilege accepted")
|
|
}
|
|
if e := c.mgr.finishTaskProjection(c.task, core.AgentResultPayload{Summary: "完成"}, nil); e != nil {
|
|
t.Fatal(e)
|
|
}
|
|
if e := c.PublishWorkCheckpoint(validCheckpoint(c, "3")); e == nil {
|
|
t.Fatal("late terminal checkpoint accepted")
|
|
}
|
|
}
|
|
|
|
func TestTaskCheckpointQuotaCorrectionAndSourceScope(t *testing.T) {
|
|
c := checkpointEnvironment(t)
|
|
for i := 0; i < 6; i++ {
|
|
cp := validCheckpoint(c, fmt.Sprint(i))
|
|
cp.Findings[0].Text = fmt.Sprintf("第%d项读取结果", i)
|
|
if e := c.PublishWorkCheckpoint(cp); e != nil {
|
|
t.Fatal(e)
|
|
}
|
|
}
|
|
cp := validCheckpoint(c, "over-limit")
|
|
if e := c.PublishWorkCheckpoint(cp); e == nil {
|
|
t.Fatal("quota ignored")
|
|
}
|
|
cp = validCheckpoint(c, "correction")
|
|
cp.Findings[0].Corrects = "date"
|
|
cp.Findings[0].Text = "上述口径需重新核验"
|
|
if e := c.PublishWorkCheckpoint(cp); e != nil {
|
|
t.Fatal("correction blocked by quota", e)
|
|
}
|
|
card, _ := c.mgr.st.GetCard(c.run.Owner, c.task.cardID)
|
|
if card.Task.CheckpointCount != 6 || card.Task.ExecutionState != "running" {
|
|
t.Fatal("correction changed execution / ordinary budget")
|
|
}
|
|
other := core.Artifact{Owner: c.run.Owner, ProjectID: "other-project", Name: "other.txt"}
|
|
if e := c.mgr.st.CreateArtifact(&other, []byte("上线六月")); e != nil {
|
|
t.Fatal(e)
|
|
}
|
|
for id, src := range c.sources {
|
|
src.Ref.ArtifactID = other.ID
|
|
c.sources[id] = src
|
|
}
|
|
cp = validCheckpoint(c, "foreign")
|
|
cp.Findings[0].Corrects = "date"
|
|
if e := c.PublishWorkCheckpoint(cp); e == nil {
|
|
t.Fatal("foreign project accepted")
|
|
}
|
|
}
|
|
|
|
func TestTaskCheckpointCorrectionWithdrawsOldClaimEvenWhenSnapshotIsFull(t *testing.T) {
|
|
c := checkpointEnvironment(t)
|
|
cp := validCheckpoint(c, "first")
|
|
if e := c.PublishWorkCheckpoint(cp); e != nil {
|
|
t.Fatal(e)
|
|
}
|
|
card, _ := c.mgr.st.GetCard(c.run.Owner, c.task.cardID)
|
|
task := *card.Task
|
|
task.Revision++
|
|
task.Findings[0].Text = strings.Repeat("x", 54000)
|
|
if e := c.mgr.cards.CommitTask(c.run.Owner, task, card.Task.Revision); e != nil {
|
|
t.Fatal(e)
|
|
}
|
|
cp = validCheckpoint(c, "large-correction")
|
|
cp.Findings[0].Corrects = "date"
|
|
cp.Findings[0].Text = strings.Repeat("y", 11000)
|
|
cp.Findings[0].Kind = "analysis"
|
|
cp.Findings[0].Assumptions = "来源尚需复核,撤回旧结论"
|
|
if e := c.PublishWorkCheckpoint(cp); e != nil {
|
|
t.Fatal("known wrong claim must be withdrawn", e)
|
|
}
|
|
card, _ = c.mgr.st.GetCard(c.run.Owner, c.task.cardID)
|
|
for _, f := range card.Task.Findings {
|
|
if f.Text == strings.Repeat("x", 54000) && f.Status == "active" {
|
|
t.Fatal("known wrong claim retained")
|
|
}
|
|
}
|
|
}
|