Files
Agent-System/internal/artifactvault/backfill_test.go
T
weichenandCursor b5337d5c77 feat(artifactvault): checkpoint backfill without scanning workspace
只枚举 snapshot、agent_commit、approved 与 completed chat turn;hazard 进 quarantine,禁止工作区路径。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-15 02:40:12 +00:00

69 lines
2.8 KiB
Go

package artifactvault
import (
"strings"
"testing"
"time"
)
func TestForbidWorkspaceScan(t *testing.T) {
if err := ForbidWorkspaceScan("SELECT work_dir FROM document_records"); err == nil {
t.Fatal("work_dir must be rejected")
}
if err := ForbidWorkspaceScan("SELECT path FROM workspaces/foo"); err == nil {
t.Fatal("workspaces/ must be rejected")
}
if err := ForbidWorkspaceScan(SQLSnapshots + SQLAgentCommits + SQLApproved + SQLChatTurns); err != nil {
t.Fatal(err)
}
}
func TestEnumeratorSQLCoversFourKindsOnly(t *testing.T) {
for _, kind := range []string{KindSnapshot, KindAgentCommit, KindApproved, KindChatTurn} {
sql, err := EnumeratorSQL(kind)
if err != nil {
t.Fatal(err)
}
if strings.Contains(strings.ToLower(sql), "workspace") {
t.Fatalf("%s leaked workspace: %s", kind, sql)
}
}
if _, err := EnumeratorSQL("workspace_dir"); err == nil {
t.Fatal("unknown kind")
}
}
func TestClassifyHazardMatrix(t *testing.T) {
now := time.Now().UTC()
okBody := []byte("# approved body for vault")
cases := []struct {
name string
c Candidate
want string
}{
{"commit ok", Candidate{Kind: KindAgentCommit, SnapshotID: 3, Payload: okBody}, HazardNone},
{"missing snapshot", Candidate{Kind: KindAgentCommit, SnapshotID: 0, Payload: okBody}, HazardMissingSnapshot},
{"legacy v0", Candidate{Kind: KindSnapshot, PayloadSHA: "", Payload: nil}, HazardMissingSnapshot},
{"legacy empty schema", Candidate{Kind: KindSnapshot, PayloadSHA: "abc", Payload: okBody, SchemaVer: 0}, HazardLegacyV0},
{"high id", Candidate{Kind: KindApproved, SourcePK: HighIDThreshold + 1, SnapshotID: 1, Payload: okBody, ApprovedAt: &now}, HazardHighID},
{"old schema", Candidate{Kind: KindApproved, SourceSchema: 12, SnapshotID: 1, Payload: okBody, ApprovedAt: &now}, HazardOldSchema},
{"fork", Candidate{Kind: KindApproved, SnapshotID: 4, HeadSnapshotID: 9, LedgerSHA: "aa", ProjectionSHA: "bb", Payload: okBody, ApprovedAt: &now}, HazardProjectionFork},
{"workspace path", Candidate{Kind: KindApproved, WorkDir: "data/dev/workspaces/x", SnapshotID: 1, Payload: okBody}, HazardWorkspacePath},
{"secret", Candidate{Kind: KindChatTurn, MessageID: 1, CompletedAt: &now, Payload: []byte("api_key=secret")}, HazardSensitivePayload},
}
for _, tc := range cases {
if got := ClassifyHazard(tc.c); got != tc.want {
t.Fatalf("%s: got %q want %q", tc.name, got, tc.want)
}
}
}
func TestProcessCandidateQuarantinesWorkspaceAndSecrets(t *testing.T) {
// ProcessCandidate without a real tx is exercised via hazard classification and
// memory ingest in dataset tests. Guard the refuse path here.
c := Candidate{Kind: KindAgentCommit, WorkDir: "workspaces/p/output.md", SnapshotID: 1, Payload: []byte("ok body here")}
if ClassifyHazard(c) != HazardWorkspacePath {
t.Fatal("workspace candidate must be classified before ingest")
}
}