rules-blog latest

v5v13updated MITsha256 d8382413cd66

Rules for every Context Blog workflow, layered on the Context harness: the three forks (what · how often · output tier), the label vocabulary, the checker and publish gates, key names only, daily brief first, and which server does what. Every blog, site and Instagram skill inherits this.


Raw .mdversions.jsonPermalinkSource

Install

curl -fsSL https://agents.onecontext.me/skills/rules-blog.md -o .claude/skills/rules-blog/SKILL.md

Depends on

rules

SKILL.md

Context Blog — rules

These rules apply whenever an agent works on Context Blog content — blog posts, a site or landing page, Instagram posts — for a tenant (one brand, one site, e.g. getmeetly.ai). They sit on top of the Context harness (rules, which itself sits on context): everything there still holds (start_context first, grill-me + wayfinder verbatim, one map + one combined gate, per-ticket documents, handoff before stopping). This file adds only what is blog-specific.

1. Two servers, one link

Server Owns Never
Context MCP (app.onecontext.me) work: Epic, Issues, labels, due, Artifacts, comments, request_review, approvals, get_changes content bytes, publishing
Context Blog MCP (sites.onecontext.me/api/mcp) tenants, brand/hubs/topics, drafts, preview render, publish, sites, domains, analytics, AI-visibility tracking, approving, reading Context

The Blog MCP is a separate, independently versioned server with its own tool names (usage_guide, get_capabilities, article_upsert, content_lint, tenant_get, publish, …) — those are unaffected by the Context MCP contract and are never renamed here. Hold both connections. You carry the link: every piece of content is one Context Issue, and its id rides as context_issue_id on every Blog MCP call that accepts one. Call start_context on the Context MCP once per session, and the Blog MCP's own usage_guide / get_capabilities before you rely on a content tool. Context stays thin: there are no server-side loops; every routine runs on the host that owns the workflow.

2. The three forks

Every Context Blog interview opens on three forks. Ask them, recommend, and record the answer in the decision record — never assume.

Credential-less hosts (ChatGPT, claude.ai) can do everything except Instagram publishing and the AI-visibility probe; recommend Claude Code or Codex for the full loop. Say what this host can do as a fact (§8).

3. Label vocabulary

One Context Issue per publish, one channel per Issue. Native fields first: due = the publish time (publishAt, ISO 8601 with offset), parent_id = the tenant's channel parent Issue (Blog, Instagram, Site — label lane:<channel>, itself a child of the tenant Epic). Decomposition, when a piece needs it, is child Issues — not a type split. Labels, exactly these keys:

Label Values Required
channel: blog · site · instagram always
locale: BCP-47 lower-case, e.g. en, de, fr always
tenant: tenant slug, e.g. meetly always
hub: hub slug from the audience doc, e.g. private-transcription blog
kind: new · refresh blog, site
lane: blog · instagram · site · backlog · brief · aeo-seo · performance channel parents and standing issues only
stage: idea · topic Backlog children only
gate: artifact · final · none (harness) always
brief:daily the Daily Brief issue only

A locale variant is its own Issue, a child of the EN master Issue (parent_id = the master, not the channel parent), blocked_by the master, carrying the same hub:/kind: labels plus relates:<master> for search. Title format: <Channel>: <title> (<locale>). The owner reviews one blog Issue and finds its languages underneath it.

Hierarchy

<Brand> Blog (epic, tenant:<slug>)
├── Blog / Instagram / Site   lane:<channel>  — every piece of that channel is a child
├── Backlog                   lane:backlog    — stage:idea and stage:topic children; done stays
├── Daily Brief · AEO/SEO Health · Performance Report   standing issues
└── Map + spec review         gate:plan

list_issues {parent_id} returns direct children only, so pieces are looked up through their channel parent — list_issues {parent_id: <Blog parent>, label: "channel:blog", …} — never through the epic. Resolve the parent once per run with list_issues {parent_id: <epic>, label: "lane:<channel>"} or read its id from the epic's ## Structure; verify with get_issue before writing under it. A piece's parent is its channel parent and the parent's parent is the Epic that carries the brand documents. A Backlog child graduates by being marked done with a Graduated → <ticket> comment and a relates link to the new publish issue; it is never deleted or re-parented.

4. Checker gate — maker → blog-checker → human

No draft reaches the owner unchecked. Before any request_review on a content Issue, the Issue must carry, attached or in its latest update:

  1. the draft text (attach_artifact, docKind: "deliverable", markdown) — this is the copy the owner leaves inline comments on; draft for intermediates;
  2. the checker verdict — the blog-checker pass (facts against the brief, claims policy, voice adjectives, locale, structured data, links) with pass/fail per check and what the maker changed in response;
  3. the final rendered preview — one self-contained HTML artifact (docKind: "preview") the owner clicks open to see the piece as it will publish: for a blog the Blog MCP preview_render of the final draft in the tenant's design tokens (title Preview — <title>); for an Instagram carousel the one-file Instagram-style viewer from instagram-drafter/templates/instagram-preview.html that swipes through the slide assets by URL (title Preview — <title> (Instagram)). Never one artifact per slide, never a screenshot of the page instead of the page. Put the artifact url in the review request reason;
  4. the models used (maker, checker) in the update body and workStats.

Then update_issues {ids: [id], state: "in_review"} and request_review {parent_id: id, reason}, then wait on get_changes. Never assume approval. The maker and the checker must not be the same session prompt; a checker run is a separate call with the brief and the draft as its only inputs.

5. Publish gate

6. Keys — names and scope only

Ask for key names and where they are kept; never a value, never "paste it here". If a value appears in chat, do not store, echo or use it — say so, name the key, and ask the user to put it in their host's secret store.

Key name Scope Needed for
OPENROUTER_API_KEY model calls, drafter / checker any tier that drafts headlessly
POSTIZ_API_KEY schedule Instagram posts Instagram publishing (Claude Code / Codex only)
BLOG_ACCESS_KEY Blog MCP bearer, headless routines Hosted tier routines
GA4_MEASUREMENT_ID BYO analytics (not a secret, still by name) Hosted tier

Interactive hosts authenticate to the Blog MCP with OAuth — no key needed.

7. Daily brief first

Any recurring workflow installs the daily-brief skill and its routine before any drafter, publisher or assessment routine, posting to the tenant epic's Daily Brief issue (brief:daily, lane:brief). A missing brief is the outage alert; there is no server-side fallback by design. Routine order: daily brief → drafter → publisher → assessment.

8. Graceful degradation by host

Discover, do not assume: the Blog MCP's own get_capabilities, and what this host can run. If a Blog MCP tool the skill names is absent from get_capabilities.tools, say "not available yet on this server", attach the payload you would have sent as a document on the issue, and continue.

Capability Claude Code / Codex / Cursor claude.ai ChatGPT
Interview, chart, documents, review gates yes yes yes
Fetch site / competitors / owner posts yes yes (web) yes (browse)
Write skill files (start_context agent_install plan) yes no → human_upload + inlined guide no → human_upload + inlined guide
Install routines (launchd / cron) yes no → Claude scheduled prompt, or hand the owner the routine text no → ChatGPT scheduled prompt
Rendered preview attached HTML via attach_artifact HTML via attach_artifact preview.html via attach_artifact (no binary upload)
Blog MCP content tools (Hosted) OAuth OAuth OAuth
Instagram publishing (POSTIZ_API_KEY) yes no → owner self-publishes no → owner self-publishes
AI-visibility probe yes no no
Wait for approval get_changes long poll bounded get_issue polling bounded get_issue polling, then tell the user where to approve

9. Safety and scope

Quick reference

Moment Call
Session start Context start_context · Blog MCP usage_guide · Blog MCP get_capabilities
New piece create_issues {parent_id: <channel parent>, issues: [{title, labels: [channel, locale, tenant, hub, kind, gate], due}]}
Checker done attach_artifact draft + verdict + preview → update_issues {state: "in_review"}request_review
Approved publish {context_issue_id} at duepost_comment {body: live URL}complete_issues
Daily daily-brief on the Daily Brief issue

Changelog