CtrlK
BlogDocsLog inGet started
Tessl Logo

try-tessl/agent-quality

Analyze agent sessions against verifier checklists, detect friction points, and create structured verifiers from skills and docs. Produces per-session verdicts and aggregated quality reports.

88

2.93x
Quality

86%

Does it follow best practices?

Impact

97%

2.93x

Average score across 3 eval scenarios

SecuritybySnyk

Passed

No known issues

Overview
Quality
Evals
Security
Files

extract_checklist.pyskills/analyze-sessions/scripts/

#!/usr/bin/env python3
"""
Extract checklist rules from verifier JSON files for judge-based review.

Reads verifier JSONs from installed tiles — searching all verifiers/
directories anywhere in the tile tree (root, skill subdirectories, etc.)
— and outputs a combined rules file for LLM evaluation.

Groups rules by source tile so the judge can see where each instruction
came from.

No external dependencies.

Usage:
    python3 extract_checklist.py --tiles-dir <path> --out rules.json

When --tiles-dir is not given, searches both <cwd>/.tessl/tiles and
~/.tessl/tiles, preferring local tiles when the same tile name appears in both.
"""

from __future__ import annotations

import argparse
import json
import os
import sys
from pathlib import Path


def _find_verifier_dirs(tile_dir: Path) -> list[Path]:
    """Find all verifiers/ directories anywhere under a tile root."""
    dirs = []
    for dirpath, dirnames, _ in os.walk(tile_dir):
        dirnames[:] = [d for d in dirnames if not d.startswith(".")]
        p = Path(dirpath)
        if p.name == "verifiers" and p != tile_dir:
            dirs.append(p)
            dirnames.clear()
    return sorted(dirs)


def load_verifiers_from_dirs(verifier_dirs: list[Path], tile_name: str) -> list[dict]:
    """Load all verifier JSON files from a list of verifiers/ directories."""
    verifiers = []
    for verifiers_dir in verifier_dirs:
        for f in sorted(verifiers_dir.glob("*.json")):
            if f.name.startswith("_"):
                continue
            try:
                raw = json.loads(f.read_text(encoding="utf-8"))
                # Handle both dict format and list-of-verifiers format
                items = raw if isinstance(raw, list) else [raw]
                for data in items:
                    if not isinstance(data, dict):
                        continue
                    checklist = data.get("checklist", [])
                    if not isinstance(checklist, list) or len(checklist) == 0:
                        continue
                    filtered_checklist = [
                        {
                            "name": item.get("name", ""),
                            "rule": item.get("rule", ""),
                            "relevant_when": item.get("relevant_when", ""),
                        }
                        for item in checklist
                        if isinstance(item, dict)
                    ]
                    if not filtered_checklist:
                        continue
                    verifiers.append({
                        "file": f.name,
                        "instruction": data.get("instruction", ""),
                        "relevant_when": data.get("relevant_when", ""),
                        "context": data.get("context", ""),
                        "checklist": filtered_checklist,
                        "_tile": tile_name,
                        "_verifiers_dir": str(verifiers_dir),
                    })
            except (json.JSONDecodeError, OSError) as e:
                print(f"  Warning: failed to read {f}: {e}", file=sys.stderr)

    return verifiers


def _get_tile_name(org_dir: Path, tile_dir: Path) -> str:
    """Read tile name from tile.json, falling back to dir path."""
    name = f"{org_dir.name}/{tile_dir.name}"
    tile_json = tile_dir / "tile.json"
    if tile_json.exists():
        try:
            data = json.loads(tile_json.read_text())
            name = data.get("name", name)
        except (json.JSONDecodeError, OSError):
            pass
    return name


def resolve_tile_dirs(explicit: str | None = None) -> list[Path]:
    """Return tile directories to search, in priority order.

    When --tiles-dir is given explicitly, use only that.  Otherwise check
    both the local project dir and the global ~/.tessl/tiles, preferring
    local (so local tiles shadow global ones with the same name).
    """
    if explicit:
        p = Path(explicit).resolve()
        return [p] if p.exists() else []

    cwd = Path(os.getcwd()).resolve()
    candidates = [
        cwd / ".tessl" / "tiles",
        Path.home() / ".tessl" / "tiles",
    ]
    return [p for p in candidates if p.exists()]


def _discover_from_dir(tiles_dir: Path) -> list[tuple[str, list[Path]]]:
    """Return (tile_name, verifier_dirs) pairs from a single tiles directory."""
    results = []
    if not tiles_dir.exists():
        return results
    for org_dir in sorted(tiles_dir.iterdir()):
        if not org_dir.is_dir() or org_dir.name.startswith("."):
            continue
        for tile_dir in sorted(org_dir.iterdir()):
            if not tile_dir.is_dir() or tile_dir.name.startswith("."):
                continue
            verifier_dirs = _find_verifier_dirs(tile_dir)
            if verifier_dirs:
                tile_name = _get_tile_name(org_dir, tile_dir)
                results.append((tile_name, verifier_dirs))
    return results


def discover_and_extract(tiles_dirs: list[Path]) -> dict:
    """Discover tiles with verifiers and extract all rules.

    Searches multiple tile directories, deduplicating by tile name (first wins).

    Trust boundary: verifier JSONs are read from user-installed tiles
    (.tessl/tiles/), not from arbitrary or untrusted third-party sources.
    """
    all_rules = []
    tiles_found = []
    seen: set[str] = set()

    for tiles_dir in tiles_dirs:
        for tile_name, verifier_dirs in _discover_from_dir(tiles_dir):
            if tile_name in seen:
                continue
            seen.add(tile_name)
            verifiers = load_verifiers_from_dirs(verifier_dirs, tile_name)
            if verifiers:
                tiles_found.append({
                    "name": tile_name,
                    "verifier_count": len(verifiers),
                    "check_count": sum(
                        len(v.get("checklist", [])) for v in verifiers
                    ),
                })
                all_rules.extend(verifiers)

    return {
        "tiles_dirs": [str(d) for d in tiles_dirs],
        "tiles": tiles_found,
        "rules": all_rules,
        "total_instructions": len(all_rules),
        "total_checks": sum(len(r.get("checklist", [])) for r in all_rules),
    }


def extract_single_tile(tiles_dirs: list[Path], tile_filter: str) -> dict:
    """Extract rules from a single tile by name, searching multiple tile directories."""
    all_rules = []
    tiles_found = []

    for tiles_dir in tiles_dirs:
        for tile_name, verifier_dirs in _discover_from_dir(tiles_dir):
            if tile_name != tile_filter:
                continue
            verifiers = load_verifiers_from_dirs(verifier_dirs, tile_name)
            if verifiers:
                tiles_found.append({
                    "name": tile_name,
                    "verifier_count": len(verifiers),
                    "check_count": sum(
                        len(v.get("checklist", [])) for v in verifiers
                    ),
                })
                all_rules.extend(verifiers)
            # Found the tile — no need to check further directories
            return {
                "tiles_dirs": [str(d) for d in tiles_dirs],
                "tiles": tiles_found,
                "rules": all_rules,
                "total_instructions": len(all_rules),
                "total_checks": sum(len(r.get("checklist", [])) for r in all_rules),
            }

    return {
        "tiles_dirs": [str(d) for d in tiles_dirs],
        "tiles": tiles_found,
        "rules": all_rules,
        "total_instructions": len(all_rules),
        "total_checks": sum(len(r.get("checklist", [])) for r in all_rules),
    }


def main():
    parser = argparse.ArgumentParser(
        description="Extract checklist rules from verifier JSONs for judge review"
    )
    parser.add_argument(
        "--tiles-dir",
        default=None,
        help="Path to .tessl/tiles/ directory (default: auto-detect local + global)",
    )
    parser.add_argument(
        "--tile",
        default=None,
        help="Extract rules for a single tile by name (e.g. amyh/research-best-practice)",
    )
    parser.add_argument(
        "--out",
        default=None,
        help="Output path (default: stdout as JSON)",
    )
    args = parser.parse_args()

    tiles_dirs = resolve_tile_dirs(args.tiles_dir)
    if not tiles_dirs:
        searched = args.tiles_dir or f"{Path.cwd() / '.tessl' / 'tiles'} and {Path.home() / '.tessl' / 'tiles'}"
        print(f"No tiles directory found. Searched: {searched}", file=sys.stderr)
        sys.exit(1)

    if args.tile:
        result = extract_single_tile(tiles_dirs, args.tile)
    else:
        result = discover_and_extract(tiles_dirs)

    output = json.dumps(result, indent=2)
    if args.out:
        out_path = Path(args.out)
        out_path.parent.mkdir(parents=True, exist_ok=True)
        out_path.write_text(output, encoding="utf-8")
        print(
            f"Extracted {result['total_instructions']} instructions "
            f"({result['total_checks']} checks) from "
            f"{len(result['tiles'])} tile(s) → {out_path}",
            file=sys.stderr,
        )
    else:
        print(output)


if __name__ == "__main__":
    main()

README.md

tile.json