c9a567883e
* fix(ollama): stop one sized install marking a whole model family installed `build_installed_set` inserted the bare family stem alongside every tag, and the heuristic half of `hf_name_to_ollama_candidates` offered that same bare stem as a candidate for any model with no `OLLAMA_MAPPINGS` entry. The two met in the middle: a single `qwen3:8b` marked 238 of the 9,250 catalog entries installed — `Qwen3-235B-A22B` and hundreds of community fine-tunes among them. Because "installed" gates the download action, those models became undownloadable in the TUI (discussion #861). Size is now the discriminator: - A sized install contributes its tag and nothing else. `qwen3:8b` says exactly which weights are on disk. - Only an untagged / `:latest` install contributes a family stem, plus the sized alias implied by the parameter count Ollama already reports in `/api/tags` (`qwen3:latest` → "8.2B" → `qwen3:8b`), so it still resolves to one model rather than a family. - A candidate derived from a sized HF name no longer includes the bare family. - Size-less candidates — `OLLAMA_MAPPINGS` tags like `phi-4` → `phi4`, or HF names with no size to parse — now match any tag of that family, which is what keeps `phi4:14b` detecting `microsoft/phi-4`. The bare-family candidate came in with #492 (fixing #481, "installed flag always false for models without explicit mapping"); this keeps that fix and drops its blast radius. Same over-match seen from another angle in #619. Regression cover: every one of the 134 `OLLAMA_MAPPINGS` entries is still detected from its own tag, and the reported scenario asserts its siblings stay uninstalled. * fix(ollama): also alias the verbatim parameter size for `:latest` installs `qwen2.5:14b` reports "14.8B", so a `:latest` install has to be aliased to the truncated marketing size. But some families are tagged with the decimal itself — `solar:10.7b`, `qwen3:1.7b`, `lfm2:1.2b`, 20 entries in `OLLAMA_MAPPINGS` — and for those the truncated alias alone reports the model as absent. Emit both forms. They stay inside the family that is genuinely installed, so the extra alias cannot resurrect the cross-family match this branch removes; one of the two is simply dead weight per install. * fix(python): read the package readme through the metadata hook `readme = "../README.md"` is rejected by current hatchling ("Readme path must be within the project directory"), which fails `uv sync` and takes the Test Suite job down on all three platforms — including on main, independently of this branch. The README belongs at the repository root and should not be duplicated or symlinked into `llmfit-python` (a symlink would checkout as a text stub on Windows runners). Hatchling accepts readme *contents* without a path constraint, so the existing custom metadata hook now supplies them: `readme` joins `version` and `license-expression` as dynamic metadata. Verified the built metadata is unchanged in substance — `Description-Content-Type: text/markdown` with the full README body.