The profile editor writes what Plaza reads - #384
Merged
Merged
Conversation
This app reads nine keys off a kind:0 and the Edit profile sheet offered three, so four of them could be displayed and never entered. The one with a consequence is `lud16`. It is the lightning address, it is how NIP-57 finds somebody's LNURL callback, and an account set up only in Plaza had no way to put one in its profile. That account could not be zapped by anyone, in any client, until its owner opened something else. Website, banner and the NIP-05 identifier are the same shape of gap with smaller stakes. The merge is untouched, which is the point. `profileMergeBase` already reads the raw published record rather than the parsed cache, so keys this app does not model survive; an emptied field removes its key rather than writing an empty string; a value too long for its buffer was never shown so it is never written; and the write refuses outright when the existing record cannot be parsed. Adding fields here is adding `setOrRemove` calls and the seeding to match, and nothing else. Seeding is the half that matters, and it is why each field is read back before it can be written. The merge publishes what the MODEL holds, so a field shown in the sheet but never seeded from the published record would go out as absent and delete the key. `profile_can_save` is what makes that unreachable: it refuses every stage where the profile has not been read, and the one stage where absent really is absent is a key minted in this app. Validation goes as far as is honest and no further. A lightning address and a NIP-05 identifier both have to look like `name@domain.tld`; a picture, banner or website has to start with a scheme. What is deliberately not checked is whether any of them resolve, because that cannot be known without asking and a checker that refused an unusual but working URL would be worse than one that let a typo through: the reader can see their own picture failing to load and cannot see why this app declined to save it. Empty is always allowed, since an empty field removes its key and that is somebody saying they do not have one. Saving is refused while a field is unusable, and the sheet says which one. A kind:0 is replaceable, so a bad value is not a private mistake: it is what every other client sees. Tests go to 655, and I checked all four are load bearing by sabotaging the two halves separately. Making the validator report everything fine fails the two validation tests; dropping the `lud16` write fails the two merge tests. My first attempt disabled only the picture check and failed nothing, which is exactly the false pass this kind of check exists to avoid. No version bump here. The plan assigned it to this PR, but Plaza has already shipped through v0.23.0 and another item is still to come, so what the next release is called is a decision rather than an increment. Closes #263.
sepehr-safari
deleted the
the-profile-editor-writes-what-plaza-reads
branch
September 22, 2026 16:00
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #263.
Plaza reads nine keys off a kind:0 and the sheet offered three, so four could be displayed and never entered.
The one with a consequence is
lud16. It is how NIP-57 finds somebody LNURL callback, so an account set up only in Plaza could not be zapped by anyone, in any client, until its owner opened something else. Website, banner and the NIP-05 identifier are the same gap with smaller stakes.name@domain.tldname@domain.tldThe merge is untouched, which is the point
profileMergeBasealready reads the raw published record rather than the parsed cache, an emptied field removes its key rather than writing"", a value too long to be shown is never written, and the write refuses outright when the existing record will not parse. Adding fields is addingsetOrRemovecalls and the seeding to match.Seeding is the half that matters. The merge publishes what the model holds, so a field shown in the sheet but never seeded would go out as absent and delete the key.
profile_can_savemakes that unreachable: it refuses every stage where the profile has not been read, and the one stage where absent really is absent is a key minted here. There is a test asserting every shown field is seeded, because that is the invariant the whole thing rests on.Validation stops where honesty stops
Shape only. Whether a lightning address has an endpoint behind it cannot be known without asking, and a checker that refused an unusual but working URL would be worse than one that let a typo through: the reader can see their own picture failing to load, and cannot see why this app declined to save it. Empty is always allowed, because an empty field removes its key and that is somebody saying they do not have one.
Saving is refused while a field is unusable and the sheet says which. A kind:0 is replaceable, so a bad value is not a private mistake.
Tests
651 to 655, and I checked all four are load bearing by sabotaging the two halves separately. Making the validator report everything fine fails the two validation tests; dropping the
lud16write fails the two merge tests.My first sabotage disabled only the picture check and failed nothing. That is precisely the false pass this kind of check exists to catch, so it is worth saying that it caught me.
Three existing tests changed. They used
lud16andnip05as the canary for "a key this app does not model", which is what this PR stops being true. They now usepronounsandlud06, which it still cannot see.Not here
No version bump. The plan put it on this PR, but Plaza has already shipped through v0.23.0 and another item is still to come, so what the next release is called is your call rather than an increment.