Commit graph

1750 commits

Author SHA1 Message Date
LLLin000
d50ea4631b fix: final cleanup before merge — stale test, helper, RGB safety
1. Stale test: test_extract_objects_renders_same_page_once_for_multiple_crops
   now asserts render_pdf_page_cached is NOT called (new PageRenderContext path)
   and pages/page_001.jpg is NOT created.

2. Extract _resolve_object_crop_pdf_path() helper with 4-case test.
   Phase 4 now uses it instead of inline fallback logic.
   Test locks in: Phase 1 resolved path beats stale meta['source_pdf'].

3. PageRenderContext: use fitz.csRGB in get_pixmap() for safe CMYK/n>3 handling.
   Removed fragile pix.n mode detection.

4. Added test_extract_and_write_objects_with_use_disk_page_cache_false_and_valid_pdf
2026-07-05 21:36:17 +08:00
LLLin000
643052489a fix: determinism + correctness fixes before further optimization
6 fixes bundled:

1. Cleanup: remove accidental empty file '6s}'

2. Rebuild determinism: add 'use_disk_page_cache' gate to _crop_asset_from_pdf.
   Rebuild (use_disk_page_cache=False) never reads or writes pages/page_XXX.jpg.
   All rendering goes through PageRenderContext in-memory.
   Legacy callers keep backward-compat behavior (default True).

3. PageRenderContext safety:
   - Only use when page_width>0 and page_height>0 and not rotation_deg
   - Fix Pixmap.n mode detection (L/RGB/RGBA -> convert to RGB)
   - Fix Image.Resampling name bug (Image -> PILImage)
   - Rotated crops always fall back to direct PDF clip path

4. Phase 1+2a merged traversal: always extract PDF lines on every page,
   regardless of whether span_metadata already exists. Fixes figure inventory
   data gaps when pages have pre-existing span coverage.

5. Phase 4: use resolved source_pdf_path from Phase 1, not ocr_meta['source_pdf']
   fallback (which may be stale or missing).

6. Added 5 determinism tests
2026-07-05 21:32:05 +08:00
LLLin000
b977adc1d8 perf: PageRenderContext — in-memory page rendering for Phase 4a, no disk writes
Add PageRenderContext class that renders each page once into memory
(PIL Image via get_pixmap + frombytes), shared across all crop tasks
in a single rebuild session. No full-page JPG is written to disk.

- _crop_asset_from_pdf: new fast path (page_render_context kwarg)
- Three task functions pass context through
- extract_and_write_objects opens PDF once, creates context, closes after
- Cold Phase 4a: 4.0s → 1.24s (60p, 30 unique pages, 42 crops)
- Full cold rebuild: 10.9s → 7.17s
2026-07-05 21:13:29 +08:00
LLLin000
9ebd1f3dcb perf: merge Phase 1+2a into single PDF pass, add _extract_lines_from_rawdict
- Extract PDF lines from rawdict data that was already fetched for span backfill,
  eliminating the separate page.get_text('dict') pass (~6s for 60 pages)
- Add _extract_lines_from_rawdict() helper to avoid rawdict re-parse
- Keep extract_pdf_lines_normalized() as backward-compatible API
- First-rebuild: 14.2s -> 10.9s (60p), 8.8s -> 8.0s (81p)
2026-07-05 20:55:10 +08:00
LLLin000
83b516aac0 fix: optimize span backfill with per-page rawdict batching and incremental re-extraction
- Group raw_blocks by page, call get_text('rawdict') once per page instead of once per block
  (1433 calls → 60 calls, 68s → 16.6s for a 60-page paper)
- Add _spans_from_rawdict() helper to filter cached rawdict by char bbox center overlap
- Keep extract_pdf_spans_for_block() as single-block compatibility API unchanged
- Add incremental backfill: skip pages where all blocks already have span_metadata
- Remove figure_title from _is_text_like_raw_block() coverage count (figure titles are
  typically image-rendered, not selectable PDF text)
- Add regression test: fast path output matches single-block API
2026-07-05 20:39:52 +08:00
LLLin000
c34ebbce81 feat: rebuild speed-up with parallel rebuild, threaded asset cropping, maintenance refactor, embed progress, CLI docs 2026-07-05 19:43:07 +08:00
LLLin000
380f935f83 docs: add fulltext rebuild safety implementation plan 2026-07-05 17:14:13 +08:00
LLLin000
7931f658bd feat: add rebuild-time fulltext backups and provenance 2026-07-05 17:00:41 +08:00
LLLin000
cdf969d85e feat: persist machine fulltext hash for initial OCR 2026-07-05 16:58:23 +08:00
LLLin000
1474c061a8 feat: surface drift state and invalidate maintenance cache 2026-07-05 16:52:17 +08:00
LLLin000
d8451947ad refactor: separate render artifact writes from user fulltext commit 2026-07-05 16:50:58 +08:00
LLLin000
0a3e40fd92 feat: add fulltext writeback state helpers 2026-07-05 16:45:31 +08:00
LLLin000
a21fdf304b docs: tighten rebuild safety spec 2026-07-05 16:10:07 +08:00
LLLin000
35e66197b4 docs: add fulltext rebuild safety design 2026-07-05 16:00:54 +08:00
LLLin000
5e5dd7c4a6 fix: add paper-lookup next action on empty results 2026-07-05 15:24:24 +08:00
LLLin000
317472eb35 fix: align paper lookup scope and command signatures 2026-07-05 15:16:26 +08:00
LLLin000
c534e481c7 fix: close 4 review gaps — registry, body/object-unit schemas, compat vector arm
Changes:
- Add paper-lookup, content-discovery, scoped-fetch to command registry
- Add unit_kind column to body_units schema (DEFAULT 'body')
- Replace object_units schema: object_role -> object_kind, object_label,
  caption_text, nearby_body_text; drop unit_text, drop object_role
- Bump schema version to 3 with deterministic drop/recreate migration for
  derived tables (body_units, body_units_fts, object_units)
- Update _upsert_body_units / _upsert_object_units for new columns
- Update build_object_units to emit object_kind, object_label, caption_text,
  nearby_body_text fields
- Add vector secondary arm to _run_compat_content_discovery: runs paper_fts
  primary, conditionally adds vector_retrieve secondary when vector is healthy
- Add/fix tests for schema columns, builder output, registry, and compat
  content-discovery vector-secondary path
2026-07-05 15:13:43 +08:00
LLLin000
88838c1842 docs: keep paper lookup at identity boundary 2026-07-05 15:06:23 +08:00
LLLin000
4dbeb5ae50 fix: address 4 review items — remove dead INTENTS dict, drop unused --limit from paper-navigation, add -> int return types, guard subsection section_path 2026-07-05 14:46:26 +08:00
LLLin000
1e6edad7ba feat: route Layer 4 gateway through body units and structure tree 2026-07-05 14:39:19 +08:00
LLLin000
2ab3aa4219 fix: deduplicate object unit_id and wire units persistence in builder
Fix 1 (units.py): object unit_id now includes the entry's block_id
instead of the node's block_span, fixing PRIMARY KEY collisions when
a section has multiple objects (e.g. two figure_captions).

Fix 2 (builder.py): retrieval units are now persisted during
build_from_index(). Scans each paper's OCR output directory for
structure-tree.json, builds body+object units and manifest, then
upserts into the DB tables and meta. Also clears body_units and
object_units at rebuild start alongside the other tables.
2026-07-05 14:28:43 +08:00
LLLin000
9d332980f0 feat: add body units, manifest, and body-unit FTS 2026-07-05 14:21:27 +08:00
LLLin000
e23f35114c feat: add LanceDB evaluation backend scaffold 2026-07-05 14:19:37 +08:00
LLLin000
9d5a008df1 feat: make paper lookup decomposed and coverage-scored 2026-07-05 14:14:03 +08:00
LLLin000
b9f4d6c4f0 refactor: add vector backend adapter with Chroma compatibility 2026-07-05 14:13:59 +08:00
LLLin000
bc27ac2255 feat: add Layer 4 gateway command surface 2026-07-05 14:12:50 +08:00
LLLin000
12b930c31d feat: add structure tree builder for paper navigation 2026-07-05 14:12:36 +08:00
LLLin000
b02e762ce4 docs: plan Layer 4 retrieval substrate 2026-07-05 02:27:47 +08:00
LLLin000
9bc12bd6a0 docs: tighten Layer 4 retrieval spec 2026-07-05 02:22:17 +08:00
LLLin000
f8d928d6ed docs: design Layer 4 retrieval substrate 2026-07-05 02:05:27 +08:00
LLLin000
7917858e24 feat: PR D — Base view cleanup
- Removed "重做OCR" view from build_base_views() (3 standard views)
- Changed ocr_status displayName to "状态"
- Removed ocr_redo property from _build_base_yaml()
- Removed deprecated ocr_redo insertion from _sanitize_base_file()
- Updated tests (28 passed)
2026-07-05 01:26:34 +08:00
LLLin000
b585e42ab2 fix: 3 micro-patches from 9.4/10 review
1. show_in_base — separate hidden from maintenance vs hidden from both
2. Unified is_degraded check — done_degraded and health yellow/red
   share one entry point
3. Hash error_summary in manifest instead of raw string
4. Fix Promise.withResolvers for ES compat
2026-07-05 01:19:59 +08:00
LLLin000
d00485777f feat: PR C — Plugin maintenance tab UI + cache + action-first display 2026-07-05 01:13:57 +08:00
LLLin000
0647c9be3f feat: PR C — Plugin maintenance tab UI + cache + action-first display
- i18n: 9 new maintenance_* keys (en + zh)
- ocr-maintenance-ui.ts: new types (DisplayAction, MaintenanceCache,
  MaintenanceDisplayRow) + cache read/write + refreshMaintenanceData
- settings.ts: _renderMaintenanceTab rewritten to action-first model
  (cache-first render, background manifest refresh, grouped tables
  with checkboxes, retry/rebuild/upgrade buttons)
- Backward compatible: old categorizeMaintenanceRow untouched
- 57 tests pass (6 files)
2026-07-05 01:13:47 +08:00
LLLin000
0a41335a7c feat: PR B — CLI manifest/keys + keyed redo 2026-07-05 01:03:30 +08:00
LLLin000
63915e98a4 feat: PR B — CLI manifest/keys + keyed redo
- list_parser: added --manifest and --keys args
- redo_parser: added positional keys args
- _run_ocr_list: manifest mode (calls compute_maintenance_manifest)
  and keys filtering
- _run_ocr_redo: keyed redo for specific papers + fallback to old path
- 11 new tests (56 total, 0 failed)
2026-07-05 01:02:55 +08:00
LLLin000
6b408c8770 feat: PR A — backend display contract + manifest 2026-07-05 00:53:35 +08:00
LLLin000
e15edb1161 feat: PR A — backend display contract + manifest
- 7 display fields on OCRMaintenanceRow (display_action, label, label_key,
  reason, reason_key, group, severity, visible_in_maintenance)
- _compute_display_fields() pure function with 12 mapping rules
- compute_maintenance_manifest() lightweight hash function
- Integration in collect_maintenance_rows()
- 45 tests covering all mapping rules + manifest
2026-07-05 00:53:18 +08:00
LLLin000
44bbad9250 docs: plan v2 — fix all P0/P1 (deps, error status, redo keys, health-bound, i18n) 2026-07-05 00:36:21 +08:00
LLLin000
069c344af7 docs: implementation plan for maintenance tab — 3 PRs (row model, CLI, plugin UI) 2026-07-05 00:28:58 +08:00
LLLin000
b4edea8ee6 docs: spec cleanup — remove duplicate old UI, add row model display fields + mapping contract 2026-07-05 00:27:44 +08:00
LLLin000
ac55a519db docs: maintenance tab design spec v2 — action-first labels, legacy handling, cache strategy 2026-07-05 00:24:08 +08:00
LLLin000
f76396220d docs: mark Layer 2 done, update project docs
- Active queue: Layer 2 added to completed with commit reference
- PROJECT-MANAGEMENT: updated header, test counts, component table,
  Layer 3 replaced health hardening with done status, active queue
  reprioritized, key file map updated, 7 decision log entries added
- Session timeline entry pending (manual update)
2026-07-04 23:41:59 +08:00
LLLin000
96fd9771ef fix(ocr-quality): contract polish — 4 P0/P1 fixes
1. compute_use_cases output uses status/gates/reasons (not recommended/gate_results)
2. write_feedback validates every mark has result_hash and fulltext_hash
3. load_readiness_policy(policy=...) bypasses user override (reproducible)
4. confidence_and_fallbacks yellow for degraded=True or weak span coverage

Minor: append_mark doesn't mutate caller dict; has_figure_evidence includes
unmatched_legend_count and held_count.
2026-07-04 23:38:03 +08:00
LLLin000
b07ac7a177 docs: add Layer 2 spec and implementation plan 2026-07-04 23:32:55 +08:00
LLLin000
8aba7feb48 Merge branch 'feat/ocr-quality-feedback' 2026-07-04 23:28:29 +08:00
LLLin000
c76f1569aa feat(ocr-quality): add evaluate_readiness() with YAML policy evaluator
Adds readiness policy evaluator layer:
- load_readiness_policy() with deep-merge, importlib.resources, user override
- _resolve_field() dotted path resolver, _apply_op() operator matcher
- _check_hard_red() for hard-red rule evaluation
- evaluate_readiness() with weighted scoring + status determination
- compute_use_cases() for all 4 use cases (reading, qa, figure_table, chunking)
- Default YAML policy with weights, hard_red rules, use_case gates
- pyproject.toml: policies/*.yaml added to package-data
- 7 tests (B1-B7) covering all paths

17/17 tests pass (A10 + B7).
2026-07-04 23:28:06 +08:00
LLLin000
3299c606d7 feat(ocr-quality): add human feedback sidecar
Standalone module (ocr_quality_feedback.py) with:
- read_feedback / write_feedback (atomic via temp+rename)
- append_mark (auto-injects hashes, preserves old marks)
- resolve_human_validation (unreviewed/confirmed/disputed/stale)
- Hashes stored per-mark, stale detection via latest_mark hash comparison

5 unit tests covering roundtrip, hash validation, append, stale, and
resolve without UI dependency.
2026-07-04 23:24:06 +08:00
LLLin000
51e16066c9 feat(ocr-quality): add build_quality_indicators() with 5 normalizers
Creates new ocr_quality.py module as pure function layer between
build_ocr_health() and evaluate_readiness(). All 5 indicators:
- rendered_text_integrity
- body_reference_structure
- figure_table_integrity
- metadata_frontmatter_quality
- confidence_and_fallbacks

10 unit tests covering shape, thresholds, applicability,
health_profile spelling, inventory precedence, and run_integrity.
2026-07-04 23:23:51 +08:00
LLLin000
01bacab4d8 feat(pr3): add column-aware same-page reference boundary 2026-07-04 22:40:30 +08:00