fix(explore): discovery is opt-in — stop advertising every public repo #5607
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.
Cross-repo impact
See what breaks downstream if this PR merges.
Risk score: calculating…
Refresh in a moment to see the pre-merge risk score for this PR.
Gate checks
All 6 checks passedGateTestDisabled 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
Why
/exploreselected onis_private = falsealone, 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, defaultFALSE(migration0131). The default is the substance of the fix:TRUEwould 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.?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.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 fromc.req.urland therefore emittedhttp://for every entry (TLS terminates at the proxy), and the sitemap advertised/api/graphqlwhile 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
/explorewill be empty, which is correct but is a publishing decision I did not make on your behalf. Pick which repos should be showcased (Gluecron.comitself and thedemo/*repos are the obvious candidates) and flip them on in Settings → Discovery.🤖 Generated with Claude Code
https://claude.ai/code/session_01TsbafFcgppHoe7tm56vnm3