package main // The local switch (localdeny.go). One invariant matters more than every other // property here, and it is asserted by driving the REAL gate over the REAL op // vocabulary rather than by reasoning about the code: // // A LOCAL SWITCH CAN ONLY EVER REMOVE REACH. // // If it could add any, the machine would become a place to escalate FROM, which // inverts the product. So the test below runs every op this box answers, // against every capability family, with the switch on and off, and fails if any // combination is allowed with the switch that was refused without it. import ( "os" "path/filepath" "runtime" "sort" "strings" "testing" "time" ) // anchoredBox is the state capsAllow needs: a real anchor with its key pinned, // and a REAL SIGNED grant for `self`. It reuses the given page's own fixtures // (uigiven_test.go) rather than hand-writing records, because capsAllow reads // them through verifyAnchorRecord — an unsigned stand-in would be refused for // the wrong reason and every assertion below would pass without testing // anything. func anchoredBox(t *testing.T, self string, caps []string) { t.Helper() uiTestConfigDir(t) priv := givenAnchoredBox(t) // The PAIRING as well as the grant. A signed grant for a host this machine // has never paired with is not a state that occurs — and localDenySet now // refuses a host it has not heard of, so a fixture without one was testing // against something the machine would never see. givenPairing(t, self, pairingActive) givenSignedGrant(t, priv, self, caps) } // ── the invariant ─────────────────────────────────────────────────────────── // THE SWITCH NEVER WIDENS. Every op, every family, both states. // // THE FIXTURE IS A NARROW GRANT, AND THAT IS THE WHOLE TEST. The first version // used a pairing granted allCaps — so almost every op was ALLOWED before the // switch, `before != ""` was false, and the widening branch never ran. A // mutation that made the switch return "allowed" instead of a refusal passed // it. A test for "X cannot turn a refusal into an allow" has to be run against // things that are REFUSED. func TestTheLocalSwitchCanOnlyEverRemoveReach(t *testing.T) { const self = "h1.host.privatae.ai" ops := mgmtOpVocabulary() if len(ops) < 10 { t.Fatalf("only %d ops in the vocabulary — this check has stopped seeing them", len(ops)) } // One family granted. Every op outside it is refused, which is the // population this invariant is about. const granted = "observe" refusedBefore := 0 for _, fam := range allCaps { for _, op := range ops { anchoredBox(t, self, []string{granted}) before := capsAllow(self, op) if before == "" { continue // in-grant: nothing for the switch to widen } refusedBefore++ if err := localDenySet(self, fam, true); err != nil { t.Fatalf("switching %s off: %v", fam, err) } if after := capsAllow(self, op); after == "" { t.Fatalf("op %q was REFUSED with %q switched on, and ALLOWED once it was "+ "switched off.\n before: %s\n"+ "A local switch that turns a refusal into an allow is an escalation "+ "path on the user's own machine.", op, fam, before) } } } if refusedBefore == 0 { t.Fatal("no op was refused by the narrow grant, so the widening branch never " + "ran and this test proved nothing — exactly how its first version passed " + "a mutation that made the switch widen") } t.Logf("%d refused (op, family) pairs checked for widening", refusedBefore) } // Turning it back on clears the denial and restores exactly what the GRANT // allowed — never more. Driven against a pairing with a NARROW grant, so // "restored" cannot be confused with "widened". func TestTurningItBackOnRestoresTheGrantAndNotMore(t *testing.T) { const self = "h1.host.privatae.ai" narrow := []string{"observe"} anchoredBox(t, self, narrow) // An op outside the grant is refused before the switch is ever touched. outside := "harness:run" if capsAllow(self, outside) == "" { t.Fatalf("%s is allowed by a grant of %v, so this test cannot tell "+ "restoring from widening", outside, narrow) } for _, fam := range allCaps { if err := localDenySet(self, fam, true); err != nil { t.Fatal(err) } } for _, fam := range allCaps { if err := localDenySet(self, fam, false); err != nil { t.Fatal(err) } } if why := capsAllow(self, outside); why == "" { t.Error("after switching everything off and back on, an op the grant never " + "included is allowed. Turning a switch back on must clear a local denial " + "and nothing else.") } // And the op the grant DID include works again. if why := capsAllow(self, "observe:agents"); why != "" { t.Errorf("an op inside the grant is still refused after switching back on: %s", why) } } // ── it applies to the anchor too ──────────────────────────────────────────── // ON A ONE-HOST MACHINE THE ONLY PAIRING IS THE ANCHOR. A switch that exempted // it would be a button with no effect on exactly the computer this feature was // asked for. func TestTheSwitchAppliesToTheAnchorPairing(t *testing.T) { uiTestConfigDir(t) givenAnchoredBox(t) anchor := gAnchorHost if why := capsAllow(anchor, "dcn_search"); why != "" { t.Fatalf("the anchor pairing is refused before any switch: %s", why) } if err := localDenySet(anchor, "dcn", true); err != nil { t.Fatal(err) } why := capsAllow(anchor, "dcn_search") if why == "" { t.Error("the anchor host is exempt from the local switch. On a machine paired " + "to one host — which IS its anchor — that makes the control do nothing at " + "all, which is the case it was built for.") } if !strings.Contains(why, "switched off on this machine") { t.Errorf("the refusal does not say a person switched it off: %q", why) } } // ── failure directions ────────────────────────────────────────────────────── // AN UNREADABLE DENY LIST SWITCHES EVERYTHING OFF. The person switched // something off; a file that will not parse cannot say what, so every family // is refused until the person resets the list at the machine. It used to read // as "nothing is off", which handed the host back exactly what was refused. func TestAnUnreadableDenyListRefusesEverything(t *testing.T) { const self = "h1.host.privatae.ai" anchoredBox(t, self, allCaps) p, err := localDenyPath() if err != nil { t.Fatal(err) } if err := os.WriteFile(p, []byte("{not json"), 0o600); err != nil { t.Fatal(err) } for _, op := range []string{"observe:agents", "session:root"} { if why := capsAllow(self, op); why == "" { t.Errorf("a corrupt deny list let %s through: an unreadable list must "+ "refuse everything, or a switch the person turned off is back on", op) } } // And it is reported rather than swallowed. if _, err := localDenyLoad(); err == nil { t.Error("the unreadable list was loaded without an error, so nothing can tell " + "the person why everything is refused") } if _, note := localDenyIndex(); !strings.Contains(note, "switch --reset") { t.Errorf("the page note does not name the way out: %q", note) } } // A MISSING list is not an unreadable one: a machine nobody has switched // anything off on serves its grant. func TestAMissingDenyListBlocksNothing(t *testing.T) { const self = "h1.host.privatae.ai" anchoredBox(t, self, allCaps) if why := capsAllow(self, "observe:agents"); why != "" { t.Errorf("with no deny list at all an op was refused: %q", why) } } // --reset sets an unreadable list aside (kept, never deleted) and serves the // grant again; it refuses on a list that reads fine, because that would // clear the person's switches without them choosing each one. func TestResetSetsAnUnreadableListAsideAndRefusesAGoodOne(t *testing.T) { const self = "h1.host.privatae.ai" anchoredBox(t, self, allCaps) p, err := localDenyPath() if err != nil { t.Fatal(err) } if err := localDenySet(self, "dcn", true); err != nil { t.Fatal(err) } if _, err := localDenyReset(); err == nil { t.Fatal("a list that reads fine was reset, clearing a switch nobody turned on") } if !localDenied(self, "dcn") { t.Fatal("the refused reset lost the switch") } if err := os.WriteFile(p, []byte("{not json"), 0o600); err != nil { t.Fatal(err) } now := time.Date(2026, 10, 30, 3, 0, 0, 0, time.UTC) kept, err := localDenyResetAt(now) if err != nil { t.Fatal(err) } if b, err := os.ReadFile(kept); err != nil || string(b) != "{not json" { t.Errorf("the unreadable file was not kept at %s: %q %v", kept, string(b), err) } if why := capsAllow(self, "observe:agents"); why != "" { t.Errorf("after a reset the grant is still refused: %q", why) } } // A family this machine does not know is REFUSED rather than stored: a deny // entry nothing will ever match is a switch that silently does nothing. func TestAnUnknownCapabilityIsRefusedNotStored(t *testing.T) { uiTestConfigDir(t) givenPairing(t, "h1.host.privatae.ai", pairingActive) err := localDenySet("h1.host.privatae.ai", "everything", true) if err == nil { t.Fatal("an unknown capability was accepted") } if !strings.Contains(err.Error(), "not a capability") { t.Errorf("the refusal does not say why: %v", err) } if got := localDenyFamilies("h1.host.privatae.ai"); len(got) != 0 { t.Errorf("it was stored anyway: %v", got) } } // Writing a fresh file over one that did not parse would discard whatever the // person had already switched off. func TestAnUnreadableListIsNotOverwritten(t *testing.T) { uiTestConfigDir(t) givenPairing(t, "h1.host.privatae.ai", pairingActive) p, err := localDenyPath() if err != nil { t.Fatal(err) } if err := os.MkdirAll(filepath.Dir(p), 0o700); err != nil { t.Fatal(err) } if err := os.WriteFile(p, []byte("{not json"), 0o600); err != nil { t.Fatal(err) } if err := localDenySet("h1.host.privatae.ai", "dcn", true); err == nil { t.Error("a switch was written over a file that could not be read, silently " + "discarding whatever was already switched off") } b, _ := os.ReadFile(p) if string(b) != "{not json" { t.Errorf("the unreadable file was replaced: %q", string(b)) } } // The file names which hosts a person has cut off from what. Private. func TestTheDenyListIsWrittenPrivate(t *testing.T) { uiTestConfigDir(t) givenPairing(t, "h1.host.privatae.ai", pairingActive) if err := localDenySet("h1.host.privatae.ai", "dcn", true); err != nil { t.Fatal(err) } p, err := localDenyPath() if err != nil { t.Fatal(err) } fi, err := os.Stat(p) if err != nil { t.Fatal(err) } if runtime.GOOS == "windows" { t.Skip("unix permission bits do not carry the same meaning here") } if got := fi.Mode().Perm(); got != 0o600 { t.Errorf("local-deny.json is %o, want 600", got) } } // Switching one family off leaves the others alone. func TestSwitchingOneFamilyOffLeavesTheRestAlone(t *testing.T) { const self = "h1.host.privatae.ai" anchoredBox(t, self, allCaps) if err := localDenySet(self, "dcn", true); err != nil { t.Fatal(err) } got := localDenyFamilies(self) want := []string{"dcn"} sort.Strings(got) if len(got) != len(want) || got[0] != want[0] { t.Fatalf("switched off = %v, want %v", got, want) } if why := capsAllow(self, "observe:agents"); why != "" { t.Errorf("switching dcn off also refused an observe op: %s", why) } } // A SWITCH CANNOT LIE BY TYPO. Deny-only means a bogus host is harmless to the // gate — nothing matches it — but the page would answer "X can no longer read // your files" about a host never paired here. func TestSwitchingOffAHostThisMachineNeverHeardOfIsRefused(t *testing.T) { uiTestConfigDir(t) givenPairing(t, "real.host.privatae.ai", pairingActive) err := localDenySet("typo.host.privatae.ai", "dcn", true) if err == nil { t.Fatal("a host this machine has never paired with was accepted, so the page " + "would confirm an action about a host that does not exist here") } if !strings.Contains(err.Error(), "no host called") { t.Errorf("the refusal does not say why: %v", err) } // The real one still works, so this is a guard and not a wall. if err := localDenySet("real.host.privatae.ai", "dcn", true); err != nil { t.Errorf("a paired host was refused: %v", err) } } // Every reader of an unreadable list gives the gate's answer: everything is // off. The given page's box-wide card included, and localDenyFamilies too. func TestEveryReaderOfAnUnreadableListSaysEverythingIsOff(t *testing.T) { const self = "h1.host.privatae.ai" anchoredBox(t, self, allCaps) p, err := localDenyPath() if err != nil { t.Fatal(err) } if err := os.WriteFile(p, []byte("{not json"), 0o600); err != nil { t.Fatal(err) } if got := localDenyFamilies(self); len(got) != len(localSwitchFamilies()) { t.Errorf("localDenyFamilies on an unreadable list: %v", got) } g := collectGiven() for _, h := range g.Hosts { for _, f := range h.Families { if !f.SwitchedOff { t.Errorf("%s: the %s card does not read as switched off", h.Host, f.Name) } } } }