feat: add vouch and report API endpoints with NIP-98 auth#7
Open
CodyTseng wants to merge 4 commits into
Open
Conversation
Two new POST endpoints (gated by vouch.enabled config) let users submit signed claims directly instead of through a Nostr event. Vouches act as equal-weight follow edges in the ranking graph, deduped against any existing follow from the same source. Reports apply a trust-weighted penalty to the target's final score: final = raw * (1 - R/(R+F)). POST /vouch and POST /report are mutually exclusive per (source, target): posting one atomically removes the opposite side, so there is no DELETE endpoint — toggling sides is the only way to retract. Submissions from pubkeys with no TrustRank (and not in seed_pubkeys) return 200 but are silently dropped to prevent spam-account inflation. The API now opens the DB in read-write mode; WAL + writeMu already coordinate it with the crawler. Migration v4 adds vouches and reports tables. 26 new tests cover NIP-98 middleware, repository mutex/toggle behaviour, and ranking integration (vouch promotes unfollowed users, reports decay scores, untrusted reporters are ignored, follow+vouch edges dedupe). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Both API and crawler now open the database read-write, so the ModeReadOnly branch was dead code. Collapse to a single New(path) entry point. The API previously inherited the write-mode pool size of 1, which would have serialized its reads; restore a 10-connection pool for all callers. Writes are still serialized by writeMu and SQLite's own locks, so extra connections do not cause contention. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
A vouch is a weaker signal than an actual follow: the user is asserting non-spam without committing to see the target's posts. Carry a per-edge weight through the graph so vouch-only edges contribute proportionally less flow than a full follow. Config: vouch.weight (default 0.5, range (0, 1]). PageRank and TrustRank inner loops now divide by outWeight (sum of outgoing edge weights) instead of outDegree (count). Each in-edge carries its own weight; a source's score flows to each target in proportion to weight / outWeight. Follow and vouch edges share the same adjacency list — only their weights differ. outDegree is still tracked as an int so the pubkeys table's Following column remains a count. New test verifies that lowering the weight produces a lower score for a vouch-only recipient. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Having both fields required the user to keep them consistent: enabling with weight=0 (or disabling with weight=0.5) both produced inconsistent states. Use weight alone — 0 means off (endpoints return 404 and the ranking calculator skips streaming vouches entirely), > 0 means on and is the edge weight. Default 0 preserves prior off-by-default behaviour. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
Summary
POST /vouchandPOST /reportendpoints (NIP-98 authenticated, gated byvouch.enabled) let users contribute to the reputation graph without actually following each other — solving the "I know this new account isn't spam but I don't want to follow them" cold-start problem.(source, target)pair. There are no DELETE endpoints — reversing a stance requires posting the opposite stance.final = raw * (1 - R / (R + F))where R is the summed trust of trusted reporters and F is the summed trust of the target's incoming edges.seed_pubkeysreturn 200 but are not persisted (prevents Sybil inflation while keeping the client unable to probe the admission oracle).ModeReadWrite; WAL mode + the existingwriteMualready serialise writes safely across the crawler and API processes. Migration v4 adds thevouchesandreportstables.Test plan
go test ./...— 26 new tests pass (11 repository, 11 NIP-98 middleware, 4 ranking)go vet ./...cleango build ./cmd/apiandgo build ./cmd/crawlerproduce binariesvouch.enabled: true🤖 Generated with Claude Code