You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(plugin-auth): scope the no-mail-transport rider on the invitation remedy
Clause-② review F1: the rider was FALSE on a reachable population. The
invitation carve-out is an ADMISSION verdict, not a verification bypass, so
the forced-verification mechanism this same line warns about for remedy (b)
applies to the INVITED login too. Measured by the reviewer on `open` and on
`email_domain` with a pending invitation: sign-up 200 with emailVerified
false, sign-in 403 EMAIL_NOT_VERIFIED — and the created row makes
probeSignInAccountsPresence answer 'present', so the report goes silent. An
operator following the PRIMARY remedy on a widened posture therefore got no
login and turned this report off: the loud-dead-end-to-quiet-dead-end
transition remedy (a) warns about, delivered by the remedy the card
commissioned.
The rider is now scoped to the default posture and carries the ordering the
reviewer measured to work — close a widened posture back to `invite_only`
BEFORE the invited person registers. All three copies (the string literal,
the block comment, the changeset) are aligned again.
Also folded in from the same review:
- N2: the invitation `email` must be stored LOWERCASE. `hasPendingInvitationFor`
searches `where: { email: target.toLowerCase() }`, so a mixed-case row is
never found and the sign-up is refused SELF_REGISTRATION_CLOSED — a silent
dead end the line was sending operators into.
- N1: `(INVALID_EMAIL_OR_PASSWORD)` is row-shape-dependent — an issuer-less
hand-written row answers 401, a fully-shaped one with a plaintext password
answers 500. Widened to "a 401 or a 500 depending on the row shape, never a
session", which holds for both.
- N3: dropped the "next boot" timing claim; under `single` the holder is
usually promoted at the sign-up itself. The outcome is unchanged, so the
line now states the outcome and not the timing.
Five new pins, because the clause that was wrong is the one nothing guarded:
the scoped phrasing itself; a widened posture admitting the invited creation
AND still forcing verification on it (the two mechanisms driven together,
since the false claim was that the first cancels the second); only the default
posture being mail-transport-free; the structural fact that an admission
verdict carries no field that could exempt verification; and N5 — every
widening posture in `AUDIENCE_POSTURES` is named in the message, read off the
vocabulary so a fourth one cannot leave the line silently stale.
⛔ Still message-text only: no admission semantics, no probe change, sign-up
path untouched.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XpTx2tbq3pZRYAdoGt6E6Y
Copy file name to clipboardExpand all lines: .changeset/boot-sign-in-report-remedy-text.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -9,6 +9,6 @@ That boot line fires on the deployment nobody can sign in to: human `sys_user` r
9
9
-**"Open the audience posture so an existing person can register their own login"** produced no login. Every posture other than `invite_only` forces `requireEmailVerification` on, so a login registered that way is refused `EMAIL_NOT_VERIFIED` at its first sign-in — and a locked-out self-hosted install is usually the shape with no mail transport wired.
10
10
-**"Write a `sys_account` credential row directly against the store"** was worse than useless. The `password` column carries a secret in the platform's own hash format, so a plaintext one authenticates nothing — and the probe behind this report asks only whether *any*`sys_account` row exists, so writing one turns the report off. The operator's first attempt at the named remedy turned the loud dead end back into the silent one the report was written to end.
11
11
12
-
The line now names the path that was measured to work: write one pending `sys_invitation` row directly against the store — an address the directory does not already hold, `status``pending`, a future `expires_at`, `inviter_id` of any existing `sys_user` — then register through the ordinary sign-up endpoint. The invitation carve-out admits that one creation under every posture, so no door is widened and no mail transport is needed; on the `single` tenancy posture the next boot promotes that account holder. The other two are still named, as the two things that look like remedies and are not, because an operator who is going to hand-write a credential row anyway needs to know it blinds the probe.
12
+
The line now names the path that was measured to work: write one pending `sys_invitation` row directly against the store — a lowercase address the directory does not already hold, `status` `pending`, a future `expires_at`, `inviter_id` of any existing `sys_user` — then register through the ordinary sign-up endpoint. The invitation carve-out admits that one creation under every posture, so no door needs widening. It is an admission verdict and not a verification bypass, though, so the line scopes what follows from that: only under the default `invite_only` posture is the recovery mail-transport-free, and it tells the operator to close a widened posture back to `invite_only` before the invited person registers — otherwise the invited login is created, refused `EMAIL_NOT_VERIFIED` at first sign-in, and has silenced this report on the way past. On the `single` tenancy posture that account holder is then promoted to platform admin. The other two are still named, as the two things that look like remedies and are not, because an operator who is going to hand-write a credential row anyway needs to know it blinds the probe.
13
13
14
14
**Message text only — no admission semantics move.** Nothing widens, nothing narrows, no accept set changes, and the probe is untouched: this changes what an operator *reads*, not what the platform *admits*. The long form of the same three facts is on the self-hosting deployment page.
0 commit comments