Blog authoring rules (/blog)

Blog authoring rules (/blog)

These are the backpressure rules for every Brioso blog post. They are enforced
by apps/web/src/data/blog/blog.rules.test.ts, which runs in the test gate,
so a post that breaks a rule cannot be merged or published. Treat this file as
the checklist; treat the test as the judge.

The goal is posts that are genuinely useful to a human first, and that also read
well for SEO and for GEO (generative / answer-engine extraction). Everything
below serves one of those two.

Purpose and targeting

  • Every post exists to serve Brioso’s two audiences: content creators and
    agencies. Pick one as the primary audience (audience: "creators" | "agencies"), or "both" for glossary / licensing explainers.
  • Choose the topic and primary keyword from
    keyword-research-bri-28.csv. Aim at the
    company’s actual product: custom music for creators, sonic branding for
    agencies. Do not chase off-product keywords (see the personalized gift-song
    note in that file’s clusters).
  • Cadence: one post every two days. Space publishedAt accordingly.
  • Write the English version. English only for now.

Structure (SEO + GEO)

  • Exactly one H1 (the post title, rendered by the route).
  • A well-formed heading outline underneath: at least one H2 (heading
    block) and at least one H3 (subheading block), nested sensibly.
  • Lead with a short, direct answer to the title question. Answer-engines lift
    the first clear paragraph, so make it standalone.
  • Author is always Brioso Team. Always show the publish date and the
    estimated reading time (both are automatic from the post data).
  • Posts release progressively, roughly a couple a week, via publishedAt: a
    written post stays hidden until its date arrives, then appears with no
    redeploy. Keep cross-links pointing at same-or-earlier posts so no link 404s
    mid-drip (mutually linked posts share a date). The gate enforces this.

Copy

  • No em-dashes or en-dashes (—, –). They read as machine-written. Use
    commas, periods, or a rewrite.
  • Put focus on key phrases with bold (**text**) and underline
    (__text__). At least one of each per post.
  • Human voice. No “in today’s fast-paced world”, no filler, no keyword
    stuffing. Get inspired by competitors, do not copy them.
  • Link to our internal product for the post’s audience: /creators for
    creator posts, /agencies for agency posts (a cta block counts). Both is
    fine when relevant.
  • Link to at least one other blog post ([label](/blog/other-slug)).
    Cross-linking is good for readers and for crawl depth.
  • The article template also renders a Related / Keep reading section
    automatically.

Media

  • At least one music-related image (the hero). Images across a post must be
    visually consistent with each other (same warm, brand-toned palette). One
    strong hero is enough; do not pad with unrelated images.
  • A generated audio example (audioExample) is optional. Add one only when
    a real track genuinely showcases what the article describes (let a reader hear
    what a podcast intro or a game loop can sound like), never as a box to tick.
    When you do add one, produce it with the Brioso worker on the SA3 medium
    model (never a stock clip), and only after the mp3 exists: the gate fails if a
    post declares an example whose file is missing.
  • Never name the model in the blog. SA3 (and any model name) is internal
    product info. Reader-facing copy calls it “a custom Brioso track”. This is
    enforced by the gate, which fails if a post’s text mentions the model.

Adding an example (only when it earns its place)

  1. Write a short brief for the track that fits the post (mood + use case).
  2. Generate it with the worker on the medium audio model.
  3. Save the mp3 to apps/web/public/audio/blog/<post-slug>.mp3.
  4. Set audioExample on the post (title, brief, src, durationSeconds). The
    gate verifies the file exists on disk.

Posts publish as soon as they are written (draft removed); the audio example
is not a gate for publishing. Do not declare audioExample before the mp3
exists, or the gate will fail.