skills/writing-setup/SKILL.md
Internal skill for creating PRECIS.md, OUTLINE.md, and ACTIVE_WORKFLOW.md. Called after brainstorm sources are gathered.
npx skillsauth add edwinhu/workflows writing-setupInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Create the project foundation: PRECIS.md (thesis, audience, claims), OUTLINE.md (document structure), and ACTIVE_WORKFLOW.md (state tracking).
Prerequisites: Brainstorm and lit review complete. User has confirmed topic, angle, and audience. Sources materialized in references/ (PDFs + markdown).
Before starting, check for an existing handoff:
.planning/HANDOFF.md existsAuto-load all constraints matching applies-to: writing-setup:
!uv run python3 ${CLAUDE_SKILL_DIR}/../../scripts/load-constraints.py writing-setup
You MUST have these constraints loaded before proceeding. No claiming you "remember" them.
START (brainstorm confirmed)
│
├─ Step 1: Create project directories
│ └─ mkdir outlines/ drafts/ references/ scratch/ .planning/
│
├─ Step 2: Interview → Create PRECIS.md
│ ├─ Ask thesis question
│ ├─ Ask counterargument question
│ └─ Write .planning/PRECIS.md (thesis, claims, audience, scope)
│
├─ Step 2b: PRECIS Review Gate
│ └─ Dispatch writing-precis-reviewer subagent
│ ├─ APPROVED → proceed to Step 3
│ └─ ISSUES_FOUND → fix PRECIS.md → re-dispatch (max 5)
│
├─ Step 3: Create OUTLINE.md
│ ├─ Step 3a: Load the DOMAIN structure template FIRST (writing-{domain} → its
│ │ document-structure section; domain is already pinned in PRECIS Step 2)
│ └─ Map sections → claims from PRECIS, CONFORMING to that structure template
│ Each section has: Goal, Claim, Key Points, Transition
│
├─ Step 4: Confirm domain (already pinned in PRECIS; do NOT re-detect after the outline)
│
├─ Step 5: Create ACTIVE_WORKFLOW.md
│
└─ GATE: All 3 files exist with required content?
├─ NO → Report missing content, fix before proceeding
└─ YES → IMMEDIATELY load writing-outline (no pause)
If text and flowchart disagree, the flowchart wins.
<EXTREMELY-IMPORTANT> ## The Iron Law of Progressive ExpansionNO OUTLINE WITHOUT PRECIS. NO DRAFTING WITHOUT OUTLINE. This is not negotiable.
The levels are:
Skipping levels produces incoherent documents. Each level expands the previous. </EXTREMELY-IMPORTANT>
mkdir -p outlines drafts references scratch .planning
echo "scratch/" >> .gitignore
touch references/sources.bib
# Seed the append-only decision log (standard state file — see writing-learnings-log.md)
[ -f .planning/LEARNINGS.md ] || printf '# Learnings — decision log\n\nAppend-only. One terse dated bullet per notable decision (angle, rejected framings, R4 restructurings, accepted gaps). Never rewrite.\n\n' > .planning/LEARNINGS.md
After writing PRECIS.md, append the scope decisions (claims cut, In/Out boundary) to .planning/LEARNINGS.md — these are the choices a resuming session cannot reconstruct from PRECIS alone.
The references/sources.bib file is the single source of truth for every
citation. Drafts use pandoc cite-keys ([@authorYEAR]) and pandoc-citeproc
renders them in Bluebook style (via the CSL configured in ACTIVE_WORKFLOW.md).
Populate the .bib during brainstorm/research — see
sources_md_to_bib.py in this skill's scripts/ directory if you have an
existing sources.md to convert.
Use AskUserQuestion to gather remaining details:
AskUserQuestion(questions=[
{
"question": "What is your thesis in one sentence?",
"header": "Thesis",
"options": [
{"label": "I have a thesis", "description": "I will type it"},
{"label": "Help me find it", "description": "Synthesize from sources"},
{"label": "Critique: X is wrong", "description": "Argue against existing view"},
{"label": "Propose: X should change", "description": "Recommend reform"}
],
"multiSelect": false
},
{
"question": "What is the strongest objection to your thesis?",
"header": "Counter",
"options": [
{"label": "I know it", "description": "I will describe the objection"},
{"label": "Find from sources", "description": "What do critics say?"},
{"label": "Steel-man for me", "description": "Generate the best counter"}
],
"multiSelect": false
}
])
Write to .planning/PRECIS.md:
# Precis: [Working Title]
## Thesis
[One sentence - the core argument]
## Audience
[From earlier interview - who is reading, what they know/believe]
## Purpose
[What reader should think/do/believe after reading]
## Hook
[Concrete problem, controversy, or question that opens the piece - draft or TBD]
## Key Claims
- **CLAIM-01**: [Claim 1] → supports thesis by...
- **CLAIM-02**: [Claim 2] → supports thesis by...
- **CLAIM-03**: [Claim 3] → supports thesis by...
## Counterarguments to Address
1. **[Objection]**: [description]
- Response: [how we will address it]
- Section: [where it appears]
## Scope
### In
- [What we cover]
### Out
- [What we explicitly exclude and why]
## Domain
[legal | econ | general] → determines which writing skill to use
After writing PRECIS.md, dispatch the precis reviewer BEFORE creating the outline. Do NOT skip this step.
Read ${CLAUDE_SKILL_DIR}/../../skills/writing-precis-reviewer/SKILL.md and follow its instructions.
Follow the reviewer skill instructions: dispatch the subagent, handle APPROVED/ISSUES_FOUND, fix and re-review up to 5 times. Only proceed to Step 3 when the reviewer returns APPROVED.
Structure the argument with sections mapped to claims from PRECIS.md.
<EXTREMELY-IMPORTANT> ### Step 3a: Load the domain's document-structure template FIRST (before building structure)NO MASTER OUTLINE WITHOUT THE DOMAIN STRUCTURE TEMPLATE IN CONTEXT. This is not negotiable.
The master ## Structure you build here commits the article's section flow — and the canonical
flow lives in the domain skill, not this skill. Building the outline before reading it means
the structure is set one-to-two phases before its own template is ever in context (the
phase-ordering defect: the domain was only loaded at draft/review). The ## Domain field is
already pinned in PRECIS.md (Step 2), so read the matching domain skill's structure section NOW:
| Domain (from PRECIS) | Read this structure section |
|---|---|
| legal | ${CLAUDE_SKILL_DIR}/../../skills/writing-legal/SKILL.md → "Law Review Article Structure" (Introduction → Background → Proof of the Claim → Conclusion) |
| econ | ${CLAUDE_SKILL_DIR}/../../skills/writing-econ/SKILL.md → its document-structure section (hook-with-finding → … → conclusion) |
| general | ${CLAUDE_SKILL_DIR}/../../skills/writing-general/SKILL.md → its structure guidance |
Build the master ## Structure so its sections CONFORM to that template. For style: legal,
SEED THE CANONICAL THREE-PART BODY by default — start at three, always:
### Introduction### Part I. Background — descriptive: the law / doctrine / facts the argument needs### Part II. The Argument — analytical: the proof, counterarguments FOLDED IN (not a separate Part)### Part III. The Prescription — normative: the reform / fix### ConclusionDo NOT open by decomposing the body into 4–5 Parts (e.g. splitting the Proof into two Parts, or breaking counterarguments out as their own Part). Splitting a Part is an EXCEPTION that requires the Part to be demonstrably too large to hold together — it is never the starting decomposition. Begin three-part; if a Part later proves unwieldy, splitting it is an R4 decision logged in LEARNINGS.md. Any deviation from the canonical flow is likewise R4 — note it, don't drift silently.
scripts/writing/writing_section_index.py parses OUTLINE.md to build the section set the
draft and review engines run on (and writing-outline-executable-guard.py gates approval on
it). Two blocks are load-bearing and must be emitted in this exact shape — get them right
here and the outline is born-canonical (the guard goes strict; nothing relies on tolerant
regex papering over drift):
## Structure — one ### <Section Name> per section, IN DOCUMENT ORDER. The heading
text MUST equal the section's outline/draft filename stem (the parser pairs
### Part I. Foo ⇄ outlines/Part I. Foo.md ⇄ drafts/Part I. Foo (Draft).md). Do NOT
prefix with bare roman numerals like ### I. Introduction unless the files are named that
way — use the real section names (### Introduction, ### Part I. <Name>, ### Conclusion).## Claim → Section Map — the CANONICAL claim→section assignment (the spec the ⊇ gate
reads). Each claim has ONE primary home (a section, by Part numeral II.A or section
name); Intro/Conclusion are echo-only. A section's draft must implements: ⊇ the claims
primary-homed to it.
</EXTREMELY-IMPORTANT>
# Outline: [Title from PRECIS]
## Structure
### Introduction
- **Goal**: Hook reader, state thesis, roadmap
- **Thesis**: [from PRECIS]
- **Claims preview**: CLAIM-01 → CLAIM-0N
### Part I. [Section Name]
- **Goal**: [what this section accomplishes]
- **Implements**: [CLAIM-01, CLAIM-02 — the claims primary-homed here, from the map below]
- **Key points**:
- Point A — [@bibkey or specific authority] (pin a real source per substantive claim)
- Point B — [@bibkey]
- **Transition to next**: [how it leads to the next section]
### Part II. [Section Name]
- **Goal**: [what this section accomplishes]
- **Implements**: [CLAIM-XX]
- **Key points**:
- [points, each with a pinned source]
### Conclusion
- **Goal**: Restate thesis with earned authority; synthesize CLAIM-01 … CLAIM-0N
- **Implications**: What follows from this argument
## Claim → Section Map
| Claim | Primary home | Setup / echo |
|-------|--------------|--------------|
| CLAIM-01 ([gloss]) | Part I.A | Introduction |
| CLAIM-02 ([gloss]) | Part II.A | Part I.B |
| CLAIM-0N ([gloss]) | Part II.B | Conclusion |
## Key Sources
[Deduplicated from search phase]
## Open Questions
[Gaps to address before drafting]
The domain is set in PRECIS.md's ## Domain (Step 2) and was used to load the structure template
in Step 3a — it must be known BEFORE the outline, not detected after it. Here, just confirm the
PRECIS domain matches the source/topic indicators and record it for ACTIVE_WORKFLOW.md. If the
indicators contradict the PRECIS domain, that is a Step-2 error — fix PRECIS and re-run Step 3a, do
not silently proceed with an outline built against the wrong structure template.
| Domain Indicators | Style | Skill | |---|---|---| | Legal cases, statutes, law reviews, constitutional | legal | writing-legal | | Economics, markets, policy, data, empirical | econ | writing-econ | | General/other | general | writing-general |
Create .planning/ACTIVE_WORKFLOW.md to track workflow state:
---
workflow: writing
style: [legal|econ|general]
phase: outline
project_root: [current directory]
bibliography: references/sources.bib
precis: .planning/PRECIS.md
outline: .planning/OUTLINE.md
current_part: [if multi-part document]
edits_since_verify: 0
verify_threshold: 10
skill_stack:
- writing
- writing-[domain]
# Optional — set if the project has an NLM notebook populated with source PDFs
# titled by their bibkeys. Enables the cite-fidelity pipeline.
nlm_notebook: [UUID or omit if no notebook]
nlm_url: [https://notebooklm.google.com/notebook/UUID or omit]
---
If nlm_notebook is populated and the notebook already contains the project
sources titled by their bibkeys, build the source inventory now so drafting
can disambiguate same-author works:
uv run ${CLAUDE_SKILL_DIR}/../../scripts/cite-fidelity/nlm_source_inventory.py
This writes references/source_summaries.md — a per-bibkey thesis,
supports, and does-not-support summary keyed by NLM LAST UPDATED
timestamp. The script is idempotent and safe to re-run after any source
update. See references/constraints/cite-fidelity-source-inventory.md for
when to run it and when to skip.
Skip this step if: the project has no NLM notebook, or the notebook is empty / sources aren't yet titled by bibkey.
Writing project initialized.
Project: [directory name]
Style: [legal/econ/general]
Phase: outline
Files created:
- .planning/PRECIS.md (thesis, audience, claims)
- .planning/OUTLINE.md (structure)
- .planning/ACTIVE_WORKFLOW.md (workflow state)
Next: Create detailed section outlines.
Before proceeding to outline phase (see constraints/gate-function-standard.md for the full 6-step gate including SUMMARY):
.planning/PRECIS.md exists with thesis, claims, audience.planning/OUTLINE.md exists with sections mapped to claims.planning/ACTIVE_WORKFLOW.md exists with style and phaseworkflow: writing and valid style:human-verify — auto-advance to writing-outline..planning/PHASE_SUMMARY.md (see constraints/phase-summary-frontmatter.md):
Skipping PRECIS verification is NOT HELPFUL — the user builds an entire document on a vague thesis that collapses under scrutiny. A vague thesis is not a thesis. Placeholder claims are not claims.
After setup is complete, IMMEDIATELY proceed to the outline phase. Do NOT pause to ask the user. Do NOT summarize what you just created. Load the next skill and continue:
Read ${CLAUDE_SKILL_DIR}/../../skills/writing-outline/SKILL.md and follow its instructions.
Then follow its instructions immediately to create detailed section outlines.
development
Build the meeting-level proxy-voting × ownership panel on the WRDS SGE grid — ISS N-PX fund votes reduced to (item × block) direction cells, joined to institutional and mutual-fund ownership. Use when working with risk.voteanalysis_npx, N-PX fund-level votes, ISS→CRSP fund linking, index/passive/active voting blocks, or a proxy-voting panel that needs ownership attached.
development
Use when "CRSP CIZ", "CRSP v2", "CRSP flat file format 2.0", "crsp.dsf_v2 / msf_v2", "StkDlySecurityData", "StkMthSecurityData", "StkSecurityInfoHist", "stocknames_v2", "DlyRet / MthRet / DlyPrc / MthPrc", "SHRCD or EXCHCD equivalent in new CRSP", "SIZ to CIZ migration", "CRSP data after 2024", "CRSP delisting returns", "CRSP cumulative adjustment factors", "CRSP index INDNO / INDFAM", or any CRSP stock/index query where the legacy SIZ column names no longer exist.
development
Use when linking or deduping datasets by entity name rather than a shared key — 'fuzzy match', 'fuzzy name matching', 'entity resolution', 'record linkage', 'match company/person names', 'dedupe entity names', 'name-based join', 'bridge identifiers' (CIK ↔ permno ↔ gvkey ↔ wficn ↔ EIN ↔ personid), or any use of char n-gram TF-IDF, cosine similarity on names, `sparse_dot_topn`, or RapidFuzz at scale.
development
Use when building a publication-quality table in Python — 'regression table', 'results table', 'summary statistics table', 'etable', 'coefplot', 'great_tables', 'GT', 'gt table', 'format a table for the paper', 'export table to LaTeX/HTML', significance stars, spanners, or column formatting for a table headed into a paper, slide deck, or notebook.