Skip to content

feat(seo): AI summary enrichment backfill (slice 3) - #113

Merged
gusmar2017 merged 5 commits into
mainfrom
mcpfind-ai-summary
Jul 27, 2026
Merged

feat(seo): AI summary enrichment backfill (slice 3)#113
gusmar2017 merged 5 commits into
mainfrom
mcpfind-ai-summary

Conversation

@gusmar2017

Copy link
Copy Markdown
Contributor

Summary

Slice 3 (Enrichment backfill) of the indexing-recovery plan — specs/stage-6-slices/00-recovery-plan.md. Merges the previously-orphaned mcpfind-ai-summary branch (migration 006) forward onto current main, fixes a guardrail bug in that migration's column comment, and adds the nightly backfill script + labeled UI rendering.

  • Migration 006 comment fix: the ai_summary column comment said to "prefer over description for structured-data SoftwareApplication.description" — this directly contradicted the accepted recovery plan's guardrail ("AI summary is a labeled supplement, never the page body"). Corrected to say the opposite: never substitute into JSON-LD description or page body copy.
  • scripts/mcpfind/ai_summary_generate.py (new): nightly orchestrator that ports apps/web/lib/indexable.ts#isIndexable 1:1 to Python for gating, computes a source hash matching migration 006's documented hash inputs, skips unchanged rows, and generates via the local Mac Mini Claude Code queue (127.0.0.1:7600) — never a raw Anthropic API key. No prior client for that queue existed in this repo, so the request/response contract is documented as an explicit assumption in the module docstring (only call_local_queue() needs updating if the real contract differs).
  • Server detail page: renders ai_summary as a clearly labeled "AI Summary" callout block near the top of the main content column, only when non-null. Confirmed (unchanged) that generateServerJsonLd in apps/web/lib/metadata.ts builds SoftwareApplication.description from server.description only — never ai_summary.

Files changed

  • supabase/migrations/006_ai_summary.sql — column comment guardrail fix
  • scripts/mcpfind/ai_summary_generate.py — new nightly backfill script
  • scripts/mcpfind/requirements.txt — new, requests dependency
  • packages/shared/src/types.tsServer.ai_summary / ai_summary_generated_at, excluded from ServerListItem
  • apps/web/lib/queries.tsSERVER_DETAIL_COLUMNS now selects the new columns
  • apps/web/app/servers/[slug]/page.tsx — new "AI Summary" supplement block
  • .gitignore__pycache__/, *.pyc (new, this repo had no prior Python tooling)

Test plan

  • pnpm --filter @mcpfind/shared build — clean
  • pnpm --filter @mcpfind/web type-check — clean
  • pnpm --filter @mcpfind/web test — 206/206 passing
  • python3 -m py_compile scripts/mcpfind/ai_summary_generate.py — clean
  • Manual assertions against is_indexable()/compute_source_hash() (3-signal pass/fail boundary, deprecated hard-exclude, hash determinism/change-detection) — all pass
  • Run ai_summary_generate.py --dry-run against real Supabase data once SUPABASE_URL/SUPABASE_SERVICE_ROLE_KEY are available in the target environment
  • Confirm local Claude Code queue contract at 127.0.0.1:7600 matches call_local_queue()'s assumed {"prompt": ...}{"completion"|"text"|"response"|"result"|"output": ...} contract, or update it
  • Visual QA of the new "AI Summary" block on a server detail page after the first real backfill run

🤖 Generated with Claude Code

gusmar2017 and others added 5 commits July 27, 2026 18:04
Adds 5 provenance columns to the servers table (ai_summary, generated_at,
model, prompt_version, source_hash) plus a sparse index for the nightly
orchestrator's incremental selection query. No search_vector changes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The ai_summary column comment said to "prefer over description for
structured-data SoftwareApplication.description" — this contradicts the
accepted recovery plan's anti scaled-content-abuse guardrail
(specs/stage-6-slices/00-recovery-plan.md, "AI summary is a labeled
supplement, never the page body"). Corrected the comment to state the
opposite: labeled supplement only, never substituted into JSON-LD
description or used as page body copy.

Slice 3 of the indexing-recovery plan.
Adds scripts/mcpfind/ai_summary_generate.py — the nightly orchestrator that
backfills ai_summary for gated (isIndexable) servers, per
specs/stage-6-slices/00-recovery-plan.md Slice 3.

- Ports apps/web/lib/indexable.ts#isIndexable to Python 1:1 (same
  README_MIN_LENGTH/MIN_SIGNALS thresholds) so only servers already clearing
  the real-data quality bar get an AI summary.
- Computes a source hash matching migration 006's documented
  ai_summary_source_hash inputs (name|description|readme_content[:8000]|
  category|package_name|package_type|registry_tags) and skips rows whose
  hash is unchanged — idempotent, no wasted regeneration.
- Generates via the local Mac Mini Claude Code queue (127.0.0.1:7600), never
  a raw Anthropic API key, consistent with this org's convention. No prior
  client for that queue existed in this repo (grepped for "7600" and
  "claude-code-local-queue" — no hits outside the migration comments), so
  the request/response contract is documented as an assumption in the
  module docstring; only call_local_queue() needs updating if the real
  contract differs.
- Reads SUPABASE_URL / SUPABASE_SERVICE_ROLE_KEY, matching the existing
  convention in packages/sync/src/index.ts and recategorize-other.ts (the
  anon key is read-only under RLS and cannot write ai_summary_*).
- argparse CLI (--dry-run, --limit, --prompt-version, --page-size,
  --sleep-seconds, -v), structured logging, per-row error isolation so one
  bad row doesn't abort the whole nightly run (exit 2 signals partial
  failure, safe to re-run).
…ytecode

Running the new ai_summary_generate.py script locally generated a .pyc that
got swept into the previous commit's `git add scripts/mcpfind/`. Untrack it
and add __pycache__/ and *.pyc to .gitignore so this doesn't recur — this
repo has no prior Python tooling/gitignore entries to reuse.
… pages

Slice 3 of the indexing-recovery plan
(specs/stage-6-slices/00-recovery-plan.md) — renders ai_summary (migration
006) as a clearly labeled "AI Summary" callout block, positioned near the
top of the main content column, right before the README section.

- packages/shared/src/types.ts: add ai_summary / ai_summary_generated_at to
  Server. Excluded from ServerListItem (same rationale as readme_content —
  detail-page only, not selected by SERVER_LIST_COLUMNS).
- apps/web/lib/queries.ts: SERVER_DETAIL_COLUMNS now selects ai_summary and
  ai_summary_generated_at alongside readme_content.
- apps/web/app/servers/[slug]/page.tsx: new section, rendered only when
  server.ai_summary is non-null, visually distinct (bordered callout,
  IconRobot, "AI Summary" heading) and explicitly labeled as a supplement
  ("supplements, not a substitute for the README below").

Guardrail verified, not changed: apps/web/lib/metadata.ts's
generateServerJsonLd already builds SoftwareApplication.description from
server.description (never ai_summary) — confirmed by reading the function
and grepping the whole apps/+packages/ tree for "ai_summary"; no other
consumer exists. This is the hard guardrail from the recovery plan's
"AI summary is a labeled supplement, never the page body" section.

Verified: pnpm --filter @mcpfind/shared build, pnpm --filter @mcpfind/web
type-check, and pnpm --filter @mcpfind/web test (206/206 passing) all clean
after this change.
@vercel

vercel Bot commented Jul 27, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
mcp-find-web Ready Ready Preview, Comment Jul 27, 2026 11:13pm

Request Review

@gusmar2017
gusmar2017 merged commit 8fadf84 into main Jul 27, 2026
4 checks passed
@gusmar2017
gusmar2017 deleted the mcpfind-ai-summary branch July 27, 2026 23:14
gusmar2017 added a commit that referenced this pull request Jul 27, 2026
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.

1 participant