carlos / contra Public

test: sign in to an account this process did not create

Every sign-in test in this repository signed up first, in the same
process, over a database that did not exist a moment earlier — including
the real-engine browser walk. That covers the ceremony and covers nothing
about durability, and they are different promises. A deployed instance
restarts on every release, so the only sign-in that matters to a real
person is the one on the far side of a restart they never saw.

The gap surfaced the way gaps do: a sign-in failed on the canary while the
whole suite was green. A suite that only ever signs into an account it
just made cannot tell "the ceremony works" from "the ceremony works and
the account is still there afterwards".

So: sign up against a named file, build a second app over the same file —
new process, same disk, same pepper, which is what a redeploy is — and
sign in through it. Then fetch bootstrap with the resulting session, because
a sign-in that mints a cookie over wraps that no longer open is a pass that
means nothing.

It passes, which is the useful part: it rules the code out. What it cannot
rule out is the instance's own state, and that is where the canary's
failure actually lives.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Paul Campbell pushed by paul@keymail.dev 7885fa4d8c62cb68ac926e0db098659329435d89 parent b07d6d7
1 file changed, +59 −0
  • internal/contratest/auth_test.go +59 −0
diff --git a/internal/contratest/auth_test.go b/internal/contratest/auth_test.go
index 16ca10b..19a8c3a 100644
--- a/internal/contratest/auth_test.go
+++ b/internal/contratest/auth_test.go
@@ -10,6 +10,7 @@ import (
"encoding/json"
"net/http"
"net/http/httptest"
+ "path/filepath"
"strings"
"testing"
@@ -517,3 +518,61 @@ func TestStoredWrapsStillOpen(t *testing.T) {
}
}
}
+
+// TestSignInSurvivesARestart signs in to an account the running process did
+// not create.
+//
+// EVERY OTHER SIGN-IN TEST IN THIS REPOSITORY SIGNS UP FIRST, in the same
+// process, over a database that did not exist a moment ago. That covers the
+// ceremony and covers nothing about durability: a deployed instance restarts
+// on every release, and the only sign-in that matters to a real person is the
+// one on the far side of a restart they never saw.
+//
+// Written on 2026-09-05 after a sign-in failed on the canary while the whole
+// suite, including a real-engine browser walk of signup-then-sign-in, was
+// green. A test that only ever signs into an account it just made cannot tell
+// the difference between "the ceremony works" and "the ceremony works and the
+// account is still there afterwards", and those are different promises.
+//
+// The second app is built over the same file with the same config, which is
+// what a redeploy is: new process, same disk, same pepper.
+func TestSignInSurvivesARestart(t *testing.T) {
+ dbPath := filepath.Join(t.TempDir(), "restart.db")
+
+ const email = "restart-person@example.invalid"
+ const passphrase = "a generated test passphrase 8f3a1c"
+
+ first, _, _ := newAppAt(t, dbPath)
+ a := doSignup(t, first, email, passphrase)
+
+ // The restart. Nothing is carried across but the file.
+ second, _, _ := newAppAt(t, dbPath)
+
+ rec := doSignIn(t, second, a.email, a.passphrase)
+ if rec.Code != http.StatusOK {
+ t.Fatalf("sign in after a restart: status %d, body %s — an account "+
+ "created before this process started could not sign in, which is "+
+ "every account on a deployed instance",
+ rec.Code, rec.Body.String())
+ }
+ if rec.Header().Get("Set-Cookie") == "" {
+ t.Fatal("sign in after a restart minted no session cookie")
+ }
+
+ // And the wraps the first process sealed still open under the second's
+ // view of the world, which is the part a changed pepper or a changed
+ // database file would break.
+ req := httptest.NewRequest(http.MethodGet, "/api/bootstrap", nil)
+ req.Header.Set("Cookie", strings.SplitN(rec.Header().Get("Set-Cookie"), ";", 2)[0])
+ boot := httptest.NewRecorder()
+ second.ServeHTTP(boot, req)
+ if boot.Code != http.StatusOK {
+ t.Fatalf("bootstrap after a restart: status %d, body %s",
+ boot.Code, boot.Body.String())
+ }
+ if !strings.Contains(boot.Body.String(), "wrap") &&
+ !strings.Contains(boot.Body.String(), "vault") {
+ t.Errorf("bootstrap after a restart returned nothing to unlock with: %s",
+ boot.Body.String())
+ }
+}