Skip to content

feat: add private publisher follow graph - #2950

Closed
giodl73-repo wants to merge 22 commits into
openclaw:mainfrom
giodl73-repo:follow-graph-notifications
Closed

feat: add private publisher follow graph#2950
giodl73-repo wants to merge 22 commits into
openclaw:mainfrom
giodl73-repo:follow-graph-notifications

Conversation

@giodl73-repo

@giodl73-repo giodl73-repo commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Summary

  • adds private, idempotent publisher follow/unfollow storage for the authenticated user
  • lists the current user's followed publishers with opaque cursor pagination
  • stores a reversible all / none delivery preference for Inbox projections
  • uses canonical publisher visibility rules and removes follow edges during account or publisher deletion in bounded, resumable batches
  • deliberately exposes no public followers/following graph

API

  • GET|POST|DELETE /api/v1/publisher-follows
  • authenticated and account-scoped; no public social-graph endpoints

Product boundary

Following is discovery state only. It does not grant official status, registry review, source trust, scan success, local approval, or install authority. The preference controls delivery projections; the follow remains available to a future chronological Following feed.

Stack

Depends on #2948. Followed publisher activity is added by #2958. The branch is commit-stacked because cross-fork PRs cannot select another fork branch as their base.

Validation

  • focused follow, HTTP, publisher deletion, and account deletion suites
  • bounded cleanup coverage for both follower and publisher edges
  • schema package build and generated route contract
  • git diff --check

@vercel

vercel Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

@giodl73-repo is attempting to deploy a commit to the OpenClaw Foundation Team on Vercel.

A member of the Team first needs to authorize it.

@giodl73-repo
giodl73-repo force-pushed the follow-graph-notifications branch from 26ccc1b to bbf3254 Compare July 3, 2026 03:37
@giodl73-repo giodl73-repo changed the title docs: add follow graph notifications spec feat: add publisher follow graph API Jul 3, 2026
@giodl73-repo

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@giodl73-repo

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@giodl73-repo
giodl73-repo force-pushed the follow-graph-notifications branch from bbf3254 to 9b8f03d Compare July 3, 2026 04:05
@clawsweeper

clawsweeper Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P3 Low-priority cleanup, docs, polish, ergonomics, or speculative work. merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. labels Jul 4, 2026
@clawsweeper

clawsweeper Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed July 22, 2026, 1:33 AM ET / 05:33 UTC.

Summary
The PR adds publisher-owned follow/unfollow persistence, authenticated and public follow-list HTTP endpoints, related publisher-feed APIs, cleanup paths, OpenAPI/docs/spec coverage, and generated schema artifacts.

Reproducibility: not applicable. This PR proposes a new publisher-follow capability rather than reporting broken existing behavior. The relevant validation is a real after-fix runtime exercise of the proposed API.

Review metrics: 2 noteworthy metrics.

  • Changed surface: 37 files, 3,777 additions, 114 deletions. The branch spans Convex schema, persistence, HTTP APIs, cleanup, generated artifacts, OpenAPI, docs, and specs, so conflict resolution and integration review are material.
  • New durable tables: 2 tables added. publisherFollows and publisherFeedPublications create persistent contracts that need upgrade and deletion-path validation.

Merge readiness
Overall: 🦪 silver shellfish
Proof: 🧂 unranked krab
Patch quality: 🦐 gold shrimp
Result: blocked until real behavior proof from a real setup is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Rebase the selected implementation onto current main and resolve the publisher-feed overlap before requesting another exact-head review.
  • Attach redacted live HTTP or Convex output for follow, repeat follow, current-user list, public list, unfollow, and a deletion-cleanup path; redact tokens, endpoints, and private identifiers.
  • Obtain explicit maintainer sponsorship for the public follow-graph API boundary.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The PR reports focused Vitest and static/type checks, but no redacted live Convex run, HTTP transcript, runtime log, or linked artifact demonstrates API-token follow, list, and unfollow behavior after the change; add that proof and update the PR body for re-review.

Risk before merge

  • [P1] Merging would establish a public, durable social-graph API and private follow-preference data model without maintainer confirmation of the long-term contract, privacy expectations, and ownership boundary.
  • [P1] The current head is dirty against main, so conflict resolution can materially change the 37-file implementation and requires a fresh exact-head review.
  • [P1] The branch overlaps the still-open publisher-feed implementation at feat: add publisher feed model API #2948, creating a risk of duplicate or conflicting feed/visibility contracts if both are advanced independently.
  • [P1] The supplied validation is mock/test-oriented; it does not prove real Convex index, pagination, API-token authentication, or cleanup behavior.

Maintainer options:

  1. Rebase and prove the selected contract (recommended)
    Resolve the current merge conflicts, coordinate the overlap with feat: add publisher feed model API #2948, and attach redacted live Convex or HTTP proof before a fresh review.
  2. Accept the new public graph as a product commitment
    A maintainer may explicitly accept the durable public follower/following and API-token contract, including its privacy and upgrade obligations, after reviewing the rebased head.
  3. Pause pending product direction
    Pause this broad branch if maintainers do not want to establish a supported social-graph API or cannot select a canonical implementation path.

Next step before merge

  • [P1] A maintainer must choose the public social-graph contract and reconcile the overlapping publisher-feed branch; contributor runtime proof and a conflict-free rebase are also required before merge.

Maintainer decision needed

  • Question: Should ClawHub adopt a durable public publisher-follow graph and its public follower/following API as a supported product contract, and if so should this branch or the overlapping publisher-feed proposal be the integration vehicle?
  • Rationale: This is new durable discovery and identity surface, not a repair to an established contract; code review alone cannot choose its privacy, ownership, and long-term API direction.
  • Likely owner: Patrick-Erichsen — The related publisher-feed work identifies Patrick as the reviewer whose feedback shaped the overlapping publisher visibility and feed contract.
  • Options:
    • Sponsor one unified contract (recommended): Approve the public follow-graph direction, designate a single branch as canonical, and require a rebase plus real runtime proof before merge.
    • Keep following internal for now: Defer public follower/following endpoints until product ownership, privacy expectations, and client use cases are explicitly defined.
    • Split the feed and graph work: Land or review the publisher-feed contract independently, then propose a smaller follow-graph PR against that settled API surface.

Security
Cleared: No concrete code-level security or supply-chain defect is established from the proposed diff, but the new authenticated and public graph boundary remains a merge-risk requiring maintainer approval and runtime proof.

Review details

Best possible solution:

Choose and document one maintainer-owned public publisher-feed/follow-graph contract, rebase the selected implementation onto current main, then provide redacted live Convex or HTTP proof covering follow, idempotent repeat follow, authenticated listing, public list visibility, unfollow, and deletion cleanup.

Do we have a high-confidence way to reproduce the issue?

Not applicable: this PR proposes a new publisher-follow capability rather than reporting broken existing behavior. The relevant validation is a real after-fix runtime exercise of the proposed API.

Is this the best way to solve the issue?

Unclear: the implementation is thoughtful and documented, but a public durable social graph is a product and privacy decision, and the branch overlaps an open publisher-feed implementation that must be reconciled first.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against a9775fc39b10.

Label changes

Label changes:

  • add merge-risk: 🚨 compatibility: The PR adds persistent schema and externally documented API routes whose contract and overlap with another open implementation must be settled before merge.
  • add rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🧂 unranked krab and patch quality is 🦐 gold shrimp.
  • remove rating: 🧂 unranked krab: Current PR rating is rating: 🦪 silver shellfish, so this older rating label is no longer current.

Label justifications:

  • P3: This is an optional discovery/social feature proposal rather than an urgent regression or broken core workflow.
  • merge-risk: 🚨 compatibility: The PR adds persistent schema and externally documented API routes whose contract and overlap with another open implementation must be settled before merge.
  • merge-risk: 🚨 security-boundary: API-token follow mutations and public social-graph visibility introduce privacy and authorization boundaries that require live proof and maintainer approval.
  • rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🧂 unranked krab and patch quality is 🦐 gold shrimp.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR reports focused Vitest and static/type checks, but no redacted live Convex run, HTTP transcript, runtime log, or linked artifact demonstrates API-token follow, list, and unfollow behavior after the change; add that proof and update the PR body for re-review.
Evidence reviewed

What I checked:

  • Current-main capability gap: The supplied PR diff adds new publisherFollows storage, follow HTTP handlers, and route constants; the reviewed current-main schema and HTTP route surfaces do not show this feature, so the central requested capability is not already implemented on main. (convex/schema.ts:1, a9775fc39b10)
  • Runtime-proof policy: Repository guidance requires real Convex validation for changes whose behavior depends on runtime semantics such as indexes, pagination, auth identity, internal/public function boundaries, actions, and HTTP actions; the PR body reports focused Vitest, lint, and type checks but no live Convex/HTTP result. (AGENTS.md:9, a9775fc39b10)
  • Public API and durable-state scope: The branch adds publisherFollows and publisherFeedPublications schema tables, API-token mutations, public follower/following lists, and bounded deletion cleanup; this is a durable product contract rather than a narrow internal refactor. (convex/schema.ts:2643, 40345239f950)
  • Overlap and merge state: The PR is currently marked dirty/non-mergeable, and the open publisher-feed PR at feat: add publisher feed model API #2948 overlaps the account-feed, visibility, and publisher-feed portions of this branch; the two landing paths need coordination before either public contract is merged. (convex/accountFeeds.ts:1, 40345239f950)
  • Validation scope reported by contributor: The PR reports 28 focused Vitest tests and static/type-oriented checks. Those are useful supplemental checks, but they do not establish the after-fix behavior of API-token follow/list/unfollow operations against a running Convex deployment. (convex/httpApiV1/publisherFollowsV1.ts:1, 40345239f950)

Likely related people:

  • Patrick-Erichsen: The related publisher-feed proposal records exact-head review fixes attributed to Patrick, connecting him to the shared publisher visibility/feed contract that this branch also changes. (role: prior reviewer on overlapping publisher-feed work; confidence: low; files: convex/lib/publishers.ts, convex/accountFeeds.ts, specs/account-feeds.md)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.
Review history (7 earlier review cycles)
  • reviewed 2026-07-04T06:01:19.325Z sha 9b8f03d538af7414889d0c820f2d15f1a17d1135 :: needs real behavior proof before merge. :: [P3] Regenerate the route sourcemap | [P3] Add the public API contract docs
  • reviewed 2026-07-04T08:18:58.858Z sha 9b8f03d538af7414889d0c820f2d15f1a17d1135 :: needs real behavior proof before merge. :: [P3] Regenerate the route sourcemap | [P3] Add the public API contract docs
  • reviewed 2026-07-06T23:29:34.557Z sha 9b8f03d538af7414889d0c820f2d15f1a17d1135 :: needs real behavior proof before merge. :: [P3] Regenerate the route sourcemap | [P3] Add the public API contract docs
  • reviewed 2026-07-06T23:59:37.987Z sha 9b8f03d538af7414889d0c820f2d15f1a17d1135 :: needs real behavior proof before merge. :: [P3] Regenerate the route sourcemap | [P3] Add the public API contract docs
  • reviewed 2026-07-07T01:14:49.972Z sha 9b8f03d538af7414889d0c820f2d15f1a17d1135 :: needs real behavior proof before merge. :: [P3] Regenerate the route sourcemap | [P3] Add the public API contract docs
  • reviewed 2026-07-08T01:54:15.330Z sha 9b8f03d538af7414889d0c820f2d15f1a17d1135 :: needs real behavior proof before merge. :: [P3] Regenerate the route sourcemap | [P3] Add the public API contract docs
  • reviewed 2026-07-09T02:13:41.893Z sha 9b8f03d538af7414889d0c820f2d15f1a17d1135 :: needs real behavior proof before merge. :: [P3] Regenerate the route sourcemap | [P3] Document the public follow API

@giodl73-repo
giodl73-repo force-pushed the follow-graph-notifications branch from 9b8f03d to 185bddc Compare July 15, 2026 15:34
@giodl73-repo
giodl73-repo marked this pull request as ready for review July 15, 2026 16:11
@giodl73-repo
giodl73-repo requested review from a team and Patrick-Erichsen as code owners July 15, 2026 16:11

@Patrick-Erichsen Patrick-Erichsen left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This adds a private, authenticated publisher-follow graph with idempotent follow/unfollow, notification preferences, bounded listing, and API-token HTTP handlers. The authentication binding and separation from trust/install authority are sound, but the implementation does not yet preserve ClawHub's existing visibility and deletion invariants.

LOC: +1274/-1 (14 files)

Findings

  1. [P1] Apply linked-user visibility before accepting or returning personal publishers. requireActivePublisher, list filtering, and isFollowingPublisher only call isPublisherActive, which checks the publisher row's own deletion flags. ClawHub's canonical public publisher path also rejects a personal publisher whose linked user is deleted or deactivated, while user bans set users.deletedAt without deactivating the publisher row. As written, an authenticated caller who knows the publisher ID can follow a banned personal publisher and retrieve its handle, display name, kind, and image through the private list even though normal publisher visibility hides it. Extract/reuse the full publisher visibility check in follow, list, and isFollowingPublisher, and add linked-user ban/deactivation tests. convex/publisherFollows.ts:22 convex/publishers.ts:287 convex/users.ts:1730

  2. [P2] Purge private follow edges during account and publisher deletion. publisherFollows is classified as permanent preference data, but self-service account cleanup never removes rows owned by the deleted follower, and publisher hard deletion never removes rows targeting the deleted publisher. Those rows become permanently unreachable private social-graph data or dangling publisher references. Add bounded, resumable cleanup through the existing follower/publisher indexes, include counts in deletion audit metadata, and cover both lifecycle paths. convex/schema.ts:2693 convex/users.ts:353 convex/publishers.ts:2014

  3. [P2] Define and test the public HTTP contract, including terminal cursor shape. The three /api/v1/publisher-follows methods are absent from OpenAPI and docs/http-api.md. The HTTP handler also exposes the internal Convex { continueCursor, isDone } result verbatim, including continueCursor: "" at completion even though the request parser rejects an empty cursor; sibling HTTP APIs expose nextCursor: string | null. Add OpenAPI schemas/operations, contract tests, and docs, and normalize terminal pagination at the HTTP boundary (or explicitly specify and test a different public shape). convex/http.ts:318 convex/publisherFollows.ts:199 convex/httpApiV1/publisherFollowsV1.ts:41

  4. [P3] Regenerate the route sourcemap. The source, JS, and declarations contain publisherFollows, but the committed routes.js.map still maps the old route object. Running the schema build changes the map to include the new property. packages/schema/dist/routes.js:32

  5. [P3] Include ordering fields in the new index names. by_follower and by_publisher both include updatedAt; the checked-in Convex guidelines require index names to include every indexed field. Rename them to by_follower_and_updatedAt and by_publisher_and_updatedAt (or the repository's equivalent convention) and update callers. convex/schema.ts:2700

Best-fix verdict: too narrow. The follow module's idempotency, auth ownership, and bounded reads are reasonable, but the best implementation shares ClawHub's canonical publisher visibility/lifecycle rules with #2948 instead of creating a second publisher-active definition.

Alternatives considered: marking every personal publisher deleted when its user is banned is too broad for unban/recovery semantics; deleting follows on every reversible suspension is also too broad. Prefer a shared visibility helper for reversible states and bounded edge cleanup for permanent deletion.

Authority check: no caller or callee uses follow state to grant official status, publisher membership, publishing permission, registry review, scan success, source trust, local approval, package eligibility, or install authority.

Validation: focused exact-head tests pass (16 passed); static, unit, packages, types-build, e2e-http, and CodeQL are green. Exact-head CI is still unstable because playwright-local-auth / moderation-star failed in the unrelated malicious-skill ban flow (the same matrix failure is present on #2948), and the external Vercel authorization status is failing.

Stack/base: #2950 and dependency #2948 are sibling branches from base 35cd2e51, not a true stack. A synthetic merge conflicts in convex/http.ts, convex/httpApiV1.ts, and specs/README.md; rebase #2950 after #2948 and rerun exact-head CI.

Reviewed exact head b5519cb2e99eecc6215f4ab756d278cfcc0a9e0a; current main observed at 3134a20492f57423ad52ef8b017788a15b8aebd5.

@giodl73-repo
giodl73-repo force-pushed the follow-graph-notifications branch from b5519cb to 5557133 Compare July 16, 2026 14:58
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. labels Jul 22, 2026
@giodl73-repo
giodl73-repo force-pushed the follow-graph-notifications branch from 4034523 to fb78bce Compare July 28, 2026 20:59
@giodl73-repo giodl73-repo changed the title feat: add publisher follow graph API feat: add private publisher follow graph Jul 28, 2026
@giodl73-repo
giodl73-repo force-pushed the follow-graph-notifications branch from fb78bce to 5b36e41 Compare July 28, 2026 21:14
@giodl73-repo
giodl73-repo force-pushed the follow-graph-notifications branch from fc85d7d to 86849e9 Compare July 28, 2026 22:32
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

This pull request has been automatically marked as stale due to inactivity.
Please update it or it will be closed.

@github-actions

Copy link
Copy Markdown
Contributor

Closing due to inactivity.
If this PR should be revived, reopen it with current context and a fresh validation plan.

@github-actions github-actions Bot closed this Aug 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. P3 Low-priority cleanup, docs, polish, ergonomics, or speculative work. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. stale status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants