$npx -y skills add stevesolun/ctx --skill docsRepo-aware recommendation manager for ctx. Scans the active repository, identifies stack and workflow signals, recommends a capped set of skills, agents, and MCP servers, and unloads helpers that no longer match the current work after user confirmation. Harnesses are recommended
| 1 | # Skill Router |
| 2 | |
| 3 | Scan a repo. Know what the current work needs. Recommend only that. Keep the |
| 4 | wiki and graph as the durable catalog behind the decision. |
| 5 | |
| 6 | ## Scope |
| 7 | |
| 8 | The router manages runtime recommendations for: |
| 9 | |
| 10 | - skills |
| 11 | - agents |
| 12 | - MCP servers |
| 13 | |
| 14 | Harnesses are separate catalog entities. They are recommended when a user wants |
| 15 | to run ctx with a non-Claude-Code host, local model, API model, or external loop |
| 16 | adapter. Once attached, the harness calls the same skills/agents/MCP |
| 17 | recommendation engine. |
| 18 | |
| 19 | ## Problem |
| 20 | |
| 21 | Every loaded helper costs tokens, attention, and operational surface area. Most |
| 22 | sessions need a small top-scored bundle from the shipped graph, not every entity |
| 23 | ctx knows about. Loading too much: |
| 24 | |
| 25 | - wastes context on irrelevant instructions, |
| 26 | - causes misfires when a helper matches the wrong task, |
| 27 | - slows the agent loop, and |
| 28 | - creates conflicting instructions. |
| 29 | |
| 30 | ## Architecture |
| 31 | |
| 32 | ```text |
| 33 | ctx/ |
| 34 | |-- src/scan_repo.py # Repo scanner -> stack profile |
| 35 | |-- src/ctx/core/resolve/resolve_skills.py # Profile -> load/unload manifest |
| 36 | |-- src/ctx/core/resolve/recommendations.py # Shared scoring/ranking engine |
| 37 | |-- src/ctx/adapters/ # Host adapters + generic tools |
| 38 | |-- src/harness_install.py # Custom-model harness install flow |
| 39 | `-- graph/wiki-graph-runtime.tar.gz # Shipped graph/wiki runtime |
| 40 | ``` |
| 41 | |
| 42 | The router has three halves: |
| 43 | |
| 44 | 1. **Scanner** - analyzes a repo and produces stack/task evidence. |
| 45 | 2. **Resolver** - scores graph/wiki entities and emits a capped manifest. |
| 46 | 3. **Wiki/graph** - persistent catalog of entities, usage, quality, and links. |
| 47 | |
| 48 | ## Startup Flow |
| 49 | |
| 50 | 1. Read the shipped graph/wiki metadata and local user overrides. |
| 51 | 2. Run `ctx-scan-repo --repo . --recommend` for the active repo. |
| 52 | 3. Resolve a load/unload manifest with the shared recommendation engine. |
| 53 | 4. Present changes with reasons and require confirmation unless the user enabled |
| 54 | automatic mode. |
| 55 | 5. Record usage/quality changes after the user accepts or rejects suggestions. |
| 56 | |
| 57 | ## Scanner |
| 58 | |
| 59 | The scanner reads repo structure and files to produce a stack profile. Detection |
| 60 | is evidence-based: every claim should map to a file, dependency, config value, or |
| 61 | import pattern. |
| 62 | |
| 63 | ### Detection Categories |
| 64 | |
| 65 | - **Languages** - file extensions, shebangs, lock files. |
| 66 | - **Frameworks and libraries** - package manifests, imports, config files. |
| 67 | - **Infrastructure and DevOps** - Docker, CI/CD, IaC, cloud, Kubernetes. |
| 68 | - **Data and storage** - databases, migrations, queues, pipelines. |
| 69 | - **Documentation and content** - MkDocs, Docusaurus, Sphinx, API specs. |
| 70 | - **Testing and quality** - pytest, Jest, Playwright, Ruff, mypy, TypeScript. |
| 71 | - **AI and agent tooling** - MCP configs, LangGraph, CrewAI, prompt dirs, model |
| 72 | config names. |
| 73 | - **Build and package** - package managers, build tools, monorepos. |
| 74 | |
| 75 | ### Scanning Rules |
| 76 | |
| 77 | 1. Start with filenames and config files. Read source only when needed to |
| 78 | disambiguate. |
| 79 | 2. Do not include speculative signals below the configured confidence floor. |
| 80 | 3. Skip generated/vendor directories such as `.git`, `node_modules`, |
| 81 | `__pycache__`, `venv`, and `.venv`. |
| 82 | 4. Keep initial scans bounded for large repos. |
| 83 | 5. Redact secret values; only record secret/key names as evidence. |
| 84 | |
| 85 | ## Resolver |
| 86 | |
| 87 | The resolver produces a manifest containing the exact helper set to load or |
| 88 | unload. |
| 89 | |
| 90 | ```json |
| 91 | { |
| 92 | "generated_at": "ISO-8601", |
| 93 | "repo_path": "/absolute/path", |
| 94 | "profile_hash": "sha256 of stack profile", |
| 95 | "load": [ |
| 96 | { |
| 97 | "name": "fastapi", |
| 98 | "type": "skill", |
| 99 | "reason": "FastAPI detected in pyproject.toml dependencies", |
| 100 | "score": 0.94 |
| 101 | } |
| 102 | ], |
| 103 | "unload": [ |
| 104 | { |
| 105 | "name": "react", |
| 106 | "type": "skill", |
| 107 | "reason": "No active frontend signal in the current repo window" |
| 108 | } |
| 109 | ], |
| 110 | "suggestions": [ |
| 111 | { |
| 112 | "name": "github", |
| 113 | "type": "mcp", |
| 114 | "reason": ".github/workflows exists and the repo uses GitHub Actions", |
| 115 | "install_command": "ctx-mcp-add ..." |
| 116 | } |
| 117 | ], |
| 118 | "warnings": [] |
| 119 | } |
| 120 | ``` |
| 121 | |
| 122 | ### Ranking Signals |
| 123 | |
| 124 | Candidates can be scored by: |
| 125 | |
| 126 | - tag/category/subcategory match |
| 127 | - semantic similarity edge weight |
| 128 | - direct wiki links |
| 129 | - source overlap |
| 130 | - type affinity |
| 131 | - usage score |
| 132 | - quality/security score |
| 133 | - user overrides (`always_load`, `never_load`) |
| 134 | - configured caps and minimum score gates |
| 135 | |
| 136 | Recommendations are capped. ctx should not recommend at all costs; below-threshold |
| 137 | candidates should be withheld and the gap should be explained. |
| 138 | |
| 139 | ## Wiki And Graph Contract |
| 140 | |
| 141 | The wiki follows a Karpathy-style durable memory pattern: schema, purpose, index, |
| 142 | log, lint, review ite |