feat: sprout notes NIP-23 long-form CLI + relay a-tag deletion#719
Merged
Conversation
This was referenced May 21, 2026
ae88048 to
6e4b48d
Compare
Combines the long-form notes CLI with its relay-side companion so the full feature lands as one reviewable change. ## CLI (`sprout notes`) Editable team-knowledge notes on kind:30023 — write a skill once, reference the naddr from agent memory instead of re-deriving it. - `set --name <slug> [--title][--summary][--tag t...][--clear-tags] --content -` Idempotent upsert keyed by (kind:30023, me, d=slug). Read-before-write preserves `published_at`, carries title/summary/tags when omitted; `""` / `--clear-tags` clears. `--title` required on first publish. Prints durable refs (event id, naddr, coordinate, slug). - `get (--naddr | --name <slug> [--author <ref>]) [--content-only]` Exact by coordinate; cross-author `#d` lookup by name. >1 hit → candidates + non-zero exit. Never guesses. - `ls [--author <ref>] [--tag t] [--limit N]` — own by default; `--author all` across the team; bounded (default 50, cap 200). - `rm --name <slug>` — NIP-09 deletion (kind:5) of your own note. Read-before-write gives a clean "nothing to delete" on a missing slug; the deletion carries an `a` tag *only* (no `e` tag), which is required for the relay's coordinate soft-delete path below to fire. Standard NIP-23 tags only; global, no h-tag. ## Relay (NIP-09 a-tag deletion, #714) `handle_a_tag_deletion` no-op'd for kind:30023 — a kind:5 targeting the addressable coordinate was accepted but never soft-deleted the row. Adds `soft_delete_by_coordinate` (sprout-db) and routes every NIP-33 kind through it, so a-tag deletion is authoritative for 30023 and all addressable kinds. The workflow branch keeps its bespoke handling. ## Tests Pure carry-forward (`build_set_event`), tag parsing (`NoteSnapshot::from_event`), and the deletion builder (`build_rm_event` — asserts a-tag-only, zero `e` tags) are unit-tested. `e2e_long_form` gains set-twice-preserves-published_at and a-tag-deletion round-trips. Verified live against a local relay: all ignored e2e pass, and the full `set → get → ls → rm → get-404` lifecycle round-trips via the `sprout notes` binary (and via an ACP agent driving it over shell). TESTING.md gains a `notes` runbook section. Signed-off-by: tlongwell-block <109685178+tlongwell-block@users.noreply.github.com> Co-authored-by: Dawn (sprout agent) <c6237ef84fa537c78dcee78efd2d4e59f728859c7f194da42ac51ededfa0be05@sprout-oss.stage.blox.sqprod.co> Co-authored-by: Max (sprout agent) <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@sprout-oss.stage.blox.sqprod.co> Co-authored-by: Quinn (sprout agent) <96f056ad5f2305c8ddf637dc65d048aa4c12d7daeb8867690e34fca46b0ef64c@sprout-oss.stage.blox.sqprod.co>
6e4b48d to
fc9ae76
Compare
wpfleger96
added a commit
that referenced
this pull request
May 22, 2026
PR #719 (NIP-23 long-form notes) merged to main with pre-0.44 API calls. Apply the same EventBuilder and Tag::parse migrations. Also fix matching dms.rs breakage (same Tag::parse/EventBuilder::new pattern) that blocked compilation, and replace the deprecated Timestamp::as_u64() with as_secs() in notes.rs.
wpfleger96
added a commit
that referenced
this pull request
May 22, 2026
PR #719 E2E test file and notes.rs test code still used deprecated Timestamp::as_u64(), old Tag::parse(&[]) signature, 3-arg EventBuilder::new(), and array-form custom_tag().
wpfleger96
added a commit
that referenced
this pull request
May 22, 2026
PR #719 (NIP-23 long-form notes) merged to main with pre-0.44 API calls. Apply the same EventBuilder and Tag::parse migrations. Also fix matching dms.rs breakage (same Tag::parse/EventBuilder::new pattern) that blocked compilation, and replace the deprecated Timestamp::as_u64() with as_secs() in notes.rs.
wpfleger96
added a commit
that referenced
this pull request
May 22, 2026
PR #719 E2E test file and notes.rs test code still used deprecated Timestamp::as_u64(), old Tag::parse(&[]) signature, 3-arg EventBuilder::new(), and array-form custom_tag().
wpfleger96
added a commit
that referenced
this pull request
May 22, 2026
PR #719 (NIP-23 long-form notes) merged to main with pre-0.44 API calls. Apply the same EventBuilder and Tag::parse migrations. Also fix matching dms.rs breakage (same Tag::parse/EventBuilder::new pattern) that blocked compilation, and replace the deprecated Timestamp::as_u64() with as_secs() in notes.rs.
wpfleger96
added a commit
that referenced
this pull request
May 22, 2026
PR #719 E2E test file and notes.rs test code still used deprecated Timestamp::as_u64(), old Tag::parse(&[]) signature, 3-arg EventBuilder::new(), and array-form custom_tag().
This was referenced May 28, 2026
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.
What
The complete long-form notes feature in one change: the
sprout notesCLI plus the relay-side NIP-09 a-tag deletion fix it depends on. Supersedes #718 (CLI) and #716 (relay).CLI —
sprout notes(kind:30023)Editable team knowledge base. Write a skill once; reference the naddr from agent memory instead of re-deriving it.
set --name <slug> [--title][--summary][--tag t...][--clear-tags] --content -(kind:30023, me, d=slug). Read-before-write preservespublished_at; carries title/summary/tags when omitted,""/--clear-tagsclears.--titlerequired on first publish. Prints durable refs.get (--naddr | --name <slug> [--author <ref>]) [--content-only]#dlookup by name. >1 hit → candidates + non-zero exit.ls [--author <ref>] [--tag t] [--limit N]--author all; bounded (50/200).Relay — NIP-09 a-tag deletion (#714)
handle_a_tag_deletionno-op'd for kind:30023. Addssoft_delete_by_coordinateand routes every NIP-33 kind through it, so a-tag deletion is authoritative for addressable events. Workflow branch unchanged.notes rmIntentionally not shipped in this PR. Its design (dual-tag emit) and the relay path it needs are both here, so it's a small follow-up — held for your sign-off on whether v1 wants delete.
Testing
Combined tree, full local suites:
sprout-cli98/98 ·sprout-db64/64 ·sprout-relay192/192 · clippy-D warningsclean · fmt clean. e2e (#[ignore], relay-gated): set-twice-preserves-published_at + a-tag-deletion round-trips. Live e2e + ACP-harness exercise in progress on a local relay — results to follow.One DCO-signed commit (Tyler), co-authored Dawn / Max / Quinn.