mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-10-19 22:17:42 +02:00
Carry allowlisted summary origin and host user ledger across the trace recovery boundary. Keep immutable snapshot links after alias failures, scope legacy padded keys, remove stale indexes under small budgets, reuse retrieval clues for labels, and add cross-platform memory CI.
74 lines
2.6 KiB
Go
74 lines
2.6 KiB
Go
package database
|
|
|
|
import (
|
|
"fmt"
|
|
"go.uber.org/zap"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestLegacyWhitespaceCheckpointKeysRespectConversationScope(t *testing.T) {
|
|
db, err := NewDB(filepath.Join(t.TempDir(), "legacy.db"), zap.NewNop())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer db.Close()
|
|
p, err := db.CreateProject(&Project{Name: "scope"})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for i, space := range []string{" ", "\t", "\r\n", "\u00a0", "\u3000"} {
|
|
canonical := fmt.Sprintf("note/context-legacy%d", i)
|
|
f, err := db.UpsertProjectFact(&ProjectFact{ProjectID: p.ID, FactKey: canonical, SourceConversationID: "other", Summary: "LEGACY_PROGRESS"})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
oldKey := space + canonical + space
|
|
// Simulate an already-stored legacy row, without migrating it on read.
|
|
if _, err := db.Exec("UPDATE project_facts SET fact_key=? WHERE id=?", oldKey, f.ID); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !IsContextCheckpointKey(oldKey) {
|
|
t.Fatal("helper did not identify legacy key")
|
|
}
|
|
if err := ValidateFactKey(oldKey); err == nil {
|
|
t.Fatal("write validation accepts noncanonical key")
|
|
}
|
|
if _, err := db.UpsertProjectFact(&ProjectFact{ProjectID: p.ID, FactKey: space + "finding/new"}); err == nil {
|
|
t.Fatal("write boundary stored noncanonical key")
|
|
}
|
|
}
|
|
if _, err := db.UpsertProjectFact(&ProjectFact{ProjectID: p.ID, FactKey: "finding/shared", Summary: "shared"}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, filter := range []ProjectFactListFilter{{RestrictContextCheckpoints: true, ContextConversationID: "current"}, {RestrictContextCheckpoints: true, ContextConversationID: "current", Search: "LEGACY_PROGRESS"}, {RestrictContextCheckpoints: true}} {
|
|
facts, err := db.ListProjectFacts(p.ID, filter, 100, 0)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, f := range facts {
|
|
if IsContextCheckpointKey(f.FactKey) {
|
|
t.Fatalf("foreign legacy note crossed scope: %q", f.FactKey)
|
|
}
|
|
}
|
|
}
|
|
index, err := db.ListProjectFactsForIndex(p.ID, false, "current")
|
|
if err != nil || len(index) != 1 || index[0].FactKey != "finding/shared" {
|
|
t.Fatalf("legacy note leaked into index: %#v %v", index, err)
|
|
}
|
|
history, err := db.ListProjectFacts(p.ID, ProjectFactListFilter{Search: "LEGACY_PROGRESS"}, 100, 0)
|
|
if err != nil || len(history) != 5 {
|
|
t.Fatalf("historical records lost: %#v %v", history, err)
|
|
}
|
|
for _, f := range history {
|
|
if f.FactKey == strings.TrimSpace(f.FactKey) {
|
|
t.Fatal("read mutated legacy evidence")
|
|
}
|
|
}
|
|
own, err := db.ListProjectFactsForIndex(p.ID, false, "other")
|
|
if err != nil || len(own) != 6 {
|
|
t.Fatalf("legacy origin no longer visible to owner: %#v %v", own, err)
|
|
}
|
|
}
|