@klhapp/skillmux 1.5.1 → 1.6.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.
- package/CHANGELOG.md +17 -0
- package/docs/calibration.md +91 -4
- package/docs/cli.md +22 -1
- package/package.json +1 -1
- package/src/adapters.ts +410 -49
- package/src/calibrate.ts +526 -22
- package/src/cli.ts +75 -0
- package/src/router-core.ts +87 -13
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,23 @@ All notable changes to this project are documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.6.0](https://github.com/klhq/skillmux/compare/v1.5.2...v1.6.0) (2026-08-18)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
* **calibrate:** add tune safety buffers ([#120](https://github.com/klhq/skillmux/issues/120)) ([66d501c](https://github.com/klhq/skillmux/commit/66d501c4ac16956e8e887622e5178caef743bec7))
|
|
14
|
+
|
|
15
|
+
## [1.5.2](https://github.com/klhq/skillmux/compare/v1.5.1...v1.5.2) (2026-08-17)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
* **calibration:** parallelize resumable evaluations ([#115](https://github.com/klhq/skillmux/issues/115)) ([49b3fba](https://github.com/klhq/skillmux/commit/49b3fba43961aa7a6648eda89c5c08d994c7433a))
|
|
21
|
+
* **calibration:** report aggregate stage timings ([#119](https://github.com/klhq/skillmux/issues/119)) ([086128f](https://github.com/klhq/skillmux/commit/086128fdba8ded82ccf6a51d2e0117a18c2eea17))
|
|
22
|
+
* **calibration:** reuse synchronized retrieval snapshot ([#117](https://github.com/klhq/skillmux/issues/117)) ([1fcf295](https://github.com/klhq/skillmux/commit/1fcf2959123b4f9ca6841a2978a3fa5552c23122))
|
|
23
|
+
* **retrieval:** expose opt-in stage timings ([#118](https://github.com/klhq/skillmux/issues/118)) ([f459c90](https://github.com/klhq/skillmux/commit/f459c90f440834cea2ee008300bad3e15771949e))
|
|
24
|
+
|
|
8
25
|
## [1.5.1](https://github.com/klhq/skillmux/compare/v1.5.0...v1.5.1) (2026-08-17)
|
|
9
26
|
|
|
10
27
|
|
package/docs/calibration.md
CHANGED
|
@@ -30,14 +30,101 @@ skillmux calibrate apply RUN_ID
|
|
|
30
30
|
```
|
|
31
31
|
|
|
32
32
|
Skillmux retrieves candidates and reranks exactly once for each evaluation
|
|
33
|
-
query. It
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
query. It runs four queries at a time by default. Set a different positive
|
|
34
|
+
worker limit with `--concurrency N`. The CLI writes completed-case progress to
|
|
35
|
+
stderr without exposing query text.
|
|
36
|
+
|
|
37
|
+
### Timing report
|
|
38
|
+
|
|
39
|
+
Add `--timing` to any `calibrate run` invocation to write an aggregate
|
|
40
|
+
performance report to **stderr** after the run finishes (with a completed or
|
|
41
|
+
failed-gates result; a thrown error produces no report). Stdout remains valid
|
|
42
|
+
JSON under `--json --timing`.
|
|
43
|
+
|
|
44
|
+
```sh
|
|
45
|
+
skillmux calibrate run --dataset ./eval/queries.json --timing
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
The report uses stable snake_case field names in milliseconds:
|
|
49
|
+
|
|
50
|
+
| Field | Description |
|
|
51
|
+
|---|---|
|
|
52
|
+
| `cases_total` | Total dataset cases |
|
|
53
|
+
| `cases_executed` | Cases retrieved in this invocation |
|
|
54
|
+
| `cases_reused` | Cases loaded from a prior interrupted run (resume) |
|
|
55
|
+
| `wall_ms` | Wall-clock duration of the full calibrateRun operation |
|
|
56
|
+
| `vault_sync_ms` | One-time vault synchronization before retrieval |
|
|
57
|
+
| `cumulative_embedding_ms` | Total worker time in embedding across all queries |
|
|
58
|
+
| `cumulative_lexical_ms` | Total worker time in lexical search across all queries |
|
|
59
|
+
| `cumulative_vector_ms` | Total worker time in vector search across all queries |
|
|
60
|
+
| `cumulative_reranker_ms` | Total worker time in reranking across all queries |
|
|
61
|
+
| `cumulative_checkpoint_ms` | Total worker time writing observation checkpoints |
|
|
62
|
+
| `policy_evaluation_ms` | Threshold selection and test-split certification |
|
|
63
|
+
|
|
64
|
+
**Cumulative vs wall time.** The cumulative fields (`cumulative_embedding_ms`,
|
|
65
|
+
`cumulative_lexical_ms`, `cumulative_vector_ms`, `cumulative_reranker_ms`,
|
|
66
|
+
`cumulative_checkpoint_ms`) are total _worker time_ summed across all concurrent
|
|
67
|
+
query retrievals. Because multiple queries run at the same time, the sum of these
|
|
68
|
+
fields typically exceeds `wall_ms`. They measure how much time each stage
|
|
69
|
+
consumed across all workers, not how much wall-clock time each stage accounted
|
|
70
|
+
for. `cases_executed + cases_reused = cases_total`.
|
|
71
|
+
|
|
72
|
+
Timing collection is fully disabled when `--timing` is absent; it does not affect
|
|
73
|
+
calibration results, resume behavior, checkpoint durability, or JSON schemas.
|
|
74
|
+
Skillmux checkpoints each observation in the calibration evidence database.
|
|
75
|
+
If inference fails or you interrupt the process, find the `running` run with
|
|
76
|
+
`calibrate list` and resume it with the same dataset and certification flags:
|
|
77
|
+
|
|
78
|
+
```sh
|
|
79
|
+
skillmux calibrate run --dataset ./eval/queries.json --resume RUN_ID
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Resume rejects changes to the dataset, corpus, inference models, recall
|
|
83
|
+
settings, candidate limit, or certification gates. After all observations
|
|
84
|
+
exist, Skillmux searches thresholds on the `tune` split and certifies the
|
|
85
|
+
selected policy on the frozen `test` split. Calibration starts only when an
|
|
86
|
+
operator invokes `calibrate run`.
|
|
36
87
|
|
|
37
88
|
The operator owns the labels: supply or review the cases, start the run,
|
|
38
89
|
inspect its evidence, and explicitly apply an acceptable result. A successful
|
|
39
90
|
run never changes live thresholds by itself.
|
|
40
91
|
|
|
92
|
+
## Certification gates and preflight feasibility
|
|
93
|
+
|
|
94
|
+
Calibration certifies threshold policies against statistical confidence gates before allowing them to be applied:
|
|
95
|
+
|
|
96
|
+
| Flag | Default | Description |
|
|
97
|
+
|---|---|---|
|
|
98
|
+
| `--min-auto-match-precision` | `0.75` | Minimum 95% Wilson score lower confidence bound on auto-match precision |
|
|
99
|
+
| `--min-auto-match-count` | `15` | Minimum number of auto-matches required in evaluation |
|
|
100
|
+
| `--min-retrieval-recall-at-k` | `0.95` | Minimum top-k retrieval recall on matchable queries |
|
|
101
|
+
| `--min-delivered-shortlist-recall-at-k` | `0.95` | Minimum delivered shortlist recall on matchable queries |
|
|
102
|
+
| `--tune-auto-match-precision-buffer` | `0.03` | Tune-only selection buffer for Wilson auto-match precision lower bound |
|
|
103
|
+
| `--tune-auto-match-count-buffer` | `3` | Tune-only selection buffer for minimum auto-match count |
|
|
104
|
+
| `--tune-delivered-shortlist-recall-buffer` | `0.02` | Tune-only selection buffer for delivered shortlist recall |
|
|
105
|
+
|
|
106
|
+
### Tune selection buffers vs production gates
|
|
107
|
+
|
|
108
|
+
Tune selection buffers ensure that threshold optimization selects policies with sufficient headroom beyond production gates. A candidate policy during tune search must satisfy the production gates plus their respective tune selection buffers. Test-split certification evaluates selected policies against the original production gates without selection buffers.
|
|
109
|
+
|
|
110
|
+
### Wilson lower confidence bound and evidence size
|
|
111
|
+
|
|
112
|
+
`min-auto-match-precision` is evaluated not as raw sample accuracy, but as a **95% Wilson score lower confidence bound** ($z \approx 1.960$). This accounts for statistical uncertainty in small datasets.
|
|
113
|
+
|
|
114
|
+
Because the Wilson lower bound penalizes small sample sizes:
|
|
115
|
+
- A gate of **0.75** lower bound requires at least **15** flawless (15/15) auto-matches ($\text{Wilson}(15, 15) \approx 0.7961$).
|
|
116
|
+
- A 20-case tune matched split can achieve at most $\text{Wilson}(20, 20) \approx 0.8389$.
|
|
117
|
+
- A gate of **0.99** lower bound is statistically impossible on small datasets; it requires at least **381** flawless auto-matches ($\text{Wilson}(381, 381) \approx 0.9900$).
|
|
118
|
+
|
|
119
|
+
### Preflight feasibility check
|
|
120
|
+
|
|
121
|
+
To avoid running expensive remote embeddings and rerankings on gates that can never pass, Skillmux executes a **preflight feasibility calculation** immediately after loading the dataset and before creating a running calibration record:
|
|
122
|
+
|
|
123
|
+
$$\text{effective\_trials} = \max(N_{\text{tune\_matched}}, \text{minAutoMatchCount})$$
|
|
124
|
+
$$\text{max\_attainable\_precision} = \text{WilsonLowerBound}(N_{\text{tune\_matched}}, \text{effective\_trials})$$
|
|
125
|
+
|
|
126
|
+
If $\text{max\_attainable\_precision} < \text{minAutoMatchPrecision}$, calibration fails immediately with an actionable error indicating the requested precision, requested count, available tune matched cases, and maximum attainable lower bound.
|
|
127
|
+
|
|
41
128
|
## Reading a run
|
|
42
129
|
|
|
43
130
|
A `run_id` identifies one immutable calibration attempt and its evidence.
|
|
@@ -105,7 +192,7 @@ Provenance: the small synthetic corpus and labelled decision cases in
|
|
|
105
192
|
[`tests/router-core.spec.test.ts`](../tests/router-core.spec.test.ts), with the
|
|
106
193
|
wire contract captured by
|
|
107
194
|
[`tests/fixtures/reranker/jina-v1-request.json`](../tests/fixtures/reranker/jina-v1-request.json).
|
|
108
|
-
That fixture is below the default
|
|
195
|
+
That fixture is below the default 15-auto-match certification minimum, so the
|
|
109
196
|
values are a smoke-test/reference profile, not a completed calibration run.
|
|
110
197
|
Run the lifecycle above against the deployment's real corpus before enabling
|
|
111
198
|
automatic matches in production.
|
package/docs/cli.md
CHANGED
|
@@ -298,9 +298,30 @@ certification gates, run evidence, reference values, and the complete operator
|
|
|
298
298
|
lifecycle.
|
|
299
299
|
|
|
300
300
|
```sh
|
|
301
|
-
# Run calibration on a dataset
|
|
301
|
+
# Run calibration on a dataset with default certification gates (min precision 0.75, min count 15)
|
|
302
302
|
skillmux calibrate run --dataset ./eval/queries.json
|
|
303
303
|
|
|
304
|
+
# Specify explicit certification gates and tune selection buffers
|
|
305
|
+
# Note: --min-auto-match-precision is interpreted as a 95% Wilson lower confidence bound.
|
|
306
|
+
# Calibration preflight validates that the requested gate is mathematically attainable on the tune split.
|
|
307
|
+
skillmux calibrate run --dataset ./eval/queries.json \
|
|
308
|
+
--min-auto-match-precision 0.75 \
|
|
309
|
+
--min-auto-match-count 15 \
|
|
310
|
+
--min-retrieval-recall-at-k 0.95 \
|
|
311
|
+
--min-delivered-shortlist-recall-at-k 0.95 \
|
|
312
|
+
--tune-auto-match-precision-buffer 0.03 \
|
|
313
|
+
--tune-auto-match-count-buffer 3 \
|
|
314
|
+
--tune-delivered-shortlist-recall-buffer 0.02
|
|
315
|
+
|
|
316
|
+
# Set the bounded worker count
|
|
317
|
+
skillmux calibrate run --dataset ./eval/queries.json --concurrency 6
|
|
318
|
+
|
|
319
|
+
# Print aggregate performance timing to stderr
|
|
320
|
+
skillmux calibrate run --dataset ./eval/queries.json --timing
|
|
321
|
+
|
|
322
|
+
# Resume a running or interrupted attempt with the same inputs and gates
|
|
323
|
+
skillmux calibrate run --dataset ./eval/queries.json --resume <run_id>
|
|
324
|
+
|
|
304
325
|
# List stored calibration runs in the evidence store
|
|
305
326
|
skillmux calibrate list
|
|
306
327
|
|
package/package.json
CHANGED