Compile — Knowledge Compiler Reads raw artifacts and compiles them into a structured, interlinked markdown wiki. Inspired by Karpathy's LLM Knowledge Bases. What This Skill Does The knowledge flywheel captures signal reactively (via , , ). closes the loop by: 1. Mining unextracted signal from git and (existing) 2. Growing learnings via validation, synthesis, and gap detection (existing) 3. Compiling raw artifacts into interlinked wiki articles (NEW — the core value) 4. Linting the compiled wiki for contradictions, orphans, and gaps (NEW) 5. Defragging stale and duplicate artifacts (existing)…

.agents/learnings/ .agents/patterns/ 2>/dev/null | while read f; do\n count=$(grep -c '^---

Compile — Knowledge Compiler Reads raw artifacts and compiles them into a structured, interlinked markdown wiki. Inspired by Karpathy's LLM Knowledge Bases. What This Skill Does The knowledge flywheel captures signal reactively (via , , ). closes the loop by: 1. Mining unextracted signal from git and (existing) 2. Growing learnings via validation, synthesis, and gap detection (existing) 3. Compiling raw artifacts into interlinked wiki articles (NEW — the core value) 4. Linting the compiled wiki for contradictions, orphans, and gaps (NEW) 5. Defragging stale and duplicate artifacts (existing)…

\"$f\")\n [ \"$count\" -gt 2 ] && echo \"STACKED_FRONTMATTER: $f ($count delimiters)\"\ndone\n\n# Bundled multi-learning files: more than one ## Learning heading\ngrep -rl '^## Learning' .agents/learnings/ 2>/dev/null | while read f; do\n count=$(grep -c '^## Learning' \"$f\")\n [ \"$count\" -gt 1 ] && echo \"BUNDLED: $f ($count learnings in one file)\"\ndone\n\n# Duplicated headings within a file\nfor f in .agents/learnings/**/*.md .agents/patterns/**/*.md; do\n [ -f \"$f\" ] || continue\n dupes=$(grep '^## ' \"$f\" | sort | uniq -d)\n [ -n \"$dupes\" ] && echo \"DUPLICATE_HEADING: $f — $dupes\"\ndone\n```\n\n**Report normalization defects** in the defrag output. If any are found, list them with severity:\n- PLACEHOLDER → HIGH (empty knowledge pollutes retrieval)\n- STACKED_FRONTMATTER → MEDIUM (parsing errors, possible data loss)\n- BUNDLED → HIGH (breaks per-learning citation tracking)\n- DUPLICATE_HEADING → LOW (cosmetic, may confuse extraction)\n\n## Step 6 — Report\n\n```bash\nmkdir -p .agents/compile\n```\n\nWrite `.agents/compile/YYYY-MM-DD-report.md`:\n\n```markdown\n# Compile Report — YYYY-MM-DD\n\n## Compilation Summary\n- Articles compiled: N (new: N, updated: N, unchanged: N)\n- Source artifacts processed: N\n- Topics identified: N\n- Backlinks created: N\n\n## Lint Summary\n- Health score: N/100\n- Contradictions: N | Orphans: N | Stale claims: N | Gaps: N\n\n## New Learnings Proposed\n- [title]: [summary] (source: [research file or synthesis])\n\n## Validations\n- Validated: N | Stale: N (list files) | Contradicted: N (list with explanation)\n\n## Knowledge Gaps\n- [topic]: [evidence] → suggested learning: \"[title]\"\n\n## Defrag Summary\n- Orphaned: N | Duplicates: N | Oscillating goals: N\n\n## Recommendations\n1. [Actionable next step]\n```\n\nIf `bd` is available, create issues for knowledge gaps:\n\n```bash\nbd add \"[Knowledge Gap] \u003ctopic>\" --label knowledge --label compile\n```\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":12115,"content_sha256":"721b190879e484418d4799d168f59ef72777b3b93eb94f955ab6c81aae8a03a1"},{"filename":"scripts/compile.sh","content":"#!/usr/bin/env bash\nset -euo pipefail\n\n# compile.sh — Pluggable LLM compilation engine for .agents/ → .agents/compiled/\n# Usage: AGENTOPS_COMPILE_RUNTIME=ollama scripts/compile.sh [--sources DIR] [--output DIR] [--incremental] [--force] [--lint-only]\n\nSOURCES_DIR=\".agents\"\nOUTPUT_DIR=\".agents/compiled\"\nINCREMENTAL=true\nLINT_ONLY=false\nHASH_FILE=\"\"\nRUNTIME=\"${AGENTOPS_COMPILE_RUNTIME:-}\"\nOLLAMA_MODEL=\"${AGENTOPS_COMPILE_MODEL:-gemma3:27b}\"\nCLAUDE_MODEL=\"${AGENTOPS_COMPILE_CLAUDE_MODEL:-claude-sonnet-4-20250514}\"\nCLAUDE_CLI_MODEL=\"${AGENTOPS_COMPILE_CLAUDE_CLI_MODEL:-}\"\nOLLAMA_API=\"${OLLAMA_HOST:-http://localhost:11434}\"\nBATCH_SIZE=\"${AGENTOPS_COMPILE_BATCH_SIZE:-25}\"\nMAX_BATCHES=\"${AGENTOPS_COMPILE_MAX_BATCHES:-0}\" # 0 = unlimited\nPREFLIGHT_ONLY=false\n\n# --- Argument parsing ---\nwhile [[ $# -gt 0 ]]; do\n case \"$1\" in\n --sources) SOURCES_DIR=\"$2\"; shift 2 ;;\n --output) OUTPUT_DIR=\"$2\"; shift 2 ;;\n --incremental) INCREMENTAL=true; shift ;;\n --force) INCREMENTAL=false; shift ;;\n --lint-only) LINT_ONLY=true; shift ;;\n --full) shift ;; # default mode, accepted for SKILL.md parity\n --batch-size) BATCH_SIZE=\"$2\"; shift 2 ;;\n --max-batches) MAX_BATCHES=\"$2\"; shift 2 ;;\n --preflight) PREFLIGHT_ONLY=true; shift ;;\n *) echo \"Unknown flag: $1\" >&2; exit 1 ;;\n esac\ndone\n\nHASH_FILE=\"$OUTPUT_DIR/.hashes.json\"\nmkdir -p \"$OUTPUT_DIR\"\n\n# --- Utility functions ---\n\ncompute_hash() {\n if command -v md5sum &>/dev/null; then\n md5sum \"$1\" | cut -d' ' -f1\n else\n md5 -q \"$1\"\n fi\n}\n\nload_hashes() {\n if [[ -f \"$HASH_FILE\" ]]; then\n cat \"$HASH_FILE\"\n else\n echo \"{}\"\n fi\n}\n\nget_stored_hash() {\n local file=\"$1\"\n local hashes=\"$2\"\n echo \"$hashes\" | python3 -c \"\nimport sys, json\ndata = json.load(sys.stdin)\nprint(data.get(sys.argv[1], ''))\n\" \"$file\" 2>/dev/null || echo \"\"\n}\n\n# --- LLM call abstraction ---\n\nllm_call() {\n local system_prompt=\"$1\"\n local user_prompt=\"$2\"\n\n case \"$RUNTIME\" in\n ollama)\n local payload\n payload=$(python3 -c \"\nimport json, sys\nprint(json.dumps({\n 'model': '$OLLAMA_MODEL',\n 'messages': [\n {'role': 'system', 'content': sys.argv[1]},\n {'role': 'user', 'content': sys.argv[2]}\n ],\n 'stream': False\n}))\n\" \"$system_prompt\" \"$user_prompt\")\n curl -sf \"$OLLAMA_API/api/chat\" \\\n -H \"Content-Type: application/json\" \\\n -d \"$payload\" | python3 -c \"import sys,json; print(json.load(sys.stdin)['message']['content'])\"\n ;;\n claude)\n local payload\n payload=$(python3 -c \"\nimport json, sys\nprint(json.dumps({\n 'model': '$CLAUDE_MODEL',\n 'max_tokens': 4096,\n 'system': sys.argv[1],\n 'messages': [{'role': 'user', 'content': sys.argv[2]}]\n}))\n\" \"$system_prompt\" \"$user_prompt\")\n curl -sf \"https://api.anthropic.com/v1/messages\" \\\n -H \"Content-Type: application/json\" \\\n -H \"x-api-key: ${ANTHROPIC_API_KEY:?ANTHROPIC_API_KEY required for claude runtime}\" \\\n -H \"anthropic-version: 2023-06-01\" \\\n -d \"$payload\" | python3 -c \"import sys,json; print(json.load(sys.stdin)['content'][0]['text'])\"\n ;;\n claude-cli)\n # Use the locally installed `claude` binary in headless (-p) mode.\n # No API key required; inherits the user's Claude Code auth.\n if ! command -v claude &>/dev/null; then\n echo \"ERROR: claude-cli runtime requested but 'claude' binary not on PATH.\" >&2\n exit 1\n fi\n local combined=\"${system_prompt}\n\n${user_prompt}\"\n if [[ -n \"$CLAUDE_CLI_MODEL\" ]]; then\n printf '%s' \"$combined\" | claude -p --model \"$CLAUDE_CLI_MODEL\" 2>/dev/null\n else\n printf '%s' \"$combined\" | claude -p 2>/dev/null\n fi\n ;;\n openai)\n local payload\n payload=$(python3 -c \"\nimport json, sys\nprint(json.dumps({\n 'model': '${AGENTOPS_COMPILE_OPENAI_MODEL:-gpt-4o}',\n 'messages': [\n {'role': 'system', 'content': sys.argv[1]},\n {'role': 'user', 'content': sys.argv[2]}\n ]\n}))\n\" \"$system_prompt\" \"$user_prompt\")\n curl -sf \"${OPENAI_BASE_URL:-https://api.openai.com}/v1/chat/completions\" \\\n -H \"Content-Type: application/json\" \\\n -H \"Authorization: Bearer ${OPENAI_API_KEY:?OPENAI_API_KEY required for openai runtime}\" \\\n -d \"$payload\" | python3 -c \"import sys,json; print(json.load(sys.stdin)['choices'][0]['message']['content'])\"\n ;;\n *)\n echo \"ERROR: AGENTOPS_COMPILE_RUNTIME must be set to one of: ollama, claude, claude-cli, openai.\" >&2\n echo \"\" >&2\n echo \"Pick one of these that matches what you have installed:\" >&2\n echo \" export AGENTOPS_COMPILE_RUNTIME=claude-cli # uses local 'claude' binary, no API key needed\" >&2\n echo \" export AGENTOPS_COMPILE_RUNTIME=ollama # needs OLLAMA_HOST (default http://localhost:11434)\" >&2\n echo \" export AGENTOPS_COMPILE_RUNTIME=claude # needs ANTHROPIC_API_KEY\" >&2\n echo \" export AGENTOPS_COMPILE_RUNTIME=openai # needs OPENAI_API_KEY\" >&2\n echo \"\" >&2\n echo \"For interactive compilation, invoke /compile directly in a Claude Code session.\" >&2\n exit 1\n ;;\n esac\n}\n\n# --- Preflight: verify the selected runtime is usable ---\n\npreflight_runtime() {\n case \"$RUNTIME\" in\n claude-cli)\n if ! command -v claude &>/dev/null; then\n echo \"ERROR: runtime=claude-cli but 'claude' binary is not on PATH.\" >&2\n echo \"Install Claude Code or switch runtime: export AGENTOPS_COMPILE_RUNTIME=ollama\" >&2\n return 1\n fi\n ;;\n claude)\n if [[ -z \"${ANTHROPIC_API_KEY:-}\" ]]; then\n echo \"ERROR: runtime=claude but ANTHROPIC_API_KEY is not set.\" >&2\n echo \"Either export ANTHROPIC_API_KEY=... or switch: export AGENTOPS_COMPILE_RUNTIME=claude-cli\" >&2\n return 1\n fi\n ;;\n openai)\n if [[ -z \"${OPENAI_API_KEY:-}\" ]]; then\n echo \"ERROR: runtime=openai but OPENAI_API_KEY is not set.\" >&2\n return 1\n fi\n ;;\n ollama)\n if ! command -v curl &>/dev/null; then\n echo \"ERROR: runtime=ollama but curl is not on PATH.\" >&2\n return 1\n fi\n if ! curl -sf --max-time 2 \"$OLLAMA_API/api/tags\" >/dev/null 2>&1; then\n echo \"WARN: runtime=ollama but $OLLAMA_API did not respond to /api/tags (continuing anyway)\" >&2\n fi\n ;;\n \"\")\n echo \"ERROR: AGENTOPS_COMPILE_RUNTIME is not set. See 'ao compile --help' for options.\" >&2\n return 1\n ;;\n *)\n echo \"ERROR: unknown runtime '$RUNTIME'. Expected one of: ollama, claude, claude-cli, openai.\" >&2\n return 1\n ;;\n esac\n return 0\n}\n\n# --- Phase: Inventory ---\n\ninventory_sources() {\n local stored_hashes\n stored_hashes=$(load_hashes)\n local changed_files=()\n local unchanged_count=0\n\n local source_dirs=(\n \"$SOURCES_DIR/learnings\"\n \"$SOURCES_DIR/patterns\"\n \"$SOURCES_DIR/research\"\n \"$SOURCES_DIR/retros\"\n \"$SOURCES_DIR/forge\"\n \"$SOURCES_DIR/knowledge\"\n )\n\n for dir in \"${source_dirs[@]}\"; do\n [[ -d \"$dir\" ]] || continue\n while IFS= read -r -d '' file; do\n local current_hash\n current_hash=$(compute_hash \"$file\")\n local stored_hash\n stored_hash=$(get_stored_hash \"$file\" \"$stored_hashes\")\n\n if [[ \"$INCREMENTAL\" == \"true\" ]] && [[ \"$current_hash\" == \"$stored_hash\" ]]; then\n unchanged_count=$((unchanged_count + 1))\n else\n changed_files+=(\"$file\")\n fi\n done \u003c \u003c(find \"$dir\" -type f -name \"*.md\" -print0)\n done\n\n echo \"Changed: ${#changed_files[@]}, Unchanged: $unchanged_count\" >&2\n\n # Output changed files, one per line\n for f in \"${changed_files[@]}\"; do\n echo \"$f\"\n done\n}\n\n# --- Phase: Compile ---\n\ncompile_articles() {\n local changed_files=()\n while IFS= read -r line; do\n [[ -n \"$line\" ]] && changed_files+=(\"$line\")\n done\n\n if [[ ${#changed_files[@]} -eq 0 ]]; then\n echo \"No changed files to compile.\" >&2\n return 0\n fi\n\n # Explicit outer batching loop: chunk changed_files into slices of\n # $BATCH_SIZE and call compile_single_batch for each slice. Keeping the\n # loop explicit (no recursion, no prefix-env-assignment) makes the flow\n # testable and readable.\n local total=${#changed_files[@]}\n local bsize=${BATCH_SIZE:-25}\n if ! [[ \"$bsize\" =~ ^[0-9]+$ ]] || [[ \"$bsize\" -lt 1 ]]; then\n bsize=25\n fi\n if [[ \"$total\" -le \"$bsize\" ]]; then\n compile_single_batch \"${changed_files[@]}\"\n return $?\n fi\n\n echo \"Batching $total changed files into batches of $bsize...\" >&2\n local batch_index=0\n local i=0\n while [[ $i -lt $total ]]; do\n if [[ \"$MAX_BATCHES\" -gt 0 ]] && [[ $batch_index -ge \"$MAX_BATCHES\" ]]; then\n echo \"Reached --max-batches=$MAX_BATCHES; stopping after $batch_index batch(es). Remaining $((total - i)) files will be picked up on next run.\" >&2\n break\n fi\n local end=$((i + bsize))\n [[ $end -gt $total ]] && end=$total\n batch_index=$((batch_index + 1))\n echo \"Batch $batch_index: files $((i+1))..$end of $total\" >&2\n if ! compile_single_batch \"${changed_files[@]:i:bsize}\"; then\n echo \"Batch $batch_index failed; aborting.\" >&2\n return 1\n fi\n i=$end\n done\n echo \"Batched compile complete: $batch_index batch(es), $total file(s).\" >&2\n return 0\n}\n\n# compile_single_batch compiles one chunk of changed files in a single LLM\n# call. Callers (compile_articles) handle chunking; this function assumes\n# the argv list fits in one prompt.\ncompile_single_batch() {\n local changed_files=(\"$@\")\n if [[ ${#changed_files[@]} -eq 0 ]]; then\n return 0\n fi\n\n # Read all changed files into a single context\n local context=\"\"\n for f in \"${changed_files[@]}\"; do\n context+=\"\n--- FILE: $f ---\n$(cat \"$f\")\n\"\n done\n\n local system_prompt=\"You are a knowledge compiler. You read raw knowledge artifacts (learnings, research, patterns, retros) and compile them into encyclopedia-style wiki articles.\n\nRules:\n- Each article covers ONE topic/theme\n- Use [[wikilinks]] for cross-references between articles\n- Include a Sources section listing source files\n- Include a Related section with [[links]] to related topics\n- Write synthesis, not summaries — connect insights across sources\n- Use YAML frontmatter with title, compiled date, sources list, and tags\n- Article filenames should be kebab-case topic slugs (e.g., testing-strategy.md)\n\nIMPORTANT: Do NOT wrap your output in markdown code fences (\\`\\`\\`). Output raw article content directly after each === ARTICLE: marker.\"\n\n local user_prompt=\"Compile the following raw knowledge artifacts into wiki articles. Output each article separated by '=== ARTICLE: \u003cfilename> ===' markers.\n\n$context\n\nFor each article output:\n=== ARTICLE: \u003ctopic-slug>.md ===\n\u003cfull article content with frontmatter>\n\nAfter all articles, output:\n=== INDEX ===\n\u003cindex.md content cataloging all articles by category>\"\n\n local result\n result=$(llm_call \"$system_prompt\" \"$user_prompt\")\n\n # Parse result into individual files\n local current_file=\"\"\n local current_content=\"\"\n local written_count=0\n\n while IFS= read -r line; do\n if [[ \"$line\" =~ ^===\\ ARTICLE:\\ (.+)\\ ===$ ]]; then\n # Save previous article if exists\n if [[ -n \"$current_file\" ]] && [[ -n \"$current_content\" ]]; then\n echo \"$current_content\" > \"$OUTPUT_DIR/$current_file\"\n echo \"Compiled: $current_file\" >&2\n written_count=$((written_count + 1))\n fi\n current_file=$(basename \"${BASH_REMATCH[1]}\")\n current_content=\"\"\n elif [[ \"$line\" =~ ^===\\ INDEX\\ ===$ ]]; then\n # Save previous article\n if [[ -n \"$current_file\" ]] && [[ -n \"$current_content\" ]]; then\n echo \"$current_content\" > \"$OUTPUT_DIR/$current_file\"\n echo \"Compiled: $current_file\" >&2\n written_count=$((written_count + 1))\n fi\n current_file=\"index.md\"\n current_content=\"\"\n elif [[ \"$line\" =~ ^[[:space:]]*\\`\\`\\`(markdown)?[[:space:]]*$ ]]; then\n # Defense-in-depth: skip opening/closing markdown code fences that\n # some LLM runtimes (notably `claude -p`) wrap around the response.\n continue\n else\n current_content+=\"$line\n\"\n fi\n done \u003c\u003c\u003c \"$result\"\n\n # Save last article\n if [[ -n \"$current_file\" ]] && [[ -n \"$current_content\" ]]; then\n echo \"$current_content\" > \"$OUTPUT_DIR/$current_file\"\n echo \"Compiled: $current_file\" >&2\n written_count=$((written_count + 1))\n fi\n\n # Only persist hashes if this batch actually produced output. If the LLM\n # returned a malformed/empty response (or the batch was otherwise lost),\n # leave the input files' hashes alone so they get retried on the next run.\n # This is the Task A fix: files scheduled but not compiled must NOT have\n # their hashes saved, otherwise they are silently stranded forever.\n if [[ $written_count -gt 0 ]]; then\n save_hashes \"${changed_files[@]}\"\n else\n echo \"WARN: batch produced no articles; skipping hash persistence for ${#changed_files[@]} input file(s) so they retry next run.\" >&2\n fi\n\n # Append to log\n local article_count\n article_count=$(find \"$OUTPUT_DIR\" -name \"*.md\" ! -name \"index.md\" ! -name \"log.md\" ! -name \"lint-report.md\" | wc -l | tr -d ' ')\n local log_entry\n log_entry=\"## [$(date +%Y-%m-%d)] compile | $article_count articles from ${#changed_files[@]} sources\n- Compiled from: ${changed_files[*]}\n\"\n echo \"$log_entry\" >> \"$OUTPUT_DIR/log.md\"\n}\n\nsave_hashes() {\n local files=(\"$@\")\n local json=\"{\"\n local first=true\n\n for f in \"${files[@]}\"; do\n local h\n h=$(compute_hash \"$f\")\n if [[ \"$first\" == \"true\" ]]; then\n first=false\n else\n json+=\",\"\n fi\n json+=\"\\\"$f\\\":\\\"$h\\\"\"\n done\n\n json+=\"}\"\n\n # Merge with existing hashes\n if [[ -f \"$HASH_FILE\" ]]; then\n python3 -c \"\nimport json, sys\nhash_file = sys.argv[1]\nnew = json.loads(sys.argv[2])\nwith open(hash_file) as f:\n existing = json.load(f)\nexisting.update(new)\nwith open(hash_file, 'w') as f:\n json.dump(existing, f, indent=2)\n\" \"$HASH_FILE\" \"$json\"\n else\n echo \"$json\" | python3 -m json.tool > \"$HASH_FILE\"\n fi\n}\n\n# --- Phase: Lint ---\n\nlint_wiki() {\n local articles=()\n while IFS= read -r -d '' f; do\n articles+=(\"$f\")\n done \u003c \u003c(find \"$OUTPUT_DIR\" -name \"*.md\" ! -name \"index.md\" ! -name \"log.md\" ! -name \"lint-report.md\" ! -name \".hashes.json\" -print0)\n\n if [[ ${#articles[@]} -eq 0 ]]; then\n echo \"No articles to lint.\" >&2\n return 0\n fi\n\n local orphans=()\n local stale_claims=()\n\n for article in \"${articles[@]}\"; do\n local basename_article\n basename_article=$(basename \"$article\" .md)\n\n # Check for orphans: articles with no inbound [[wikilinks]]\n local inbound=0\n for other in \"${articles[@]}\"; do\n [[ \"$other\" == \"$article\" ]] && continue\n if grep -q \"\\[\\[$basename_article\\]\\]\" \"$other\" 2>/dev/null; then\n inbound=$((inbound + 1))\n break\n fi\n done\n if [[ $inbound -eq 0 ]]; then\n orphans+=(\"$basename_article\")\n fi\n\n # Check for stale code references\n while IFS= read -r ref; do\n if [[ -n \"$ref\" ]] && [[ ! -e \"$ref\" ]]; then\n stale_claims+=(\"$basename_article references $ref\")\n fi\n done \u003c \u003c(grep -oE '`[a-zA-Z0-9_./-]+\\.(go|py|sh|ts|js|yaml|json|md)`' \"$article\" 2>/dev/null | tr -d '`' || true)\n done\n\n # Write lint report\n cat > \"$OUTPUT_DIR/lint-report.md\" \u003c\u003c REPORT\n# Wiki Lint Report — $(date +%Y-%m-%d)\n\n## Orphan Pages: ${#orphans[@]}\n$(for o in \"${orphans[@]}\"; do echo \"- [[$o]]\"; done)\n\n## Stale Claims: ${#stale_claims[@]}\n$(for s in \"${stale_claims[@]}\"; do echo \"- $s\"; done)\n\n## Articles Scanned: ${#articles[@]}\nREPORT\n\n echo \"Lint complete: ${#orphans[@]} orphans, ${#stale_claims[@]} stale claims\" >&2\n}\n\n# --- Main ---\n\nmain() {\n echo \"=== Knowledge Compiler ===\" >&2\n echo \"Runtime: ${RUNTIME:-inline}\" >&2\n echo \"Sources: $SOURCES_DIR\" >&2\n echo \"Output: $OUTPUT_DIR\" >&2\n echo \"Incremental: $INCREMENTAL\" >&2\n echo \"Batch size: ${BATCH_SIZE}\" >&2\n\n if [[ \"$PREFLIGHT_ONLY\" == \"true\" ]]; then\n preflight_runtime\n return $?\n fi\n\n if [[ \"$LINT_ONLY\" == \"true\" ]]; then\n lint_wiki\n return 0\n fi\n\n # Verify runtime is configured before doing any work.\n preflight_runtime || return 1\n\n # Inventory → Compile → Lint\n local changed_files\n changed_files=$(inventory_sources)\n\n if [[ -n \"$changed_files\" ]]; then\n echo \"$changed_files\" | compile_articles\n else\n echo \"All source files unchanged — skipping compilation.\" >&2\n fi\n\n lint_wiki\n echo \"=== Compilation complete ===\" >&2\n}\n\nmain\n","content_type":"application/x-sh; charset=utf-8","language":"bash","size":16387,"content_sha256":"177a51e95a362eed738d1210fcc214ae590a5a454a71b32c1c325cff9545ae4f"},{"filename":"scripts/tests/test-fence-stripping.sh","content":"#!/usr/bin/env bash\n# test-fence-stripping.sh — empirically verify that the splitter in\n# compile.sh skips markdown code fences (```markdown / ```) emitted by\n# some LLM runtimes (notably `claude -p`).\n#\n# Standalone: does NOT source compile.sh (it tops-out in side-effect code);\n# instead it replicates the fence-skipping rule and asserts it matches\n# every fence variant we've seen in real smoke runs.\n\nset -euo pipefail\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nCOMPILE_SH=\"$SCRIPT_DIR/../compile.sh\"\n\n# 1. Static check: the splitter contains the fence-skipping clause.\nif ! grep -q 'markdown.*code fences' \"$COMPILE_SH\"; then\n echo \"FAIL: compile.sh splitter is missing fence-stripping clause\" >&2\n exit 1\nfi\n\n# 2. Static check: system prompt tells the LLM NOT to emit fences.\nif ! grep -q 'Do NOT wrap your output in markdown code fences' \"$COMPILE_SH\"; then\n echo \"FAIL: compile.sh system prompt is missing fence-suppression instruction\" >&2\n exit 1\nfi\n\n# 3. Behavioral check: the regex must match exactly the fence-lines we want\n# to strip and nothing else. Mirror the splitter's regex.\nfence_regex='^[[:space:]]*```(markdown)?[[:space:]]*

Compile — Knowledge Compiler Reads raw artifacts and compiles them into a structured, interlinked markdown wiki. Inspired by Karpathy's LLM Knowledge Bases. What This Skill Does The knowledge flywheel captures signal reactively (via , , ). closes the loop by: 1. Mining unextracted signal from git and (existing) 2. Growing learnings via validation, synthesis, and gap detection (existing) 3. Compiling raw artifacts into interlinked wiki articles (NEW — the core value) 4. Linting the compiled wiki for contradictions, orphans, and gaps (NEW) 5. Defragging stale and duplicate artifacts (existing)…

\n\nexpect_match() {\n local label=\"$1\" line=\"$2\"\n if [[ \"$line\" =~ $fence_regex ]]; then\n return 0\n fi\n echo \"FAIL: expected match for $label: [$line]\" >&2\n exit 1\n}\n\nexpect_nomatch() {\n local label=\"$1\" line=\"$2\"\n if [[ \"$line\" =~ $fence_regex ]]; then\n echo \"FAIL: expected NO match for $label: [$line]\" >&2\n exit 1\n fi\n}\n\nexpect_match \"opening-markdown-fence\" '```markdown'\nexpect_match \"bare-closing-fence\" '```'\nexpect_match \"indented-opening-fence\" ' ```markdown'\nexpect_match \"trailing-space-fence\" '``` '\n# Must NOT match legitimate in-article fenced blocks with languages we care about.\nexpect_nomatch \"python-fence\" '```python'\nexpect_nomatch \"bash-fence\" '```bash'\nexpect_nomatch \"inline-backticks\" 'the `foo` command'\nexpect_nomatch \"prose-with-backticks\" 'run ```bash then continue'\n\necho \"OK: fence-stripping invariants hold.\"\n","content_type":"application/x-sh; charset=utf-8","language":"bash","size":2051,"content_sha256":"e1f245ccf75c5185ffd3199ca280da53697ae60d1630914951125d3e235ee7e0"},{"filename":"scripts/validate.sh","content":"#!/usr/bin/env bash\nset -euo pipefail\nSKILL_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")/..\" && pwd)\"\n# Verify SKILL.md exists and has frontmatter\n[[ -f \"$SKILL_DIR/SKILL.md\" ]] || { echo \"FAIL: missing SKILL.md\"; exit 1; }\nhead -1 \"$SKILL_DIR/SKILL.md\" | grep -q \"^---$\" || { echo \"FAIL: missing frontmatter\"; exit 1; }\necho \"OK: $(basename \"$SKILL_DIR\")\"\n","content_type":"application/x-sh; charset=utf-8","language":"bash","size":354,"content_sha256":"792f4602829837c0d71cd470c0bbcf686bad89bd1dac3f8de3113ce19ae3d7c6"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"Compile — Knowledge Compiler","type":"text"}]},{"type":"paragraph","content":[{"text":"Reads raw ","type":"text"},{"text":".agents/","type":"text","marks":[{"type":"code_inline"}]},{"text":" artifacts and compiles them into a structured, interlinked markdown wiki. Inspired by ","type":"text"},{"text":"Karpathy's LLM Knowledge Bases","type":"text","marks":[{"type":"link","attrs":{"href":"https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f","title":null}}]},{"text":".","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"What This Skill Does","type":"text"}]},{"type":"paragraph","content":[{"text":"The knowledge flywheel captures signal reactively (via ","type":"text"},{"text":"/retro","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"/post-mortem","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"/forge","type":"text","marks":[{"type":"code_inline"}]},{"text":"). ","type":"text"},{"text":"/compile","type":"text","marks":[{"type":"code_inline"}]},{"text":" closes the loop by:","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Mining","type":"text","marks":[{"type":"strong"}]},{"text":" unextracted signal from git and ","type":"text"},{"text":".agents/","type":"text","marks":[{"type":"code_inline"}]},{"text":" (existing)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Growing","type":"text","marks":[{"type":"strong"}]},{"text":" learnings via validation, synthesis, and gap detection (existing)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Compiling","type":"text","marks":[{"type":"strong"}]},{"text":" raw artifacts into interlinked wiki articles (NEW — the core value)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Linting","type":"text","marks":[{"type":"strong"}]},{"text":" the compiled wiki for contradictions, orphans, and gaps (NEW)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Defragging","type":"text","marks":[{"type":"strong"}]},{"text":" stale and duplicate artifacts (existing)","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"No vector DB.","type":"text","marks":[{"type":"strong"}]},{"text":" At personal scale (~100-400 articles), the compiled wiki fits in context windows. The wiki IS the retrieval layer.","type":"text"}]},{"type":"paragraph","content":[{"text":"Output:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":".agents/compiled/","type":"text","marks":[{"type":"code_inline"}]},{"text":" — encyclopedia-style markdown with ","type":"text"},{"text":"[[backlinks]]","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"index.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" catalog, and ","type":"text"},{"text":"log.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" chronological record.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Pluggable Compute Backend","type":"text"}]},{"type":"paragraph","content":[{"text":"Set ","type":"text"},{"text":"AGENTOPS_COMPILE_RUNTIME","type":"text","marks":[{"type":"code_inline"}]},{"text":" to choose the LLM backend:","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Value","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Backend","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Notes","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"claude-cli","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Local ","type":"text"},{"text":"claude","type":"text","marks":[{"type":"code_inline"}]},{"text":" binary","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Zero-config. Inherits your Claude Code auth — no API key needed. Auto-selected if ","type":"text"},{"text":"claude","type":"text","marks":[{"type":"code_inline"}]},{"text":" is on PATH and nothing else is set.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"ollama","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Ollama API","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Default model: ","type":"text"},{"text":"gemma3:27b","type":"text","marks":[{"type":"code_inline"}]},{"text":". Set ","type":"text"},{"text":"OLLAMA_HOST","type":"text","marks":[{"type":"code_inline"}]},{"text":" for remote (e.g., ","type":"text"},{"text":"ssh -L 11435:localhost:11435 bushido-windows","type":"text","marks":[{"type":"code_inline"}]},{"text":").","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"claude","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Claude API (HTTP)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Uses ","type":"text"},{"text":"ANTHROPIC_API_KEY","type":"text","marks":[{"type":"code_inline"}]},{"text":". Model: ","type":"text"},{"text":"claude-sonnet-4-20250514","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"openai","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"OpenAI-compatible","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Uses ","type":"text"},{"text":"OPENAI_API_KEY","type":"text","marks":[{"type":"code_inline"}]},{"text":" + ","type":"text"},{"text":"OPENAI_BASE_URL","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"(unset)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Claude Code session","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Compilation happens inline via the current session's LLM.","type":"text"}]}]}]}]},{"type":"paragraph","content":[{"text":"When ","type":"text"},{"text":"AGENTOPS_COMPILE_RUNTIME","type":"text","marks":[{"type":"code_inline"}]},{"text":" is unset, ","type":"text"},{"text":"ao compile","type":"text","marks":[{"type":"code_inline"}]},{"text":" first tries to auto-detect a local ","type":"text"},{"text":"claude","type":"text","marks":[{"type":"code_inline"}]},{"text":" binary (claude-cli runtime). If that is also absent, headless compile fails fast with an explicit error naming the env var to set. Interactive ","type":"text"},{"text":"/compile","type":"text","marks":[{"type":"code_inline"}]},{"text":" invocations still run compilation prompts inline — the agent reading this SKILL.md IS the compiler.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Runtime preference (override auto-detect)","type":"text"}]},{"type":"paragraph","content":[{"text":"To force a non-auto-detected runtime permanently (e.g. you have ","type":"text"},{"text":"claude","type":"text","marks":[{"type":"code_inline"}]},{"text":" installed but prefer Ollama for privacy), set it in ","type":"text"},{"text":"~/.agentops/config.yaml","type":"text","marks":[{"type":"code_inline"}]},{"text":":","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"yaml"},"content":[{"text":"compile:\n preferred_runtime: ollama","type":"text"}]},{"type":"paragraph","content":[{"text":"Precedence (high → low): ","type":"text"},{"text":"--runtime","type":"text","marks":[{"type":"code_inline"}]},{"text":" flag, ","type":"text"},{"text":"AGENTOPS_COMPILE_RUNTIME","type":"text","marks":[{"type":"code_inline"}]},{"text":" env, ","type":"text"},{"text":"compile.preferred_runtime","type":"text","marks":[{"type":"code_inline"}]},{"text":" config, ","type":"text"},{"text":"claude","type":"text","marks":[{"type":"code_inline"}]},{"text":"-binary auto-detect, empty (error).","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Large-corpus batching","type":"text"}]},{"type":"paragraph","content":[{"text":"ao compile","type":"text","marks":[{"type":"code_inline"}]},{"text":" passes ","type":"text"},{"text":"--batch-size","type":"text","marks":[{"type":"code_inline"}]},{"text":" to the headless compiler (default ","type":"text"},{"text":"25","type":"text","marks":[{"type":"code_inline"}]},{"text":" changed files per LLM prompt). A fresh run against a 2000+ file corpus will split into batches automatically instead of sending one giant prompt.","type":"text"}]},{"type":"paragraph","content":[{"text":"Flags:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"--batch-size N","type":"text","marks":[{"type":"code_inline"}]},{"text":" — files per batch (default 25)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"--max-batches N","type":"text","marks":[{"type":"code_inline"}]},{"text":" — cap batches per invocation; remaining files are picked up on the next run (default 0 = unlimited)","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Execution Steps","type":"text"}]},{"type":"paragraph","content":[{"text":"Phase-by-phase detail lives in ","type":"text"},{"text":"references/phases.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/phases.md","title":null}}]},{"text":". Summary of modes:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"/compile","type":"text","marks":[{"type":"code_inline"}]},{"text":" — Full cycle: Mine → Grow → Compile → Lint → Defrag","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"/compile --compile-only","type":"text","marks":[{"type":"code_inline"}]},{"text":" — Skip mine/grow, just compile + lint","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"/compile --lint-only","type":"text","marks":[{"type":"code_inline"}]},{"text":" — Only lint the existing compiled wiki","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"/compile --defrag-only","type":"text","marks":[{"type":"code_inline"}]},{"text":" — Only run defrag/cleanup","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"/compile --mine-only","type":"text","marks":[{"type":"code_inline"}]},{"text":" — Only run mine + grow (legacy behavior)","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"The steps are:","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Mine","type":"text","marks":[{"type":"strong"}]},{"text":" — extract signal from git + ","type":"text"},{"text":".agents/research/","type":"text","marks":[{"type":"code_inline"}]},{"text":" + complexity hotspots","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Grow","type":"text","marks":[{"type":"strong"}]},{"text":" — LLM-driven validation, synthesis, gap detection; adjust learning confidence","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Compile","type":"text","marks":[{"type":"strong"}]},{"text":" — inventory → topic extraction → wiki articles with ","type":"text"},{"text":"[[backlinks]]","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Lint","type":"text","marks":[{"type":"strong"}]},{"text":" — contradictions, orphans, missing cross-refs, stale claims","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Defrag","type":"text","marks":[{"type":"strong"}]},{"text":" — prune stale, dedup near-duplicates, sweep oscillating goals, normalization scan","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Report","type":"text","marks":[{"type":"strong"}]},{"text":" — write ","type":"text"},{"text":".agents/compile/YYYY-MM-DD-report.md","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"paragraph","content":[{"text":"See ","type":"text"},{"text":"references/phases.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/phases.md","title":null}}]},{"text":" for the full per-phase procedure, confidence-scoring table, auto-promotion rules, template shapes for article / index / log / lint-report / compile-report, and the normalization defect scan.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Scheduling / Auto-Trigger","type":"text"}]},{"type":"paragraph","content":[{"text":"Lightweight defrag (prune + dedup, no mining or compilation) runs automatically at session end via the ","type":"text"},{"text":"compile-session-defrag.sh","type":"text","marks":[{"type":"code_inline"}]},{"text":" hook. This keeps the knowledge store clean without requiring manual ","type":"text"},{"text":"/compile","type":"text","marks":[{"type":"code_inline"}]},{"text":" invocations. The hook:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Fires on every ","type":"text"},{"text":"SessionEnd","type":"text","marks":[{"type":"code_inline"}]},{"text":" event after ","type":"text"},{"text":"session-end-maintenance.sh","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Skips silently if the ","type":"text"},{"text":"ao","type":"text","marks":[{"type":"code_inline"}]},{"text":" CLI is not available","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Runs only ","type":"text"},{"text":"ao defrag --prune --dedup","type":"text","marks":[{"type":"code_inline"}]},{"text":" (no compilation or mining)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Has a 20-second timeout to avoid blocking session teardown","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"For full compilation, invoke ","type":"text"},{"text":"/compile","type":"text","marks":[{"type":"code_inline"}]},{"text":" manually or schedule the headless compiler script with your host OS:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Example: external cron entry for nightly compilation on bushido\n0 3 * * * cd /path/to/repo && AGENTOPS_COMPILE_RUNTIME=ollama bash skills/compile/scripts/compile.sh --force","type":"text"}]},{"type":"paragraph","content":[{"text":"AgentOps exposes this flow through ","type":"text"},{"text":"ao compile","type":"text","marks":[{"type":"code_inline"}]},{"text":". If you want unattended compilation, use your host scheduler (","type":"text"},{"text":"launchd","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"cron","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"systemd","type":"text","marks":[{"type":"code_inline"}]},{"text":", CI, etc.) to invoke ","type":"text"},{"text":"ao compile --force --runtime ollama","type":"text","marks":[{"type":"code_inline"}]},{"text":" or call the lower-level ","type":"text"},{"text":"bash skills/compile/scripts/compile.sh","type":"text","marks":[{"type":"code_inline"}]},{"text":" directly. If you want the broader private overnight loop, use ","type":"text"},{"text":"ao overnight start","type":"text","marks":[{"type":"code_inline"}]},{"text":" instead of inventing a parallel Dream wrapper inside ","type":"text"},{"text":"/compile","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Interactive Modes","type":"text"}]},{"type":"paragraph","content":[{"text":"These modes describe the interactive ","type":"text"},{"text":"/compile","type":"text","marks":[{"type":"code_inline"}]},{"text":" skill behavior:","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Mode","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Description","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--compile-only","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Skip mine/grow, just compile + lint","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--lint-only","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Only lint the existing compiled wiki","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--defrag-only","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Only run defrag/cleanup","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--mine-only","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Only run mine + grow (legacy behavior)","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--full","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Full cycle: mine → grow → compile → lint → defrag","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--since 26h","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Time window for the mine phase","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--incremental","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Skip unchanged source files (hash-based)","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--force","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Recompile all articles regardless of hashes","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Headless Script Flags","type":"text"}]},{"type":"paragraph","content":[{"text":"For unattended runs, ","type":"text"},{"text":"bash skills/compile/scripts/compile.sh","type":"text","marks":[{"type":"code_inline"}]},{"text":" supports:","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Flag","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Default","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Description","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--sources \u003cdir>","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":".agents","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Source root for learnings, patterns, research, retros, forge, and knowledge","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--output \u003cdir>","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":".agents/compiled","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Target directory for compiled wiki output","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--incremental","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"on","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Skip unchanged source files (hash-based)","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--force","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"off","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Recompile all articles regardless of hashes","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--lint-only","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"off","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Only run the lint pass on the existing compiled wiki","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--full","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"on","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Accepted for parity; default behavior already runs the full headless compile path","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Examples","type":"text"}]},{"type":"paragraph","content":[{"text":"User says:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"/compile","type":"text","marks":[{"type":"code_inline"}]},{"text":" — Full Mine → Grow → Compile → Lint → Defrag cycle.","type":"text"}]},{"type":"paragraph","content":[{"text":"User says:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"/compile --compile-only","type":"text","marks":[{"type":"code_inline"}]},{"text":" — Just compile raw artifacts into wiki.","type":"text"}]},{"type":"paragraph","content":[{"text":"User says:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"/compile --lint-only","type":"text","marks":[{"type":"code_inline"}]},{"text":" — Scan existing wiki for health issues.","type":"text"}]},{"type":"paragraph","content":[{"text":"User says:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"/compile --since 7d","type":"text","marks":[{"type":"code_inline"}]},{"text":" — Mines with a wider window (7 days).","type":"text"}]},{"type":"paragraph","content":[{"text":"Scheduled externally:","type":"text","marks":[{"type":"strong"}]},{"text":" Nightly compilation on bushido GPU via Ollama.","type":"text"}]},{"type":"paragraph","content":[{"text":"Pre-evolve warmup:","type":"text","marks":[{"type":"strong"}]},{"text":" Run ","type":"text"},{"text":"/compile","type":"text","marks":[{"type":"code_inline"}]},{"text":" before ","type":"text"},{"text":"/evolve","type":"text","marks":[{"type":"code_inline"}]},{"text":" for a fresh, validated knowledge base.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Troubleshooting","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Problem","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Cause","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Solution","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"ao mine","type":"text","marks":[{"type":"code_inline"}]},{"text":" not found","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"ao CLI not in PATH","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use manual fallback in Step 1","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"No orphaned research","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"All research already referenced","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Skip 2b, proceed to synthesis","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Empty mine output","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"No recent activity","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Widen ","type":"text"},{"text":"--since","type":"text","marks":[{"type":"code_inline"}]},{"text":" window","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Oscillation sweep empty","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"No oscillating goals","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Healthy state — no action needed","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Ollama connection refused","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Tunnel not running or wrong host","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Run ","type":"text"},{"text":"ssh -L 11435:localhost:11435 bushido-windows","type":"text","marks":[{"type":"code_inline"}]},{"text":" or check ","type":"text"},{"text":"OLLAMA_HOST","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Compilation too slow","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Large corpus on small model","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"--incremental","type":"text","marks":[{"type":"code_inline"}]},{"text":" or switch to larger model","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Hash file missing","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"First compilation","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Normal — full compile runs, hashes saved after","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Reference Documents","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/compile.feature","type":"text","marks":[{"type":"link","attrs":{"href":"references/compile.feature","title":null}}]},{"text":" — Executable spec: Mine→Grow→Lint→Defrag rebuild, lint-not-autofix, incremental batching, evolve warmup (soc-qk4b)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/phases.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/phases.md","title":null}}]},{"text":" — full per-phase procedure (mine → grow → compile → lint → defrag → report)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/confidence-scoring.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/confidence-scoring.md","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/knowledge-synthesis-patterns.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/knowledge-synthesis-patterns.md","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/flywheel-diagnostics.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/flywheel-diagnostics.md","title":null}}]}]}]}]},{"type":"hr","attrs":{"markup":"---"}}]},"metadata":{"date":"2026-06-05","name":"compile","author":"@skillopedia","source":{"stars":375,"repo_name":"agentops","origin_url":"https://github.com/boshu2/agentops/blob/HEAD/packs/agentops/overlay/.claude/skills/compile/SKILL.md","repo_owner":"boshu2","body_sha256":"581addccf943eb9c34a6c56377aa10af2298f367074dd18b1d3f74e3553d9ee3","cluster_key":"fee189628638ee00b8af40623a3bac46925cdad76cf6cb74da5a7268b5245b08","clean_bundle":{"format":"clean-skill-bundle-v1","source":"boshu2/agentops/packs/agentops/overlay/.claude/skills/compile/SKILL.md","attachments":[{"id":"4bd44196-f17d-53a7-8a8b-cab36079c53a","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/4bd44196-f17d-53a7-8a8b-cab36079c53a/attachment.feature","path":"references/compile.feature","size":1591,"sha256":"6b6be4a68fe7cfc57b75f0ff90ca03ef7860e340a366a45c1a52036dd2955f5c","contentType":"text/plain; charset=utf-8"},{"id":"bc8ef19b-87c9-5ece-9215-f726f35cdad0","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/bc8ef19b-87c9-5ece-9215-f726f35cdad0/attachment.md","path":"references/confidence-scoring.md","size":3982,"sha256":"3691516930c174a2ae348aeb5c6cf7fe087c2e475d8f3ec4d530069d8a2ab5f6","contentType":"text/markdown; charset=utf-8"},{"id":"ce77ea93-dad5-53fa-9902-e319ed907eba","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/ce77ea93-dad5-53fa-9902-e319ed907eba/attachment.md","path":"references/flywheel-diagnostics.md","size":5926,"sha256":"2c91f985a4a851f4cdec7ada081a3845ed4bae48fba546c89a288ccdbb21a3d9","contentType":"text/markdown; charset=utf-8"},{"id":"84346710-6382-5c36-bdfe-5d2af7335e9d","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/84346710-6382-5c36-bdfe-5d2af7335e9d/attachment.md","path":"references/knowledge-synthesis-patterns.md","size":5606,"sha256":"cae5b26811d68387edcca23423206a141a59a40fc6ca1c6b36b4a8d697b8b161","contentType":"text/markdown; charset=utf-8"},{"id":"f4a5468d-bd83-5e00-be48-e662e68eb007","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/f4a5468d-bd83-5e00-be48-e662e68eb007/attachment.md","path":"references/phases.md","size":12115,"sha256":"721b190879e484418d4799d168f59ef72777b3b93eb94f955ab6c81aae8a03a1","contentType":"text/markdown; charset=utf-8"},{"id":"b23f763d-5354-5e19-ba94-a513d3101089","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/b23f763d-5354-5e19-ba94-a513d3101089/attachment.sh","path":"scripts/compile.sh","size":16387,"sha256":"177a51e95a362eed738d1210fcc214ae590a5a454a71b32c1c325cff9545ae4f","contentType":"application/x-sh; charset=utf-8"},{"id":"1d280973-fbf5-516a-be8a-931b5e7977ef","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/1d280973-fbf5-516a-be8a-931b5e7977ef/attachment.sh","path":"scripts/tests/test-fence-stripping.sh","size":2051,"sha256":"e1f245ccf75c5185ffd3199ca280da53697ae60d1630914951125d3e235ee7e0","contentType":"application/x-sh; charset=utf-8"},{"id":"7ebf3259-d3db-5430-b10b-883a23a786ce","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/7ebf3259-d3db-5430-b10b-883a23a786ce/attachment.sh","path":"scripts/validate.sh","size":354,"sha256":"792f4602829837c0d71cd470c0bbcf686bad89bd1dac3f8de3113ce19ae3d7c6","contentType":"application/x-sh; charset=utf-8"}],"bundle_sha256":"f9e3829fd116d4d08d4ef43f9f4b4b8e6dd18fa503be7098735d60fa04149650","attachment_count":8,"text_attachments":7,"attachment_storage":"skillopedia-attachments-v1","binary_attachments":1,"excluded_attachments":[]},"cluster_size":1,"skill_md_path":"packs/agentops/overlay/.claude/skills/compile/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"general","category_label":"General"},"exact_dupes_collapsed_into_this":0},"context":{"intent":{"mode":"task"},"window":"fork","sections":{"exclude":["TASK"]},"intel_scope":"full"},"version":"v1","category":"general","consumes":[],"metadata":{"tier":"knowledge","stability":"stable","dependencies":[]},"produces":[".agents/compiled/lint-report.md"],"practices":["wiki-knowledge-surface","ddd-bounded-context"],"import_tag":"clean-skills-v1","context_rel":[],"description":"Compile .agents knowledge wiki.","hexagonal_role":"supporting","user-invocable":true,"output_contract":".agents/compiled/*.md, .agents/compiled/index.md, .agents/compiled/log.md, .agents/compiled/lint-report.md","skill_api_version":1}},"renderedAt":1782986631014}

Compile — Knowledge Compiler Reads raw artifacts and compiles them into a structured, interlinked markdown wiki. Inspired by Karpathy's LLM Knowledge Bases. What This Skill Does The knowledge flywheel captures signal reactively (via , , ). closes the loop by: 1. Mining unextracted signal from git and (existing) 2. Growing learnings via validation, synthesis, and gap detection (existing) 3. Compiling raw artifacts into interlinked wiki articles (NEW — the core value) 4. Linting the compiled wiki for contradictions, orphans, and gaps (NEW) 5. Defragging stale and duplicate artifacts (existing)…