CtrlK
BlogDocsLog inGet started
Tessl Logo

jbaruch/speaker-toolkit

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 102-entry Presentation Patterns taxonomy (91 observable, 11 unobservable go-live items) for scoring, brainstorming, and go-live preparation.

78

1.18x
Quality

91%

Does it follow best practices?

Impact

77%

1.18x

Average score across 27 eval scenarios

SecuritybySnyk

Advisory

Suggest reviewing before use

Overview
Quality
Evals
Security
Files

SKILL.mdskills/vault-profile/

name:
vault-profile
description:
Generates or updates the structured speaker-profile.json from vault data. Aggregates rhetoric summary, slide design spec, confirmed intents, and structured talk data into a machine-readable profile used by the presentation-creator skill. Also generates speaker achievement badges. Triggers: "generate speaker profile", "update speaker profile", "regenerate speaker profile", "sync speaker profile".
user_invocable:
Yes

Vault Profile — Speaker Profile Generator

Generate or update speaker-profile.json from vault data. This profile is the structured bridge between the vault and the presentation-creator skill.

The vault lives at ~/.claude/rhetoric-knowledge-vault/ (may be a symlink). Read tracking-database.json from there to get vault_root.

Key Files & References

File / ReferencePurpose
tracking-database.jsonSource of truth — talks, config, confirmed intents
rhetoric-style-summary.mdRunning rhetoric & style narrative
slide-design-spec.mdVisual design rules from PDF + PPTX analysis
speaker-profile.jsonOutput — machine-readable profile
references/speaker-profile-schema.mdProfile JSON schema
references/schemas-config.mdConfig fields + confirmed intents schema
scripts/load-vault.pyRead vault sources, emit JSON payload to stdout
scripts/validate-profile.pyValidate profile required keys + schema_version
scripts/compute-pacing-adherence.pyCompute pacing.adherence from scored talks + slide budgets

Prerequisites

  • 10+ talks parsed AND config.clarification_sessions_completed >= 1.
  • Also runs on explicit request (overrides prerequisites).
  • Auto-triggered by vault-ingress Step 7 (Regenerate Speaker Profile) if profile already exists.

Process the steps below in order; each step's output (vault payload, aggregated data, validated profile) feeds the next. Do not skip ahead.

Step 1 — Load Vault Sources

Run scripts/load-vault.py to read tracking-database.json, rhetoric-style-summary.md, and slide-design-spec.md from the vault root. The script emits a single JSON payload on stdout.

python3 skills/vault-profile/scripts/load-vault.py > /tmp/vault-payload.json

I/O contract:

  • Args: optional vault-root path; defaults to ~/.claude/rhetoric-knowledge-vault.
  • Stdout (JSON): {vault_root, config, confirmed_intents, talks, processed_talks, summary, design_spec}.
  • Exit non-zero with stderr message if tracking-database.json or rhetoric-style-summary.md are missing or malformed.

If the script aborts on missing rhetoric-style-summary.md, run vault-ingress first. If slide-design-spec.md is missing, design_spec is "" and the design-spec section of the profile remains empty — continue without aborting.

Proceed immediately to Step 2.

Step 2 — Aggregate Structured Data

Aggregate structured_data from processed_talks in the Step 1 payload. Skip talks with empty structured_data; for those, fall back to prose extraction from summary (the rhetoric-style-summary.md contents) for the matching dimensions.

If all processed talks have empty structured_data, warn the speaker and fall back entirely to prose extraction. Continue.

Proceed immediately to Step 3.

Step 3 — Extract Template Layouts

If config.template_pptx_path is set, call the vault-ingress PPTX extraction script:

python3 skills/vault-ingress/scripts/pptx-extraction.py "$TEMPLATE_PPTX_PATH" > /tmp/template-layouts.json

I/O contract (defined in vault-ingress; see skills/vault-ingress/scripts/pptx-extraction.py):

  • Args: path to a .pptx file.
  • Stdout (JSON): per-slide visual data, shape types, global design stats, and the master layouts list under the top-level template_layouts key. Each layout entry has {index, master_index, name, placeholders: [{idx, type}]}.
  • Exit non-zero with stderr message if the file is missing, unreadable, or not a valid .pptx.

Merge the resulting layouts list into infrastructure.template_layouts in the profile being constructed. The script emits structural fields (index, master_index, name, placeholders); the use_for field is speaker-curated and is not emitted. When merging, key by the (master_index, name) pair — PowerPoint allows the same layout name to appear under different slide masters, so name alone is insufficient. For each fresh layout, copy any existing use_for value from the prior profile's matching (master_index, name) entry. Layouts present in the prior profile but absent from the fresh extraction are dropped — the script is the source of truth for layout existence. If template_pptx_path is not set, leave template_layouts as an empty list and continue.

Proceed immediately to Step 4.

Step 4 — Construct the Profile

Construct the speaker-profile.json dict per references/speaker-profile-schema.md. Map vault sources to profile sections:

Profile sectionSource
speaker / infrastructureconfig (from Step 1 payload)
presentation_modes / instrument_catalogsummary sections (from Step 1 payload)
rhetoric_defaultsconfirmed_intents (from Step 1 payload)
pacing / guardrail_sourcesaggregated structured_data (from Step 2)
pattern_profilepattern_observations across processed_talks
visual_style_historydimension 13f observations from summary

Top-level keys (full nested schema in references/speaker-profile-schema.md):

schema_version, generated_date, talks_analyzed, speaker, infrastructure,
presentation_modes, instrument_catalog, rhetoric_defaults, confirmed_intents,
guardrail_sources, pacing, pattern_profile, visual_style_history,
publishing_process, design_rules, badges

When building pattern_profile, attribute score_trend instead of leaving it a bare label. A declining score has two symmetric causes — bad things present and good things absent — and score_drivers MUST name whichever moved:

  • Antipatterns rising — every antipattern_frequency entry with trend increasing.
  • Patterns fading or breadth narrowing — every pattern_usage entry with trend decreasing (signature OR regular), and a pattern_breadth.trend of narrowing, which drives a decline even when no single pattern fades. Underuse alone can lower the score with zero antipatterns.

Also compute pattern_breadth (average distinct observable patterns per talk + trend) and underused_patterns — the union of never_used_patterns with the patterns in the never_tried and rare tiers of mastery_levels, kept only where the pattern's taxonomy Vault Dims fit the speaker's presentation_modes. This is the positive-space coaching signal, framed as growth, not deficiency.

Compute pattern_profile.by_mode — the per-mode baseline. The tracking DB has no per-talk mode field. Assign each processed_talk to the presentation_modes entry whose when_to_use best matches the talk's structured_dataslide_count and meme_count density, audience_interaction_count, opening_type, narrative_arc_type, and slide_design_style. This assignment is a classification judgment, not a stored value — it stays LLM-side. Then, for each mode with ≥3 assigned talks, emit average_pattern_score, avg_distinct_patterns_per_talk, top_antipatterns, and stable: true. Modes below 3 talks are omitted (or stable: false); consumers fall back to the global baseline. This prevents false underuse findings when a short-format mode is judged against a keynote baseline.

Compute pattern_profile.strengths — the speaker's signature patterns (from mastery_levels.signature) and signature_combinations, each with a lean_in line. This is the positive-space counterpart to recurring_issues/underused_patterns; keep it distinct from Step 8 badges (badges are celebratory, strengths are actionable reinforcement the creator skill amplifies).

Compute pacing.adherence by running scripts/compute-pacing-adherence.py. The deterministic arithmetic — duration parsing, slides-per-minute, budget-band classification, over-budget counts, rate, and trend — lives in the script per script-delegation, not in this prose.

echo "$PACING_INPUT" | python3 skills/vault-profile/scripts/compute-pacing-adherence.py

I/O contract (parse + budget-band rules in the script's top-of-file docstring):

  • Stdin (JSON): {"talks": [...], "slide_budgets": [...]}. Pass each scored talk as {filename, date, slide_count, talk_duration_estimate}, taking slide_count and talk_duration_estimate from the talk's structured_data; pass guardrail_sources.slide_budgets unchanged.
  • Stdout (JSON): the pacing.adherence data fields (talks_over_budget, talks_scored, over_budget_rate, trend, worst_offenders). Copy them into pacing.adherence; the schema's note is optional descriptive text (as elsewhere in the schema) and is not emitted by the script.
  • Exit non-zero on malformed input.

This is the quantitative counterpart to Dimension 14's transcript-evident "rushing" read. The duration estimate is approximate. Flag marginal overages softly.

Cross-check against Section 15 of rhetoric-style-summary.md, which carries the same baselines in prose. See references/speaker-profile-schema.md pattern_profile.

Set schema_version to 2 and generated_date to today's date in YYYY-MM-DD form.

Proceed immediately to Step 5.

Step 5 — Validate the Profile

Pipe the constructed profile dict through scripts/validate-profile.py to verify all required top-level keys exist and schema_version is 2.

echo "$PROFILE_JSON" | python3 skills/vault-profile/scripts/validate-profile.py

I/O contract:

  • Stdin (JSON): the profile dict.
  • Stdout (JSON): {valid, schema_version, missing_keys}.
  • Exit code: 0 on valid, 1 on invalid.

If exit code is 1, list every missing key from the script output and abort without writing. Fix the offending fields in Step 4 and rerun this step.

Proceed immediately to Step 6.

Step 6 — Diff Against Existing Profile

If {vault_root}/speaker-profile.json already exists, diff the new profile against it. Report to the speaker:

  • New instruments added to instrument_catalog
  • Revised thresholds in guardrail_sources
  • New guardrails added to recurring_issues
  • Shifts in pattern_profile.score_drivers — a newly declining direction, a new antipattern_drivers entry with a rising frequency_trend, or a pattern_breadth.trend flipping to narrowing (using fewer of the toolkit) is a regression signal worth flagging.
  • A worsening pacing.adherence.trend or a rising over_budget_rate — the speaker is increasingly running long.
  • New presentation modes — flag prominently (the highest-signal field change for creator-skill behavior).

If no prior profile exists, skip this step and proceed.

Proceed immediately to Step 7.

Step 7 — Save the Profile

Write the validated profile to {vault_root}/speaker-profile.json with 2-space indentation. Confirm: "speaker-profile.json written — {N} talks, {M} confirmed intents."

Proceed immediately to Step 8.

Step 8 — Generate Achievement Badges

Generate fun, self-deprecating achievements grounded in real vault data (e.g., "Narrative Arc Master 22/24", "Pattern Polyglot 12+ patterns"). The badge tone matters: badges should sound like the speaker's own voice, not corporate gamification. Append the resulting array to the profile's badges field and re-save.

Finish here.

skills

.mcp.json

README.md

tile.json