Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
4b18c88
chore: complete v2.0 Maximum Accuracy milestone
opencdlee-dotcom Apr 11, 2026
e5d8a3e
feat: integrate post-v2.0 improvements — skew, zoom-verify, prompt ad…
opencdlee-dotcom Apr 11, 2026
3c2e855
docs: start milestone v3.0 Verified Accuracy
opencdlee-dotcom Apr 11, 2026
008910f
docs: complete project research
opencdlee-dotcom Apr 11, 2026
40150c1
docs: define milestone v3.0 requirements (12 requirements)
opencdlee-dotcom Apr 11, 2026
f9d4fdc
docs: create milestone v3.0 roadmap (4 phases, 12 requirements)
opencdlee-dotcom Apr 11, 2026
4441918
docs(06): capture phase context
opencdlee-dotcom Apr 11, 2026
02acc5c
docs(06): add validation strategy
opencdlee-dotcom Apr 11, 2026
041c212
docs(06-measurement-foundation): create phase plan
opencdlee-dotcom Apr 11, 2026
8f50ce4
test(06-01): add failing test_v4_migration_columns stub (RED)
opencdlee-dotcom Apr 11, 2026
6a394bb
feat(06-02): add _MIGRATIONS[4] and bump CURRENT_SCHEMA_VERSION to 4
opencdlee-dotcom Apr 11, 2026
3e2cac5
test(06-01): add Wave 0 RED stubs for TestMarkerRate, TestCalibrateCo…
opencdlee-dotcom Apr 11, 2026
1a6602c
docs(06-01): complete Wave 0 RED stubs plan — SUMMARY, STATE, ROADMAP…
opencdlee-dotcom Apr 11, 2026
915d05c
feat(06-02): extend data models and add marker rate computation in ev…
opencdlee-dotcom Apr 11, 2026
c2413a0
docs(06-02): complete v4 schema migration plan - SUMMARY, STATE, ROAD…
opencdlee-dotcom Apr 11, 2026
3eaaed1
feat(06-03): add provenance capture and marker rate computation to ev…
opencdlee-dotcom Apr 11, 2026
56e16a1
feat(06-03): add marker_rate column and provenance header to benchmar…
opencdlee-dotcom Apr 11, 2026
48c7e66
test(06-03): fix two test stubs that lacked run setup for DB assertions
opencdlee-dotcom Apr 11, 2026
96ffee5
docs(06-03): complete provenance+marker-rate plan — SUMMARY, STATE, R…
opencdlee-dotcom Apr 11, 2026
0ab3405
feat(06-04): add benchmark calibrate subcommand and cost projection g…
opencdlee-dotcom Apr 11, 2026
4113351
docs(06-04): complete CLI surface plan — SUMMARY, STATE, ROADMAP updated
opencdlee-dotcom Apr 11, 2026
22632d1
docs(phase-6): complete phase execution — 8/8 must-haves verified
opencdlee-dotcom Apr 11, 2026
8046e7d
docs(07): research + validation strategy for IAM ingestion + sweep phase
opencdlee-dotcom Apr 13, 2026
62e0933
docs(07): 4 plans across 3 waves — IAM ingest + sweep + per-writer re…
opencdlee-dotcom Apr 13, 2026
3f21735
test(07-01): add TestIAMIngest RED stubs (IAM-01, 9 stubs)
opencdlee-dotcom Apr 13, 2026
0bed2ec
test(07-02): implement TestIAMIngest RED tests for parse_iam_lines an…
opencdlee-dotcom Apr 13, 2026
56e179c
feat(07-02): implement parse_iam_lines() and ingest_iam() in ingest.py
opencdlee-dotcom Apr 13, 2026
f165a4c
feat(07-02): implement parse_iam_lines, ingest_iam, and benchmark ing…
opencdlee-dotcom Apr 13, 2026
85341cf
docs(07-02): complete IAM ingest plan — SUMMARY, STATE, ROADMAP, REQU…
opencdlee-dotcom Apr 13, 2026
7170344
Reorg 2026-04-17: cleanup + new bucketed layout
claude Apr 17, 2026
d08ac1a
feat(postprocess): add multi-word phrase correction + v4.0 proposal
opencdlee-dotcom May 6, 2026
8f53d0e
Merge feat/phrase-postcorrect: multi-word phrase correction + v4.0 pr…
opencdlee-dotcom May 6, 2026
ba682d6
feat(trained_correction): synthetic-data corrector pipeline (v0)
opencdlee-dotcom May 6, 2026
3d2b935
docs(trained_correction): add subpackage README with quick-start, arc…
opencdlee-dotcom May 6, 2026
23e1c77
docs(trained_correction): eval results — 26% relative CER reduction, …
opencdlee-dotcom May 6, 2026
62df1b4
feat(trained_correction): v4.1 safeguards + real-data ingestion path
opencdlee-dotcom May 6, 2026
96e0409
feat(07-03): sweep infrastructure — run_sweep, line_level/auto_retry …
opencdlee-dotcom May 6, 2026
dd6acd8
feat(07-04): per-writer CER report — generate_per_writer_report + --p…
opencdlee-dotcom May 6, 2026
7754b03
docs(phase-7): mark Phase 7 complete in STATE/ROADMAP, add NEXT-STEPS.md
opencdlee-dotcom May 6, 2026
9ca259e
docs: draft S2-S5 specs (writer few-shot, skill bridge, feedback loop…
opencdlee-dotcom May 6, 2026
1bd790d
feat(S3): engine-side CLI bridge for handwriting-reader skill
opencdlee-dotcom May 6, 2026
af361cc
chore: track uv.lock for reproducible installs
opencdlee-dotcom May 6, 2026
0ab024d
feat(S4): engine-side record_correction() + corrections table
opencdlee-dotcom May 6, 2026
a9b18a7
feat(S2): per-writer few-shot exemplars
opencdlee-dotcom May 6, 2026
c628e5b
feat(S5): char-level consensus + confusion-pair postprocess
opencdlee-dotcom May 6, 2026
da56c24
feat(S5): thread writer_profile through vote/smart strategies
opencdlee-dotcom May 6, 2026
1ff632b
feat(phase-8): statistics layer for benchmark compare (STAT-01, STAT-02)
opencdlee-dotcom May 6, 2026
b17d583
feat(09-01): pinned baseline for regression detection (RPT-01)
opencdlee-dotcom May 7, 2026
d7e6ae8
feat(09-02): benchmark recommend with composite 70/15/15 score (RPT-02)
opencdlee-dotcom May 7, 2026
717ee18
feat(09-03): benchmark ingest-lab guided annotation (RPT-03)
opencdlee-dotcom May 7, 2026
055f3de
docs(phase-9): mark RPT-01/02/03 implemented + add 09-{01,02,03} summ…
opencdlee-dotcom May 7, 2026
2f85ada
fix(trained_correction): raise ImportError when optional deps missing
opencdlee-dotcom May 7, 2026
65c67c9
Merge pull request #2 from opencdlee-dotcom/feat/trained-corrector
opencdlee-dotcom May 7, 2026
085b015
Merge main: the branch keeps its work, main brings the machinery that…
opencdlee-dotcom Aug 24, 2026
da036af
Commit the lock I regenerated, which the merge commit did not carry
opencdlee-dotcom Aug 24, 2026
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
122 changes: 122 additions & 0 deletions .planning/NEXT-STEPS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# NEXT-STEPS — What to do after Phase 7

**Status:** Phase 7 (IAM Data Ingestion + Sweep Infrastructure) shipped 2026-05-06.
The infrastructure is ready. The remaining unblockers are **manual data acquisition** and **one sweep run**, after which Phases 8-9 + the trained-corrector real-data retrain are all unblocked.

---

## Why this exists

Phase 7 ended with all 17 RED stubs GREEN, all 4 plans landed, and `benchmark sweep` / `benchmark report --per-writer` callable from the CLI. But two downstream goals remain blocked on **user-side work that can't be automated:**

1. **Phase 8 (Statistics Layer)** needs ≥10-sample multi-strategy runs in the benchmark DB. That requires running the sweep against real IAM data.
2. **Trained-corrector real-data retrain** needs (vlm_text, ground_truth) pairs from real VLM runs. Today the corrector is gated OFF (`HE_USE_TRAINED_CORRECTOR=0`) because synthetic-only training causes hallucinations on hard cases — see `handwriting_engine/trained_correction/EVAL-RESULTS.md`. The sweep produces exactly those pairs.

Both unblock from a single sweep run.

---

## Step 1 — Download the IAM Handwriting Database

The IAM dataset is registration-gated, so this is manual.

1. Register and download from one of:
- [HEIA-FR mirror](https://fki.tic.heia-fr.ch/databases/iam-handwriting-database)
- Original Univ. Bern site (legacy)
2. Extract `lines.tgz` (line-level images) and `ascii.tgz` (transcriptions). Layout expected:
```
<iam-root>/
├── ascii/
│ └── lines.txt
└── lines/
└── <writer>/<form>/<form>-<line>.png
```
3. **Optional but recommended:** also grab the `largeWriterIndependentTextLineRecognitionTask/` partition files. They split IAM into `trainset.txt`, `validationset1.txt`, `testset.txt`. The sweep should run against `testset.txt` only — never on training data, or the baseline isn't a true generalization measure.

---

## Step 2 — Ingest IAM into the benchmark DB

```bash
cd "/Users/user/Documents/Work & Projects/VSCode Projects/handwriting-engine"

# Test partition only (safer, ~2k samples):
python3 -m handwriting_engine.cli benchmark ingest-iam \
--ascii-dir <iam-root>/ascii \
--lines-dir <iam-root>/lines \
--partition-file <iam-root>/largeWriterIndependentTextLineRecognitionTask/testset.txt

# Verify ingestion:
python3 -m handwriting_engine.cli benchmark list --show-samples | head -20
```

Expected: rows with `category='iam'`, `student='iam-writer-XXX'`. The CLI prints `{ingested, skipped_dup, skipped_missing}` counts.

> **Cost note:** The next step runs ALL FIVE strategies against every ingested sample. If you ingest the full test set (~2k lines), one sweep can run ~$3-5 in API calls (Gemini Flash is the cheap default). If unsure, ingest ~50 samples first using a partition subset, do a smoke sweep, then scale up.

---

## Step 3 — Run the multi-strategy sweep

```bash
python3 -m handwriting_engine.cli benchmark sweep --provider gemini
# Confirms cost projection, then executes all 5 strategies:
# baseline, self_correct, line_level, prompt_adapted, zoomed_verify
# Returns one run_id per strategy.
```

Add `--yes` to skip the confirmation prompt (useful in CI / headless runs).

---

## Step 4 — Inspect per-writer breakdown

```bash
# Replace <run_id> with one of the run_ids the sweep printed:
python3 -m handwriting_engine.cli benchmark report --run-id <run_id> --per-writer
```

This is the IAM-03 deliverable: shows whether a strategy's CER gain is consistent across writers or driven by a few easy ones.

---

## Step 5 — Retrain the trained corrector on real data

Now the (vlm_output, ground_truth) pairs from the sweep can fine-tune the FLAN-T5 corrector that's currently gated off:

```bash
# Continue from the v1 synthetic checkpoint (don't start from scratch — preserves
# the easy-error fixes the synthetic data already taught it):
python3 -m handwriting_engine.trained_correction.train \
--from-benchmark-db ~/.handwriting-engine/benchmark.db \
--continue-from ~/.handwriting-engine/models/trained-corrector-v1 \
--output-dir ~/.handwriting-engine/models/trained-corrector-v2 \
--epochs 3

# A/B eval: v2 vs v1 vs heuristic-only
python3 -m handwriting_engine.cli trained-correction eval --n-pairs 200 --seed 9999
```

Expected: hallucinations on hard cases (the 3/10 spot-check failures documented in `trained_correction/EVAL-RESULTS.md`) drop substantially — because the model now sees the actual VLM error distribution rather than a guessed-at synthetic one. Once the gated A/B passes, flip `HE_USE_TRAINED_CORRECTOR=1` to default-on the combined heuristic→trained pipeline.

---

## Step 6 — Plan Phase 8

Once the sweep run lives in the DB, Phase 8 (Statistics Layer) is unblocked:
- Wilcoxon signed-rank p-values on `benchmark compare`
- 95% bootstrap CIs on CER estimates
- Cohen's r effect size

Run `/gsd:plan-phase 8` from inside the engine directory when ready.

---

## Out-of-band side projects flagged in the broader strategy

These do not block Phase 8 but are worth queuing for follow-up sessions:

- **S2 — Per-writer few-shot exemplars.** Currently `writer_profile_store.build_calibration_block()` injects writer-specific text hints into prompts. Stronger: pull 2-3 already-labeled images of the same writer from the benchmark DB and pass them as multi-image prompts (Gemini and Claude both support it). Likely the biggest single CER gain on returning writers (lab notebook semester scenarios). **Spec drafted: `.planning/S2-SPEC-per-writer-few-shot.md` (2026-05-06).**
- **S3 — Wire `~/.claude/skills/handwriting-reader/` skill to call the engine library directly.** The skill currently does its own multi-pass workflow. One source of truth = engine improvements propagate immediately. **Spec drafted: `.planning/S3-SPEC-skill-engine-bridge.md` (2026-05-06).**
- **S4 — Professor OS feedback loop.** `professor/LabNoteBookGrader/` graders should surface low-confidence reads, capture corrections, and write them back to the benchmark DB as per-writer ground truth. Per-writer accuracy then compounds over a semester. **Spec drafted: `.planning/S4-SPEC-professor-feedback-loop.md` (2026-05-06).**
- **S5 — Char-level consensus + confusion-pair-aware postprocess.** Word-level voting catches obvious disagreements; char-level catches single-character swaps (`rn↔m`, `cl↔d`). The drill-down report already tracks confusion pairs; postprocess can consume them. **Spec drafted: `.planning/S5-SPEC-char-consensus-confusion-postprocess.md` (2026-05-06).**
16 changes: 8 additions & 8 deletions .planning/REQUIREMENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ Requirements for the benchmarking milestone. Each maps to a roadmap phase.

### Reporting

- [ ] **RPT-01**: Schema v4 adds `is_baseline` flag to runs table; `benchmark set-baseline RUN_ID` pins a run as the regression anchor; `detect_regressions()` compares against the pinned baseline, not runs[-2].
- [ ] **RPT-02**: `benchmark recommend` outputs the best strategy+provider configuration with a weighted composite score (70% CER / 15% cost / 15% stability across runs).
- [ ] **RPT-03**: Developer can collect and store ground-truth transcriptions from real student lab notebooks using `benchmark ingest-lab` with a guided annotation workflow, enabling production-distribution benchmarks distinct from IAM.
- [x] **RPT-01**: Schema v6 adds `is_baseline` flag to runs table; `benchmark set-baseline RUN_ID` pins a run as the regression anchor; `detect_regressions()` compares against the pinned baseline, not runs[-2]. (shipped 2026-05-06)
- [x] **RPT-02**: `benchmark recommend` outputs the best strategy+provider configuration with a weighted composite score (70% CER / 15% cost / 15% stability across runs). (shipped 2026-05-06; end-to-end on multi-strategy sweep gated on IAM data)
- [x] **RPT-03**: Developer can collect and store ground-truth transcriptions from real student lab notebooks using `benchmark ingest-lab` with a guided annotation workflow, enabling production-distribution benchmarks distinct from IAM. (shipped 2026-05-06)

## v4.0 Requirements (Deferred)

Expand Down Expand Up @@ -63,11 +63,11 @@ Requirements for the benchmarking milestone. Each maps to a roadmap phase.
| IAM-01 | Phase 7 | Complete |
| IAM-02 | Phase 7 | Pending |
| IAM-03 | Phase 7 | Pending |
| STAT-01 | Phase 8 | Pending |
| STAT-02 | Phase 8 | Pending |
| RPT-01 | Phase 9 | Pending |
| RPT-02 | Phase 9 | Pending |
| RPT-03 | Phase 9 | Pending |
| STAT-01 | Phase 8 | Implemented (verification gated on IAM data) |
| STAT-02 | Phase 8 | Implemented (verification gated on IAM data) |
| RPT-01 | Phase 9 | Implemented |
| RPT-02 | Phase 9 | Implemented (verification gated on IAM sweep) |
| RPT-03 | Phase 9 | Implemented |

**Coverage:**
- v3.0 requirements: 12 total
Expand Down
36 changes: 22 additions & 14 deletions .planning/ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ Full details: `.planning/milestones/v2.0-ROADMAP.md`
### v3.0 — Verified Accuracy

- [x] **Phase 6: Measurement Foundation** — Reproducible baseline + variance floor + cost guardrails (completed 2026-04-11)
- [ ] **Phase 7: IAM Data Ingestion + Sweep Infrastructure** — Full IAM benchmark pipeline
- [ ] **Phase 8: Statistics Layer** — Statistical defensibility for all comparisons
- [ ] **Phase 9: Final Sweep, Recommendation, and Baseline Lock** — Best config identified, regression anchor committed
- [x] **Phase 7: IAM Data Ingestion + Sweep Infrastructure** — Full IAM benchmark pipeline (completed 2026-05-06)
- [ ] **Phase 8: Statistics Layer** — Statistical defensibility for all comparisons (implementation shipped 2026-05-06; criterion verification gated on user IAM download + first sweep run; see `.planning/NEXT-STEPS.md`)
- [ ] **Phase 9: Final Sweep, Recommendation, and Baseline Lock** — Best config identified, regression anchor committed (implementation shipped 2026-05-06; verification of "best config recommendation" gated on user IAM download + first multi-strategy sweep)

## Phase Details

Expand All @@ -42,9 +42,9 @@ Full details: `.planning/milestones/v2.0-ROADMAP.md`

Plans:
- [x] 06-01-PLAN.md — Wave 0 test stubs: failing tests for all Phase 6 behaviors (FOUND-01 through FOUND-04) (completed 2026-04-11)
- [ ] 06-02-PLAN.md — v4 schema migration + dataclass extensions (db.py, models.py)
- [x] 06-03-PLAN.md — Provenance capture + marker rate computation + report display (evaluate.py, report.py)
- [ ] 06-04-PLAN.md — CLI surface: benchmark calibrate subcommand + cost guardrail + provenance flags (cli.py)
- [x] 06-02-PLAN.md — v4 schema migration + dataclass extensions (db.py, models.py) (completed 2026-04-11)
- [x] 06-03-PLAN.md — Provenance capture + marker rate computation + report display (evaluate.py, report.py) (completed 2026-04-11)
- [x] 06-04-PLAN.md — CLI surface: benchmark calibrate subcommand + cost guardrail + provenance flags (cli.py) (completed 2026-04-11)

### Phase 7: IAM Data Ingestion + Sweep Infrastructure
**Goal**: The developer can load the IAM Handwriting Database into the benchmark system and execute a full multi-strategy sweep against it, with per-writer variance visible in reports.
Expand All @@ -57,10 +57,10 @@ Plans:
**Plans**: 4 plans

Plans:
- [ ] 07-01-PLAN.md — Wave 0 RED test stubs: 16 failing tests across TestIAMIngest, TestSweep, TestPerWriterReport (IAM-01, IAM-02, IAM-03)
- [ ] 07-02-PLAN.md — IAM ingest infrastructure: parse_iam_lines(), ingest_iam(), benchmark ingest-iam CLI (IAM-01)
- [ ] 07-03-PLAN.md — Sweep infrastructure: line_level/auto_retry threading, run_sweep(), benchmark sweep CLI (IAM-02)
- [ ] 07-04-PLAN.md — Per-writer report: generate_per_writer_report(), benchmark report --per-writer flag (IAM-03)
- [x] 07-01-PLAN.md — Wave 0 RED test stubs: 17 failing tests across TestIAMIngest, TestSweep, TestPerWriterReport (IAM-01, IAM-02, IAM-03) (completed 2026-04-11)
- [x] 07-02-PLAN.md — IAM ingest infrastructure: parse_iam_lines(), ingest_iam(), benchmark ingest-iam CLI (IAM-01) (completed 2026-04-12)
- [x] 07-03-PLAN.md — Sweep infrastructure: line_level/auto_retry threading, run_sweep(), benchmark sweep CLI (IAM-02) (completed 2026-05-06)
- [x] 07-04-PLAN.md — Per-writer report: generate_per_writer_report(), benchmark report --per-writer flag (IAM-03) (completed 2026-05-06)

### Phase 8: Statistics Layer
**Goal**: CER comparisons between strategies are statistically defensible — not just raw delta numbers — so the developer can assert with confidence that a measured improvement is real.
Expand All @@ -69,7 +69,10 @@ Plans:
**Success Criteria** (what must be TRUE when this phase completes):
1. Running `benchmark compare RUN_A RUN_B` on any two runs with n >= 10 samples automatically appends a Wilcoxon signed-rank p-value and Cohen's r effect size to the output, with no extra flags needed.
2. The same `benchmark compare` output includes 95% bootstrap confidence intervals on both CER estimates, so the developer can see whether the CI bands overlap and judge whether the difference is distinguishable from sampling noise.
**Plans**: TBD
**Plans**: 1 plan

Plans:
- [x] 08-01-PLAN.md — Stats module + compare_runs wire-up: paired Wilcoxon, percentile bootstrap CI, Cohen's r (no scipy dep) (completed 2026-05-06; criterion verification gated on IAM data)

### Phase 9: Final Sweep, Recommendation, and Baseline Lock
**Goal**: The developer knows which strategy+provider configuration is best for lab notebook grading, and a regression baseline is pinned so any future code change that silently degrades accuracy is immediately detectable.
Expand All @@ -79,7 +82,12 @@ Plans:
1. Developer runs `benchmark set-baseline RUN_ID` to pin any run as the regression anchor; `detect_regressions()` then compares future runs against that pinned run (not the penultimate run), and the schema tracks the `is_baseline` flag durably across sessions.
2. `benchmark recommend` outputs a single ranked recommendation with a composite score (70% CER / 15% cost / 15% stability) and the winning strategy+provider combination is unambiguous.
3. Developer can run `benchmark ingest-lab` against real student lab notebook images and store ground-truth transcriptions via a guided annotation workflow, producing a production-distribution test set that is separate from IAM.
**Plans**: TBD
**Plans**: 3 plans

Plans:
- [x] 09-01-PLAN.md — Schema v6 is_baseline + set_baseline/get_baseline + detect_regressions retarget + CLI (RPT-01) (completed 2026-05-06)
- [x] 09-02-PLAN.md — recommend_strategy() composite 70/15/15 score + CLI (RPT-02) (completed 2026-05-06; verification gated on multi-strategy IAM sweep)
- [x] 09-03-PLAN.md — ingest_lab() guided annotation + CLI (RPT-03) (completed 2026-05-06)

## Progress

Expand All @@ -91,6 +99,6 @@ Plans:
| 4. Preprocessing + Writer Adaptation | v2.0 | 1/1 | ✅ Complete | 2026-04-09 |
| 5. Post-Processing + Benchmark Suite | v2.0 | 1/1 | ✅ Complete | 2026-04-09 |
| 6. Measurement Foundation | 4/4 | Complete | 2026-04-11 | - |
| 7. IAM Data Ingestion + Sweep Infrastructure | 1/4 | In Progress| | - |
| 8. Statistics Layer | v3.0 | 0/? | Not started | - |
| 7. IAM Data Ingestion + Sweep Infrastructure | v3.0 | 4/4 | ✅ Complete | 2026-05-06 |
| 8. Statistics Layer | v3.0 | 0/? | Blocked on user IAM download + first sweep | - |
| 9. Final Sweep, Recommendation, and Baseline Lock | v3.0 | 0/? | Not started | - |
Loading