CtrlK
BlogDocsLog inGet started
Tessl Logo

jbaruch/speaker-toolkit

Seven-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, create and publish talk-content Agent Skills with talk pages to a Jekyll shownotes site, and verify a recorded screencast against its storyboard. Includes a 113-entry Presentation Patterns taxonomy (83 observable: 64 patterns + 19 antipatterns; 30 unobservable: 21 patterns + 9 antipatterns) for scoring, brainstorming, and go-live preparation.

75

Quality

94%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Passed

No findings from the security scan

Overview
Quality
Evals
Security
Files

SKILL.mdskills/vault-clarification/

name:
vault-clarification
description:
Runs interactive clarification sessions with the speaker after talk processing. Resolves ambiguities in rhetoric observations, validates findings, captures speaker intent, conducts humor post-mortems, and probes for blind-spot moments invisible to transcripts. Stores confirmed intents and infrastructure config in the tracking database. Opens with the topics vault-ingress recorded when the speaker accepted the session, and closes that session in the run obligations ledger. Triggers: "run clarification session", "humor post-mortem", "blind spot review", "capture speaker intent", "clarify rhetoric findings", "resume clarification session".
user_invocable:
Yes

Vault Clarification — Interactive Session

Process steps in order. Do not skip ahead.

Each step's output informs the next. The first-session infrastructure capture in Step 6 gates profile generation downstream.

Resolve the absolute path of this loaded SKILL.md, then set speaker_toolkit_root to the plugin root two directories above the directory containing this file. Never derive it from the consumer working directory. Treat {speaker_toolkit_root} as absolute in every toolkit-owned command; vault paths remain consumer-owned.

Run after vault-ingress has processed talks. Purpose: resolve ambiguities, validate findings, capture intent, and fill in speaker infrastructure config.

vault-ingress Step 9 invokes this skill for an accepted session, and that call carries run_id: the run in {vault_root}/ingress-obligations.json whose session is pending. A call without run_id is standalone; Step 2 still checks the ledger for a session left pending by a host that could not make the call.

The vault lives at ~/.claude/rhetoric-knowledge-vault/ (may be a symlink). Set host_python to the current host's explicit absolute interpreter path (not a PATH lookup). The sole interpreter-bootstrap exception is this one stdlib-only strict-owner read; never parse the database directly:

"{host_python}" "{speaker_toolkit_root}/skills/vault-ingress/scripts/read-tracking-database.py" \
  "~/.claude/rhetoric-knowledge-vault/tracking-database.json"

Use the report's database and SHA-256 to resolve vault_root and the exact non-empty config.python_path. Set python_path to that value, immediately repeat the owner read with "{python_path}" against the resolved {vault_root}/tracking-database.json, and require the database and SHA-256 to match the bootstrap report. The unconfigured host_python is authorized only for that first owner-reader invocation. For missing, changed, or unusable configuration, stop and invoke Skill(skill: "vault-ingress") at Step 1; never fall back to python3 on PATH for another toolkit script.

For every tracking-database change, compose a schema-v1 typed plan and run mutate-tracking-database.py in its default dry-run mode. Review changes, then run the same plan with --apply --expected-sha256 <input_sha256> and re-read the database. Every mutation carries an exact value/record expectation; use {"$missing": true} only when absence is expected. A failed precondition applies nothing. The canonical command and operation contract is in ../vault-ingress/references/schemas-db.md.

Key Files & References

File / ReferencePurpose
tracking-database.jsonSource of truth — config, confirmed intents
rhetoric-style-summary.mdRunning rhetoric & style narrative
analyses/{talk_filename}.mdPer-talk analysis files
ingress-obligations.jsonRun obligations ledger, owned by vault-ingress — the session's seed agenda; read and closed only through run-obligations.py
../vault-ingress/references/schemas-obligations.mdLedger schema, states, and the session-agenda reader contract
references/schemas-config.mdConfig fields + confirmed intents schema
references/humor-post-mortem.mdProtocol for grading humor effectiveness
references/blind-spot-moments.mdProtocol for capturing audience/room data

Step 1 — Verify Tracking Schema

Run the vault-ingress owner migration in dry-run mode before reading session state:

"{python_path}" "{speaker_toolkit_root}/skills/vault-ingress/scripts/migrate-tracking-database.py" \
  "{vault_root}/tracking-database.json"

Exit 0 writes one JSON object with from_schema_version, to_schema_version, changed, database_written: false, input_sha256, and record_counts. Continue only for changed: false at the current database generation in the owner compatibility contract with config schema v2. A legacy root or config report requires the owner workflow; invoke Skill(skill: "vault-ingress") with the migration report as handoff context, then finish this clarification run. Exit 2 writes one error object to stdout plus an ERROR: diagnostic to stderr; stop without changing session state.

Every tracking write in Steps 3–9 is current-only. Preserve the owner-current root, config schema 2, talk schema 8, and every unrelated record. Stamp confirmed intents with schema 1 and new improvement goals with schema 2. Capture the exact input bytes immediately before each write, reject a changed generation, validate the complete current shape, and use a same-directory atomic replacement. Never turn this authorized writer into an implicit migrator.

Proceed immediately to Step 2.

Step 2 — Resolve the Seed Agenda

The seed agenda is the list of candidate topics vault-ingress recorded when it offered this session. It lives in the run obligations ledger (../vault-ingress/references/schemas-obligations.md), which only run-obligations.py writes. Read it through that owner: never open the ledger file directly, and never write it in this step.

"{python_path}" "{speaker_toolkit_root}/skills/vault-ingress/scripts/run-obligations.py" \
  "{vault_root}/tracking-database.json" session-agenda [--run-id "{run_id}"]

Pass --run-id when the call carries one. Without it, the command selects the accepted session that never finished, if any; which one, when several are pending, is the script's rule (run-obligations.py, the pending_sessions docstring). Exit 0 with session: null means this session is standalone: it has no seed agenda and touches the ledger no further. Otherwise session.run_id is this session's run and session.topics, in its recorded order, is the seed agenda. Exit 2 writes {"ok": false, "error", "reason_code"} to stdout and the same message to stderr: a named run with no pending session (invalid_transition), an unknown run (run_not_found), or a ledger not yet adopted (ledger_not_adopted). Stop and report it; never guess the topics.

Proceed immediately to Step 3.

Step 3 — Rhetoric Clarification

Open with the seed agenda when Step 2 found one: put each recorded topic to the speaker in its recorded order, one topic per AskUserQuestion where the host has it, otherwise one plain-text question per topic, and wait for each answer before the next topic. Do this before anything this session finds on its own. A topic the speaker chooses not to discuss is answered as such and moves on, never dropped silently. Then, or from the start of a standalone session, ask about each surprising, contradictory, or ambiguous observation, one topic at a time: intentional vs accidental patterns, invisible context, conflicting signals, and flagged improvement areas. Update summary and DB after each answer. Use the typed mutation protocol above for the DB portion; do not batch answers into one unreviewed write at the end.

Example clarification question:

AskUserQuestion(
  question: "Your talks show a delayed self-introduction pattern — brief bio at slide 3,
  then a fuller re-intro mid-talk. Is this intentional or accidental?",
  options: [
    {label: "Deliberate", description: "I do this on purpose to hook first, credential later"},
    {label: "Accidental", description: "I didn't realize I was doing this"},
    {label: "Context-dependent", description: "Depends on the audience/venue"}
  ]
)

Proceed immediately to Step 4.

Step 4 — Blind Spot Moments

Follow references/blind-spot-moments.md — ask about audience reactions, physical performance, and room context that transcripts cannot capture.

Proceed immediately to Step 5.

Step 5 — Humor Post-Mortem

Follow references/humor-post-mortem.md — walk through detected humor beats, grade effectiveness, capture spontaneous material.

Proceed immediately to Step 6.

Step 6 — Speaker Infrastructure (first session only)

If config.clarification_sessions_completed is already ≥ 1, skip this step and proceed immediately to Step 7.

Otherwise, ask for any empty config fields (speaker_name through publishing_process.*). See references/schemas-config.md for the full field list and questions to ask. Persist each confirmed answer with set_config, expecting the exact value observed by the latest strict read.

Proceed immediately to Step 7.

Step 7 — Structured Intent Capture

Persist each confirmed intent with upsert_confirmed_intent, expecting either the exact existing record for that pattern or {"$missing": true}. Example:

{
  "schema_version": 1,
  "pattern": "delayed_self_introduction",
  "intent": "deliberate",
  "rule": "Use two-phase intro: brief bio at slide 3, full re-intro mid-talk",
  "note": "Speaker confirmed this is intentional — hooks audience before credentialing"
}

See references/schemas-config.md for the full schema.

Proceed immediately to Step 8.

Step 8 — Set Improvement Goals

Close the coaching loop. Review Section 15 of rhetoric-style-summary.md as narrative coaching context, plus any regressed/stalled goals from a prior session, then ask the speaker (via AskUserQuestion, one topic at a time) which 1–2 they want to focus on before the next batch of talks. Coaching only works when the speaker owns the target, so never auto-pick more than they choose.

For each chosen focus area, persist a complete schema-v2 improvement_goals record with upsert_improvement_goal, expecting either the exact existing record or {"$missing": true} — every field, not a subset. A partial record cannot be verified: vault-ingress needs metric to compute current_value, and id/issue/kind to identify and route the goal. Set id (kebab-case), issue, kind, metric, antipattern_id (the exact ID only for an antipattern goal, otherwise null), baseline_value, the speaker's stated target, status: "active", set_date to today, set_by: "vault-clarification", current_value: "", last_checked: null, checked_by: null, verification_state: "pending", verification_reasons: [], supersedes_goal_id: null, and schema_version: 2.

For speaker-chosen antipattern and underuse goals, the baseline is catalog-derived. Read the exact occurrence metric only from a validated schema-v4 or schema-v5 profile whose pattern provenance matches the active catalog and scoring-v5 contract, copy pattern_profile.pattern_baseline unchanged into baseline_provenance.pattern_baseline, and set the lane to pattern_scoring. Raw occurrence rows do not themselves classify a pattern as recurring, underused, or a signature. A schema-v5 derived label may inform the choices only when its exact classification domain is available; schema v4 supplies no derived labels. The speaker must explicitly choose the target. Never parse the numeric baseline or generation identity from Section 15 prose. If no matching non-empty raw-score-comparable current pattern cohort exists, explain that the pattern goal has no verifiable baseline yet and do not create it. pacing uses the separate pacing lane; a catalog release must not invalidate it. other uses independent and must not conceal a catalog-pattern metric.

Run "{python_path}" "{speaker_toolkit_root}/skills/vault-clarification/scripts/goal_generation_provenance.py" before writing the candidate. Send one JSON object on stdin: {"goals": [<candidate-goal-object>], "current_pattern_baseline": <pattern_profile.pattern_baseline-object-or-null>}. Exit 0 writes one JSON object to stdout: {"schema_version": 1, "assessments": [{"goal_id": "<id>", "comparable": <boolean>, "decision": "comparable|needs_rebaseline|unverifiable", "reason_codes": [<stable-code>, ...]}]}. Require exit 0 and one assessment for the candidate. Write the candidate only for "comparable": true; surface decision and reason_codes for a false assessment. Malformed JSON or a contract violation exits 1, writes no stdout, and writes ERROR: <diagnostic> to stderr; stop without writing the candidate. The script owns generation comparability; do not reproduce its fingerprint/schema comparison in prose.

Retire goals the speaker no longer wants with retire_improvement_goal, naming its exact id and expecting the complete current record. That operation changes only status to retired, so legacy fields and fixed provenance survive unchanged; leave achieved goals in place as history. A schema-v1 pattern goal is historical and unverifiable, never a baseline to restamp. If the speaker explicitly chooses to rebaseline one, retire the old record and create a new schema-v2 record whose supersedes_goal_id points to it. This preserves the old fixed yardstick rather than silently overwriting it. Full field list and kind values: references/schemas-config.md Improvement Goals Schema.

A later vault-ingress run verifies these against the fresh baseline — see ../vault-ingress/references/processing-rules.md Improvement Goal Verification.

If Section 15 has no speaker-selected pattern target, or the validated profile has no non-empty matching raw-score-comparable current pattern cohort, say so and skip pattern goal-setting. Proceed to Step 9. Independent pacing goals may still be available.

Proceed immediately to Step 9.

Step 9 — Mark Session Complete

Using the latest strict read, persist config.clarification_sessions_completed + 1 with set_config, expecting the exact prior integer. This counter gates profile generation (vault-profile skill requires >= 1). The owner mutation preserves config.schema_version: 2 and every unrelated field.

Then close the ledger session Step 2 resolved; a standalone session with no seed agenda finishes here. Name profile_inputs: changed when this session wrote a confirmed intent, a config field (Step 6), or the rhetoric summary, or created, retired, or changed an improvement goal; unchanged otherwise. List the recorded topics the session covered.

  • Invoked from vault-ingress Step 9: return run_id, profile_inputs, and the covered topics to the caller, which records the session per Clarification Handoff. Do not record it here; the caller owns the profile refresh the record may require.

  • Standalone, with a session session-agenda selected: record it yourself, once:

    "{python_path}" "{speaker_toolkit_root}/skills/vault-ingress/scripts/run-obligations.py" \
      "{vault_root}/tracking-database.json" record-session \
      --run-id "{run_id}" --now "{iso_timestamp}" --profile-inputs changed|unchanged [--profile-refreshed]

    Exit 2 with profile_refresh_required means changed inputs and an existing {vault_root}/speaker-profile.json: invoke Skill(skill: "vault-profile") with the resolved {vault_root} and exact {python_path} as handoff context, then repeat the command with --profile-refreshed. report_reopened: true in the output means the run's end report is owed again; say so, and the next vault-ingress run delivers it. Any other exit 2 is reported as returned, and the session stays pending for the next run to record.

Finish here.

Important Notes

  • One topic at a time — don't dump all questions at once.
  • The seed agenda is the ledger's: never invent a recorded topic, never drop one, and never touch ingress-obligations.json except through run-obligations.py.
  • Update the summary and apply one reviewed typed DB plan after each answer, not in a batch at the end.
  • After completing a session, suggest running the vault-profile skill if 10+ talks are processed and the profile hasn't been generated yet.

skills

README.md

tile.json