agent-wiki-synthesize-skill · git:20260610.3e26154 · 2026-06-10 · sha256 739a0d1a58a54fe7
agent-wiki-synthesize-skill git:20260610.3e26154A
Immutable. This exact content is served forever at /api/v1/blob/739a0d1a58a54fe7.
---
name: agent-wiki-synthesize-skill
description: Read a normalized Claude Code trajectory JSON and produce a wiki-resident SKILL.md page that future agents can invoke. Use when a trajectory captured a non-trivial successful workflow worth promoting from a free-text guideline to an executable, callable artifact.
---
# Agent Wiki — Synthesize Skill
## Overview
Promote a successful workflow from a saved trajectory into an **executable
agent skill** living inside a wiki at `<wiki>/skills/<slug>/SKILL.md`. The
output is the procedural counterpart to `agent-wiki-extract-guidelines`'s
declarative pages: a guideline tells a future agent *what to do*; a synthesized
skill is a structured workflow page the future agent can read and *execute
directly*, optionally invoking sibling scripts via Bash.
This is the per-trajectory **promote-to-procedural** pass of the `agent-wiki`
family. Run it after one or more trajectories captured the same recipe and
you want future agents to invoke that recipe instead of re-deriving it.
> **Ingesting a whole batch end-to-end?** Prefer the `agent-wiki-ingest`
> skill, which sequences summarize → extract → synthesize → **consolidate**
> → catalog. It runs this skill at the right point (after extraction, before
> consolidation) and guarantees the consolidation pass that clusters the
> surviving atomics is never skipped. Use this standalone skill only to
> promote a single trajectory's workflow.
## When To Use
Use this skill when a trajectory captured:
- A **non-trivial successful workflow** — multiple tool calls, with at least
one custom script or non-obvious sequence — that produced the answer after
trial-and-error. The eventual happy path is worth saving.
- A **reusable command sequence or script** the agent wrote. Particularly
if the agent had to reconstruct it across multiple attempts.
- A pattern a future agent will hit on a similar-but-not-identical task —
parsing a binary format, walking a structured directory, reaching a
specific tool fallback.
Skip this skill — let `agent-wiki-extract-guidelines` cover the case with a
guideline alone — when:
- The workflow is a single trivial command (`grep -c TODO ...`).
- The path embeds secrets, tokens, or one-off user inputs.
- A skill with the same trigger already exists in `<wiki>/skills/`.
- The session ended without reaching a clear successful answer.
## Input
A path that is either:
- a normalized trajectory JSON file
- a directory of such files
Default if no path is given:
`trajectories/normalized`.
## Workflow
### Step 1: Resolve input files
Use `Glob` to enumerate JSON files.
### Step 2: Glance at existing skills
`Glob <wiki>/skills/*/SKILL.md` to see what's already there. **Don't
re-author a skill with the same name** unless the trajectory's recipe
materially refines or generalizes it.
### Step 3: For each trajectory
Read the file. The fields you need:
- `session_id`, `agent`, `model`
- `openai_chat_completion.messages` — the source of truth for what happened
Walk the messages and identify:
#### 3a. The successful workflow
The **final, working** tool sequence — the one that produced the answer.
Distinguish it from the trial-and-error leading up to it. Capture the
exact tool calls, scripts, or command sequences verbatim.
#### 3b. The trial-and-error context
What didn't work — the dead ends. You'll use this to author a *trigger
description* so a future agent knows when to reach for this skill **instead
of** the failing approaches.
#### 3c. Environment assumptions
What was missing or had to be installed (no `exiftool`, `pip install
Pillow` needed, etc.).
If no clearly successful workflow is in the trajectory, output zero
skills for it and continue.
### Step 4: Decide a skill name and trigger
The skill **name** must be:
- kebab-case, action-oriented (`extract-jpeg-exif-camera-optics`,
`parse-png-dimensions`, `walk-zip-central-directory`)
- specific enough that a future agent reading just the name can guess
what it does
- not a duplicate of any existing skill in `<wiki>/skills/`
The skill **description** (one line in frontmatter) describes the *task*,
not the trajectory. Bad: "Solves the lens-model question from session
07d60d9f." Good: "Read camera-optics fields (lens model, focal length,
aperture, ISO) from JPEG EXIF using stdlib `struct` when system EXIF
tools are unavailable."
The **trigger** (frontmatter + `## When To Use`) describes the broad
task context, not the narrow original request.
### Step 5: Synthesize a JSON object
```json
{
"name": "<kebab-case-name>",
"description": "<one-line task description>",
"trigger": "<situational context when this applies>",
"session_id": "<from JSON>",
"normalized_path": "<path to the JSON, relative to repo root>",
"related_summary": "summaries/<sid>.md",
"agent": "<from JSON, default 'claude-code'>",
"tags": ["<2-4 short tags>"],
"overview": "<1-2 sentences: what the skill does and when>",
"when_to_use": [
"<trigger condition 1>",
"<trigger condition 2>"
],
"workflow_steps": [
"<step 1: an instruction to the future agent>",
"<step 2: ...>"
],
"scripts": [
{
"name": "<action>.py",
"language": "python",
"content": "<full script contents>"
}
]
}
```
Notes on each field:
- **`overview`** — the SKILL.md's `## Overview` section body. Keep it
to 1-2 sentences. Don't retell the original session.
- **`when_to_use`** — a bulleted list of trigger conditions. The
future agent matches its current task against these.
- **`workflow_steps`** — the procedural body. Each step is an
instruction the agent will follow. Reference scripts as
`Run \`bash <wiki>/skills/<name>/scripts/<file>.sh\`` (the helper
resolves `<wiki>` at write time).
- **`scripts`** — optional. If the workflow needs a non-trivial script,
include it here. The helper writes it to
`<wiki>/skills/<name>/scripts/<file>` and references it in the
workflow body. Keep scripts minimal — strip incidental log lines or
one-off args; replace literal file names with positional arguments.
### Step 6: Pipe the JSON to the helper
```bash
echo '<json>' | uv run python explorations/agent-wiki/skills/scripts/build_agent_wiki.py render-skill
```
Add `--rewrite` to overwrite an existing skill page.
The helper:
- Validates the JSON: `name` must be kebab-case, `description` and
`workflow_steps` non-empty; sibling scripts must have `name` matching
`^[\w.-]+$`.
- Writes `<wiki>/skills/<slug>/SKILL.md` with frontmatter (`name`,
`description`, `trigger`, `agent`, `sources`, `related_summary`,
`tags`, `verified_at`) and body (Overview, When To Use, Workflow,
Sources).
- Writes `<wiki>/skills/<slug>/scripts/<file>` for each script, marks
shell scripts executable.
- Updates `<wiki>/skills/_id_index.json` (skill slug → relpath).
- Appends `synthesize_skill` to `<wiki>/_audit.log` with session_id +
slug.
- Skips silently if the skill already exists and `--rewrite` was not
passed.
### Step 7: Refresh indexes
After processing all trajectories, run **once**:
```bash
uv run python explorations/agent-wiki/skills/scripts/build_agent_wiki.py catalog
```
This regenerates `<wiki>/skills/index.md`, the section indexes, and
`_index.jsonl` (which gains a `kind: "skill"` row per skill, sorted
between `cluster:` and `guideline:` rows). No LLM cost.
## Output structure
```
<wiki>/skills/
├── _id_index.json skill slug → relpath
├── index.md alphabetical listing (auto-generated)
└── <slug>/
├── SKILL.md the synthesized skill
└── scripts/ optional supporting scripts
└── <action>.{sh,py}
```
The SKILL.md frontmatter shape:
```yaml
---
id: skill:<slug>
type: skill
name: <kebab-case-name>
description: <one-line task description>
trigger: <situational context>
agent: claude-code
sources:
- <normalized_path>
related_summary: summaries/<sid>.md
verified_at: <date>
tags: [<tags>]
---
```
## Skills vs guidelines vs clusters
- **Guideline** (in `<wiki>/guidelines/`): the agent reads it and *decides*
what to do. Free-text advice. Use when the lesson is conceptual.
- **Cluster** (in `<wiki>/guidelines/<slug>__cluster.md`): an aggregator
page grouping related atomics. Recall-preferred over its members.
- **Skill** (in `<wiki>/skills/<slug>/SKILL.md`): a structured workflow
page the agent reads and *executes*. Use when the lesson is a concrete,
reusable recipe with a well-defined input/output.
At retrieval time, `_index.jsonl` lists all three kinds. Sort order is
`cluster` → `skill` → `guideline` → `task` so callable artifacts surface
first. The agent reads the SKILL.md, follows its Workflow section, and
invokes any sibling scripts via Bash.
## Best practices
1. **One skill per workflow.** Two unrelated successful workflows in one
trajectory → two synthesize calls with different names.
2. **Cite the trajectory.** The helper records `sources` +
`related_summary` automatically; you just need to set `session_id`
and `normalized_path` correctly.
3. **Don't promote one-shots.** A skill is worth synthesizing only if
the trigger is plausibly recurring. Single-use trajectories should
stay as guidelines (or nothing at all).
4. **Don't paraphrase failure.** The skill describes what *worked*. If
you're tempted to write "this skill avoids the problem where exiftool
isn't installed," restate as "uses Pillow / stdlib struct; works in
environments without system EXIF tools."
5. **Keep scripts minimal.** Strip log lines, debug prints, validation
that wasn't actually exercised in the trajectory.
6. **Generality is everything.** A skill named `extract-gps-from-jpeg`
will not match a lens-model query. If the trajectory only exercised
one EXIF field, name the skill broadly (`extract-jpeg-exif-camera-optics`)
so future agents recognize its applicability to siblings.