CodeIssuesPull RequestsActionsSecurityInsights
✨ AI
More
Settings

fix(explore): discovery is opt-in — stop advertising every public repo #5607

Open⚡ AI-generatedXLccantynz wants to mergefix/explore-discovery-opt-inmain↑9opened 22h agoLive: 0 editing
ccantynzcommented 22h ago

Why

/explore selected on is_private = false alone, which made the discovery feed a directory of the whole instance rather than a shop window.

In production that rendered 36 cards, 33 of them one account's client work — an agency site, a named client's real-estate site, a dictation product, a trades business OS. Any anonymous visitor could read the owner's client roster off the front page. Thirty of those cards also read "No description yet" with 0 stars, so the same page managed to leak commercially sensitive names and make the platform look abandoned.

Repo visibility answers "may this be fetched". That is the wrong question for "should this be advertised". They are separate consents.

What changed

  • repositories.listed_in_explore, default FALSE (migration 0131). The default is the substance of the fix: TRUE would re-list all 36 on the next deploy and reintroduce the leak for every future repo — precisely the GitHub behavior being declined. Existing rows take the default, so the migration is also the remediation — no backfill, no window where the leak persists.
  • All three query branches filtered — default, ?q=, ?topic=. Search is covered deliberately: filtering only the default branch would leave ?q= as an enumeration back door into the unlisted set, i.e. the same leak with one extra query parameter.
  • Going private clears the flag, so a repo made public again does not silently re-list.
  • Settings → Discovery toggle, disabled with an explanatory hint while the repo is private.
  • Empty-state copy now states the opt-in rule instead of promising public repos "show up here", which after this change would be untrue.

Also bundled: three silent crawler-facing defects — robots.txt used a relative Sitemap: path (the spec gives it no base, so crawlers dropped it), sitemap.xml built its origin from c.req.url and therefore emitted http:// for every entry (TLS terminates at the proxy), and the sitemap advertised /api/graphql while robots.txt disallows /api/.

Blast radius

Public repos remain reachable by URL, cloneable and forkable exactly as before. Only the advertising changes.

Tests

src/__tests__/explore-listing-opt-in.test.ts — unlisted public repo hidden; listed repo shown; ?q= back door closed; private-but-flagged never listed; column defaults to false on insert.

Note for the owner

After deploy /explore will be empty, which is correct but is a publishing decision I did not make on your behalf. Pick which repos should be showcased (Gluecron.com itself and the demo/* repos are the obvious candidates) and flip them on in Settings → Discovery.

🤖 Generated with Claude Code

https://claude.ai/code/session_01TsbafFcgppHoe7tm56vnm3

ccantynzAI Reviewcommented 22h ago

AI Triage

(no summary)

Priority: medium Risk area: mixed

Suggested labels: (no label suggestions) Suggested reviewers: (no reviewer suggestions)

Suggestions only — nothing has been applied. The PR author stays in control.

gluecron[bot]🤖 botAI Reviewcommented 22h ago

AI review unavailable

The platform's AI balance is exhausted, so AI generation is temporarily unavailable. Nothing was lost. You can queue this as a repair for the internal agent from the repository's Health page, or try again once the balance is restored. The PR is otherwise unchanged.

Files changed

Side-by-side diff for fix/explore-discovery-opt-in → main.

View diff →

Cross-repo impact

See what breaks downstream if this PR merges.

Analyze →
Risk score: calculating…
Refresh in a moment to see the pre-merge risk score for this PR.

Gate checks

All 6 checks passed
GateTestDisabled in settingsSkipped
Secret scanFound 11 secrets (0 critical)Passed
Security scanStatic rules ran (8 checks, no AI required) — no static findings. AI review unavailable: The platform's AI balance is exhausted, so AI generation is temporarily unavailable. Nothing was lost. You can queue this as a repair for the internal agent from the repository's Health page, or try again once the balance is restored.Skipped
Merge checkFast-forward merge possiblePassed
CICI green: 1 workflowPassed
AI ReviewAIAI review could not run (AI service unavailable) — not blocking the mergeSkipped
c comment · e edit title · m merge · a approve · r request changes · ? shortcuts