skills/writing-validate/SKILL.md
Validate draft sections cover all PRECIS claims before review.
npx skillsauth add edwinhu/workflows writing-validateInstall 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.
Announce: "Using writing-validate (Phase 3.5) to validate draft sections against PRECIS.md claims."
Phase between draft and review. Maps every PRECIS.md claim to a draft section and verifies coverage. This is the writing equivalent of DS's DQ validation — without it, review checks quality on prose that may not even address the argument.
<EXTREMELY-IMPORTANT> ## The Iron Law of ValidationNO REVIEW WITHOUT CLAIM VALIDATION. This is not negotiable.
writing-review MUST NOT start until .planning/VALIDATION.md confirms all PRECIS claims are addressed in drafts. Validation is the writing equivalent of test coverage — without it, review is theater.
</EXTREMELY-IMPORTANT>
This phase sits between writing-draft and writing-review. It runs the same constraint checks that review uses — from the writing constraints, the domain skill, and ai-anti-patterns — but earlier, so gaps are caught before review begins. Review should NOT be discovering missing claims, broken expansion hierarchy, or AI writing smell.
The constraint checks ARE the validation. This phase doesn't invent new checks — it systematically runs the existing ones against every draft section.
Auto-load all constraints matching applies-to: writing-validate:
!uv run python3 ${CLAUDE_SKILL_DIR}/../../scripts/load-constraints.py writing-validate
You MUST have these constraints loaded before proceeding. No claiming you "remember" them.
Load and run checks from three sources:
Run these checks from the constraint files:
| Check | From Constraint | What to Verify | |-------|----------------|----------------| | Progressive Expansion | Expansion Hierarchy | Every PRECIS claim → OUTLINE section → outlines/ file → drafts/ file. No gaps in the chain. | | Claim Coverage | NO DRAFT WITHOUT OUTLINE | Every PRECIS claim has a corresponding draft section that argues it (not just mentions it) | | Thesis Threading | Structural intent | Each draft section connects back to the PRECIS thesis. No tangential sections. | | Constraint Loading | Constraint Loading Protocol | Domain skill + ai-anti-patterns were loaded before drafting (check for violations in prose) |
Read .planning/ACTIVE_WORKFLOW.md for the style field, then load the matching domain skill:
| Style | Skill to Load |
|-------|--------------|
| legal | skills/writing-legal/SKILL.md |
| econ | skills/writing-econ/SKILL.md |
| general | skills/writing-general/SKILL.md |
Run domain-specific checks against each draft section (citation format, style compliance, terminology).
Invoke Skill(skill="workflows:ai-anti-patterns") and check each draft section for AI writing indicators.
┌────────────────────────────┐
│ LOAD constraint checks │
│ (constraints + domain + │
│ ai-anti-patterns) │
└────────────┬───────────────┘
│
▼
┌────────────────────────────┐
│ READ .planning/PRECIS.md │
│ Extract all CLAIM-XX IDs │
└────────────┬───────────────┘
│
▼
┌────────────────────────────┐
│ READ .planning/OUTLINE.md │
│ Map claims → sections │
└────────────┬───────────────┘
│
▼
┌────────────────────────────┐
│ For each claim: │
│ READ drafts/ file │◄──┐
│ RUN all constraint checks │ │
│ CLASSIFY: COVERED / │ │
│ PARTIAL / MISSING │ │
└────────────┬───────────────┘ │
│ │
│ more claims │
└───────────────────┘
│ all claims checked
▼
┌────────────────────────────┐
│ Run check-all.sh │
│ (mechanical constraint │
│ checks — hard block) │
└────────────┬───────────────┘
│
▼
┌────────────────────────────┐
│ WRITE .planning/ │
│ VALIDATION.md │
└────────────┬───────────────┘
│
┌────┴────┐
│ status? │
└────┬────┘
┌───────┴───────┐
▼ ▼
validated gaps_found
│ │
▼ ▼
→ review Present to user
│
┌──────┴──────┐
▼ ▼
fix (→draft) accept (→review)
Load all three check sources before reading any drafts. This ensures every section is evaluated against the same criteria.
Read .planning/PRECIS.md and extract every claim:
Read .planning/OUTLINE.md and map each claim to sections:
For each claim, read the corresponding draft file and run ALL constraint checks:
| Check | PASS | FAIL |
|-------|------|------|
| Draft exists | File in drafts/ present | MISSING — no draft for this claim |
| Substantive | >200 words, real argument | Placeholder, stub, or outline-level content |
| Evidence | Citations/sources present per claim | Unsupported assertions |
| Thesis threading | Section argues the PRECIS claim | Tangent — section exists but doesn't address the claim |
| Domain compliance | Passes domain skill checks | Style violations (citation format, terminology, etc.) |
| AI anti-patterns | No AI writing indicators | AI smell detected |
| Classification | Criteria | |---------------|----------| | COVERED | All checks pass — section exists, argues the claim, has evidence, passes domain + AI checks | | PARTIAL | Section exists but fails one or more checks (weak evidence, AI smell, domain violation, tangent) | | MISSING | No draft section addresses this claim |
Run the constraint test suite as the first leg of two-legged verification:
bash ${CLAUDE_SKILL_DIR}/../../scripts/check-all.sh
This runs all constraint check scripts (progressive-expansion, claim-id-traceability, flowchart-authority, no-pause-between-phases). Any failure is a hard block — fix before proceeding to Step 6.
The second leg (convention scoring via judgment) happens in Steps 4-5 above and in the writing-review phase.
When gaps are found, present them with the specific check that failed:
Only the user can decide whether a gap means the claim should be rewritten, dropped, or restructured. </EXTREMELY-IMPORTANT>
Compile all results into .planning/VALIDATION.md using the template below.
---
status: validated | gaps_found
date: [ISO 8601]
claims_total: N
covered: N
partial: N
missing: N
---
# Claim Validation
## Claims Map
| # | PRECIS Claim | Draft Section | Exists | Substantive | Evidence | Threading | Domain | AI Check | Classification |
|---|-------------|---------------|--------|-------------|----------|-----------|--------|----------|----------------|
| 1 | [from PRECIS] | [drafts/Section.md] | PASS | PASS | PASS | PASS | PASS | PASS | COVERED |
| 2 | [from PRECIS] | [drafts/Section.md] | PASS | PASS | WARN | PASS | PASS | WARN | PARTIAL |
| 3 | [from PRECIS] | — | FAIL | — | — | — | — | — | MISSING |
## Gap Details
[For any PARTIAL or MISSING claim, include:
- Which constraint check failed
- The specific finding
- Suggested remediation (for user decision)]
## Summary
- Claims: N total
- Covered: X
- Partial: Y
- Missing: Z
| Condition | Status |
|-----------|--------|
| All claims COVERED | validated |
| Any PARTIAL or MISSING remain | gaps_found |
.planning/VALIDATION.md must exist before proceeding.
validated: proceed to writing-review. Gate type: human-verify — auto-advance.gaps_found: present gaps to user before proceeding. Gate type: decision — wait for user.
SUMMARY: Append phase summary to .planning/PHASE_SUMMARY.md (see constraints/phase-summary-frontmatter.md):
Gaps in claim coverage are not cosmetic — they mean the argument has holes. Only the user can decide whether a gap is acceptable or requires returning to the draft phase. </EXTREMELY-IMPORTANT>
When validation finds gaps (status: gaps_found), present a claim coverage summary table to help the user decide:
## Claim Coverage Summary
| Claim | Section | Status | Issue |
|-------|---------|--------|-------|
| CLAIM-01 | Part I | COVERED | — |
| CLAIM-02 | Part II | PARTIAL | Weak evidence (domain check failed) |
| CLAIM-03 | — | MISSING | No draft section addresses this claim |
Coverage: 1/3 COVERED, 1/3 PARTIAL, 1/3 MISSING
This table is generated from VALIDATION.md and presented inline. No separate script needed unless the user asks for the same view 3+ times.
Observe → record → offer: record in .planning/LEARNINGS.md what the user attends to here (e.g., "user re-checked CLAIM-02 evidence"). Only after the same view is requested 3+ times, offer (do not impose) to script it — e.g., a coverage heatmap. Text is the default; visual output is never a hard requirement. See references/constraints/writing-learnings-log.md.
After validation is complete, discover and read the writing-review skill:
Read ${CLAUDE_SKILL_DIR}/../../skills/writing-review/SKILL.md and follow its instructions.
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.