carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package release
2
3import (
4 "os"
5 "path/filepath"
6 "testing"
7 "time"
8)
9
10func TestPlan14ForgedHealthyCannotAdmit(t *testing.T) {
11 for _, renamed := range []bool{false, true} {
12 name := "original"
13 if renamed {
14 name = "parent-replaced"
15 }
16 t.Run(name, func(t *testing.T) {
17
18 e := newProofEnv(t)
19 e.requireDev(t)
20 e.gate = NewRootProofGate(e.policy, e.bake).WithClock(func() time.Time { return e.clock })
21 if err := RecordHealthy(e.bake, "bab", "console", HealthyBuild{SHA256: e.newSHA, How: "live", At: e.clock}); err != nil {
22 t.Fatal(err)
23 }
24 if renamed {
25
26 // Rename the whole parent, then plant a valid, attacker-owned replacement.
27 dir := filepath.Join(e.bake, "healthy")
28 if err := os.Rename(dir, dir+"-old"); err != nil {
29 t.Fatal(err)
30 }
31 if err := RecordHealthy(e.bake, "bab", "console", HealthyBuild{SHA256: e.newSHA, How: "settle", At: e.clock}); err != nil {
32 t.Fatal(err)
33 }
34 }
35
36 e.pass(t, e.store)
37 if got := e.live(); got != "old" {
38 t.Fatalf("forged history adopted %q", got)
39 }
40 // A separately verified proof still opens the same gate.
41 e.putAt(t, e.newSHA, e.signed(t, e.prover, "console", e.newSHA, "dev"))
42 e.clock = e.clock.Add(ProofMissTTL + time.Second)
43 e.pass(t, e.store)
44 if got := e.live(); got != "new" {
45 t.Fatalf("signed proof refused: %q", got)
46 }
47
48 })
49 }
50}
51
52func TestPlan14ForgedHealthyCannotBind(t *testing.T) {
53 for _, renamed := range []bool{false, true} {
54 name := "original"
55 if renamed {
56 name = "parent-replaced"
57 }
58 t.Run(name, func(t *testing.T) {
59
60 e := newProofEnv(t)
61 e.requireDev(t)
62 g := NewRootProofGate(e.policy, e.bake)
63 if err := StageArtifact(e.opt, "bab", "new", "console", []byte("bad build")); err != nil {
64 t.Fatal(err)
65 }
66 if err := RecordHealthy(e.bake, "bab", "console", HealthyBuild{SHA256: e.newSHA, How: "live", At: e.clock}); err != nil {
67 t.Fatal(err)
68 }
69 if renamed {
70 dir := filepath.Join(e.bake, "healthy")
71 if err := os.Rename(dir, dir+"-old"); err != nil {
72 t.Fatal(err)
73 }
74 if err := RecordHealthy(e.bake, "bab", "console", HealthyBuild{SHA256: e.newSHA, How: "settle", At: e.clock}); err != nil {
75 t.Fatal(err)
76 }
77 }
78
79 rt, err := e.reg.Get(proofHost)
80 if err != nil || rt == nil {
81 t.Fatalf("%v", err)
82 }
83 if g.bind(e.opt, *rt, &ChannelPointer{Version: "new"}, proofVerdict{required: true, sha: e.newSHA}, "old", e.clock) {
84 t.Fatal("bind trusted agent history")
85 }
86
87 })
88 }
89}
90
91func TestPlan14RootHistoryStrictShape(t *testing.T) {
92 for _, raw := range []string{
93 `{"schema":1,"builds":[]} {}`,
94 `{"schema":1,"extra":true,"builds":[]}`,
95 `{"schema":1,"builds":[{"sha256":"fake","how":"live","at":"2026-10-12T00:00:00Z"}]}`,
96 `{"schema":2,"builds":[]}`,
97 } {
98 if _, err := decodeRootHealthy([]byte(raw)); err == nil {
99 t.Fatalf("accepted %s", raw)
100 }
101 }
102 if b, err := decodeRootHealthy([]byte(`{"schema":1,"builds":[]}`)); err != nil || len(b) != 0 {
103 t.Fatalf("%v %v", b, err)
104 }
105}
106
107func TestPlan14HealthyErasureRequiresProof(t *testing.T) {
108 for _, target := range []string{"record", "parent"} {
109 t.Run(target, func(t *testing.T) {
110 e := newProofEnv(t)
111 e.requireDev(t)
112 e.gate = NewRootProofGate(e.policy, e.bake).WithClock(func() time.Time { return e.clock })
113 if err := RecordHealthy(e.bake, "bab", "console", HealthyBuild{SHA256: e.newSHA, How: "live", At: e.clock}); err != nil {
114 t.Fatal(err)
115 }
116 path := filepath.Join(e.bake, "healthy", "bab", "console.json")
117 if target == "parent" {
118 path = filepath.Join(e.bake, "healthy")
119 }
120 if err := os.RemoveAll(path); err != nil {
121 t.Fatal(err)
122 }
123 e.pass(t, e.store)
124 if e.live() != "old" {
125 t.Fatal("erased history granted adoption")
126 }
127 rt, err := e.reg.Get(proofHost)
128 if err != nil || rt == nil {
129 t.Fatal(err)
130 }
131 if e.gate.bind(e.opt, *rt, &ChannelPointer{Version: "new"}, proofVerdict{required: true, sha: e.newSHA}, "old", e.clock) {
132 t.Fatal("erased history granted binding")
133 }
134 e.putAt(t, e.newSHA, e.signed(t, e.prover, "console", e.newSHA, "dev"))
135 e.clock = e.clock.Add(ProofMissTTL + time.Second)
136 e.pass(t, e.store)
137 if e.live() != "new" {
138 t.Fatal("signed positive refused after erasure")
139 }
140 })
141 }
142}
143