Conversation
added 5 commits
September 12, 2026 17:26
Add the NIP-09 e/k tag names to the single home of kind and tag constants, a parser for kind 5 requests, and a signer helper that publishes one for a page revision. The parser only accepts a request about our page revisions in this group: the h tag, when present, must match, and a foreign k is rejected. The h tag is written on publish so the request is scoped to the group and can be read back with the same filter as the content. NIP-09 is a request, not a guarantee: docs/09-security-privacy.md.
buildPages takes the set of revision ids a NIP-09 request removed. They are dropped from the exposed list and from the leaves, and the survivors are reconnected around them: a survivor whose parent-rev names a removed revision is re-pointed at the nearest surviving ancestor, first parent first, with a cycle guard. The parent references of a removed revision are no longer collected, because the repair already keeps its parents from looking like leaves again. Blame and findCommonAncestor need no change: they are fed the repaired list, so the walk crosses the gap on the bridged predecessor. A page whose only revision was removed disappears instead of showing a removed head.
SpaceStore reads kind 5 for the group on a fifth subscription, keeps the parsed requests and derives the removed set on every rebuild. The gate the relay does not provide is ours: a request counts only against the requester's own revision. Nothing is removed from the store — the request is a tombstone, so the chain can bridge across it and a reload re-derives the removal from the relay. HistoryView offers "Request deletion" only on one's own revisions, next to the admin 9005 button. The confirm and result text call it a request, name the copy that may remain on other relays and clients, and never say "deleted". A muted note lists the revisions of the page that were removed by their authors. Test maintenance beyond the ticket, both needed to keep the gate green on a machine where the local dev relays are running: - the CON-36 reconnect test expects the fifth subscription now; - the tests that render a mention or run the live editor (editor-complete, formatting-help, markdown-live, Markdown, task-marker, markdown-flavour) prime the profile cache, which opened a real WebSocket to the configured profile relays during tests and made vitest fail intermittently with an undici Event-realm error. The profile store is mocked there; none of those tests asserts a fetched name.
# Conflicts: # src/ui/Markdown.test.tsx # src/ui/markdown-live.test.ts
… reachable `parseDeletion` tolerated a missing `h` tag on the grounds that NIP-09 does not define one. That was the wrong way round: the subscription asks for `#h`, so a request without it never reaches this app at all, while accepting one anyway let a relay hand us a request from a foreign group and have it remove a revision in this one. The tag is required now, and the check stays here rather than being trusted from the filter. `DELETION_REQUEST` joins `APP_CONTENT_KINDS`, so a relay that enforces a group's `supported_kinds` does not reject the one event whose whole point is to be accepted. Our own relay enforces nothing here; this is a declaration for the ones that do. Repairing the chain around a removed revision followed only the first-parent path, so a removed *merge* left its other ancestors with nothing pointing at them and they came back as leaves — a fork out of a deletion. They are collected as `bridged` and counted as referenced instead of being made parents: a revision's arity is what its author signed, and a successor that inherited two parents would wear a merge badge for a merge nobody made. The history view now explains the removal in both of its branches. Removing the last revision of a page makes the page itself disappear, which is exactly the moment the reader needs to be told why — so the callouts are computed off the route's slug and drawn above "No revisions left for this slug." as well.
Owner
Author
|
Closing unmerged: CON-10 is rejected as a product decision — being able to delete a single revision of a page is not a feature Akasha needs right now. Not a verdict on the branch, which is green on typecheck, lint, tests and build; the one open defect from the UI pass (the kind 5 carries no The branch Note for #87 and #88: both are stacked on this branch and carry commits 098cbc4, 0a199cf and 5c8390f, so merging either as it stands would land the rejected feature anyway. See the CON-10 ticket for the two options. |
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 CON-10.
A writer can ask the relay to remove one of their own revisions (NIP-09, kind 5), and the history explains what that did and did not achieve.
What is in it
SpaceStorereads kind 5 for the group on a subscription of its own, keeps the parsed requests and derives the removed set on every rebuild. Nothing is dropped from the store: the request is a tombstone, so a reload re-derives the removal from the relay instead of trusting local state.buildPagesreconnects the chain around a removed revision instead of tearing it: a survivor whoseparent-revnames a removed revision is re-pointed at the nearest surviving ancestor. A removed merge's other ancestors are marked as referenced rather than made parents, so they do not come back as leaves and no successor wears a merge badge for a merge nobody made.parseDeletionrequires thehtag naming this group. The subscription asks for#hanyway, so tolerating its absence only left room for a relay to hand us a request from another group.DELETION_REQUESTis declared inAPP_CONTENT_KINDS, for relays that enforce a group'ssupported_kinds.How to test
Local relay and seeded group:
./scripts/dev-relay-up.sh,./scripts/dev-group-seed.sh, thennpm run dev.Automated:
npm run typecheck && npm run lint && npm test && npm run build— green.Stack
Base for [CON-11]. Merge this one first.