只枚举 snapshot、agent_commit、approved 与 completed chat turn;hazard 进 quarantine,禁止工作区路径。 Co-authored-by: Cursor <cursoragent@cursor.com>
69 lines
2.8 KiB
Go
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")
|
|
}
|
|
}
|