device_revoked was built twice, three lines of identical prose, in the
two places that raise it. It is the sentence a person reads and the code
a client keys on, so the two copies were one edit away from disagreeing
on whichever path nobody touched.
Five refusals across 21 call sites now have one definition each, in the WireError factory block beside forbidden and notFound rather than
in a pattern of my own:
device_revoked 2 sites
Malformed device id. 6 sites, 4 files
Credential not accepted. 5 sites
Token is scoped to a different device. 4 sites
That device belongs to another account. 4 sites
Malformed attachment id. 2 sites
base64url was implemented three times, byte for byte: Token.swift at
file scope, SignupChallenge.b64/unb64, and APNs.base64url. The
first pair is canonical and the other two now call it. Three copies of
the encoding used to sign APNs tokens and verify sign-up challenges is
three places for one of them to drift.
Sixteen duplicated strings are left alone on purpose. The password rules,
the reset-code refusal and the rate-limit sentences live in one or two
files each and may reasonably diverge as those flows change; collapsing
them would couple unrelated code to look tidy.
`device_revoked` was built twice, three lines of identical prose, in the
two places that raise it. It is the sentence a person reads and the code
a client keys on, so the two copies were one edit away from disagreeing
on whichever path nobody touched.
Five refusals across 21 call sites now have one definition each, in the
`WireError` factory block beside `forbidden` and `notFound` rather than
in a pattern of my own:
device_revoked 2 sites
Malformed device id. 6 sites, 4 files
Credential not accepted. 5 sites
Token is scoped to a different device. 4 sites
That device belongs to another account. 4 sites
Malformed attachment id. 2 sites
base64url was implemented three times, byte for byte: `Token.swift` at
file scope, `SignupChallenge.b64`/`unb64`, and `APNs.base64url`. The
first pair is canonical and the other two now call it. Three copies of
the encoding used to sign APNs tokens and verify sign-up challenges is
three places for one of them to drift.
Sixteen duplicated strings are left alone on purpose. The password rules,
the reset-code refusal and the rate-limit sentences live in one or two
files each and may reasonably diverge as those flows change; collapsing
them would couple unrelated code to look tidy.
736 tests green, build clean with no warnings.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
device_revokedwas built twice, three lines of identical prose, in thetwo places that raise it. It is the sentence a person reads and the code
a client keys on, so the two copies were one edit away from disagreeing
on whichever path nobody touched.
Five refusals across 21 call sites now have one definition each, in the
WireErrorfactory block besideforbiddenandnotFoundrather thanin a pattern of my own:
device_revoked 2 sites
Malformed device id. 6 sites, 4 files
Credential not accepted. 5 sites
Token is scoped to a different device. 4 sites
That device belongs to another account. 4 sites
Malformed attachment id. 2 sites
base64url was implemented three times, byte for byte:
Token.swiftatfile scope,
SignupChallenge.b64/unb64, andAPNs.base64url. Thefirst pair is canonical and the other two now call it. Three copies of
the encoding used to sign APNs tokens and verify sign-up challenges is
three places for one of them to drift.
Sixteen duplicated strings are left alone on purpose. The password rules,
the reset-code refusal and the rate-limit sentences live in one or two
files each and may reasonably diverge as those flows change; collapsing
them would couple unrelated code to look tidy.
736 tests green, build clean with no warnings.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com
assigned to @paulhitt
restored source branch
chore/one-device-revokedmentioned in commit
735cef7ed2