Repository navigation
okl now needs Python 3.11 or newer: 3.10 is past end of life, and no filelock or pillow
release that installs on it is free of the advisories open against it (0.8.9 stays
installable there). The relevance floor weighs a one-word match by how common the word is,
which refuses three of the six no-match prompts instead of one at no recall cost; okl recap --report says how a session went; okl seed --refresh takes a pack's newer lessons without
the rest of the pack; the reranker's model leaves the system temp directory; and a
check-time model load stays offline after an online one in the same process.
- okl needs Python 3.11 or newer (#285). Python 3.10 reached end of life on 2026-10-01, and the libraries the
hybridandrerankextras pull in have moved on: no release of filelock or pillow that installs on 3.10 is free of the advisories open against it (filelock 4.1.0 has six, one high; pillow 12.3.0 has twelve, one critical), and the fixes need 3.11. On 3.10, pip keeps installing 0.8.9, the last release for it. The files okl copies into a repo still run on 3.10, since they run on that repo's Python. For contributors: CI drops its 3.10 job, adds 3.15 (released 2026-10-09), and checks thatuv.lockmatchespyproject.toml(it had drifted for weeks, which is where the alerts came from), and Dependabot now updates both through itsuvecosystem. - The relevance floor weighs a one-word match by how common the word is (#277, REPORT §4v). A record that shares one word with the task in its title or symptom is briefed on that word only when at most one record in twenty carries it; a word in five or fewer records always counts, so a small store keeps the old rule; two shared words and a one-word alias admit as before. Measured by the probe at one commit against the control: no recall row moved (held-out, authored or the probe's own) and three of the six no-match prompts are now refused at a three-lesson budget, where one was ("give me a doc for that too" 11 → 2, the search prompt 12 → 6). The share is a scan of the store per check, 12 ms at 323 records. The pipeline diagrams and the README's floor sentence name the rule;
evals/common_word_grid.pyis the selection grid andevals/probe_rephrase.py --common-sharethe probe's switch. okl recap --report: how a session went (#279). From the local store's own logs and git, over a window (--sinceas ISO 8601 or90m,6h,2d; otherwise the transcript's start, otherwise a day): prompts briefed and the lessons shown most, lessons shown while stale, lessons recorded and retired with their reasons, check runs with every failure named, commits, the lessons that govern files changed in the window, and what is stale now. Markdown by default,--format jsonfor scripts. It says what it does not cover yet: corrections made withokl update, which carry no timestamp, and anything a shared service logged. 0.4 s on this repo's store.okl seed --refresh: pick up a pack's newer lessons without taking the rest of the pack. A store that was seeded with the starter subset could not receive the symptoms and aliases the packs gained (REPORT §4o, §4p) except by importing whole packs, which pours a .NET or geospatial pack into a Python repo.--refreshre-imports only the records the store already holds, from the packs they came from, keeps their verification as every re-seed does, writes an edge only when both ends were refreshed, finds the bundled packs from the store's own seed ids when no path is given, and names the packs it was seeded from that are not bundled (a repo's own file) so they can be passed by path.- Two retrieval follow-ups measured, nothing changed in behaviour (REPORT §4u). The admission rule §4t proposed for the reranker (first-stage cosine and second-stage rank together) is settled on the selection set: no line admits a lifted lesson without admitting chat filler (
evals/admission_grid.py). The floor's two-word rule for a candidate only the semantic arm returned was pre-registered and measured: it admits the one lesson it was built for and the cutoff still drops it behind fifteen kept records, so the knob (core.SEMANTIC_WORD_FLOOR) ships at None, besidecore.FETCH_MULTIPLIERandevals/window_grid.py, which found both neutral on the selection set. The probe gains--semantic-words. The next retrieval question is the order among kept records, not the floor. - The reranker's model is cached under the cache home, not the system temp directory. fastembed's default cache is
$TMPDIR/fastembed_cache, which macOS prunes on its own schedule, so a model that loaded offline one day was "not cached" the next andokl check --rerankfell back to the first-stage order.okl embednow fetches it to$XDG_CACHE_HOME/okl/models(~/.cache/okl/models), or toFASTEMBED_CACHE_PATHwhen that is set. The embedder is unaffected (model2vec reads the Hugging Face hub cache). Runokl embedonce online after upgrading; the old copy in the temp directory is not read. - A check-time model load stays offline after an online one in the same process (#290). huggingface_hub reads
HF_HUB_OFFLINEonce, at import, so in a process whose first load was online (okl embedfetching the reranker), later loads that set the variable still went to the network first: twelve connection attempts before the cache answered, and a test suite that stalled for minutes when the network was slow. The CLI was unaffected, since each command is its own process. okl's offline switch now sets huggingface_hub's own constant beside the variable and restores both, honouringTRANSFORMERS_OFFLINEas the library does.