返回 DeepSeek-Reasonix
submission_test.go
根目录 / internal / session / submission_test.go
1 package session
2
3 import (
4 "bytes"
5 "encoding/json"
6 "path/filepath"
7 "testing"
8
9 "reasonix/internal/provider"
10 )
11
12 func TestSubmissionMetadataSurvivesReplayForkAndRetraction(t *testing.T) {
13 root := t.TempDir()
14 dir := filepath.Join(root, "parent")
15 s, err := Open(dir, "parent")
16 if err != nil {
17 t.Fatal(err)
18 }
19 receipt := SubmissionReceipt{SessionID: "parent", SubmissionID: "send", Fingerprint: "fingerprint", TurnID: "turn", MessageID: "user"}
20 data, _ := json.Marshal(receipt)
21 message := provider.Message{ID: "user", Role: provider.RoleUser, Content: "synthetic compatibility fixture"}
22 payload, _ := json.Marshal(map[string]any{"message": message})
23 commit, err := s.Append(t.Context(), Batch{OperationID: "accept", TurnID: "turn", Events: []Event{
24 {Kind: "turn/start"}, {Kind: "submission/accepted", Optional: true, Payload: data},
25 {Kind: "message/complete", Payload: payload}, {Kind: "turn/end", Payload: json.RawMessage(`{"status":"completed"}`)},
26 }})
27 if err != nil {
28 t.Fatal(err)
29 }
30 if _, err := s.Fork(t.Context(), filepath.Join(root, "child"), "child", commit.LastSequence()); err != nil {
31 t.Fatal(err)
32 }
33 if err := s.Close(t.Context()); err != nil {
34 t.Fatal(err)
35 }
36 s, err = Open(dir, "parent")
37 if err != nil {
38 t.Fatal(err)
39 }
40 defer s.Close(t.Context())
41 if got, ok := s.Submission("send"); !ok || got != receipt {
42 t.Fatalf("receipt after restart: %+v %v", got, ok)
43 }
44 model, _ := json.Marshal(s.DeriveMessages())
45 if bytes.Contains(model, []byte("submissionId")) || bytes.Contains(model, []byte("fingerprint")) {
46 t.Fatal("host metadata entered model messages")
47 }
48 entries := []PersistentMessage{{MessageID: "user"}}
49 attachSubmissionEntries(s.Snapshot().Projection.Submissions, "parent", entries)
50 if entries[0].SubmissionID != "send" {
51 t.Fatal("recent baseline lost submission identity")
52 }
53 if rows := s.transcriptRows(s.DeriveMessages()); len(rows) != 1 || rows[0].SubmissionID != "send" {
54 t.Fatalf("history: %+v", rows)
55 }
56 child, err := Open(filepath.Join(root, "child"), "child")
57 if err != nil {
58 t.Fatal(err)
59 }
60 defer child.Close(t.Context())
61 if _, found := child.Submission("send"); found {
62 t.Fatal("parent identity leaked into child acceptance scope")
63 }
64 if len(child.DeriveMessages()) != 1 {
65 t.Fatal("fork lost the historical message")
66 }
67 if _, err := s.Append(t.Context(), Batch{OperationID: "retract", Events: []Event{{Kind: "message/retract", Payload: json.RawMessage(`{"messageIds":["user"]}`)}}}); err != nil {
68 t.Fatal(err)
69 }
70 if got, ok := s.Submission("send"); !ok || got != receipt {
71 t.Fatal("retraction removed acceptance")
72 }
73 }
74
74 lines GO