# AI Radar — Architecture & Implementation Plan

Status: proposal for review. No application code written yet.

---

## 1. Analysis of the idea

The product is not a news site. It is a **filter with a website attached**.

That distinction drives everything. On a normal news site, more content is more
value, so the engineering goes into publishing throughput. Here, more content is
*less* value, so the engineering goes into rejection quality. The scarce thing we
produce is the decision not to publish something.

Three consequences:

1. **The editorial reject rate is the core metric**, not article count. If we
   publish 80% of what we find, the product has failed even if every item is
   accurate.
2. **Structured fields beat prose.** Fixed slots (`what_changed`, `why_it_matters`)
   are cheap to generate, cheap to verify, scannable, and hard to pad with filler.
   An LLM asked for a paragraph will waffle; asked for "one sentence on what
   changed" it mostly cannot.
3. **The moat is trust, and trust is lost asymmetrically.** One confidently wrong
   "OpenAI drops prices 80%" costs more than fifty correct items earn. The pipeline
   should be biased toward dropping uncertain items, not toward coverage.

### Honest risks

Two things worth flagging before you commit:

**Timing vs. quality is a real tension.** Verification takes time. A "radar" implies
freshness. The plan resolves this by running ingestion every 2 hours but holding
low-confidence items for the next cycle rather than rushing them out. You will
sometimes be 2-4 hours behind Twitter. That is the correct trade for this product --
being second and right beats being first and wrong, and people who need instant AI
news already have Twitter.

**SEO for a filter site is a slow burn.** You are deliberately publishing fewer pages
than competitors. Traffic will not come from volume. It will come from (a) branded
return visits, and (b) a small number of pages that rank for specific queries like
"claude opus 5 pricing" because they are terse and directly answer the question.
Expect 6-12 months before ad revenue is meaningful. If the goal is fast ad revenue,
this is the wrong product. If the goal is a useful tool that eventually pays for
itself, the plan is sound.

---

## 2. Simplest architecture

```
+-------------------------------------------------------------+
|  SOURCES (RSS / Atom / JSON / GitHub API / HTML fallback)   |
+----------------------------+--------------------------------+
                             |  Vercel Cron, every 2 hours
                             v
+-------------------------------------------------------------+
|  STAGE 0 - FETCH            (plain code, $0)                |
|  parse feeds -> raw_items rows, ETag/Last-Modified caching  |
+----------------------------+--------------------------------+
                             v
+-------------------------------------------------------------+
|  STAGE 1 - PREFILTER        (plain code, $0)  kills ~55%    |
|  url hash - content hash - source trust - keyword gate      |
|  - embedding near-dup vs last 30 days                       |
+----------------------------+--------------------------------+
                             v
+-------------------------------------------------------------+
|  STAGE 2 - TRIAGE           (Haiku, batched 12/call)        |
|  is_new? significant? marketing? -> importance 0-100        |
|  everything under threshold dies here                       |
+----------------------------+--------------------------------+
                             v
+-------------------------------------------------------------+
|  STAGE 3 - EVENT CLUSTER    (plain code + embeddings)       |
|  group N sources reporting the SAME event -> pick primary   |
+----------------------------+--------------------------------+
                             v
+-------------------------------------------------------------+
|  STAGE 4 - WRITE            (Haiku, structured output)      |
|  fill the AI Radar fields from fetched source text          |
+----------------------------+--------------------------------+
                             v
+-------------------------------------------------------------+
|  STAGE 5 - VERIFY           (Sonnet, top ~6% only)          |
|  check every factual claim against source text              |
|  fail -> hold for manual review, never auto-publish         |
+----------------------------+--------------------------------+
                             v
+-------------------------------------------------------------+
|  STAGE 6 - PUBLISH          (plain code, $0)                |
|  slug - SEO meta - ISR revalidate - sitemap ping            |
+-------------------------------------------------------------+
```

### Stack

| Layer | Choice | Why |
|---|---|---|
| Framework | **Next.js 15, App Router** | ISR gives static-speed pages with periodic refresh. One deploy target for site + cron + admin. |
| Hosting | **Vercel Hobby -> Pro** | Cron built in. Hobby is $0 and enough until real traffic. |
| Database | **Postgres (Neon or Supabase)** free tier | Need relational joins + `pgvector` for dedup. Free tier covers this workload for a long time. |
| Vectors | **pgvector** in the same DB | No second service. Dedup is the only vector use case; it does not justify Pinecone. |
| LLM | **Claude Haiku 4.5** bulk, **Sonnet 5** verify | Haiku handles classification and templated writing fine. Sonnet only where being wrong is expensive. |
| Embeddings | `text-embedding-3-small` | $0.02/1M. Effectively free at our volume. |
| Admin auth | Single env-var password + signed cookie | One user. Anything more is overhead. |
| Styling | **Tailwind + CSS variables** | Variables make the dark/light token system clean. |

**Explicitly rejected:** Redis (Postgres is fast enough), a queue (cron is the queue),
a CMS (the DB is the CMS), Docker (Vercel), microservices, GraphQL, Prisma
(node-postgres + SQL is less machinery for ~12 tables).

---

## 3. Data model

```sql
-- ========== INGESTION SIDE ==========

CREATE TABLE sources (
  id            SERIAL PRIMARY KEY,
  name          TEXT NOT NULL,
  homepage_url  TEXT,
  feed_url      TEXT,
  kind          TEXT NOT NULL,   -- rss | atom | json | github_releases | html
  company_id    INT REFERENCES companies(id),
  trust_tier    SMALLINT NOT NULL DEFAULT 2,  -- 1 primary, 2 reliable, 3 noisy
  is_primary    BOOLEAN NOT NULL DEFAULT FALSE,
  enabled       BOOLEAN NOT NULL DEFAULT TRUE,
  blacklisted   BOOLEAN NOT NULL DEFAULT FALSE,
  etag          TEXT,            -- HTTP caching, avoids refetch
  last_modified TEXT,
  last_fetch_at TIMESTAMPTZ,
  fail_count    INT NOT NULL DEFAULT 0,   -- auto-disable after N failures
  created_at    TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE TABLE raw_items (
  id             BIGSERIAL PRIMARY KEY,
  source_id      INT NOT NULL REFERENCES sources(id),
  url            TEXT NOT NULL,
  url_hash       TEXT NOT NULL UNIQUE,   -- sha256(normalized url), THE dedup key
  content_hash   TEXT,                   -- sha256(title+body), catches re-posts
  title          TEXT,
  raw_text       TEXT,
  published_at   TIMESTAMPTZ,
  fetched_at     TIMESTAMPTZ NOT NULL DEFAULT now(),
  embedding      VECTOR(1536),
  stage          TEXT NOT NULL DEFAULT 'fetched',
                 -- fetched|prefiltered|triaged|clustered|written|verified|published|rejected
  reject_reason  TEXT,
  reject_stage   TEXT,
  triage_score   SMALLINT,
  tokens_spent   INT NOT NULL DEFAULT 0,  -- per-item cost tracking
  cost_usd       NUMERIC(10,6) NOT NULL DEFAULT 0
);
CREATE INDEX ON raw_items (stage, fetched_at DESC);
CREATE INDEX ON raw_items USING ivfflat (embedding vector_cosine_ops);

-- Same real-world event reported by several outlets
CREATE TABLE events (
  id             BIGSERIAL PRIMARY KEY,
  canonical_slug TEXT UNIQUE,
  centroid       VECTOR(1536),
  first_seen_at  TIMESTAMPTZ NOT NULL DEFAULT now(),
  post_id        BIGINT REFERENCES posts(id)
);
CREATE TABLE event_items (
  event_id  BIGINT REFERENCES events(id),
  raw_id    BIGINT REFERENCES raw_items(id),
  PRIMARY KEY (event_id, raw_id)
);

-- ========== PUBLISHED SIDE ==========

CREATE TABLE companies (
  id       SERIAL PRIMARY KEY,
  name     TEXT NOT NULL,
  slug     TEXT NOT NULL UNIQUE,
  logo_url TEXT
);

CREATE TABLE posts (
  id                SERIAL PRIMARY KEY,
  slug              TEXT NOT NULL UNIQUE,
  category          TEXT NOT NULL,   -- news|tool|update|model|pricing|research
  title             TEXT NOT NULL,
  summary           TEXT NOT NULL,        -- 1-2 sentences
  what_changed      TEXT NOT NULL,
  why_it_matters    TEXT NOT NULL,
  who_should_care   TEXT[] NOT NULL,      -- ['developers','founders']
  worth_trying      TEXT NOT NULL,        -- yes | no | maybe
  worth_trying_note TEXT,

  company_id        INT REFERENCES companies(id),
  tool_name         TEXT,

  source_url        TEXT NOT NULL,
  source_name       TEXT NOT NULL,
  source_published  TIMESTAMPTZ,
  published_at      TIMESTAMPTZ,          -- NULL until published

  importance        SMALLINT NOT NULL,    -- 0-100, drives homepage rank
  confidence        SMALLINT NOT NULL,    -- 0-100, verification result
  trending_score    REAL NOT NULL DEFAULT 0,       -- recomputed hourly
  source_count      SMALLINT NOT NULL DEFAULT 1,   -- outlets on this event

  featured          BOOLEAN NOT NULL DEFAULT FALSE,
  status            TEXT NOT NULL DEFAULT 'draft',
                    -- draft|published|held|unpublished
  sponsored         BOOLEAN NOT NULL DEFAULT FALSE,  -- future, always labelled

  seo_title         TEXT,
  seo_description   TEXT,
  tags              TEXT[],

  created_at        TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at        TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX ON posts (status, published_at DESC);
CREATE INDEX ON posts (category, published_at DESC);

CREATE TABLE pipeline_runs (
  id            BIGSERIAL PRIMARY KEY,
  started_at    TIMESTAMPTZ NOT NULL DEFAULT now(),
  finished_at   TIMESTAMPTZ,
  fetched       INT DEFAULT 0,
  prefiltered   INT DEFAULT 0,
  triaged       INT DEFAULT 0,
  published     INT DEFAULT 0,
  cost_usd      NUMERIC(10,6) DEFAULT 0,
  errors        JSONB
);

CREATE TABLE ad_slots (
  key        TEXT PRIMARY KEY,   -- 'home_top', 'article_middle', ...
  enabled    BOOLEAN NOT NULL DEFAULT FALSE,
  provider   TEXT,               -- 'adsense'
  unit_id    TEXT,
  min_width  INT                 -- desktop-only slots
);
```

Two design notes worth calling out:

- **`raw_items` keeps rejects forever.** Rejected rows are how you tune the editor.
  Without them you cannot answer "are we dropping good stories?" They are also the
  dedup memory -- you must remember what you refused.
- **`events` separates "the thing that happened" from "our post about it."** This is
  what lets you say "12 outlets covered this" (a strong importance signal) and still
  publish exactly one item.

---

## 4. The editorial workflow in detail

### Stage 1 - Prefilter (code only, no AI)

Runs in order, cheapest check first:

1. `url_hash` already in `raw_items` -> drop, `seen_url`
2. `content_hash` match -> drop, `republished`
3. Source blacklisted or disabled -> drop
4. Title matches junk regex (`top 10`, `you won't believe`, `here's why`, `in 2026`)
   AND `trust_tier = 3` -> drop, `listicle`
5. No AI-relevant keyword in title+first 500 chars -> drop, `off_topic`
6. Cosine similarity > 0.92 against any embedding from last 30 days -> attach to that
   `event`, drop as a post candidate, `duplicate_event`

Kills ~55% for zero LLM spend. **This is the single most important cost lever in the
system.**

### Stage 2 - Triage (Haiku, 12 items per call)

Sends title + 400-char excerpt + source tier. Returns per item:

```json
{ "id": 1, "is_significant": true, "is_marketing": false,
  "category": "model", "importance": 78, "reason": "new frontier model" }
```

Drop rules: `importance < 45`, or `is_marketing && importance < 70`.
Batching 12 at a time is what keeps triage under $3/month at 5k volume.

### Stage 3 - Event clustering

Survivors are grouped by embedding similarity (>0.85) within a 72-hour window. For
each cluster pick the primary: lowest `trust_tier` number wins, tie broken by
earliest `published_at`. `source_count` becomes an importance multiplier -- five
outlets on one story is real signal.

### Stage 4 - Write (Haiku, structured output)

Full source text in, strict JSON out matching the post fields. Hard constraints in
the prompt:

- `summary` <= 2 sentences
- `what_changed` <= 40 words, facts only, no adjectives
- `why_it_matters` <= 40 words, must name a concrete consequence
- `worth_trying` must be justified by something in the source
- **Forbidden**: any number, price, benchmark, or date not literally present in the
  source text

### Stage 5 - Verify (Sonnet, top ~6% only)

Triggered when `importance >= 70` **or** the draft contains a price, percentage,
benchmark score, or model name. Gets source text + draft, returns per-claim
supported/unsupported and a confidence score.

- `confidence >= 80` -> publish
- `60-79` -> publish with claim stripped, or hold
- `< 60` -> `status = 'held'`, appears in admin, never auto-publishes

### Stage 6 - Publish

Slug from title + short hash. SEO title/description generated in Stage 4 (free --
same call). Daily publish cap of 20 as a runaway guard. Trigger ISR revalidation for
`/`, `/today`, the category page, and the new post URL.

### Daily digest

A separate 06:00 cron builds the "AI RADAR - September 11 / 5 important things"
block from the last 24 hours of published posts. Pure SQL ranked by `importance` --
no AI call needed.

---

## 5. Sources to monitor

**Tier 1 - primary, always trusted (the backbone)**

| Source | Feed |
|---|---|
| OpenAI news + changelog | RSS |
| Anthropic news + API changelog | RSS |
| Google DeepMind / AI blog | RSS |
| Meta AI | RSS |
| Mistral, Cohere, xAI | RSS |
| Hugging Face blog + trending models | RSS / API |
| GitHub Releases (~30 repos: vLLM, llama.cpp, LangChain, Ollama, Transformers, Cursor, Continue, ...) | GitHub API |
| Cursor / Vercel / Replit / LangChain changelogs | RSS |
| Stability, ElevenLabs, Midjourney, Runway, Pika | RSS / HTML |
| arXiv cs.AI + cs.CL (filtered hard -- high volume) | Atom |

**Tier 2 - reliable secondary**

Product Hunt (AI topic), Hacker News (>150 points, AI keyword), TechCrunch AI,
The Verge AI, VentureBeat AI, Ars Technica AI, Simon Willison's blog, The Batch.

**Tier 3 - noisy, aggressive filtering**

Reddit r/LocalLLaMA + r/MachineLearning (high score only), selected X accounts via
RSS bridge, AI newsletters.

**Deliberately excluded:** SEO content farms, Medium, "AI tool directory" sites,
press-release wires, YouTube. All noise, no signal.

Start with **Tier 1 only** (~40 sources). That yields roughly 800-1,500 candidates a
month -- the cheap tier, and almost all genuinely useful. Add Tier 2 in Phase 4 once
the reject rules are proven. Tier 3 probably never.

---

## 6. Cost estimates

Pricing used: Haiku 4.5 $1/$5 per 1M in/out, Sonnet 5 $3/$15, embeddings $0.02/1M.

### Without the code prefilter (naive -- do not build this)

| Candidates/mo | Triage | Write | Verify | Embed | **Total** |
|---|---|---|---|---|---|
| 1,000 | $0.55 | $1.50 | $1.27 | $0.01 | **$3.33** |
| 5,000 | $2.75 | $7.50 | $6.38 | $0.03 | **$16.66** |
| 10,000 | $5.50 | $15.00 | $12.75 | $0.06 | **$33.31** |

### With the code prefilter (~55% killed free) -- the actual plan

| Candidates/mo | After prefilter | **Total/mo** | Published | Per day |
|---|---|---|---|---|
| 1,000 | 450 | **$1.68** | ~74 | ~2.5 |
| 5,000 | 2,250 | **$8.41** | ~371 | ~12.4 |
| 10,000 | 4,500 | **$16.81** | ~743 | ~25 |

**Read this table as a design constraint, not a forecast.** 5,000 candidates/month
is the sweet spot: $8.41, ~12 published items/day, inside your $10 budget. The 10k
row is a warning -- if you ever hit it you have added noisy sources, and the fix is
removing sources, not raising the budget. 25 items/day also breaks the brand promise.

Hosting: $0 on Vercel Hobby + Neon free tier until real traffic; ~$20/mo on Vercel
Pro after. **Realistic total to run: under $10/month for the first year.**

Extra safeguards: hard monthly spend cap in env (pipeline halts and alerts),
per-run cost logged to `pipeline_runs`, prompt caching on the static system prompts.

---

## 7. Code vs. AI

The rule: **AI only where judgement or language is genuinely required.** Everything
deterministic is code, because code is free, instant, testable, and never
hallucinates.

| Task | Code | AI | Note |
|---|---|---|---|
| Fetch, parse feeds | yes | | |
| URL / content hash dedup | yes | | Exact match, no AI needed |
| Near-duplicate detection | yes | | Embeddings + cosine -- maths, not reasoning |
| Keyword / listicle gate | yes | | Regex |
| Event clustering | yes | | Vector similarity |
| Primary-source selection | yes | | Sort by trust tier |
| Importance *ranking* | yes | | Formula over AI score, recency, source_count |
| Trending score | yes | | Velocity of new sources per event |
| Slug, sitemap, OG tags | yes | | Templates |
| Daily digest assembly | yes | | SQL ORDER BY |
| **Is this significant?** | | yes | Real judgement |
| **Is this marketing fluff?** | | yes | Real judgement |
| **Categorise** | | yes | Haiku, cheap |
| **Write the structured fields** | | yes | Language generation |
| **SEO title/description** | | yes | Free ride on the write call |
| **Verify claims vs source** | | yes | Sonnet, high stakes only |

Two anti-patterns to avoid: never ask an LLM to sort or rank a list (a formula does
it better and free), and never ask an LLM whether two URLs are the same (a hash
does it).

---

## 8. MVP pages

| Route | Purpose |
|---|---|
| `/` | The dashboard. Today's digest, hero, sections. Primary experience. |
| `/today` | Permalink for today's digest -- shareable, SEO-friendly |
| `/news/[slug]`, `/tools/[slug]`, `/models/[slug]`, `/updates/[slug]`, `/pricing/[slug]`, `/research/[slug]` | Item pages, category in URL |
| `/tools`, `/models`, `/updates`, `/api-pricing`, `/news` | Category archives |
| `/companies/[slug]` | Everything from OpenAI / Anthropic / Google |
| `/search` | Client-side over a small JSON index |
| `/about` | Methodology + the editorial promise. Matters for trust and for AdSense review. |
| `/admin` | Posts list, edit, publish/unpublish, feature, hold queue, sources, run log |
| `/sitemap.xml`, `/rss.xml`, `/robots.txt` | |

**Not in MVP:** tags pages, author pages, `/archive/[date]`, newsletter signup,
per-tool landing pages. Each is a thin-content risk with no traffic until there is a
corpus.

---

## 9. What to cut

Things that look reasonable but should not be built:

| Cut | Why |
|---|---|
| Redis / queue / worker service | Cron + Postgres handles this volume completely |
| Prisma or any ORM | ~12 tables, hand-written SQL is less machinery |
| Multi-user admin, roles | One user |
| Tag archive pages | Thin content, Google penalty risk, no traffic |
| Comments, accounts, saved items | Explicitly out of scope, huge moderation cost |
| Image generation per post | Cost + slop. Use company logos and typography |
| Full-text search service | Postgres FTS or a static JSON index is enough |
| Real-time / websockets | The data changes every 2 hours |
| Social auto-posting (Phase 1) | Just store `social_text` in the write call, wire up later |
| Custom ad server | AdSense until traffic justifies direct sales |
| A/B testing framework | No traffic to test with |
| arXiv in Phase 1 | Volume would swamp the pipeline before tuning |

One thing worth **adding** that was not in your brief: a **"Why we didn't publish"**
admin view over rejected items. It is your only feedback loop on whether the editor
is too aggressive, and it costs nothing -- the data is already in `raw_items`.

---

## 10. Phased implementation

**Phase 0 - Foundations (1/2 day)**
Next.js + TS + Tailwind, Postgres + pgvector, schema migration, seed companies and
~40 Tier 1 sources, env config, deploy an empty site.

**Phase 1 - Ingestion, no AI (1 day)**
Fetchers (RSS/Atom/JSON/GitHub), normalisation, hashing, ETag caching, Stage 1
prefilter, `pipeline_runs` logging, a `/admin/raw` table.
*Milestone: real candidates flowing in, ~55% auto-rejected, $0 spent.*

**Phase 2 - AI editor (1-2 days)**
Triage (batched), embeddings + clustering, write stage, verify stage, cost tracking,
spend cap. Run against the Phase 1 backlog and hand-check ~50 decisions.
*Milestone: drafts that read correctly, with a defensible reject rate.*

**Phase 3 - The site (2 days)**
Design tokens, components, homepage with hierarchy, item pages, categories,
companies, SEO (metadata, canonical, sitemap, JSON-LD `NewsArticle`), dark/light,
mobile, ad slot components rendering nothing.
*Milestone: publicly usable site.*

**Phase 4 - Automate & harden (1 day)**
Vercel Cron every 2h, digest cron at 06:00, ISR revalidation, admin (publish,
feature, hold queue, blacklist source, run log), failure alerts, add Tier 2 sources.
*Milestone: runs without you.*

**Phase 5 - Monetise (1/2 day, after traffic exists)**
AdSense into the existing slots, `ad_slots` config toggles, Core Web Vitals check.

**Phase 6 - Distribution (later, optional)**
`social_text` is already stored; add X/Telegram posting and a weekly digest.

Roughly **5-7 working days to a live, self-running site.** Phases 0-2 are the real
product; 3 is presentation; 4 is what makes it hands-off.

---

## 11. Design system

### Colour

Dark is the primary theme and gets designed first.

```css
:root[data-theme="dark"] {
  --bg:          #0A0C10;   /* near-black, slight blue */
  --surface:     #111419;   /* cards */
  --surface-2:   #171B22;   /* hover */
  --border:      #212630;   /* hairlines */
  --text:        #E8EAED;
  --text-2:      #9BA3AF;   /* metadata - still AA on --bg */
  --text-3:      #6B7280;   /* minimum, large text only */
  --accent:      #3DDC97;   /* radar green */
  --accent-dim:  #1F5C45;
  --warn:        #F5A623;
  --danger:      #E5484D;
}
:root[data-theme="light"] {
  --bg:          #FFFFFF;
  --surface:     #F7F8FA;
  --surface-2:   #EFF1F5;
  --border:      #E2E5EA;
  --text:        #0D1117;
  --text-2:      #5A6472;
  --text-3:      #78808D;
  --accent:      #0F9D66;   /* darkened for contrast on white */
  --accent-dim:  #C8EFDD;
}
```

Category accents are used **only** as a small chip label, never as card backgrounds:
model `violet`, tool `cyan`, update `blue`, pricing `amber`, research `slate`,
news `green`.

One accent, used sparingly -- active nav, live indicator, links, "Worth Trying"
ticks. Everything else is greyscale so the content carries the page.

### Typography

`Inter` (or `Geist`) for UI and body, `JetBrains Mono` for metadata, timestamps and
category chips -- the mono is what creates the "technical instrument" feel without
making the whole thing a terminal.

| Token | Size / line-height | Use |
|---|---|---|
| `display` | 32/38, 600, -0.02em | Daily header |
| `h1` | 26/32, 600 | Hero title |
| `h2` | 20/28, 600 | Section headers |
| `card-title` | 17/24, 550 | Card titles |
| `body` | 15/24, 400 | Summaries |
| `meta` | 12.5/16, 500, mono | Source, time |
| `chip` | 11/14, 600, mono, 0.06em, uppercase | Category |

Body measure capped at 68ch. No grey text below 12.5px.

### Spacing & shape

4px base scale. Radius: 10px cards, 6px chips, 8px buttons. Borders are 1px
`--border` -- that plus a background shift is the primary card definition. Shadows
only on hover, and barely. No shadow in dark mode (it does nothing on near-black);
use a border-colour lift instead.

### Motion

150ms ease-out on hover, 200ms on theme change. The radar pulse is a 2s
`ease-in-out` opacity loop on a 6px dot, next to "LIVE" in the header. That is the
only ambient animation on the page. All of it respects `prefers-reduced-motion`.

---

## 12. Homepage wireframe - desktop (>=1280px)

```
+--------------------------------------------------------------------------+
| ((o)) AI RADAR   Today  News  Tools  Models  Updates  API    [?]  [D]    |  sticky 56px
+--------------------------------------------------------------------------+
|                                                                          |
|  FRIDAY, SEPTEMBER 11 . 2026                        * LIVE . updated 2h  |
|  5 important things happened in AI today                                 |  digest
|                                                                          |
|  +--------------------------------------------------------------------+  |
|  | 01 - Anthropic ships Claude Opus 5 with 1M context      MODEL      |  |  numbered
|  | 02 - OpenAI cuts GPT-5 API pricing by 40%               PRICING    |  |  list,
|  | 03 - Google opens Gemini 3 Flash to free tier           MODEL      |  |  clickable
|  | 04 - Cursor 2.0 adds background agents                  UPDATE     |  |
|  | 05 - Mistral releases 8B open-weights model             MODEL      |  |
|  +--------------------------------------------------------------------+  |
|                                                                          |
|     New Tools 4  .  Models 2  .  Updates 3  .  API changes 1             |  counters
+--------------------------------------------------------------------------+
| +------------------------------------------+  +-----------------------+  |
| | IMPORTANT TODAY                          |  |  TRENDING             |  |
| |                                          |  |  1 Claude Opus 5   ^  |  |
| | +--------------------------------------+ |  |  2 GPT-5 pricing   ^  |  |
| | | MODEL RELEASE          Anthropic.2h  | |  |  3 Gemini 3 Flash     |  |
| | |                                      | |  |  4 Cursor 2.0         |  |
| | | Claude Opus 5 released with 1M       | |  |  5 Mistral 8B         |  |
| | | token context                        | |  +-----------------------+  |
| | |                                      | |                             |
| | | Anthropic launched Opus 5 with a 1M  | |  +-----------------------+  |
| | | context window and better coding.    | |  |                       |  |
| | |                                      | |  |   [AD] AdSidebar      |  |
| | | > WHY IT MATTERS                     | |  |   300x600             |  |
| | |   Long-context agents no longer      | |  |   sticky, below fold  |  |
| | |   need chunking pipelines.           | |  |                       |  |
| | |                                      | |  +-----------------------+  |
| | | + Worth trying   Developers.Founders | |                             |
| | | -------------------------------------| |  +-----------------------+  |
| | | anthropic.com >   7 sources          | |  |  WORTH TRYING         |  |
| | +--------------------------------------+ |  |  + Claude Opus 5      |  |
| |                                          |  |  + Mistral 8B         |  |
| | +-----------------+ +-----------------+  |  |  + Cursor 2.0         |  |
| | | PRICING    2h   | | MODEL      4h   |  |  +-----------------------+  |
| | | OpenAI cuts     | | Gemini 3 Flash  |  |                             |
| | | GPT-5 API 40%   | | free tier       |  |                             |
| | | Summary line... | | Summary line... |  |                             |
| | | > Why: cheaper  | | > Why: free...  |  |                             |
| | | openai.com  +   | | google.com  +   |  |                             |
| | +-----------------+ +-----------------+  |                             |
| +------------------------------------------+                             |
+--------------------------------------------------------------------------+
|  [AD]  AdTopFeed - 728x90 / responsive, "ADVERTISEMENT" label above      |  AD 1
+--------------------------------------------------------------------------+
|  NEW AI TOOLS                                              View all >    |
|  +--------------+ +--------------+ +--------------+ +--------------+     |
|  | TOOL         | | TOOL         | | TOOL         | | TOOL         |     |  compact
|  | Tool name    | | Tool name    | | Tool name    | | Tool name    |     |  4-up
|  | One line...  | | One line...  | | One line...  | | One line...  |     |
|  | + worth try  | |              | | + worth try  | |              |     |
|  +--------------+ +--------------+ +--------------+ +--------------+     |
+--------------------------------------------------------------------------+
|  PRODUCT UPDATES                                           View all >    |
|  ----------------------------------------------------------------------  |
|   2h  UPDATE   Cursor 2.0 adds background agents        cursor.com   +   |  dense
|   5h  UPDATE   ChatGPT projects get shared folders      openai.com       |  list,
|   8h  UPDATE   Midjourney v8 adds style refs            mj.com           |  no cards
|  11h  UPDATE   Perplexity adds Spaces API               pplx.ai          |
+--------------------------------------------------------------------------+
|  [AD]  AdBetweenSections - responsive                                    |  AD 2
+--------------------------------------------------------------------------+
|  NEW MODELS               |  PRICING & API CHANGES                       |  two-col
|  -----------              |  ---------------------                       |
|   Mistral 8B        2h    |   OpenAI GPT-5 -40%              2h          |
|   Gemini 3 Flash    4h    |   Anthropic batch API 50% off    1d          |
|   Qwen 3.5 VL       9h    |   Groq free tier limits cut      2d          |
+--------------------------------------------------------------------------+
|  About . Methodology . RSS . Contact      Everything important in AI.    |
+--------------------------------------------------------------------------+
```

**Desktop ad inventory: 3** (sidebar, top-feed, between-sections). All below the
first useful content. Nothing above the digest.

## Homepage wireframe - mobile (<768px)

```
+-----------------------------+
| ((o)) AI RADAR      [?] [=] |  sticky 52px
+-----------------------------+
| FRI, SEP 11    * LIVE       |
| 5 important things          |
| happened in AI today        |
|                             |
| 01 - Claude Opus 5    MODEL |
| 02 - GPT-5 -40%     PRICING |
| 03 - Gemini 3 free    MODEL |
| 04 - Cursor 2.0      UPDATE |
| 05 - Mistral 8B       MODEL |
|                             |
| Tools 4 . Models 2 . Upd 3  |
+-----------------------------+
| IMPORTANT TODAY             |
| +-------------------------+ |
| | MODEL       Anthropic.2h| |
| | Claude Opus 5 released  | |  hero, full width
| | with 1M context         | |
| | Anthropic launched...   | |
| | > WHY IT MATTERS        | |
| |   Long-context agents...| |
| | + Worth trying          | |
| | anthropic.com . 7 srcs  | |
| +-------------------------+ |
| +-------------------------+ |
| | PRICING           2h    | |  stacked,
| | OpenAI cuts GPT-5 40%   | |  progressively
| | > Why: cheaper agents   | |  more compact
| +-------------------------+ |
| +-------------------------+ |
| | MODEL             4h    | |
| | Gemini 3 Flash free     | |
| +-------------------------+ |
+-----------------------------+
| [AD] AdMobileFeed           |  AD 1 - after 4 items
+-----------------------------+
| NEW TOOLS         View all >|
|  . Tool one          +      |
|  . Tool two                 |
|  . Tool three        +      |
|                             |
| UPDATES           View all >|
|  2h  Cursor 2.0             |
|  5h  ChatGPT folders        |
|  8h  Midjourney v8          |
+-----------------------------+
| [AD] AdBetweenSections      |  AD 2
+-----------------------------+
| MODELS . PRICING            |
|  stacked lists              |
+-----------------------------+
| About . RSS . Contact       |
+-----------------------------+
```

**Mobile ad inventory: 2.** Trending and sidebar collapse away entirely rather than
being stacked at the bottom -- they are desktop affordances.

## Item page

```
  < Back to today
  MODEL RELEASE                                    Anthropic . 2h ago
  Claude Opus 5 released with 1M token context
  [1-2 sentence summary, 20px, --text-2]
  -----------------------------------------------------------------
  WHAT CHANGED          [<=40 words]
  WHY IT MATTERS        [<=40 words]
  -----------------------------------------------------------------
  [AD] AdArticleMiddle                                       AD 1
  -----------------------------------------------------------------
  WHO SHOULD CARE       [Developers] [AI founders]
  WORTH TRYING          + Yes - [one-line reason]
  -----------------------------------------------------------------
  SOURCE   Anthropic official announcement >
           Also covered by 7 outlets v
  Verified against primary source . confidence 94
  -----------------------------------------------------------------
  RELATED    [3 compact cards]
  [AD] AdArticleBottom                                       AD 2
```

Ads come **after** `why_it_matters` -- the reader has already got the value. Never
between title and summary.

### Ad components

`<AdSlot slotKey="home_top" />` reads `ad_slots`, renders `null` when disabled or
unfilled (no collapsing layout, no empty boxes), lazy-loads below the fold, and
always renders a 10px mono `ADVERTISEMENT` label. No ad markup is ever hard-coded
into a page. Sponsored posts, when they exist, get a `SPONSORED` chip in the
category slot and are excluded from `importance` ranking entirely.

---

## 13. Component structure

```
components/
  layout/     Header  Nav  Footer  ThemeToggle  RadarPulse
  digest/     DailyHeader  TopFiveList  StatCounters
  cards/      HeroCard  StandardCard  CompactCard  ListRow  ToolCard
  post/       PostHeader  FieldBlock  WorthTrying  SourceBlock  RelatedPosts
  sections/   SectionHeader  CardGrid  DenseList  TrendingList
  ads/        AdSlot  (single component, config-driven)
  ui/         Chip  Badge  TimeAgo  Skeleton  EmptyState
lib/
  db/         client  queries  migrations
  pipeline/   fetch  prefilter  triage  cluster  write  verify  publish
  ai/         claude  embeddings  prompts  cost
  seo/        metadata  jsonld  sitemap
```

Four card variants only -- hero, standard, compact, list row. That is the visual
hierarchy, and it is enforced by having no fifth option.

---

## 14. Decisions I need from you

1. **Database** - Neon or Supabase? Both free-tier fine. Neon is a cleaner pure
   Postgres; Supabase gives you a table UI, which is handy for a solo project.
   I lean Neon.
2. **Domain** - needed for canonical URLs and sitemap. Do you have one?
3. **Accent colour** - I have proposed radar green `#3DDC97`. Cyan or violet are
   equally workable. Green reads most "signal/instrument".
4. **Publishing threshold** - start conservative (~8/day) or moderate (~12/day)?
   I recommend conservative for the first two weeks so you can hand-check every
   item, then loosen.
5. **API keys** - an Anthropic key, and an OpenAI key purely for embeddings. Do you
   have both?

Once you confirm those, I would start at Phase 0 and stop after Phase 1 so you can
look at real ingested data before any money is spent on AI.
