Skip to content
Back to skills

Extract Corpus

ASecurity

Extract a writer's full published corpus from a Substack newsletter (vanilla or custom-domain) given only its URL — the complete archive at full fidelity, cleaned, segmented, and fidelity-tagged, with a coverage manifest. This is step 3 (Ingest) of the Context Kit. Use whenever someone wants to build AI context from a Substack newsletter, "load my newsletter," "pull my archive," or onboard a writer's body of work. v1 supports free Substack only; paid posts return previews.

  • 2 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 27, 2026
ai-agentspythongobashapi

Works with

  • api

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned September 27, 2026

npx -y skills add Artifacts7/newsletter-context-kit --skill extract-corpus --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Extract Corpus?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Extract Corpus
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/artifacts7-extract-corpus/badge)](https://www.skillsdirectory.com/skills/artifacts7-extract-corpus)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: extract-corpus
description: >
  Extract a writer's full published corpus from a Substack newsletter (vanilla or
  custom-domain) given only its URL — the complete archive at full fidelity, cleaned,
  segmented, and fidelity-tagged, with a coverage manifest. This is step 3 (Ingest)
  of the Context Kit. Use whenever someone wants to build AI context from a Substack
  newsletter, "load my newsletter," "pull my archive," or onboard a writer's body of
  work. v1 supports free Substack only; paid posts return previews.
allowed-tools: Bash(python3 *)
---

# Extract Corpus (Substack, v1)

Turns a Substack URL into a clean, full-fidelity corpus — the foundation every later
step (subject, voice, brief) depends on. White-labeled: no publication-specific
assumptions; works for any free Substack.

## When to use
- **The last step of Phase A** — "the agent reads it all." This is the heavy read.
- Refreshing a corpus with new issues (the Compound step).
- Any "load / pull / ingest my Substack archive" request.

## Precondition (don't fetch too early)
Run this **only after** the writer has gone through onboarding (0 — where work lives),
describe (1 — `newsletter-context/seed-context.md`), and stated identity (2 — `newsletter-context/identity-stated.md`). The
full corpus is the heaviest, last-loaded context (progressive loading, D8): pulling it
before the writer has said how they see their newsletter inverts the intended order.
If those earlier artifacts don't exist yet, do those first.

## How to run

**Default: fetch the 25 most recent issues** — that's the strongest signal for voice/identity and keeps token use sane. First check the archive size, then **ask the writer** before going bigger:

> "Your archive has ~N issues. I'll read the **most recent 25** by default — that's plenty for a sharp read and keeps it fast/cheap. Want me to pull the **full archive** instead? (more complete, but noticeably more tokens and time.)"

```
# default
python3 ${CLAUDE_SKILL_DIR}/substack_fetch.py <publication-url> ./newsletter-context/corpus --limit 25 [--appendix-markers "a,b,c"]
# only if the writer opts in to the full archive
python3 ${CLAUDE_SKILL_DIR}/substack_fetch.py <publication-url> ./newsletter-context/corpus
```
Custom domains work the same (`https://www.example.com`). Everything lands in **`./newsletter-context/`** (the kit's convention).

`${CLAUDE_SKILL_DIR}` resolves when installed as a plugin. **If running from a cloned repo** (the paste-the-link path), use the script's path in the clone instead — e.g. `skills/extract-corpus/substack_fetch.py`.

## Procedure (what the agent does)

1. **Acquire.** Run the fetcher on the URL. It paginates the archive API and pulls
   each free post's full body. Report the manifest: total posts, date range,
   full-prose vs. preview/short counts, any errors.
2. **Surface era/language splits.** Scan dates + language of the manifest/titles.
   If the archive spans languages or a clear style era (common in long-running
   newsletters), FLAG it — voice/identity must not be averaged across phases. Default
   downstream work to the current-language, recent era; treat older eras as history.
3. **Detect appendix sections (segmentation).** Read 2–3 recent issues. If the writer
   has recurring trailing sections (link roundups, book lists, footers), identify their
   headers and re-run with `--appendix-markers "..."` so those zones are split out of
   the essay body (they carry curation signal, not voice — D14). If none, skip — the
   tool safely keeps the whole essay in body.
4. **Report scope honestly.** State coverage (e.g. "78/80 full-prose, 2 paid/preview"),
   what was excluded, and any non-Substack/paywall limits hit.

## Output
- `<output-dir>/<slug>.md` — per issue: metadata + `## BODY` (essay) + `## APPENDICES`.
- `<output-dir>/manifest.json` — coverage, dates, fidelity per issue, sampled count.

Hand the corpus to the distillation steps (subject → reconcile → brief; then voice).

## Limits (v1)
- **Free Substack only.** Non-Substack URLs exit cleanly with a message. Paid posts → preview only (need the owner's Settings → Export).
- **Appendix markers are per-newsletter** — detected in step 3, not hardcoded.
- Rate-limited APIs handled via exponential backoff; very large archives take a few minutes.

_Validated across 4 publications (Artifacts, Astral Codex Ten, Gary Marcus, + graceful
fail on non-Substack)._

---
_**Language:** if the newsletter isn't in English, converse with the writer — and write outputs — in the newsletter's language._

Files in this skill

  • SKILL.md4.5 KB
  • substack_fetch.py5.8 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.