5 Commits
Author SHA1 Message Date
krisf 1e7e951c91 ingest: suppress Google-news shared placeholder image (googleusercontent) -> null -> category cover fallback
Root cause: Google News RSS items carry no enclosures; pipeline fell back
to og:image from the news.google.com interstitial, which serves ONE shared
Google-branded tile (lh3.googleusercontent.com/J6_coFbo...) for every
article. 601 rows shared that URL (maple 243 / finance 358). New
image-guard blocks *.googleusercontent.com images at ingest; 16/16
regression tests; prod DBs migrated tile->NULL; images rebuilt
technews:10 finance:4 maple-brief:11 and deployed.
2026-08-18 21:30:23 -04:00
krisf 86a77b4907 Serve article images locally: /images proxy route with SSRF-guarded
upstream fetch, magic-byte validation, persistent /data/media cache,
immutable cache headers, CoverImage fallback component, og:image to
absolute proxy URL. Ported from technews 6f08da3.
2026-08-18 18:11:44 -04:00
krisf b79c439c7f chore(gate): commit pre-push gate (secret -> build -> test, fail-closed)
- scripts/gate/gate.sh: 3-stage gate — 1) gitleaks, 2) build
  (tsc on commit, full next build on push), 3) LLM parse contract
  tests. Fail-closed: setup errors, timeouts, and findings all block.
- scripts/gate/hooks/{pre-commit,pre-push}: exec gate.sh commit|push.
- scripts/install/install-hooks.sh: idempotent installer (verifies repo
  root, bootstraps pinned gitleaks 8.30.1 if absent, wires both hooks).
- scripts/install/bootstrap-gitleaks.sh: pinned per-user install,
  x86_64/arm64, GitHub release download + SHA-less checksum pin.
- .gitleaks.toml: useDefault=true; single allowlist = .env.example
  placeholder lines (secret= and change-me values) by path+regex.
  Real secrets — even inside .env.example — still trip the gate
  (empirically verified: OpenAI/AWS/Slack/GitHub tokens all caught).
- tests/llm-parse.test.ts: pins parse.ts contracts (strict 6-paragraph
  body, headline/scalar/or array rejection, stopword rules, tag
  fallback) — the choke point for LLM output parsing.
- package.json: 'test' script.
- README: 'Commit gate' section (install, stages, verified fail-closed
  modes).

Verified before commit: clean tree PASSes all 3 stages; staged
realistic secret FAILs stage 1 (exit 1); broken type FAILs stage 2;
broken assertion FAILs stage 3; next build exit 0.
2026-08-16 00:27:41 -04:00
krisf d1bf2962ff final cut: remaining synthesis wording (package.json, Dockerfile env) 2026-08-15 22:52:24 -04:00
krisf 1010f27f44 MapleBrief: production Canadian news aggregator
Next.js 14 + TypeScript + Tailwind + Prisma/SQLite.
- LLM synthesis abstraction (OpenAI/Anthropic/Ollama) + admin settings UI
- RSS ingestion pipeline (parser + cheerio content) + node-cron worker
- AdSense AdUnit placements (header/in-feed/in-article/sidebar)
- Sources analysis attribution, nofollow links, canonical/OG, sitemap/robots
- Admin auth (ADMIN_API_KEY, timingSafeEqual, fail-closed 401)
- Multi-cell lady-ga-ga marker, sitemap, robots, legal pages
- Comprehensive README (setup, LLM config, AdSense, migrations, deploy)
2026-08-15 16:07:07 -04:00