lythoskill-hello-world
A minimal hello-world skill. No scripts, no dependencies. Demonstrates the simplest possible thin-skill: just a SKILL.md.
lythoskill-arena
Test play for skills and deck configurations. DEFAULT: agent reads config, spawns parallel subagents via native Agent tool, judges outputs. Single-deck test AND multi-deck A/B comparison both run agent-orchestrated (no CLI). Cross-player comparison (kimi vs codex) is the ONLY case that needs the ...
Full skill instructions
Test play for skills and deck configurations. Not "which is best" — "which is best for what."
User says: "test/compare/arena/benchmark/A vs B"
│
├── Cross-PLAYER? (kimi vs codex vs claude)
│ OR user explicitly says useAgent/specific player
│ OR platform doesn't support Agent tool subagents
│ → CLI runner REQUIRED (useAgent → Bun.spawn)
│ → bunx @lythos/skill-arena vs --config arena.toml
│ → Each side spawns its player CLI process
│
└── Same player, different DECKS? (DEFAULT)
→ Agent-orchestrated — NO CLI
→ YOU spawn subagents via Agent tool
→ CLI prepare-workdir + CLI archive + parallel dispatch
→ Judge subagent collects + scores
This is how arena works 95% of the time. The agent and CLI operate as a two-way control transfer protocol. Agent delegates mechanical invariants to CLI. CLI hands control back via its exit paths (success → next step; error → fix command). Agent stays in its own main loop — the subagent pattern is container spawn, not external RPC.
flowchart TD
A["🤖 Agent: parse request"] --> B{Cross-PLAYER?}
B -->|Yes| C[🔧 CLI vs --config]
B -->|No — DEFAULT| D["🤖 Agent → 🔧 CLI: prepare-workdir"]
D -->|"✅ workdir ready"| E["🤖 Agent: spawn subagents"]
E --> F["🤖 Subagents: execute + write artifacts"]
F --> G["🤖 Agent: collect + spawn judge"]
G --> H["🤖 Judge: score → report.md"]
H --> I["🤖 Agent → 🔧 CLI: archive"]
I -->|"✅ archived"| J["🤖 Agent → 🔧 CLI: deck link restore"]
The protocol in one line: Agent hands to CLI (prepare-workdir, archive, deck link). CLI exits with success (✅ workdir ready → spawn) or HATEOAS error (❌ missing --deck → here's the fix command → retry). Agent reads the exit, decides next move, continues. Three CLI exit points, three handoffs back to agent.
🤖→🔧 prepare-workdir --out /tmp/arena-xxx --brief "task"
CLI exits: ✅ Workdir ready → 🤖 spawn subagent
🤖 Agent tool spawn: subagent executes in workdir, writes artifacts + decision-log-<cell-id>.jsonl
🤖→🔧 archive --from /tmp/arena-xxx --to ./playground --sides side-a
CLI exits: ✅ Archive complete → 🤖 done
🤖→🔧 deck link parent deck (restore)
🤖→🔧 prepare-workdir × N (each side isolated, each with own deck)
CLI exits: ✅ Workdir ready × N → 🤖 spawn N subagents in parallel
🤖 Agent tool spawn ×N, run_in_background=true
🤖 Collect: merge each side's per-cell decision logs → {side}/decision-log.jsonl
🤖 Spawn judge subagent: score per criteria → report.md
🤖→🔧 archive --from /tmp/arena-xxx --to ./playground --sides side-a,side-b
🤖→🔧 deck link parent deck (restore)
Why agent-orchestrated is default: Subagent = container spawn, not external RPC. Agent stays in its own main loop — can read subagent output, fix failures mid-run (switch mirror, adjust timeout, retry), spawn judge. Decision-log.jsonl from each subagent provides full observability. Cross-deck vs IS map-reduce — same agent type, different decks, parallel spawn, judge reduce.
Use ONLY when comparing different players (kimi vs codex vs deepseek vs claude). The Agent tool can only spawn the same agent type — it CANNOT simulate another CLI's memory, hooks, or tool-use semantics. This is a hard runtime boundary, not a preference.
# Single deck, explicit player
bunx @lythos/[email protected] single \
--deck ./skill-deck.toml \
--brief "Investigate this repo" \
--player kimi
# vs mode with arena.toml (each side's player in config)
bunx @lythos/[email protected] vs --config ./arena.toml
See references/player-setup.md for player discovery, installation, and API key setup.
Purpose: Verify that a skill's mental model (SOP, behavior pattern, decision chain) actually shapes agent behavior — not just that the skill file is read.
Minimal deck principle: Include ONLY the governance skill (lythoskill-deck) and the target skill under test. Extra skills dilute the signal — you are testing whether the target skill's intent survives when no other skills are there to compensate.
Standard posture (4 steps):
Prepare — prepare-workdir with minimal deck
bunx @lythos/[email protected] prepare-workdir \
--deck ./test-deck.toml \
--out /tmp/arena-$(date +%Y%m%d-%H%M%S) \
--brief "Execute the target skill's core workflow"
Dispatch — spawn subagent with decision-log mandate
Observe — collect decision-logs, not just artifacts
decision-log-*.jsonl from workdir, or the merged decision-log.jsonl after the collect stepJudge — score mindset alignment, not output correctness
Why this matters: A skill that declares "MUST FILL" but agents consistently leave empty has a mindset gap — the skill's intent is stated but not enforced by the agent's decision chain. Arena catches this before the skill reaches users.
For EACH side, use prepare-workdir (same behavior as CLI single mode):
# Plan-first: review before executing
bunx @lythos/[email protected] prepare-workdir \
--deck ./side-a.toml \
--out /tmp/arena-$(date +%Y%m%d-%H%M%S)-side-a \
--brief "task description" \
--dry-run
# Execute (same command minus --dry-run)
bunx @lythos/[email protected] prepare-workdir \
--deck ./side-a.toml \
--out /tmp/arena-$(date +%Y%m%d-%H%M%S)-side-a \
--brief "task description"
/tmpis the experiment sandbox. Never run experiments in committed directories. Plan-first (--dry-run) shows skills, workdir path, link needed — review before IO.
pwd && ls .claude/skills/ 2>/dev/null || ls .agents/skills/ 2>/dev/null && touch .arena-write-test && rm .arena-write-test && echo "OK"
If ANY fail → fix before proceeding.
One subagent per cell:
subagent prompt:
"You are an arena cell. Your working directory: {workDir}.
Deck: {deckPath}.
Task: {brief}
MANDATORY: write decision-log-{cellId}.jsonl to your CWD.
Each line: {"t":<seconds>,"phase":"...","decision":"...","reason":"..."}"
All subagents run in PARALLEL. Each writes to its own isolated workdir. No file conflicts.
Cell id is mandatory when cells share a workdir. Several cells of one side may run against the same workdir — a filename is a path, so two cells mandated to write the same
decision-log.jsonlmeans the last writer erases the others (2026-09-09 run: side-a kept S1a's 9 entries, S3a/S4a/S5a gone). Give every cell a distinct id (s1a,s3a, …) and a per-cell name: the files cannot collide, and the collect step below merges them. A cell alone in its workdir may keep the baredecision-log.jsonl.
Platform note:
run_in_background(or your platform's async spawn equivalent) keeps parent unblocked. Subagent inherits parent CWD — include"Your working directory is {workDir}"in the prompt so it cd's to the right place. Subagent skills load from the working set directory in that workdir (default.claude/skills/).
After ALL complete:
1. Collect
decision-log-<cell-id>.jsonl. Read them per cell (they are
the attributable evidence) or let archive merge them into one decision-log.jsonl per
side — see the Archive step below. The merge is lossless and ordered by cell id, but a
merged line carries no cell attribution, so the per-cell files are kept.2. Judge
report.md3. Archive (same behavior as CLI --out)
Use archive command (same copy logic as CLI single mode). Plan-first: dry-run to review what will be copied, then execute. archive is also the collect step for decision logs: when a side holds per-cell logs (decision-log-<cell-id>.jsonl), it merges them into <out>/<side>/decision-log.jsonl and leaves the per-cell files in place. A side whose only log is the bare decision-log.jsonl is already merged and is copied untouched.
# Plan-first
bunx @lythos/[email protected] archive \
--from /tmp/arena-$(date +%Y%m%d-%H%M%S) \
--to playground/arena-$(date +%Y%m%d-%H%M%S) \
--sides side-a,side-b \
--report ./report.md \
--dry-run
# Execute (same minus --dry-run)
bunx @lythos/[email protected] archive \
--from /tmp/arena-$(date +%Y%m%d-%H%M%S) \
--to playground/arena-$(date +%Y%m%d-%H%M%S) \
--sides side-a,side-b \
--report ./report.md
Archive contract (same skipSet as CLI --out: skips .claude, skill-deck.toml, skill-deck.lock, AGENTS.md) (same as CLI default):
| File | Required | Purpose |
|---|---|---|
report.md | YES | Comparative analysis + verdict |
README.md | YES | Deck configs, task brief, run metadata |
{side}/decision-log.jsonl | YES | Agent reasoning per side — merged from the per-cell logs by archive |
{side}/decision-log-<cell-id>.jsonl | YES | Per-cell reasoning; the only attributable view (a merged line does not name its cell) |
{side}/artifacts/* | YES | HTML, docx, pdf, etc. |
reproduce.sh | NO | Shell script recording prepare-workdir + archive commands (agent spawn is manual, CLI commands are reproducible) |
4. Restore
deck link --deck ./skill-deck.tomlIf task context is large (cortex cards, research notes), pass file REFERENCES, not inline text:
TASK: Review the API design.
Read: docs/adr/ADR-xxx.md, docs/patterns/xxx.md
Then implement in src/.
Subagent has the same Read capability — shorter prompt, lower cost, can re-read. Use inlining only for small, self-contained tasks.
# single — most common
bunx @lythos/[email protected] single \
--deck ./deck.toml --brief "task" --out ./output
# vs — declarative config
bunx @lythos/[email protected] vs --config ./arena.toml
# Parameters
# --brief "<prompt>" Inline task (primary input for single)
# --deck <path|url> Deck for single subagent (URL auto-fetched)
# --player <name> Only for cross-player: kimi|codex|deepseek|claude
# --timeout <ms> Complex tasks need 300000-600000
# --out <dir> All artifacts copy here after run
# --config <path> arena.toml for vs mode
# --dry-run Print execution plan without running
deck link --deck ./skill-deck.tomlCLI scaffolds, agent executes: The CLI only creates directories + deck files. It does NOT dispatch subagents or score outputs.
Agent tool CANNOT cross-player: Only Bun.spawn can call different CLI binaries. Agent tool spawn is same-agent only.
Judge is not a script: Semantic comparison ("which better fits the scenario") requires LLM inference. Token counting is scriptable; judgment is not.
vs does not pick a winner: Pareto frontier analysis — a cheap-medium-quality deck and expensive-high-quality deck can both be non-dominated.
Subagent spawn parameters (Claude Code baseline — adapt to your platform):
| Parameter | What it does | What it does NOT do |
|---|---|---|
run_in_background | Async spawn. Parent continues. Completion triggers notification. | Does NOT change subagent CWD. Must set via prompt. |
prompt | Initial instructions to subagent. | Does NOT auto-load skills. Skills load from subagent's actual workdir. |
subagent_type | Which agent implementation (claude, general-purpose, etc.) handles the task. | Does NOT set cross-player mode. Cross-player requires CLI runner with --player. |
| When you need to… | Read |
|---|---|
| Set up players, API keys, discovery | references/player-setup.md |
| Look up arena.toml or player config schema | references/configuration-schemas.md |
| Understand Pareto frontier scoring | references/pareto-analysis.md |
| Map arena operations to card game test play | references/test-play-model.md |
| Detect deck synergy and combos | references/combo-and-synergy.md |
| Set up continuous monitoring | references/continuous-monitoring.md |
| Let agent self-initiate arena runs | references/agent-autonomous-arena.md |
| Review design principles | references/design-principles.md |
| Write or run reproduce.sh BDD scenarios | references/reproduce-sh-bdd-contract.md |
A minimal hello-world skill. No scripts, no dependencies. Demonstrates the simplest possible thin-skill: just a SKILL.md.
User-acceptance-driven release workflow using heredoc patch files. Each iteration produces a timestamped pr-<timestamp>-<desc>.sh that self-archives after execution. No tag without explicit user LGTM. Supports rollback via archived backups.
User-acceptance-driven release workflow using heredoc patch files. Each iteration produces a timestamped pr-<timestamp>-<desc>.sh that self-archives after execution. No tag without explicit user LGTM. Supports rollback via archived backups.
Register tasks BEFORE fixing bugs. Close epics when work is done. Always move state through the CLI — never mv files by hand: CLI moves write Status History, manual moves create probe mismatches. Never leave state drift for the next agent to discover via git log. GTD (Getting Things Done)-style g...
Scaffold and build projects for the lythoskill ecosystem only. Creates thin-skill monorepos: heavy logic in npm packages (Starter), agent-facing instructions in lightweight SKILL.md (Skill), build output committed to skills/ (Output).
Declarative skill deck governance. `deck link` reconciles the working set to match skill-deck.toml — deny-by-default removes undeclared skills. DEFAULT patterns: PHASE SWITCH via separate deck files (deck link --deck phase<N>.toml), SEED bootstrap (minimal deck → agent self-expands via deck add +...
Session context dump. Self-assess what the conversation contains that has NO other carrier (no task, no ADR, no epic) — pitfalls, working-tree anomalies, why-we-chose-this, specific next steps — and write to daily/YYYY-MM-DD.md. Things WITH structured carriers go to their carriers. Things WITHOUT...
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience