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

validate-returns.pyskills/vault-ingress/scripts/

#!/usr/bin/env python3
"""Validate a batch of vault-ingress subagent returns without writing state.

Usage:
    validate-returns.py <batch-or-return.json> [...] [--catalog-dir <patterns-dir>]

Each input may be one return object, an array of returns, or a directory of
`*.json` return files. Inputs are flattened into one batch, so duplicate talk
filenames are caught across files and directories.

The same validator runs inside persist-results.py and write-analysis.py. This
standalone entry point is for the batch gate immediately after agents return.
It prints a structured JSON report on success and a concise stderr diagnostic
with exit code 1 on failure.
"""

import json
import sys
from pathlib import Path

from failure_diagnostics import emit_unexpected_failure
from return_validation import (
    ReturnValidationError,
    audit_batch,
    load_catalog,
    load_json,
    validation_report,
)


def parse_args(argv):
    args, catalog_dir = [], None
    index = 0
    while index < len(argv):
        if argv[index] == "--catalog-dir":
            if index + 1 >= len(argv):
                raise ReturnValidationError("--catalog-dir requires a path")
            catalog_dir = argv[index + 1]
            index += 2
            continue
        args.append(argv[index])
        index += 1
    if not args:
        raise ReturnValidationError(
            f"Usage: {sys.argv[0]} <batch-or-return.json> [...] "
            "[--catalog-dir <patterns-dir>]"
        )
    return args, catalog_dir


def load_inputs(paths):
    """Flatten return objects and arrays from files or shallow directories."""
    returns = []
    files = []
    for raw in paths:
        path = Path(raw)
        candidates = sorted(path.glob("*.json")) if path.is_dir() else [path]
        if path.is_dir() and not candidates:
            raise ReturnValidationError(
                f"return directory contains no *.json files: {path}"
            )
        for candidate in candidates:
            payload = load_json(candidate, "return")
            files.append(str(candidate))
            if isinstance(payload, dict):
                returns.append(payload)
            elif isinstance(payload, list):
                returns.extend(payload)
            else:
                raise ReturnValidationError(
                    f"return file {candidate} must contain an object or array, "
                    f"got {type(payload).__name__}"
                )
    return returns, files


def main():
    try:
        input_paths, catalog_dir = parse_args(sys.argv[1:])
        returns, files = load_inputs(input_paths)
        catalog = load_catalog(catalog_dir) if catalog_dir else None
        resolved_catalog, errors = audit_batch(returns, catalog)
        if errors:
            for error in errors:
                print(f"ERROR: {error['error']}", file=sys.stderr)
            print(
                f"ERROR: {len(errors)} validation error(s) across "
                f"{len(returns)} return(s)",
                file=sys.stderr,
            )
            sys.exit(1)
    except ReturnValidationError as exc:
        print(f"ERROR: {exc}", file=sys.stderr)
        sys.exit(1)
    report = validation_report(returns, resolved_catalog)
    report["input_files"] = files
    # Serialize before writing: a `json.dump` straight to stdout that fails
    # partway leaves a truncated document the batch gate would try to parse.
    sys.stdout.write(json.dumps(report, ensure_ascii=False) + "\n")


def run_cli() -> int:
    """Run the CLI behind its failure boundary. Returns the process exit code.

    Importable so the boundary's contract is testable without executing the
    module as a script.
    """
    try:
        main()
    # The batch gate runs this immediately after agents return and reads a
    # non-zero exit as "the batch is not validated"; emit one closed stderr
    # document because a traceback would leak return paths and rejected values
    # into the gate's log, and the gate could not tell a failed validation from
    # a failed validator.
    except Exception as exc:  # noqa: BLE001 - outer-boundary-process-contract
        emit_unexpected_failure(
            exc,
            "validate_returns_unexpected_failure",
            "vault-ingress return validation failed unexpectedly. This script "
            "writes no state, so nothing was changed — but the batch is "
            "UNVALIDATED and must not be persisted until a clean run reports "
            "on stdout.",
        )
        return 2
    return 0


if __name__ == "__main__":
    raise SystemExit(run_cli())

skills

vault-ingress

scripts

adherence_baseline.py

aggregate-catalog-feedback.py

apply-source-repairs.py

artifact_locator.py

artifact_metadata.py

artifact_supervisor.py

audit-pattern-catalog.py

audit-persisted-pattern-observations.py

audit-source-identities.py

batch-download-videos.py

build-contact-sheet.py

build-crop-reviewer.py

build-score-basis.py

catalog_dimension_registry.py

catalog_io.py

catalog_normalization.py

check-runtime.py

classify-pptx-evidence.py

cloud_artifacts.py

cooperative_lock.py

crop_frames.py

crop-reviewer-shell.html

crop-reviewer-shell.html.txt

crop-reviewer.js

crop-reviewer.js.txt

establish-date-provenance.py

failure_diagnostics.py

fetch-transcript.py

ingress_contract.py

local_media_contract.py

local_media_download.py

local_media_evidence.py

local_media_process.py

local_media_sampling.py

local_media_transcription.py

local_media_words.py

markdown_deck.py

migrate-tracking-database.py

mutate-tracking-database.py

pattern_evidence.py

pdf_evidence.py

persist-results.py

persisted_pattern_observations.py

pptx_catalog_selection.py

pptx_deck_facts.py

pptx_discovery_contract.py

pptx_evidence.py

pptx_talk_identity.py

pptx-extraction.py

preflight-vault.py

queue_claim_contract.py

queue-state.py

read-tracking-database.py

render-markdown-deck.py

render-vault-status.py

retained_stage.py

return_validation.py

run-obligations.py

scan-shownotes.py

source_alias_contract.py

source_identity_matching.py

summary_lock.py

sweep-pptx-talk-identity.py

tracking_database_io.py

tracking_database.py

transcript_quality.py

transcript_timing.py

validate-returns.py

vault_root_authority.py

video_evidence.py

video_integrity.py

video-slide-extraction.py

vtt-cleanup.py

write-analysis.py

ytdlp_runtime.py

SKILL.md

README.md

tile.json