Skip to content

Add competitive directory routes with exact subscriptions - #827

Merged
tomcasaburi merged 6 commits into
masterfrom
codex/feature/seedit-directory-routes
Jul 20, 2026
Merged

Add competitive directory routes with exact subscriptions#827
tomcasaburi merged 6 commits into
masterfrom
codex/feature/seedit-directory-routes

Conversation

@tomcasaburi

@tomcasaburi tomcasaburi commented Jul 20, 2026

Copy link
Copy Markdown
Member

Summary

  • make reserved /s/<code> routes resolve deterministic versioned directory winners
  • keep account subscriptions, the home feed, Join actions, and /comments/<cid> permalinks pinned to exact community addresses
  • offer consented switch, keep-both, or keep-current actions when a winner changes, with opt-in per-directory automatic switching and safe undo
  • canonicalize submit, settings, post, and about actions to exact community routes
  • add compact desktop/mobile winner disclosure, translations, synchronization tooling, tests, and an architecture decision record

Lists dependency

Validation

  • 25 test files / 168 tests
  • production build, lint, type-check, Knip, and AI workflow parity
  • corepack yarn install --immutable, yarn llms:generate, and git diff --check
  • changed-scope React Doctor completed; its older default-branch version reports nine pre-existing barrel-import warnings in touched files
  • Chrome, Firefox, and WebKit at desktop and mobile viewports, including light/dark themes and no overflow
  • Chromium mid-throttle warm navigation

Closes #826


Note

Cursor Bugbot is generating a summary for commit d0d4a9d. Configure here.

@vercel

vercel Bot commented Jul 20, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
seedit Ready Ready Preview, Comment Jul 20, 2026 9:41am

Request Review

@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 104 files, which is 4 over the limit of 100.

To get a review, narrow the scope:
• coderabbit review --type committed # exclude uncommitted changes
• coderabbit review --dir # limit to a subdirectory
• coderabbit review --base # compare against a closer base

Upgrade to a paid plan to raise the limit.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 735f3f66-211b-4017-bb8d-b7f234eb5512

📥 Commits

Reviewing files that changed from the base of the PR and between a0b8d85 and 92bb184.

📒 Files selected for processing (104)
  • docs/agent-runs/directory-routes/feature-list.json
  • docs/agent-runs/directory-routes/progress.md
  • docs/architecture/directory-routes.md
  • package.json
  • public/translations/ar/default.json
  • public/translations/bn/default.json
  • public/translations/cs/default.json
  • public/translations/da/default.json
  • public/translations/de/default.json
  • public/translations/el/default.json
  • public/translations/en/default.json
  • public/translations/es/default.json
  • public/translations/fa/default.json
  • public/translations/fi/default.json
  • public/translations/fil/default.json
  • public/translations/fr/default.json
  • public/translations/he/default.json
  • public/translations/hi/default.json
  • public/translations/hu/default.json
  • public/translations/id/default.json
  • public/translations/it/default.json
  • public/translations/ja/default.json
  • public/translations/ko/default.json
  • public/translations/mr/default.json
  • public/translations/nl/default.json
  • public/translations/no/default.json
  • public/translations/pl/default.json
  • public/translations/pt/default.json
  • public/translations/ro/default.json
  • public/translations/ru/default.json
  • public/translations/sq/default.json
  • public/translations/sv/default.json
  • public/translations/te/default.json
  • public/translations/th/default.json
  • public/translations/tr/default.json
  • public/translations/uk/default.json
  • public/translations/ur/default.json
  • public/translations/vi/default.json
  • public/translations/zh/default.json
  • scripts/sync-directories.js
  • src/app.tsx
  • src/components/directory-auto-switch-control/directory-auto-switch-control.module.css
  • src/components/directory-auto-switch-control/directory-auto-switch-control.tsx
  • src/components/directory-auto-switch-control/index.ts
  • src/components/directory-subscription-reconciler/directory-subscription-reconciler.tsx
  • src/components/directory-subscription-reconciler/index.ts
  • src/components/directory-subscription-updates-notice/directory-subscription-updates-notice.module.css
  • src/components/directory-subscription-updates-notice/directory-subscription-updates-notice.tsx
  • src/components/directory-subscription-updates-notice/index.ts
  • src/components/exact-community-action-route/exact-community-action-route.tsx
  • src/components/exact-community-action-route/index.ts
  • src/components/header/header.module.css
  • src/components/header/header.tsx
  • src/components/search-bar/search-bar.tsx
  • src/components/sidebar/sidebar.module.css
  • src/components/sidebar/sidebar.tsx
  • src/components/starter-subscriptions-notice/starter-subscriptions-notice.tsx
  • src/components/subscribe-button/subscribe-button.tsx
  • src/components/topbar/topbar.tsx
  • src/data/seedit-directories/seedit-askseedit-directory.json
  • src/data/seedit-directories/seedit-aww-directory.json
  • src/data/seedit-directories/seedit-directories-defaults.json
  • src/data/seedit-directories/seedit-funny-directory.json
  • src/data/seedit-directories/seedit-gaming-directory.json
  • src/data/seedit-directories/seedit-interestingasfuck-directory.json
  • src/data/seedit-directories/seedit-memes-directory.json
  • src/data/seedit-directories/seedit-news-directory.json
  • src/data/seedit-directories/seedit-pics-directory.json
  • src/data/seedit-directories/seedit-todayilearned-directory.json
  • src/data/seedit-directories/seedit-videos-directory.json
  • src/data/seedit-starter-communities.json
  • src/data/vendored-directory-lists.ts
  • src/hooks/use-auto-subscribe.test.ts
  • src/hooks/use-default-subscriptions.test.ts
  • src/hooks/use-default-subscriptions.ts
  • src/hooks/use-directory-list.test.ts
  • src/hooks/use-directory-list.ts
  • src/hooks/use-resolved-community-route.test.ts
  • src/hooks/use-resolved-community-route.ts
  • src/hooks/use-time-filter.ts
  • src/lib/utils/community-route-utils.test.ts
  • src/lib/utils/community-route-utils.ts
  • src/lib/utils/directory-account-transforms.test.ts
  • src/lib/utils/directory-account-transforms.ts
  • src/lib/utils/directory-codes.test.ts
  • src/lib/utils/directory-codes.ts
  • src/lib/utils/directory-list-utils.test.ts
  • src/lib/utils/directory-list-utils.ts
  • src/lib/utils/directory-subscriptions.test.ts
  • src/lib/utils/directory-subscriptions.ts
  • src/lib/utils/legacy-default-subscriptions.test.ts
  • src/lib/utils/legacy-default-subscriptions.ts
  • src/lib/utils/starter-account.ts
  • src/lib/utils/starter-subscriptions.test.ts
  • src/lib/utils/starter-subscriptions.ts
  • src/lib/utils/url-utils.test.ts
  • src/lib/utils/url-utils.ts
  • src/views/about/about.tsx
  • src/views/community-settings/community-data-editor/community-data-editor.tsx
  • src/views/community-settings/community-settings.tsx
  • src/views/community/community.tsx
  • src/views/home/home.tsx
  • src/views/post-page/post-page.tsx
  • src/views/submit-page/submit-page.tsx

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Review on demand using usage pricing
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/feature/seedit-directory-routes

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Comment thread src/views/post-page/post-page.tsx Outdated

const { commentCid } = params;
const routeCommunityAddress = resolveCommunityRouteAddress(params.communityAddress);
const { communityAddress: routeCommunityAddress } = useResolvedCommunityRoute();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Directory permalink join skips provenance

Medium Severity

On a directory-coded post URL such as /s/funny/comments/…, the sidebar SubscribeButton is rendered without directoryCode or directoryRevision. While the post is still loading and the canonical redirect to the owner’s exact address has not run, Join uses the generic subscribe() path instead of joinDirectoryWinnerAccount, so the account can gain the community without the matching directory slot metadata.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit d0d4a9d. Configure here.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed in 92bb184. Directory-coded post aliases now suppress the sidebar subscription action until the post owner is known and the route has canonicalized to the exact community address, so Join cannot create ambiguous or incorrect provenance.

const winnerIsHidden = Boolean(hideNsfwCommunities && winner?.nsfw);

useEffect(() => {
if (!account || !list || !winner || winnerIsHidden) return;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hidden NSFW skips directory reconciliation

Medium Severity

When hideNsfwCommunities is on and the directory winner is marked NSFW, DirectorySlotReconciler returns early and ManualDirectoryChangeNotice renders nothing. Users with auto-switch enabled therefore never get an automatic subscription update or a manual winner-change prompt for that slot while the filter stays enabled.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit d0d4a9d. Configure here.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Declined intentionally. When hideNsfwCommunities is enabled, a hidden NSFW winner must not prompt the user or silently auto-subscribe them to content they chose to hide. Reconciliation resumes if a later winner is visible or the user disables the filter.

@tomcasaburi

Copy link
Copy Markdown
Member Author

Review follow-up: the live post-merge sync check exposed a stale-cache race between GitHub's master contents listing and raw.githubusercontent.com/master. The latest commit pins both listing and raw downloads to one resolved immutable commit SHA, preventing yarn sync:directories from downgrading vendored snapshots immediately after a Lists merge.

Verified the fix against Lists merge a8902a5: two consecutive remote syncs and one local-source sync are idempotent, and the vendored snapshots/default subscriptions match Lists byte-for-byte. The full 168-test, build, lint, type-check, Knip, AI-workflow, generated-context, and diff-check gate passes. The remaining React Doctor output is the default branch's known baseline plus nine pre-existing barrel-import warnings in touched files.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

There are 3 total unresolved issues (including 2 from previous reviews).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 0a00264. Configure here.

? advanceStarterProvenance(account, previousAddress, winner, result, 'trackWinner')
: account.seeditStarterSubscriptions;
return applyDirectoryState(account, result, provenance);
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Auto-switch enable leaves old subscription

Medium Severity

Turning on per-directory automatic switching after the directory winner already changed uses joinDirectorySubscription, which adds the new winner and retargets the slot but leaves the prior slot address in account.subscriptions. Later automatic reconciliation sees the slot already on the winner and does not remove the old follow, so the home feed can keep both communities.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 0a00264. Configure here.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed in 92bb184. Enabling auto-switch now atomically adopts the current acknowledged winner: it removes the previous slot-attributable subscription unless another slot still tracks it, keeps the current winner, and updates provenance. Added a regression test.

@tomcasaburi

Copy link
Copy Markdown
Member Author

Review follow-up (92bb1840):

  • Fixed directory-coded post aliases so Join/Leave stays unavailable until the route canonicalizes to the post owner's exact community address.
  • Fixed enabling auto-switch after a previously acknowledged winner change so the current winner is adopted atomically and the prior slot-owned subscription is removed when safe.
  • Kept hidden-NSFW reconciliation suppressed intentionally: a content filter must not prompt or auto-subscribe users to hidden NSFW winners.

Verification: 169 Vitest tests, production build, lint, TypeScript, Knip, AI workflow parity, llms generation, immutable directory sync, and Chrome/Firefox/WebKit desktop+mobile route regression checks all pass. React Doctor reports only the nine existing barrel-import advisories already present in touched files.

@tomcasaburi
tomcasaburi merged commit 7a01633 into master Jul 20, 2026
8 checks passed
@tomcasaburi
tomcasaburi deleted the codex/feature/seedit-directory-routes branch July 20, 2026 09:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Short community routes conflict with durable subscriptions and permalinks

1 participant