GuruGuard
Engineering Teardown
Chrome Manifest V3 extension and Cloudflare Pages + D1 platform for checking Instagram marketing claims, browsing source-linked community reports, and hiding or blocking accounts.
Built around three rules: community criticism never fabricates an automated score, browser code is MIT-licensed in a separate repo, and blocking always hands final confirmation to Instagram.
inert) & native Block01 / v8 deterministic rules & Version-2 contract
Automated scoring and community links are separated. The Version-2 contract returns reviewPriority: number | null (0–14 low, 15–34 medium, 35–100 high) and status (completed, needs_review, insufficient_data, failed). Missing text returns null instead of a false 0 score.
src/lib/marketing-policy.json shares rules across TypeScript and Android. HTTPS URL parsing rejects lookalike domains; negation and warning contexts suppress false positives. Every match requires a verbatim quote.
Code: src/lib/marketing-policy.json · src/lib/review-contract.ts
02 / Private core vs. MIT extension repo
Moderation, discovery, and billing live in the private core (cobanfurkanx/guruguard), while the browser extension is published separately under MIT (cobanfurkanx/guruguard-extension).
In-page UI renders in a Shadow DOM. Local Hide/Unhide stores up to 500 handles with serialized writes and sets reversible inert / aria-hidden attributes on matching posts. Block opens Instagram's native dialog without auto-clicking confirmation.
Code: apps/extension/ · scripts/prepare-extension-repo.py
03 / Atomic D1 trial quotas & keyset pagination
Migration 0010_free_ai_trial.sql anchors the 30-day AI trial to created_at so re-login cannot reset expiry. Trial checks and paid credit refunds execute atomically in Cloudflare D1 (SQLite):
-- Max 5 pending/completed trial checks per UTC day
-- Paid ledger untouched during trial; failed paid checks refund once
Migration 0011_directory_pagination.sql and /api/community-list?limit=50&cursor=... provide keyset pagination with region/category filters and O(1) handle lookups.
Code: apps/pages/ · migrations/0010_free_ai_trial.sql · 0011_directory_pagination.sql
04 / Moderation & feed discovery bounds
Anonymous suggestions enter a pending queue reviewed via /moderation.html. The admin bearer key stays in volatile page memory (never written to localStorage), and approval prevents duplicate active handles.
/api/maintenance/discover polls 3 Reddit Atom feeds under a 10s timeout and 1-run/UTC-day lock, queueing up to 10 sourced drafts for human review with zero paid scraping.
Code: apps/pages/src/community-expansion.ts · docs/feed-protection.md
Payment webhooks
Creem can send the same payment event more than once. I added a D1 inbox so repeated deliveries cannot grant credits twice. Temporary failures are saved and retried, up to five attempts.
Signed event → D1 inbox → Credit ledger
↑ |
└── Retry on temporary failure
12 SQLite integration tests cover concurrent deliveries, failed writes, out-of-order refunds and recovery after a crash. Tests use synthetic payments; production rollout is pending.