Brief Gate
The brief is the contract between research and drafting. SCS stores it as article Markdown with compact YAML front matter and fixed H2 sections. The CSV is the index and gate record; the Markdown body is the writing spec and, later, the article draft.
Why Markdown, not YAML or CSV
- Long prose, competitor matrices, source tables, and link plans do not fit CSV.
- YAML is fragile for AI-generated prose and unpleasant to review in nvim.
- Markdown gives you readable diffs, nvim editing, and a stable structure for
scs brief --check.
Files
data/<workspace>/md/<pid>--<slug>.md # brief and article in one Markdown file
data/<workspace>/<workspace>-briefs.csv # index and gate fields
The file has two halves:
<!-- scs:brief -->
## 1. Decision
...
## 10. QA handoff
...
<!-- scs:article -->
# Article title
scs brief --checkvalidates only the brief half.scs publishsends only the article half.- Files without markers keep the legacy behaviour (whole body used for both).
briefs.csv owns workflow fields such as brief_status, brief_depth,
brief_path, and article_path. Because the brief and the article share one
file, brief_path and article_path point to the same Markdown file. Compact
writer context belongs in front matter; the outline and detailed prose/research
belong in the Markdown body and research workspace, not in the CSV or front
matter.
The Markdown body owns the prose and tables: the decision rationale, SERP snapshot, H2 matrix, differentiation, outline, sources, internal links, QA handoff, and eventually the article itself.
Render
scs brief --workspace bs --pid FS-0001
This creates/updates the briefs.csv row if needed, renders front matter into
the article Markdown, and seeds the body from the template when it is empty.
Running it again updates generated front matter and preserves the existing
body.
Minimum required data for the first render:
- an existing workspace
- a
keywords.csvrow for that PID with at leastpid,title(orkeyword), andsite_id
Optional matching rows in clusters.csv, publishing.csv, and links.csv
enrich the generated front matter; missing rows render as empty/null fields.
Depth levels
| Cluster role | brief_depth | Required sections |
|---|---|---|
| Topic / Pillar Page | full | 1–10 |
| Keyword Cluster | standard | 1–8 + 10 |
| Sub Topic / Supporting | light | 1–5 + 7 + 8 |
brief_depth is set from the cluster kc_type when the row is created and can
be overridden in briefs.csv.
Template sections
## 1. Decision
## 2. Audience
## 3. SERP snapshot
### H2 matrix
### Gaps
## 4. Differentiation
## 5. Structure
### H2/H3 outline
## 6. Evidence & sources
## 7. Internal links
## 8. Conversion
## 9. Generation notes
## 10. QA handoff
Use - H2: ... lines in the outline. scs brief --check counts them.
Check
scs brief --workspace bs --pid FS-0001 --check
The check fails when:
keywords.csvdecisionis notgo.- A required section is missing, empty, or too thin.
- A standard/full brief has fewer than 3 competitor URLs or 2 source URLs.
- The outline has fewer than 4 H2 lines for standard/full, or 2 for light.
- An H2 is outside 3–12 words or uses a vague title such as “Overview” or “Conclusion”.
- The brief still contains
TODO,TBD,[insert,[fill, orlorem ipsum. - There is no
links.csvrow and section 7 does not saynone.
These are structural and workflow checks. Competitor/source URL counts and H2 counts do not measure research quality or editorial usefulness. A passing check does not establish that sources support claims, the page is differentiated, or the outline satisfies reader needs; the approver must review those judgments.
Approve
scs brief --workspace bs --pid FS-0001 --approve
Approval only succeeds after a passing check. It sets
briefs.csv brief_status=Approved and moves a Selected keyword to Briefed.
Edit workflow fields in briefs.csv with VisiData. Edit writer context in the
article front matter and outline/prose in its Markdown body with nvim/opencode.
Re-run scs brief after changing CSV-owned values so generated front matter
stays in sync.
Front matter
Public CMS fields appear at the top level; SCS-specific context is nested under
scs. The compact structure is:
title: "Article title"
description: null
category: "Investing"
tags:
- "balance sheet"
content_type: "reference"
status: "Draft"
date: null
slug: null
scs:
schema: scs-content/v3
identity:
pid: "FS-0001"
site_id: "fundamentalstock"
writing:
audience: "Beginner investors"
intent: "Informational"
primary_keyword: "balance sheet"
supporting_keywords: []
angle: "A practical reading method"
differentiation: "Use a worked example"
target_words: 1800
tone: "Clear and practical"
author_role: "Practitioner"
entities_to_cover:
- "assets"
- "liabilities"
questions_to_answer: []
links:
internal: []
editorial:
reviewer: null
review_due: null
disclosure: null
research:
path: "data/<workspace>/research/FS-0001/"
status: "needs_review"
Top-level description and slug come from publishing.csv fields
meta_description and slug. title uses the article title; meta_title is
not currently emitted as a separate field. Multi-value fields render as YAML
lists. Detailed SERP evidence, metrics, and performance history stay in
CSV/research files. The outline stays in the Markdown body, under the Structure
section. Rendering regenerates front matter while preserving the authored body.