From 792b0506bc7b2300e11de71114b3872e601d4f4e Mon Sep 17 00:00:00 2001 From: Matthew Meszaros Date: Tue, 29 Sep 2026 20:27:26 +0200 Subject: [PATCH] feat: return the passkey button to ready after an aborted explicit sign-in so it can be retried, and document that a new worker command type must be safe to lose while the fleet is still on the previous release --- docs/content/docs/development/events.mdx | 2 ++ web/src/app/auth/login/page.tsx | 3 +++ 2 files changed, 5 insertions(+) diff --git a/docs/content/docs/development/events.mdx b/docs/content/docs/development/events.mdx index f8e1b0009..24f58021d 100644 --- a/docs/content/docs/development/events.mdx +++ b/docs/content/docs/development/events.mdx @@ -23,6 +23,8 @@ Schemas are derived from the Go structs (`internal/models/event_schema.go`), and Two things follow. The registered document is the marshalled schema, not `Schema.String()`, which omits defaults and would throw the guarantee away. And the registry stays on `BACKWARD` rather than `FORWARD`: adding a field is safe under both, but adding a new event type adds a union branch, which `BACKWARD` accepts and `FORWARD` refuses. When a registration is refused and the subject's effective level is `FORWARD` or `FULL` (or their transitive forms), the publisher sets that subject to `BACKWARD` and registers again, so the registry key needs permission to change a subject's compatibility. Any other level, and any other refusal, is left as it is. Nothing in this reaches production untested. `internal/app/eventschemas` lists every schema a release publishes and keeps the one the registry last accepted under `testdata/`. CI decodes the recorded schema with the new one, which is the registry's own `BACKWARD` check, and fails a change the registry would refuse. It also fails a compatible change that has not been recorded, so a schema change is always in the diff: run `make schemas` and commit the result. On release the backend registers every listed schema when it boots, and the fleet does not move to the release until that has succeeded. + +The registry check covers the schema, not the rollout. Readers decode with the schema id each message carries, so a worker still on the previous release reads new fields fine, but a command type it has never heard of is logged and skipped. The backend rolls out before the fleet, so a new worker command type must be safe to lose while the fleet catches up: send it only to a worker whose reported version handles it, or have the backend retry it until one does. The Rust tracking service follows both switches. It speaks Kafka only when compiled with its `kafka` cargo feature, which is what the `tracking:*-kafka` image is, and it encodes with `CODEC_PROVIDER` on either transport. So a Kafka deployment on `CODEC_PROVIDER=json` needs no Schema Registry at all, and `avro` there is refused at boot without `SCHEMA_REGISTRY_URL` rather than failing at the first published event. diff --git a/web/src/app/auth/login/page.tsx b/web/src/app/auth/login/page.tsx index a0cc6f48e..9cb19c42c 100644 --- a/web/src/app/auth/login/page.tsx +++ b/web/src/app/auth/login/page.tsx @@ -414,6 +414,9 @@ export default function LoginPage() { } else if (e.reason === "timeout") { setPasskeyStatus("timeout"); toast.error("Safari didn't show a passkey prompt. Try again, or use password sign-in."); + } else { + // Aborted: nothing to explain, but the button has to be usable again. + setPasskeyStatus("ready"); } } else { setPasskeyStatus("error");