Six-skill presentation system: ingest talks into a rhetoric vault, run interactive clarification, generate a speaker profile, create presentations that match your documented patterns, produce the deck illustrations + thumbnail visual layer, and publish talk pages to a Jekyll shownotes site. Includes a 111-entry Presentation Patterns taxonomy (81 observable: 62 patterns + 19 antipatterns; 30 unobservable: 21 patterns + 9 antipatterns) for scoring, brainstorming, and go-live preparation.
—
—
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Low
Low-risk findings worth noting
Reference for Step 7 (thumbnail) in SKILL.md. The
thumbnail-generation-rules steering rule is auto-loaded — apply it, don't
restate it.
Before any thumbnail work, confirm the inputs:
speaker-profile.json — publishing_process.thumbnail config and
visual_style_history.secrets.json — Gemini API key.presentation-spec.md — talk slug, metadata.outline.yaml — slide references; the
style_anchor block (if present) feeds --portrait-style.config.python_path for the
mutation in Sub-step 10. Missing or invalid config stops this flow and invokes
Skill(skill: "vault-ingress") at Step 1.Set host_python to the current host's explicit absolute interpreter path (not
a PATH lookup). The sole interpreter-bootstrap exception is one stdlib-only
owner read:
"{host_python}" "{speaker_toolkit_root}/skills/vault-ingress/scripts/read-tracking-database.py" \
"~/.claude/rhetoric-knowledge-vault/tracking-database.json"Resolve vault_root and python_path from that report, then immediately repeat
the read with "{python_path}" against the resolved database and require the
same database bytes/SHA-256. The unconfigured host_python is authorized only for the first
owner-reader invocation. Every command below uses the configured interpreter;
never fall back to a PATH interpreter.
Read tracking-database.json through the vault path used by
presentation-creator. Selection and composition may read legacy database schema
0 or current schema 1 without mutation. Before copying the approved thumbnail or
writing tracking state, require database schema 1, current independent records,
and talk schema 5. Invoke Skill(skill: "vault-ingress") for schema 0 and stop
this run. Unknown future generations are no usable prior state. Preserve every
schema field and use the presentation-creator exact-generation atomic-write
contract.
If shownotes are needed too (Step 7.2 in presentation-creator) and don't exist yet, STOP and ask before generating the thumbnail.
Scan the outline for high-impact slides. Suggest 3–5 candidates ranked by visual engagement:
Avoid: bio slides, shownotes URL slides, bullet-heavy slides, generic titles.
Present candidates to the speaker with slide numbers and brief descriptions. The speaker picks one — never auto-select.
Resolution chain:
illustrations/ for
slide-{NN}.* matching the chosen slide."{python_path}" "{speaker_toolkit_root}/skills/illustrations/scripts/generate-thumbnail.py" \
--extract-slide deck.pptx 15 --output slide-15.pngResolution order:
publishing_process.thumbnail.speaker_photo_path from speaker profile.The photo must be a real photograph — never AI-generated. Expression should convey engagement and energy, not a neutral corporate headshot.
NOT the full talk title. A 3–5 word hook designed for thumbnail readability at small sizes.
Walk the precedence chain (thumbnail-generation-rules Rule 7):
publishing_process.thumbnail.aesthetic_preference — explicit speaker
preference ("photo" or "comic_book"). Honor it and stop.visual_style_history.default_illustration_style — fuzzy-match against
the comic-book family (comic_book / comic-book / halftone /
illustrated / cartoon / caricature) → recommend comic_book.
Documented styles outside that set (retro_tech_manual, watercolor,
etc.) → out-of-scope; ask the speaker before generating.visual_style_history.confirmed_visual_intents — same fuzzy-match
against each entry's pattern and rule fields.photo.Lead with the recommended aesthetic. Offer a two-candidate side-by-side only when the speaker is genuinely undecided — not as a default. Comic-book is high-variance: when it works, CTR rises significantly; when it misses, it looks off-brand.
If outline.yaml has a style_anchor block (with full / imgtxt anchor
paragraphs), pass the matching format's anchor paragraph to
generate-thumbnail.py via --portrait-style "<anchor>". The script
pre-stylizes the speaker photo
into the anchor's medium (sepia tech-manual, watercolor, pen-and-ink, etc.)
before composition, so the output palette matches the deck. Without this pass-through, photographic skin tones beside
an illustrated background produce a jarring two-medium composite even when
the aesthetic is otherwise correct.
If Phase 2 didn't produce a style anchor (stock-image-only deck), omit
--portrait-style.
# Single recommended candidate (the precedence-chain winner)
"{python_path}" "{speaker_toolkit_root}/skills/illustrations/scripts/generate-thumbnail.py" \
--slide-image illustrations/slide-15.png \
--speaker-photo ~/photos/headshot.jpg \
--title "JUDGMENT DAY" \
--subtitle "DevNexus 2026" \
--vault ~/.claude/rhetoric-knowledge-vault \
--aesthetic <photo|comic_book> \
--style slide_dominant \
--title-position top \
--brand-colors "#5B2C6F,#C0392B" \
--output thumbnail.png
# Anchor-matched (when the deck has a style_anchor block)
"{python_path}" "{speaker_toolkit_root}/skills/illustrations/scripts/generate-thumbnail.py" \
--slide-image illustrations/slide-15.png \
--speaker-photo ~/photos/headshot.jpg \
--title "JUDGMENT DAY" \
--aesthetic photo \
--portrait-style "<full anchor paragraph>" \
--output thumbnail-anchored.pngApply other speaker preferences from publishing_process.thumbnail:
style_preference → --styletitle_position → --title-positionbrand_colors → --brand-colorsaesthetic_preference is consumed at Sub-step 5 — don't re-apply it.
The script (per invocation, runs once per --aesthetic):
thumbnail.png in the
illustrations dir).Present the generated thumbnail. If rejected, iterate — never regenerate from scratch:
--title-position.If publishing_process.shownotes.enabled is true, the SSG template expects
the thumbnail at a specific path relative to the shownotes site root —
otherwise the live page falls back to a placeholder with no warning.
Resolve the destination using publishing_process.shownotes:
{shownotes.source.path_or_url}/{shownotes.thumbnail_path_template}with {slug} substituted from the Presentation Spec. For Jekyll-based
shownotes the default template is
assets/images/thumbnails/{slug}-thumbnail.png — the nested thumbnails/
subdirectory AND the -thumbnail suffix are both mandatory. Do not strip
either.
Create the thumbnails/ directory if it doesn't exist, then copy (don't
move) the generated thumbnail. The local copy in illustrations/thumbnail.png
stays with the talk's working directory for tracking.
If shownotes.ssg_template_pointer is set, read that file after a site
redesign to re-derive the path convention. Don't reinvent it from folklore.
Prepare this complete thumbnails[] record:
{
"schema_version": 1,
"talk_slug": "judgment-day",
"youtube_url": "https://youtube.com/watch?v=...",
"source_slide_num": 15,
"speaker_photo_used": "/path/to/headshot.jpg",
"thumbnail_path": "illustrations/thumbnail.png",
"shownotes_thumbnail_path": "assets/images/thumbnails/judgment-day-thumbnail.png",
"dimensions": "1280x720",
"file_size_kb": 185,
"created_at": "2026-04-20",
"approved": true
}Persist it with the ingress owner's upsert_thumbnail mutation, expecting the
exact existing record for the slug or {"$missing": true}. In the same plan, use
update_talk_publishing to set thumbnail_generated: true on the exact talk
filename, expecting its current value. Dry-run the whole plan, review it, apply
against the reported input SHA, and re-read as specified by the
owner mutation contract.
Keep that talk at schema_version: 5. illustrations is an authorized writer of
current thumbnail and talk records; vault-ingress remains their schema owner.
Never rewrite tracking-database.json directly.
.tessl-plugin
rules
skills
illustrations
presentation-creator
references
patterns
build
deliver
prepare
scripts
shownotes-publisher
vault-clarification
vault-ingress
references
scripts
vault-profile