Skip to content

Commit d8fd418

Browse files
arnav2claude
andcommitted
release: v0.2.1 — packaging hotfix
Bumps version. Adds RELEASE_NOTES_v0.2.1.md (consumed by release.yml). Includes two follow-ups that got lost in the squash of PR #9: - gitignore docs/planning/ (internal recall worklist) - drop two stale docs/planning/ links from recall-investigation.md Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 1328894 commit d8fd418

6 files changed

Lines changed: 104 additions & 8 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,5 +71,8 @@ rust/**/Cargo.lock.bak
7171
# Downloaded benchmark corpora (see scripts/download_corpora.sh)
7272
data/corpora/
7373

74+
# Internal planning notes (kept locally, not published to the open-source repo)
75+
docs/planning/
76+
7477
# Conductor / Claude Code transient state
7578
.claude/

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ Template for a new release (copy this block, fill in, move Unreleased items in):
4545

4646
## [Unreleased]
4747

48+
## [0.2.1] — 2026-05-19
49+
4850
### ⚠️ BREAKING (Fixed — see also #ks-xlsx-parser channel report)
4951
- Repository layout flattened on `src/` was leaking 13 generic top-level
5052
packages (`models`, `utils`, `parsers`, …) into installed wheels and
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# ks-xlsx-parser v0.2.1 — Packaging hotfix 📦
2+
3+
**Headline:** v0.2.0 shipped a broken wheel. `from ks_xlsx_parser.pipeline import parse_workbook` (and every public entry point that depends on it) raised `ModuleNotFoundError` for everyone who installed from PyPI. **v0.2.1 fixes it.**
4+
5+
If you're on 0.2.0:
6+
7+
```bash
8+
pip install --upgrade ks-xlsx-parser # or: uv pip install --upgrade ks-xlsx-parser
9+
python -c "from ks_xlsx_parser.pipeline import parse_workbook; print('ok')"
10+
```
11+
12+
## What was broken
13+
14+
The source tree was laid out flat under `src/``pipeline.py` and `api.py` as top-level *modules*, with 13 sibling *packages* (`models`, `utils`, `parsers`, `analysis`, …) next to them. The setuptools build picked up the packages but **silently dropped the top-level modules**, because `[tool.setuptools.packages.find]` only finds packages, never modules. The published wheel's `top_level.txt`:
15+
16+
```
17+
analysis annotation charts chunking comparison export formula
18+
ks_xlsx_parser models parsers rendering storage utils verification
19+
```
20+
21+
— 14 top-level entries, 13 of them generic. Two consequences:
22+
23+
1. `from ks_xlsx_parser.pipeline import ...` failed because `pipeline.py` was never copied into the wheel.
24+
2. Anyone with an unrelated `models` / `utils` / `parsers` package in `site-packages` had it shadowed by ks-xlsx-parser's internal ones.
25+
26+
CI couldn't catch this because the test matrix used an editable install — `src/` lives on `sys.path` and the wheel-packaging defect is invisible.
27+
28+
## What changed in 0.2.1
29+
30+
* **Proper nested package.** Everything now lives under `src/ks_xlsx_parser/`. The wheel's `top_level.txt` contains only `ks_xlsx_parser`. Imports inside the package switched from `from pipeline import …` to relative / fully-qualified `ks_xlsx_parser.pipeline`.
31+
* **`scripts/verify_wheel.py`** — builds the wheel, installs it in a clean venv, asserts the public import surface resolves and there's no namespace pollution. Wired into both `ci.yml` (new `wheel-check` job — required) and `release.yml` (a `Verify wheel` step that runs before PyPI publish). The class of bug that produced 0.2.0 cannot recur.
32+
* **CI overhaul** — separate `test` / `wheel-check` / `lint` / `typecheck` jobs; `uv`-backed installs (faster); `make install-dev` alias.
33+
* **Docker benchmark + accuracy tracking**`Dockerfile.bench` reproduces the SpreadsheetBench retrieval benchmark; a new `.github/workflows/benchmark.yml` runs a 60-instance sample on every PR touching the parser and the full 912-corpus weekly. `scripts/append_bench_history.py` keeps a commit-over-commit history file. (Goal: text recall@5 > 0.90.)
34+
* **Recall failure triage**`eval_retrieval.py --emit-failures` + `scripts/triage_recall.py` turn "recall@5 = X" into a bucket histogram with exemplar failures. `docs/recall-investigation.md` documents the diagnosis framework.
35+
36+
## ⚠️ Breaking — if you depended on the leaked top-level packages
37+
38+
Anyone whose downstream code did:
39+
40+
```python
41+
from models import WorkbookDTO # ← used to "work" because of the leak
42+
from parsers.workbook_parser import
43+
```
44+
45+
must update to:
46+
47+
```python
48+
from ks_xlsx_parser.models import WorkbookDTO
49+
from ks_xlsx_parser.parsers.workbook_parser import
50+
```
51+
52+
If you only used the documented public surface (`from ks_xlsx_parser import parse_workbook` and `ks_xlsx_parser.pipeline.parse_workbook`), nothing changes — those names still resolve, and now they actually *load*.
53+
54+
## Upgrade
55+
56+
```bash
57+
pip install --upgrade ks-xlsx-parser
58+
# or
59+
uv pip install --upgrade ks-xlsx-parser
60+
```
61+
62+
Then:
63+
64+
```python
65+
from ks_xlsx_parser import parse_workbook
66+
result = parse_workbook(path="report.xlsx")
67+
print(result.workbook.total_cells)
68+
for chunk in result.chunks:
69+
print(chunk.source_uri, chunk.render_text[:120])
70+
```
71+
72+
## Verification used to ship this release
73+
74+
```
75+
1041 passed, 11 deselected # full test suite
76+
verifying ks_xlsx_parser-0.2.1-py3-none-any.whl
77+
wheel contents OK (61 entries, top-level: ks_xlsx_parser)
78+
clean-venv import OK
79+
wheel verification PASSED
80+
```
81+
82+
`scripts/verify_wheel.py` ran as a release-workflow step before the PyPI publish, with the wheel that's now on PyPI.
83+
84+
## Thanks
85+
86+
Frank for the bug report — the channel screenshot was the right level of detail to reproduce in five minutes.
87+
88+
## See also
89+
90+
* [CHANGELOG.md](https://github.com/knowledgestack/ks-xlsx-parser/blob/main/CHANGELOG.md) — full diff log.
91+
* [`docs/recall-investigation.md`](https://github.com/knowledgestack/ks-xlsx-parser/blob/main/docs/recall-investigation.md) — diagnosis framework for the recall→0.90 roadmap.
92+
* [`docs/benchmark-local-setup.md`](https://github.com/knowledgestack/ks-xlsx-parser/blob/main/docs/benchmark-local-setup.md) — reproduce the benchmark on your laptop.

docs/recall-investigation.md

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,11 @@ failures in the seed=1337 sample:
4343
`answer_position` cell range in `input.xlsx` is empty by design. A
4444
parser cannot retrieve what isn't there. These instances need to be
4545
filtered from the headline metric (TODO 05).
46-
* **30 are truly actionable** parser failures, clustering into 4 named
47-
buckets (TODOs 00, 01, 02, 03, 04 in
48-
[docs/planning/recall-90/](./planning/recall-90/)).
46+
* **30 are truly actionable** parser failures, clustering into a small
47+
number of named buckets (benchmark-spec parser bugs in
48+
`scripts/eval_retrieval.py`; array-formula rendering; chunk range vs
49+
text mismatch; cell-drop / uncached-formula rendering; single-chunk
50+
dilution).
4951
* Zero of the 30 are `present_but_ranked_low`. Chunk-size dilution
5052
may matter on the full 912-corpus but is NOT the dominant problem
5153
on the 200-sample.
@@ -60,9 +62,6 @@ When the in-scope filter is applied, real `recall_text@5` is
6062
**0.59**, not 0.635. Closing the 30 actionable failures gets us
6163
near 0.90 on the in-scope metric.
6264

63-
See [docs/planning/recall-90/](./planning/recall-90/) for the
64-
ranked TODO list.
65-
6665
## A priori hypotheses (now confirmed/refuted; left as history)
6766

6867
### H1 — `present_but_ranked_low` is the biggest bucket

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "ks-xlsx-parser"
7-
version = "0.2.0"
7+
version = "0.2.1"
88
description = "Production-grade Excel Workflow Parser for RAG + auditability systems"
99
readme = "README.md"
1010
license = {text = "MIT"}

src/ks_xlsx_parser/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"""
1414
from __future__ import annotations
1515

16-
__version__ = "0.2.0"
16+
__version__ = "0.2.1"
1717

1818
from .pipeline import ( # noqa: F401
1919
ParseResult,

0 commit comments

Comments
 (0)