package inventory import ( "strings" "testing" "time" ) // An ask for a module's own secret at a desk is bounded by the record (novox/hq ADR 0277): one open per secret, // three an hour, and every one says who asked and how it ended. func TestASecretAskIsOneAtATimeAndFewAnHour(t *testing.T) { inv := ForTest(t) ctx := t.Context() if _, err := inv.AddNode(ctx, "shanks"); err != nil { t.Fatal(err) } first, err := inv.OpenSecretAsk(ctx, "shanks", "mounts", "smb-credentials", "g14/claude-code", "shanks") if err != nil { t.Fatal(err) } if _, err := inv.OpenSecretAsk(ctx, "shanks", "mounts", "smb-credentials", "laptop/agent", "shanks"); err == nil || !strings.Contains(err.Error(), "still open") || !strings.Contains(err.Error(), "g14/claude-code") { t.Errorf("a second ask while one is open: %v", err) } // Another secret is its own. other, err := inv.OpenSecretAsk(ctx, "shanks", "mounts", "other", "laptop/agent", "shanks") if err != nil { t.Fatal(err) } if err := inv.EndSecretAsk(ctx, other, "dismissed"); err != nil { t.Fatal(err) } if err := inv.EndSecretAsk(ctx, first, "given"); err != nil { t.Fatal(err) } for i := 0; i < SecretAsksPerHour-1; i++ { id, err := inv.OpenSecretAsk(ctx, "shanks", "mounts", "smb-credentials", "g14/claude-code", "shanks") if err != nil { t.Fatalf("ask %d: %v", i+2, err) } if err := inv.EndSecretAsk(ctx, id, "timed-out"); err != nil { t.Fatal(err) } } if _, err := inv.OpenSecretAsk(ctx, "shanks", "mounts", "smb-credentials", "g14/claude-code", "shanks"); err == nil || !strings.Contains(err.Error(), "times in the last hour") { t.Errorf("a fourth ask in an hour: %v", err) } if _, err := inv.OpenSecretAsk(ctx, "nowhere", "mounts", "smb-credentials", "x", "nowhere"); err == nil { t.Error("a machine the mesh does not know was taken") } asks, err := inv.SecretAsks(ctx, time.Now().Add(-time.Hour)) if err != nil || len(asks) != SecretAsksPerHour+1 { t.Fatalf("%d asks, %v", len(asks), err) } if a := asks[len(asks)-1]; a.Node != "shanks" || a.Module != "mounts" || a.Name != "smb-credentials" || a.AskedBy != "g14/claude-code" || a.Outcome != "given" || a.EndedAt == nil { t.Errorf("the first ask: %+v", a) } }