{"title":"Skills and Libraries","story":[{"type":"markdown","id":"4c42ed83703a4dd4","text":"A **skill** is a text prompt — instructions, examples, and rules given to an LLM that shape how it behaves on a task. A **library** is executable code that runs directly, without LLM involvement. Both can accomplish the same outcome. The question of which to use, and when to graduate a skill into a library, is one of the core design decisions in an AI-augmented workflow."},{"type":"markdown","id":"cb526f57dc9f48c1","text":"## What a Skill Actually Is\n\nA skill file (like `~/.claude/skills/fedwiki-page/SKILL.md`) contains no executable code. It is loaded into the LLM's context window and shapes the model's next output. When Claude creates a wiki page using the fedwiki-page skill, it is:\n\n1. Reading the rules and examples in the skill file\n2. Interpreting your natural language request\n3. Generating JSON that follows those rules\n\nThe skill is probabilistic — Claude *understands* the pattern and applies judgment. It handles ambiguity, fills in missing details, and adapts to context. It is also slow (LLM inference time) and not guaranteed to produce identical output twice."},{"type":"markdown","id":"2f3bfd3afdc4443e","text":"## What a Library Actually Is\n\nA library function like `create_page(title, story_items)` runs deterministically. Given the same inputs it produces the same output, instantly, with no API call. The fedwiki pattern in `main.py` already has embryonic library code:\n\n```python\ndef make_id():\n    return uuid.uuid4().hex[:16]\n```\n\nThis is a one-line library. A fuller `fedwiki.py` module could offer `make_page()`, `make_item()`, `make_journal()` — the entire JSON-building pattern extracted from the skill into importable functions."},{"type":"markdown","id":"d5a889bfcf344eca","text":"## When They Do the Same Thing\n\nThe fedwiki-page skill and a hypothetical `fedwiki.py` library can both produce valid wiki page JSON. They overlap when:\n\n- The task is **well-defined** — the output structure is known and fixed\n- The inputs are **structured** — a title string and a list of content items\n- There is **no judgment required** — no need to decide what the content should be\n\nIn this zone, the skill is over-engineered. You are using an LLM to do something a ten-line Python function could do faster, cheaper, and more reliably."},{"type":"markdown","id":"73cfb11b76a94be2","text":"## When a Skill Is the Right Tool\n\nUse a skill when the task requires **understanding and judgment**:\n\n- **Natural language input** — \"write a page about router models\" requires Claude to decide content, structure, examples, and emphasis. No function can do this.\n- **Ambiguity** — the user hasn't fully specified the output. The skill guides Claude to fill in the gaps sensibly.\n- **One-off creative work** — pages written once by a human collaborating with Claude, not generated programmatically at scale.\n- **Pattern is still evolving** — you are still learning what good output looks like. A skill is easy to edit; refactoring library code is harder.\n\nThe fedwiki skills are correct as skills for all these reasons. Claude uses them to author pages, not to mechanically stamp out JSON."},{"type":"markdown","id":"35fbeaffab254331","text":"## When to Graduate a Skill into a Library\n\nGraduate a skill to a library when:\n\n1. **The pattern has stabilised** — you know exactly what valid output looks like and the skill has stopped changing\n2. **Volume** — you need to generate many pages programmatically (bulk import, API responses, data pipelines)\n3. **Reliability matters** — a ghost page endpoint like `/claude-ghost` must always return valid JSON. A library guarantees structure; a skill might hallucinate a wrong ID or forget a field under load\n4. **Composition** — you want to call the operation from other code, chain it with other functions, or test it with unit tests\n5. **Speed** — library calls are microseconds; skill invocations are seconds\n\nThe ghost page endpoints in `main.py` are a good example: the *content* is generated by Claude (skill), but the *page structure* — wrapping the content in valid JSON with correct IDs — should be a library function."},{"type":"markdown","id":"65512a48091f4d0a","text":"## The Fedwiki Case: Building a Library from Skills\n\nThe fedwiki skills (fedwiki-page, fedwiki-journal, fedwiki-reindex, fedwiki-ghost) collectively describe a complete pattern. That pattern could become a `fedwiki.py` library:\n\n```python\n# fedwiki.py\nimport uuid, json, time\n\ndef make_id():\n    return uuid.uuid4().hex[:16]\n\ndef make_item(text, item_type='markdown'):\n    return {'type': item_type, 'id': make_id(), 'text': text}\n\ndef make_page(title, items):\n    story = [make_item(**i) if isinstance(i, dict) else make_item(i) for i in items]\n    return {\n        'title': title,\n        'story': story,\n        'journal': [{\n            'type': 'create',\n            'item': {'title': title, 'story': story},\n            'date': int(time.time() * 1000),\n            'certificate': 'from marvin'\n        }]\n    }\n\ndef write_page(domain, slug, page, farm='~/Music/Guides/Private'):\n    import os, pathlib\n    path = pathlib.Path(farm).expanduser() / domain / 'pages' / slug\n    path.write_text(json.dumps(page, indent=2))\n```\n\nThe skill remains the *author* — it decides what goes in the page. The library is the *builder* — it assembles the JSON correctly every time."},{"type":"markdown","id":"2e91ef796f8c4b56","text":"## The Right Division of Labour\n\n| Task | Skill | Library |\n|---|---|---|\n| Decide what a page should say | ✅ | ✗ |\n| Build valid page JSON from known content | ✗ | ✅ |\n| Strip and rewrite a journal | ✅ (judgment on what to keep) | ✅ (if always strip-to-create) |\n| Generate IDs | ✗ | ✅ |\n| Write the file to disk | ✗ | ✅ |\n| Reindex a wiki domain | ✗ | ✅ |\n| Interpret a user's natural language request | ✅ | ✗ |\n\nA well-designed system has skills calling library functions: Claude authors the content, the library assembles and stores it correctly."},{"type":"markdown","id":"feacb34670a24e0d","text":"## Practical Path for the Fedwiki Skills\n\n1. **Keep the skills as skills** — they are the right tool for authoring, editing, and one-off page creation with Claude\n2. **Extract a `fedwiki.py` module** into the FastAPI project for programmatic page generation (ghost pages, bulk import, API responses)\n3. **Have the skills reference the library** — the skill documentation can say \"the library is at `assets/api-test/fedwiki.py`\" so Claude uses it rather than re-implementing the pattern\n4. **Test the library, not the skill** — unit tests on `make_page()`, `write_page()` etc. give confidence in the mechanical parts; the skill's quality is evaluated by reading its output\n\n## Related\n\n- [[Fedwiki Page Skill]] — the skill this page discusses graduating\n- [[Fedwiki Ghost Skill]] — already partially library-like in FastAPI\n- [[LiteLLM Routing]] — an example of a library (LiteLLM) replacing hand-coded routing logic"}],"journal":[{"type":"create","item":{"title":"Skills and Libraries","story":[{"type":"markdown","id":"4c42ed83703a4dd4","text":"A **skill** is a text prompt — instructions, examples, and rules given to an LLM that shape how it behaves on a task. A **library** is executable code that runs directly, without LLM involvement. Both can accomplish the same outcome. The question of which to use, and when to graduate a skill into a library, is one of the core design decisions in an AI-augmented workflow."},{"type":"markdown","id":"cb526f57dc9f48c1","text":"## What a Skill Actually Is\n\nA skill file (like `~/.claude/skills/fedwiki-page/SKILL.md`) contains no executable code. It is loaded into the LLM's context window and shapes the model's next output. When Claude creates a wiki page using the fedwiki-page skill, it is:\n\n1. Reading the rules and examples in the skill file\n2. Interpreting your natural language request\n3. Generating JSON that follows those rules\n\nThe skill is probabilistic — Claude *understands* the pattern and applies judgment. It handles ambiguity, fills in missing details, and adapts to context. It is also slow (LLM inference time) and not guaranteed to produce identical output twice."},{"type":"markdown","id":"2f3bfd3afdc4443e","text":"## What a Library Actually Is\n\nA library function like `create_page(title, story_items)` runs deterministically. Given the same inputs it produces the same output, instantly, with no API call. The fedwiki pattern in `main.py` already has embryonic library code:\n\n```python\ndef make_id():\n    return uuid.uuid4().hex[:16]\n```\n\nThis is a one-line library. A fuller `fedwiki.py` module could offer `make_page()`, `make_item()`, `make_journal()` — the entire JSON-building pattern extracted from the skill into importable functions."},{"type":"markdown","id":"d5a889bfcf344eca","text":"## When They Do the Same Thing\n\nThe fedwiki-page skill and a hypothetical `fedwiki.py` library can both produce valid wiki page JSON. They overlap when:\n\n- The task is **well-defined** — the output structure is known and fixed\n- The inputs are **structured** — a title string and a list of content items\n- There is **no judgment required** — no need to decide what the content should be\n\nIn this zone, the skill is over-engineered. You are using an LLM to do something a ten-line Python function could do faster, cheaper, and more reliably."},{"type":"markdown","id":"73cfb11b76a94be2","text":"## When a Skill Is the Right Tool\n\nUse a skill when the task requires **understanding and judgment**:\n\n- **Natural language input** — \"write a page about router models\" requires Claude to decide content, structure, examples, and emphasis. No function can do this.\n- **Ambiguity** — the user hasn't fully specified the output. The skill guides Claude to fill in the gaps sensibly.\n- **One-off creative work** — pages written once by a human collaborating with Claude, not generated programmatically at scale.\n- **Pattern is still evolving** — you are still learning what good output looks like. A skill is easy to edit; refactoring library code is harder.\n\nThe fedwiki skills are correct as skills for all these reasons. Claude uses them to author pages, not to mechanically stamp out JSON."},{"type":"markdown","id":"35fbeaffab254331","text":"## When to Graduate a Skill into a Library\n\nGraduate a skill to a library when:\n\n1. **The pattern has stabilised** — you know exactly what valid output looks like and the skill has stopped changing\n2. **Volume** — you need to generate many pages programmatically (bulk import, API responses, data pipelines)\n3. **Reliability matters** — a ghost page endpoint like `/claude-ghost` must always return valid JSON. A library guarantees structure; a skill might hallucinate a wrong ID or forget a field under load\n4. **Composition** — you want to call the operation from other code, chain it with other functions, or test it with unit tests\n5. **Speed** — library calls are microseconds; skill invocations are seconds\n\nThe ghost page endpoints in `main.py` are a good example: the *content* is generated by Claude (skill), but the *page structure* — wrapping the content in valid JSON with correct IDs — should be a library function."},{"type":"markdown","id":"65512a48091f4d0a","text":"## The Fedwiki Case: Building a Library from Skills\n\nThe fedwiki skills (fedwiki-page, fedwiki-journal, fedwiki-reindex, fedwiki-ghost) collectively describe a complete pattern. That pattern could become a `fedwiki.py` library:\n\n```python\n# fedwiki.py\nimport uuid, json, time\n\ndef make_id():\n    return uuid.uuid4().hex[:16]\n\ndef make_item(text, item_type='markdown'):\n    return {'type': item_type, 'id': make_id(), 'text': text}\n\ndef make_page(title, items):\n    story = [make_item(**i) if isinstance(i, dict) else make_item(i) for i in items]\n    return {\n        'title': title,\n        'story': story,\n        'journal': [{\n            'type': 'create',\n            'item': {'title': title, 'story': story},\n            'date': int(time.time() * 1000),\n            'certificate': 'from marvin'\n        }]\n    }\n\ndef write_page(domain, slug, page, farm='~/Music/Guides/Private'):\n    import os, pathlib\n    path = pathlib.Path(farm).expanduser() / domain / 'pages' / slug\n    path.write_text(json.dumps(page, indent=2))\n```\n\nThe skill remains the *author* — it decides what goes in the page. The library is the *builder* — it assembles the JSON correctly every time."},{"type":"markdown","id":"2e91ef796f8c4b56","text":"## The Right Division of Labour\n\n| Task | Skill | Library |\n|---|---|---|\n| Decide what a page should say | ✅ | ✗ |\n| Build valid page JSON from known content | ✗ | ✅ |\n| Strip and rewrite a journal | ✅ (judgment on what to keep) | ✅ (if always strip-to-create) |\n| Generate IDs | ✗ | ✅ |\n| Write the file to disk | ✗ | ✅ |\n| Reindex a wiki domain | ✗ | ✅ |\n| Interpret a user's natural language request | ✅ | ✗ |\n\nA well-designed system has skills calling library functions: Claude authors the content, the library assembles and stores it correctly."},{"type":"markdown","id":"feacb34670a24e0d","text":"## Practical Path for the Fedwiki Skills\n\n1. **Keep the skills as skills** — they are the right tool for authoring, editing, and one-off page creation with Claude\n2. **Extract a `fedwiki.py` module** into the FastAPI project for programmatic page generation (ghost pages, bulk import, API responses)\n3. **Have the skills reference the library** — the skill documentation can say \"the library is at `assets/api-test/fedwiki.py`\" so Claude uses it rather than re-implementing the pattern\n4. **Test the library, not the skill** — unit tests on `make_page()`, `write_page()` etc. give confidence in the mechanical parts; the skill's quality is evaluated by reading its output\n\n## Related\n\n- [[Fedwiki Page Skill]] — the skill this page discusses graduating\n- [[Ghost Pages Skill]] — already partially library-like in FastAPI\n- [[LiteLLM Routing]] — an example of a library (LiteLLM) replacing hand-coded routing logic"}]},"date":1781004546000,"certificate":"from marvin"}]}