Skip to content
MCS · Design

How we publish.

Two non-negotiable rules. Six chained stages. The brief commits only past its gates.

Section 1 · 2 non-negotiable rules

The two rules.

  • Rule #1

    Specs come from a hand-curated YAML catalog.

    No model invents a spec. Every numeric token in review, guide, rig, component and changelog prose must trace back to content/_specs/<slug>.yaml or the build fails. Briefs are exempt as a collection, because their numbers come from the sources they cite: a brief commits only when its headline number is printed in the source it cites.

    CI evidence ↗
    • validator·scripts/validate-specs.ts
    • doctrine·content/_specs/_README.md
    • schema·content/_specs/_SCHEMA.md
    • CI step·.github/workflows/content-gate.yml · validate:specs
    • brief exemption·content/_specs/_grandfathered.yaml · collections
    • brief gate·lib/synthesize/orchestrator.ts · numberIsSourced
  • Rule #2

    The LLM is forbidden from voice-bearing sections.

    Voice-bearing headings — Verdict, Intro, Recommendation — may only appear in documents whose frontmatter author is on the allowlist, or the build fails. The validator checks headings, not who wrote the prose: the daily brief is written by a model (stage 6 below) and carries none of those sections.

    CI evidence ↗
    • validator·scripts/validate-authorship.ts
    • CI step·.github/workflows/content-gate.yml · validate:authorship

Section 2 · 6 stages

The pipeline, stage by stage.

Every stage runs on a Vercel cron. Each one writes only its declared output and holds a single boundary it never crosses.

CatchClusterStripQuantifyGateSynthesizeMainhourly, on the hourhourly, at :20hourly, at :4011:00 UTC daily11:00 UTC daily11:00 UTC dailypast the gates

Run order · Gate’s PRs are drafts that wait for review · the brief commits to main past its gates

  • Stage 1

    Catch

    hourly, on the hour

    Reads
    Ten sources: HN Algolia, Phoronix, the NVIDIA Developer Blog, r/LocalLLaMA, arXiv cs.AR, TechCrunch AI, The Verge AI, two YouTube channel lists (AI, robotics), and frontier-lab news feeds
    Writes
    mcs_signal_candidate (deduped by source + source_id)
    Never
    persists Reddit body text — only title, score, permalink, url, created_utc (ToS perimeter).
  • Stage 2

    Cluster

    hourly, at :20

    Reads
    unprocessed mcs_signal_candidate rows in a 48-hour window
    Writes
    mcs_signal_cluster + mcs_signal_cluster_member (3-shingle Jaccard ≥ 0.45)
    Never
    uses an LLM or embeddings — pure JS, lead-only centroid, deterministic.
  • Stage 3

    Strip

    hourly, at :40

    Reads
    mature clusters (closed_at NOT NULL OR member_count ≥ 3)
    Writes
    topic_label heuristically + mcs_signal_claim rows (kind: spec | benchmark | event | price)
    Never
    writes voice — no Verdict, Intro, or Recommendation prose. Subject vocab is allowlisted.
  • Stage 4

    Quantify

    11:00 UTC daily (one cron with Gate and Synthesize)

    Reads
    unverified mcs_signal_claim rows + the spec catalog
    Writes
    verdict on each claim: confirmed | conflict | novel | weak
    Never
    writes copy — verdicts are advisory inputs to Gate, never published prose.
  • Stage 5

    Gate

    11:00 UTC daily (after Quantify)

    Reads
    ready clusters meeting threshold (≥1 conflict OR ≥3 novels OR ≥3 cluster members)
    Writes
    a draft GitHub PR per topic — changelog stub, conflict YAML, novel-spec stub
    Never
    merges. A draft PR waits for review; nothing merges it automatically.
  • Stage 6

    Synthesize

    11:00 UTC daily (after Gate)

    Reads
    the last 36 hours of caught rows and the past week of drift detections
    Writes
    content/briefs/<date>.mdx, committed straight to main. The only stage that calls an LLM.
    Never
    commits a brief with a dead link, or with a headline number its cited source does not print. Three failed drafts skip the day, and brief-watch files an issue.

Section 3 · Topology

One picture.

        HN ─┐
  Phoronix ─┤
    NVIDIA ─┤
  r/LocalL ─┤
     arXiv ─┤
TechCrunch ─┼──→ Catch ──→ Cluster ──→ Strip ──→ Quantify ──→ Gate ──→ DRAFT PR
  Verge AI ─┤    hourly    hourly      hourly    11:00 UTC    11:00 UTC    │
YouTube AI ─┤      │                                               waits for review
 YT robots ─┤      │                                                       │
  Lab news ─┘      │                                                       ▼
                   │                                                  /changelog
                   │
                   │
                   └──→ Synthesize ──→ link + number gates ──→ main ──→ /signal
                        11:00 UTC      3 drafts, then skip the day

Ten sources fan in. Six stages run. Two ways out: Gate’s draft PRs wait for review, and the daily brief commits to main once its links resolve and its headline number checks out.

Section 4 · The boundary

What the LLM is and isn't allowed to do.

  • Allowed

    Draft the daily brief from the day’s caught sources (Synthesize).

    Forbidden

    Commit a brief whose headline number its cited source does not print, or whose links do not resolve.

    Enforced by

    lib/synthesize/orchestrator.ts + lib/links/check.ts (in-process, before the commit)

  • Allowed

    Recommend rigs from the catalog (The Specifier).

    Forbidden

    Invent a number in review, guide, rig, component or changelog prose.

    Enforced by

    scripts/validate-specs.ts (Rule #1)

  • Allowed

    Summarize an article in a PR description.

    Forbidden

    Write a verdict, intro, or recommendation paragraph.

    Enforced by

    scripts/validate-authorship.ts (Rule #2)

  • Allowed

    Render specs from YAML the human committed.

    Forbidden

    Persist Reddit body text into mcs_signal_candidate.raw_payload.

    Enforced by

    lib/catch/sources/reddit-localllama.ts perimeter (ToS, operational)