Eleven skills for conference speakers covering rhetoric analysis, talk authoring, deck building and export, CFP submissions, publishing, illustrations, shownotes, and screencast production, informed by a 113-entry Presentation Patterns taxonomy (83 observable: 64 patterns + 19 antipatterns; 30 unobservable: 21 patterns + 9 antipatterns).
90%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Low
Low-risk findings worth noting
NEVER call the qrcode library directly or generate QR images through any
other means. ALWAYS use generate-qr.py. The script handles URL shortening,
custom back-half, tracking DB updates, color matching, and secrets.
When the target is not a .pptx deck (e.g., presenterm, PDF, or standalone PNG),
use --png-only mode:
python3 generate-qr.py --png-only --talk-slug SLUG --shownotes-url URL \
--output /path/to/qr.png --bg-color "128,0,128"The short link's back-half MUST ALWAYS be the talk slug — the bit.ly custom
back-half AND the rebrand.ly slashtag, with no override. When a custom domain is
configured in the vault profile (bitly_domain / rebrandly_domain), the short
link MUST use it. The script does this automatically: --talk-slug devnexus26-robocoders with bitly_domain: jbaru.ch creates
jbaru.ch/devnexus26-robocoders (not bit.ly/a3xK9f).
When the slug back-half cannot be set:
link_id and short_url."shortener": "none"
authorizes raw encoding (§3).Random hashes are untraceable and unprofessional. The back-half IS the slug.
The QR code MUST encode the bit.ly/rebrandly URL, never the raw shownotes URL. The shortener is the decoupling layer — if the shownotes URL changes later, update the shortener target, and every printed QR code stays valid.
The only exception is "shortener": "none" (explicit opt-out), where the raw
URL is the only option.
--shownotes-url is required in every mode, including MCP-preresolved. It is
the canonical redirect target the catalog records; the short URL never stands in
for it.
The qr_codes record MUST describe what was actually produced:
path_root explicitly (deck_dir, cwd, or absolute).mcp_preresolved is a
last-resort marker for when the agent supplies neither.short_path as the short URL's back-half, which §2 requires to equal
the talk slug. A pre-resolved link whose back-half differs stops the run under
§2; it is never recorded with the slug asserted onto it.The back-half IS talk.slug — composed and agreed with the author in Phase 1
(per the speaker's slug_convention.template) and persisted in outline.yaml.
The QR step uses it VERBATIM: never invent, rephrase,
re-derive, abbreviate, or date-prefix it. The back-half must equal the published
shownotes slug.
devnexus26-robocoders, not 2026-04-16-devnexus-robocoders)When the speaker profile has no shortener configured (key missing, not set
to "none"), STOP and ask the user to choose one.
"shortener": "none" → explicit opt-out, proceed without shorteningshortener key missing → NOT CONFIGURED → ask before proceedingSilent generation with a raw URL when shortening was never discussed = failure.
On the direct API path, if secrets.json is missing or lacks the selected
shortener's token, STOP and guide the user to create it. MCP-preresolved links
and explicit shortener: none do not require direct API tokens. Do not silently degrade to a raw URL.
The script prints actionable creation commands — but the agent must treat a missing token as a blocker, not a fallback trigger.
The first time a short link is created for the active shortener, the custom-domain
decision MUST be recorded in the vault profile. Three states of
publishing_process.qr_code.{shortener}_domain:
jbaru.ch) and SAVE the answer before the link is created.null → recorded decision: no custom domain, use the shortener default (bit.ly).Save the decision either way — the domain string, or null for "no custom domain".
A null is a recorded decision, not an absent value; never re-ask once saved. On
the Direct API path generate-qr.py STOPS when the key is absent; on the MCP path
the agent makes the same check before resolving the link.
short_url or target_url from qr_codes, or one of this run's own URLs.generate-qr.py owns QR identification and its thresholds.closing and both target the last slide the audience sees.--slides N[,N...]: the listed 1-based slides replace detection.--slides stays in place, and the run names its slide..tessl-plugin
rules
skills
cfp-writer
references
illustrations
presentation-builder
presentation-creator
references
patterns
build
deliver
prepare
scripts
presentation-publisher
screencast-editor
screencast-recorder
shownotes-publisher
vault-clarification
vault-ingress
references
scripts
vault-profile