@klhapp/skillmux 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,8 @@
1
- # This entire file is optional. Skill Router indexes an externally managed
2
- # agentskills.io-compatible vault and uses local GTE-small semantic retrieval.
3
- # vault_path is a neutral path, never a harness's static-loading scan
4
- # surface (e.g. ~/.agents/skills) see docs/sdd/skr-cli/think.md.
1
+ # This file is optional. It configures the Skillmux CLI or the full Skillmux
2
+ # server image with local inference. Skillmux manages and indexes an
3
+ # agentskills.io-compatible canonical vault. Keep the vault separate from
4
+ # client skill directories such as ~/.agents/skills; skillmux sync selects
5
+ # which core and project skills appear in those directories.
5
6
  vault_path = "~/skills"
6
7
 
7
8
  # Optional, default []: machine-local override-only vaults, checked before
@@ -1,5 +1,8 @@
1
- # Connect stronger inference endpoints. The reranker section is optional.
2
- vault_path = "~/.agents/skills"
1
+ # Configure remote inference endpoints. This describes where inference runs,
2
+ # not where Skillmux runs; local stdio and shared HTTP deployments can both use
3
+ # this file. The reranker section is optional.
4
+ # Keep the canonical vault separate from client skill directories.
5
+ vault_path = "~/skills"
3
6
 
4
7
  [inference]
5
8
  mode = "remote"
@@ -18,7 +21,9 @@ endpoint = "https://reranker.example.com/v1/rerank"
18
21
  model = "your-reranker-model"
19
22
  api_key_env = "RERANKER_API_KEY"
20
23
 
21
- # Required when a reranker is configured. Calibrate these for your model.
24
+ # Optional. Without these values, reranked results remain ambiguous.
25
+ # Calibrate locally against your corpus before enabling automatic matches.
26
+ # See docs/calibration.md; these example values are not universal defaults.
22
27
  [inference.thresholds]
23
28
  match_score = 0.90
24
29
  match_margin = 0.30
package/docs/README.md ADDED
@@ -0,0 +1,52 @@
1
+ # Skillmux documentation
2
+
3
+ Skillmux manages one `SKILL.md` vault. Choose a workflow based on where skills
4
+ need to appear and where Skillmux should run.
5
+
6
+ ## Choose a use case
7
+
8
+ | Goal | Start with | Recommended installation |
9
+ | --- | --- | --- |
10
+ | Put a small skill set in native client directories | [Manage native skills](getting-started.md#manage-native-skills) | Skillmux CLI |
11
+ | Let one client search the full vault through MCP | [Add local MCP retrieval](getting-started.md#add-local-mcp-retrieval) | Skillmux CLI |
12
+ | Serve the vault to several MCP clients | [Run a shared MCP service](getting-started.md#run-a-shared-mcp-service) | Full Skillmux server image |
13
+
14
+ You can combine native management and local MCP retrieval on one machine. The
15
+ shared service uses the same MCP tools over HTTP.
16
+
17
+ Install the CLI with the Bun package, or use the standalone Linux executable
18
+ when Bun is unavailable. The full server image is the shared-service default;
19
+ the slim image is an advanced choice for remote embeddings or lexical-only
20
+ retrieval.
21
+
22
+ ## Learn the model
23
+
24
+ - [Getting started](getting-started.md): choose an installation, prepare a
25
+ vault, and follow one of three setup recipes.
26
+ - [Concepts](concepts.md): separate delivery tiers, deployment topology, and
27
+ retrieval capability.
28
+ - [Managing skills](skill-management.md): install, scan, pin, sync, inspect,
29
+ and recover skills.
30
+ - [MCP routing](mcp-routing.md): register stdio or HTTP MCP and understand
31
+ retrieval outcomes.
32
+
33
+ ## Operate Skillmux
34
+
35
+ - [Deployment](deployment.md): deploy the shared server, choose slim only when
36
+ needed, expose HTTP, and operate the service.
37
+ - [Configuration reference](configuration.md): configure inference, manifests,
38
+ server settings, and local overlays.
39
+ - [CLI reference](cli.md): use commands, contexts, JSON output, and exit codes.
40
+ - [Policy calibration](calibration.md): create labelled datasets and certify
41
+ reranker thresholds.
42
+ - [Troubleshooting](troubleshooting.md): diagnose vault, sync, model, and server
43
+ problems.
44
+
45
+ ## Integrate and contribute
46
+
47
+ - [MCP contract](schema.json): JSON Schema 2020-12 definitions for tool inputs
48
+ and results.
49
+ - [Contributing](../CONTRIBUTING.md): development setup, tests, and pull request
50
+ conventions.
51
+ - [Releasing](releasing.md): maintainer release procedure.
52
+ - [Security](../SECURITY.md): vulnerability reporting.
@@ -0,0 +1,156 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 720" role="img" aria-labelledby="title desc">
2
+ <title id="title">Three ways to use Skillmux</title>
3
+ <desc id="desc">One canonical skill vault supports native skill management and local MCP retrieval through the Skillmux CLI, plus a shared HTTP MCP service through the full or slim Skillmux server image.</desc>
4
+
5
+ <defs>
6
+ <filter id="shadow" x="-15%" y="-15%" width="130%" height="140%">
7
+ <feDropShadow dx="0" dy="5" stdDeviation="8" flood-color="#0f172a" flood-opacity="0.10"/>
8
+ </filter>
9
+ <marker id="arrow-teal" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto">
10
+ <path d="M0 0L10 5L0 10Z" fill="#0f766e"/>
11
+ </marker>
12
+ <marker id="arrow-blue" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto">
13
+ <path d="M0 0L10 5L0 10Z" fill="#2563eb"/>
14
+ </marker>
15
+ <marker id="arrow-violet" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto">
16
+ <path d="M0 0L10 5L0 10Z" fill="#7c3aed"/>
17
+ </marker>
18
+ <style>
19
+ text {
20
+ font-family: "DejaVu Sans", Arial, sans-serif;
21
+ }
22
+ .title {
23
+ font-size: 27px;
24
+ font-weight: 750;
25
+ fill: #0f172a;
26
+ }
27
+ .subtitle {
28
+ font-size: 16px;
29
+ font-weight: 400;
30
+ fill: #475569;
31
+ }
32
+ .card-title {
33
+ font-size: 21px;
34
+ font-weight: 750;
35
+ fill: #0f172a;
36
+ }
37
+ .label {
38
+ font-size: 15px;
39
+ font-weight: 650;
40
+ fill: #1e293b;
41
+ }
42
+ .body {
43
+ font-size: 14px;
44
+ font-weight: 400;
45
+ fill: #475569;
46
+ }
47
+ .mono {
48
+ font-family: "DejaVu Sans Mono", Consolas, monospace;
49
+ font-size: 14px;
50
+ font-weight: 650;
51
+ fill: #1e293b;
52
+ }
53
+ .mono-light {
54
+ fill: #ffffff;
55
+ }
56
+ .chip {
57
+ font-size: 12px;
58
+ font-weight: 750;
59
+ letter-spacing: .5px;
60
+ }
61
+ </style>
62
+ </defs>
63
+
64
+ <rect width="1200" height="720" rx="24" fill="#f8fafc"/>
65
+ <rect x="1" y="1" width="1198" height="718" rx="23" fill="none" stroke="#e2e8f0" stroke-width="2"/>
66
+
67
+ <text x="48" y="50" class="title">One vault, three ways to use Skillmux</text>
68
+ <text x="48" y="78" class="subtitle">Choose a local workflow or serve the same retrieval contract to several clients.</text>
69
+
70
+ <g filter="url(#shadow)">
71
+ <rect x="330" y="106" width="540" height="118" rx="18" fill="#ffffff" stroke="#cbd5e1" stroke-width="2"/>
72
+ <circle cx="374" cy="147" r="18" fill="#0f172a"/>
73
+ <path d="M364 141H377L383 147L377 153H364M370 135V159" fill="none" stroke="#ffffff" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
74
+ <text x="408" y="144" class="card-title">Canonical skill vault</text>
75
+ <text x="408" y="172" class="mono">~/skills/&lt;skill-id&gt;/SKILL.md</text>
76
+ <text x="408" y="200" class="body">Install · scan · pin · index · inspect usage</text>
77
+ <rect x="701" y="139" width="137" height="34" rx="9" fill="#f1f5f9" stroke="#cbd5e1"/>
78
+ <text x="769.5" y="161" text-anchor="middle" class="mono">skillmux.toml</text>
79
+ </g>
80
+
81
+ <path d="M480 224V252H220V277" fill="none" stroke="#0f766e" stroke-width="3" marker-end="url(#arrow-teal)"/>
82
+ <path d="M600 224V277" fill="none" stroke="#2563eb" stroke-width="3" marker-end="url(#arrow-blue)"/>
83
+ <path d="M720 224V252H980V277" fill="none" stroke="#7c3aed" stroke-width="3" marker-end="url(#arrow-violet)"/>
84
+
85
+ <g filter="url(#shadow)">
86
+ <rect x="40" y="284" width="360" height="302" rx="18" fill="#ffffff" stroke="#99d5cc" stroke-width="2"/>
87
+ <rect x="62" y="306" width="91" height="26" rx="13" fill="#ccfbf1"/>
88
+ <text x="107.5" y="324" text-anchor="middle" class="chip" fill="#115e59">USE CASE 1</text>
89
+ <text x="62" y="365" class="card-title">Skillmux CLI</text>
90
+ <text x="62" y="390" class="body">Manage native skills on the client machine.</text>
91
+
92
+ <rect x="62" y="414" width="276" height="48" rx="10" fill="#f0fdfa" stroke="#99d5cc"/>
93
+ <text x="200" y="444" text-anchor="middle" class="mono">skillmux init · sync</text>
94
+ <path d="M200 462V487" fill="none" stroke="#0f766e" stroke-width="2.5" marker-end="url(#arrow-teal)"/>
95
+ <rect x="62" y="493" width="276" height="49" rx="10" fill="#f8fafc" stroke="#cbd5e1"/>
96
+ <text x="200" y="514" text-anchor="middle" class="label">Native skill directories</text>
97
+ <text x="200" y="533" text-anchor="middle" class="body">managed core and project links</text>
98
+
99
+ <text x="62" y="570" class="body">Install with</text>
100
+ <rect x="160" y="550" width="85" height="27" rx="8" fill="#0f172a"/>
101
+ <text x="202.5" y="568" text-anchor="middle" class="chip" style="font-size: 10px" fill="#ffffff">BUN PACKAGE</text>
102
+ <rect x="251" y="550" width="87" height="27" rx="8" fill="#f1f5f9" stroke="#cbd5e1"/>
103
+ <text x="294.5" y="561" text-anchor="middle" class="chip" style="font-size: 10px" fill="#334155"><tspan x="294.5">LINUX</tspan><tspan x="294.5" dy="11">EXECUTABLE</tspan></text>
104
+ </g>
105
+
106
+ <g filter="url(#shadow)">
107
+ <rect x="420" y="284" width="360" height="302" rx="18" fill="#ffffff" stroke="#93c5fd" stroke-width="2"/>
108
+ <rect x="442" y="306" width="91" height="26" rx="13" fill="#dbeafe"/>
109
+ <text x="487.5" y="324" text-anchor="middle" class="chip" fill="#1d4ed8">USE CASE 2</text>
110
+ <text x="442" y="365" class="card-title">Add local MCP retrieval</text>
111
+ <text x="442" y="390" class="body">Run Skillmux beside one MCP client.</text>
112
+
113
+ <rect x="442" y="414" width="102" height="48" rx="10" fill="#f8fafc" stroke="#cbd5e1"/>
114
+ <text x="493" y="444" text-anchor="middle" class="label">AI client</text>
115
+ <path d="M544 438H573" fill="none" stroke="#2563eb" stroke-width="2.5" marker-end="url(#arrow-blue)"/>
116
+ <text x="558" y="428" text-anchor="middle" class="body">stdio</text>
117
+ <rect x="579" y="414" width="179" height="48" rx="10" fill="#eff6ff" stroke="#93c5fd"/>
118
+ <text x="668.5" y="444" text-anchor="middle" class="label">Local Skillmux</text>
119
+
120
+ <rect x="442" y="484" width="316" height="58" rx="10" fill="#f8fafc" stroke="#cbd5e1"/>
121
+ <text x="600" y="507" text-anchor="middle" class="label">FTS5 + local GTE-small</text>
122
+ <text x="600" y="530" text-anchor="middle" class="body">downloaded and cached on this machine</text>
123
+
124
+ <text x="442" y="570" class="body">Skillmux CLI: Bun package or Linux executable</text>
125
+ </g>
126
+
127
+ <g filter="url(#shadow)">
128
+ <rect x="800" y="284" width="360" height="302" rx="18" fill="#ffffff" stroke="#c4b5fd" stroke-width="2"/>
129
+ <rect x="822" y="306" width="91" height="26" rx="13" fill="#ede9fe"/>
130
+ <text x="867.5" y="324" text-anchor="middle" class="chip" fill="#6d28d9">USE CASE 3</text>
131
+ <text x="822" y="365" class="card-title">Run a shared MCP service</text>
132
+ <text x="822" y="390" class="body">Serve several clients from one deployment.</text>
133
+
134
+ <rect x="822" y="414" width="102" height="48" rx="10" fill="#f8fafc" stroke="#cbd5e1"/>
135
+ <text x="873" y="435" text-anchor="middle" class="label">AI clients</text>
136
+ <text x="873" y="453" text-anchor="middle" class="body">one or more</text>
137
+ <path d="M924 438H953" fill="none" stroke="#7c3aed" stroke-width="2.5" marker-end="url(#arrow-violet)"/>
138
+ <text x="938" y="428" text-anchor="middle" class="body">HTTP</text>
139
+ <rect x="959" y="414" width="179" height="48" rx="10" fill="#f5f3ff" stroke="#c4b5fd"/>
140
+ <text x="1048.5" y="435" text-anchor="middle" class="label">Skillmux server</text>
141
+ <text x="1048.5" y="453" text-anchor="middle" class="mono">POST /mcp</text>
142
+
143
+ <rect x="822" y="484" width="148" height="58" rx="10" fill="#f5f3ff" stroke="#c4b5fd"/>
144
+ <text x="896" y="507" text-anchor="middle" class="label">Full image</text>
145
+ <text x="896" y="530" text-anchor="middle" class="body">GTE-small included</text>
146
+ <rect x="982" y="484" width="156" height="58" rx="10" fill="#f8fafc" stroke="#cbd5e1"/>
147
+ <text x="1060" y="507" text-anchor="middle" class="label">Slim image</text>
148
+ <text x="1060" y="530" text-anchor="middle" class="body">remote or lexical</text>
149
+
150
+ <text x="822" y="570" class="body">Recommended for a shared HTTP deployment</text>
151
+ </g>
152
+
153
+ <rect x="420" y="616" width="740" height="66" rx="14" fill="#0f172a"/>
154
+ <text x="444" y="643" class="chip" fill="#cbd5e1">SHARED MCP CONTRACT</text>
155
+ <text x="444" y="667" class="mono mono-light">retrieve → rerank → resolve_skill / fetch_skill → verified SKILL.md</text>
156
+ </svg>
Binary file
@@ -0,0 +1,111 @@
1
+ # Policy calibration
2
+
3
+ Calibration selects the three reranker-score thresholds that turn an ordered
4
+ shortlist into `matched`, `ambiguous`, or `no_match`. It is an operator action,
5
+ not background learning, and it currently runs only against a local Skillmux
6
+ target.
7
+
8
+ Read [MCP routing](mcp-routing.md#retrieval-pipeline) before calibrating a new
9
+ retrieval deployment.
10
+
11
+ ## Lifecycle
12
+
13
+ The complete workflow is:
14
+
15
+ ```text
16
+ install CLI → configure vault/index/embedding/reranker → obtain labelled dataset
17
+ → calibrate run → review calibrate show RUN_ID → calibrate apply RUN_ID
18
+ → live-reloaded policy handles subsequent requests
19
+ ```
20
+
21
+ First configure and index the same vault, embedding model, and reranker that
22
+ will serve requests. Supply a reviewed dataset, or generate a starting point
23
+ and review every label:
24
+
25
+ ```sh
26
+ skillmux calibrate generate-dataset --out ./eval/queries.json
27
+ skillmux calibrate run --dataset ./eval/queries.json
28
+ skillmux calibrate show RUN_ID
29
+ skillmux calibrate apply RUN_ID
30
+ ```
31
+
32
+ Skillmux retrieves candidates and reranks exactly once for each evaluation
33
+ query. It caches those observations, searches thresholds on the `tune` split,
34
+ then certifies the selected policy on the frozen `test` split. Calibration
35
+ starts only when an operator invokes `calibrate run`.
36
+
37
+ The operator owns the labels: supply or review the cases, start the run,
38
+ inspect its evidence, and explicitly apply an acceptable result. A successful
39
+ run never changes live thresholds by itself.
40
+
41
+ ## Reading a run
42
+
43
+ A `run_id` identifies one immutable calibration attempt and its evidence.
44
+ `calibrate show RUN_ID` is read-only. It reports:
45
+
46
+ - selected thresholds and tune/test metrics;
47
+ - auto-match precision confidence and sample counts;
48
+ - retrieval and delivered-shortlist recall;
49
+ - a closed failure reason when certification fails;
50
+ - reranker, embedding, corpus, and dataset fingerprints;
51
+ - dataset provenance and the number of human-labelled cases; and
52
+ - the attempt count for the dataset hash.
53
+
54
+ `calibrate apply RUN_ID` accepts only a completed, test-certified run. It
55
+ rechecks the reranker fingerprint, rejects thresholds masked by environment
56
+ variables, atomically updates the TOML file, and lets the config watcher
57
+ activate the new snapshot.
58
+
59
+ ## Dataset responsibilities
60
+
61
+ Each case needs a query, expected outcome, relevant skill ids, and a fixed
62
+ `tune` or `test` split. Unknown skill ids are rejected. Keep a skill entirely
63
+ within one split so the test set measures generalization rather than memorized
64
+ skill wording.
65
+
66
+ Generated datasets are scaffolding, not ground truth. Review paraphrases,
67
+ near-miss negatives, and ambiguous cases before using them for certification.
68
+ Audit-derived cases require an explicit human label and provenance. Raw audit
69
+ queries are excluded unless the importer is deliberately configured to retain
70
+ them.
71
+
72
+ ## When to recalibrate
73
+
74
+ Re-run calibration after a material change to the corpus, embedding or
75
+ retrieval behavior, reranker adapter or model, or after collecting enough new
76
+ human-labelled feedback. Do not recalibrate per user request. Every rerun gets
77
+ a new `run_id`; the active policy remains unchanged until one is applied.
78
+
79
+ ## Local and remote targets
80
+
81
+ Here, `local` and `remote` name CLI administration targets, not inference
82
+ locations or MCP transports. Calibration is local-target-only in this release.
83
+ Local commands operate on the
84
+ configured local vault, index, inference endpoints, dataset path, evidence
85
+ database, and TOML file. Human output always prints `Target: local`; JSON output
86
+ uses `"target": "local"`.
87
+
88
+ Remote servers advertise `"calibration": false`. Every
89
+ `/admin/v1/calibrations` route returns HTTP `501` with
90
+ `error: "not_implemented"`, and the CLI rejects remote calibration before
91
+ uploading or claiming to execute a local dataset path. This also prevents raw
92
+ evaluation queries from being exposed through the admin API.
93
+
94
+ ## Reference starting profile
95
+
96
+ Reranker scores are not portable across models, adapters, model revisions, or
97
+ corpora. The profile below is published only to make the checked-in BGE example
98
+ concrete; it is not a certified substitute for calibration.
99
+
100
+ | Model | Adapter | `match_score` | `match_margin` | `candidate_floor` |
101
+ |---|---|---:|---:|---:|
102
+ | `BAAI/bge-reranker-v2-m3` | `jina-v1` | `0.90` | `0.20` | `0.40` |
103
+
104
+ Provenance: the small synthetic corpus and labelled decision cases in
105
+ [`tests/router-core.spec.test.ts`](../tests/router-core.spec.test.ts), with the
106
+ wire contract captured by
107
+ [`tests/fixtures/reranker/jina-v1-request.json`](../tests/fixtures/reranker/jina-v1-request.json).
108
+ That fixture is below the default 30-auto-match certification minimum, so the
109
+ values are a smoke-test/reference profile, not a completed calibration run.
110
+ Run the lifecycle above against the deployment's real corpus before enabling
111
+ automatic matches in production.