Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions CHANGES_SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# Changes Summary — chronowords hardening

Three review-queue PRs (docs, design, tests), all green, **none merged**. Plus this
meta-PR carrying the summary. Triage at your leisure; nothing was decided for you.

| PR | Branch | Title |
|----|--------|-------|
| #6 | `docs-overhaul` | Docs overhaul: contract docstrings + rebuilt quickstart/tutorials/troubleshooting |
| #7 | `design-review` | Design review: pre-mortem report + safe type/exception tightening |
| #8 | `test-hardening` | Test hardening: property-based tests + mutation-score gaps closed |
| #9 | `changes-summary` | This summary |

The branches are independent (each off `main`), so they can be reviewed and merged
in any order. There are no file overlaps between them except that #7 and #8 both
touch areas #6 documents — merging #6 first is the natural order but not required.

## PR #6 — Docs overhaul (safe to merge; two judgement calls flagged)

What it does:
- Rewrites every public-API docstring as an honest **contract** (preconditions,
what's raised explicitly vs. implicitly, what's silently swallowed), including the
previously near-undocumented Cython `PPMIComputer`.
- New, **verified-runnable** Quickstart; a Tutorial for the semantic-shift workflow;
a Troubleshooting page; completed API reference; fixed README and installation page.
- Docs build with **0 Sphinx warnings** (was 77).

Two changes worth your eye (both flagged in the PR body):
1. **Re-exports added** to `algebra/`, `alignment/`, `topics/`, `utils/` `__init__.py`.
The documented imports (`from chronowords.algebra import SVDAlgebra`) previously
raised `ImportError`; the README example could not run. The fix is additive and
behaviour-preserving, but it does add public names — confirm you're happy with the
surface.
2. **Removed `sphinx-autodoc-typehints`** (from `conf.py`, `pyproject.toml [docs]`,
`docs/requirements.txt`). It is deprecated (emits `RemovedInSphinx10` warnings) and
mangles napoleon admonitions, which blocked zero-warnings. Types still render in
signatures via built-in autodoc. Docs-only; revert if you prefer to keep it.

## PR #7 — Design review (report + minimal safe edits)

What it does:
- Adds **`PRE-MORTEM.md`**: 8 future-bug post-mortems for the numerical core, plus
cross-cutting themes and a "Needs human decision" list.
- Applies **only** safe, behaviour-preserving type fixes:
`ProcrustesAligner.get_word_similarity` → `-> float | None`;
`ProcrustesAligner.__init__` → `-> None`.
- Changes **no** runtime behaviour and narrows **no** exception handling.

## PR #8 — Test hardening (additive; safe to merge)

What it does:
- New `tests/strategies.py` + property tests: SVD save/load round-trip, Procrustes
transform-is-an-isometry, Procrustes save/load round-trip, PPMI non-negativity.
- Adds **`MUTATION_TESTING.md`** with a guided mutation pass: core-sample score
**5/9 → 8/9 (89%)** after adding 3 targeted tests for real survivors.
- Note: `mutmut` v3 didn't work with this `src`-layout/editable/Cython setup, so it
was removed and a manual guided pass used instead (details in the file).

## Needs your decision (carried from PRE-MORTEM.md, NOT applied)

These are real findings deliberately left untouched because they change public
behaviour — your call:

1. **`CountMinSketch.estimate_error` ignores its `confidence` argument** — a genuine
dead-code bug. Any fix changes returned values; decide the intended bound first.
2. **Narrow the broad `except Exception`** in `SVDAlgebra.train` (svds → noisy dense
fallback) and `TopicModel._compute_topic_similarity` (returns 0.0 on any error).
Narrowing is desirable but will surface currently-swallowed exceptions.
3. **Zero-norm guard for `ProcrustesAligner.get_word_similarity`** — currently yields
`nan`; decide between `None` / 0.0 / epsilon-floor.
4. **Input validation** on constructors and `train`/`fit` (shapes, positive counts,
`n_components`/`n_topics` ranges) — currently invalid inputs fail late with opaque
NumPy/sklearn errors.
5. **Promote the hard-coded `>5` PPMI count threshold** in `count_skipgrams.pyx` to a
named constant/parameter — exposing it is an API addition.

## Things I chose not to touch, and why

- **The asymmetric PPMI `alpha` smoothing** (`count_skipgrams.pyx`): it looks like a
bug but is the intended SGNS-style context smoothing. Documented in code/pre-mortem;
not changed.
- **The dense-SVD-with-noise fallback** in `train`: changing it (seeding, logging,
narrowing the except) alters behaviour/output — left for you (pre-mortem #1).
- **Wider type tightening** (e.g. replacing `np.ndarray` with shaped types, dict →
TypedDict): higher risk of behaviour/typing churn than value here; skipped.
- **CI integration of mutation testing**: would need `src`-layout config or a
different tool; out of scope for this pass.
- **`main`**: never touched. No force-pushes, no PyPI, no CI secrets.

## How to verify locally

```bash
uv sync --all-groups
uv run pytest # all branches green
uv run pytest --doctest-modules src/chronowords
uv run ty check src tests
uv run ruff check . && uv run ruff format --check .
cd docs && uv run make html # PR #6: 0 warnings
```
Loading