10 KiB
Tasks: attachment OCR (roadmap 37)
Spec: spec.md. Rules: AGENTS.md, docs/CODE-MAP.md.
One task = one agent; execute in order, dependencies are preceding tasks. Each task has its own test boundary; backend tests use fakes until approval. Existing paths verified with rg --files and source reads on 2026-10-21; paths marked new do not exist yet. No new crate; no workspace/layer registration needed. If owner instead approves a new crate, first revise tasks to own its manifest, root Cargo.toml and xtask/src/layers.rs, package/layer/dependency registration and crate smoke test before use.
First tool call rule: first tool call reads at most three listed inputs; write FIRST file in OWNS in SECOND tool call, with compiling stub and one failing test, then make it pass. Do not spend second call exploring. For document-only tasks write initial acceptance checklist in second call and review/complete it instead of a code stub.
Standing VERIFY (future implementation only): export PATH="$HOME/.cargo/bin:$PATH"; cargo test -p <owned-package>; cargo clippy -p <owned-package> --all-targets -- -D warnings; rustfmt --edition 2024 <owned Rust files>. UI tasks add cargo xtask i18n and render/read snapshot PNG. Last implementation task adds cargo xtask layers, cargo xtask tree, cargo xtask ci. These commands are instructions, not commands run during this spec-writing request.
Standing DO NOT: touch outside OWNS; change git state; run cargo fmt --all; add dependency without owner response; unsafe/panics/unchecked slicing; rewrite source attachments; hardcode UI strings; bypass engine commands. No production claim until platform acceptance passes.
Phase 1 — validated contract
- 1. Pure OCR result model and capability contract.
OWNS:
crates/index/src/ocr.rs(new, FIRST),crates/index/src/lib.rs(declare/re-export),crates/index/src/error.rs(validation error only). FILES TO OPEN:specs/plugins-parity/attachment-ocr/spec.mdD1;crates/index/src/lib.rs;crates/index/src/error.rs. GOAL:OcrDocument,OcrPage,OcrLine,OcrWord,OcrRect,OcrCapabilities,validate()with named caps; pure model, no OCR engine/no IO. Optional confidence only, no fabricated values; backend-neutral typed unsupported status. JSON persistence stays engine if serde unavailable here; no manifest edit. TESTS: image/page geometry orientation, empty successful result, NaN/outside box, page 0, 501 pages, duplicate page, text/word cap, unsupported language/capability description; fixture reading order retained. VERIFY: standing index;cargo test -p notescraft-index ocrruns actual new module tests. DO NOT: native APIs, dependency, OCR implementation, IO or synthetic Markdown postings.
Phase 2 — backend gate and worker
- 2. Approve native adapter boundary (document-only decision).
OWNS:
specs/plugins-parity/attachment-ocr/backend-decision.md(new, FIRST). FILES TO OPEN: spec questions; rootCargo.toml;crates/engine/Cargo.toml. GOAL: inventory already-installed safe bindings; primary-source verified API/OS/packaging/language availability; exact proposed dependency versions/licenses and safe-call proof. Compare OS-first vs bundled ocrs/model footprint. Obtain recorded owner response before native task; unavailable safe path blocks task 4, not contract tests. No new crate proposed. TESTS: documented compile feasibility cases macOS Vision request creation and Windows desktop WinRT OCR initialization without project unsafe; identify any unsupported package configuration explicitly. VERIFY: manual source/manifest review, no cargo required for decision document; owner approval remains pending until actual response. DO NOT: edit manifests, unsafe adapter, C/Swift helper or auto download. - 3. Bounded worker, cache and registry commands with fake backend.
OWNS:
crates/engine/src/ocr/mod.rs(new, FIRST),crates/engine/src/ocr/worker.rs(new),crates/engine/src/ocr/cache.rs(new),crates/engine/src/ocr/commands.rs(new),crates/engine/src/lib.rs,crates/engine/src/commands.rs,crates/engine/src/ai/assistant_gate.rs,crates/engine/tests/core_commands.rs,crates/engine/tests/ocr.rs(new). FILES TO OPEN: spec D1–D3;crates/engine/src/viewers/info.rs;crates/engine/src/vault/pdf_preview.rs; later remaining owned registry files andcrates/engine/tests/common/mod.rs. GOAL: bounded one-worker queue/cancel/generation, explicit progress, validated hash-keyed atomic cache, five command IDs with read/write policy; fake backend in tests and production unsupported capability until native adapter exists. Reuse existing sha2 hash implementation pattern, never mtime-only cache key. No pretend recognition. TESTS: queue full, cancel races, deadline, hash replacement same size/mtime, corrupt schema/cache, read-only, bounds, source unchanged, no late publication after vault switch; cache hit schedules zero recognition. VERIFY: standing engine; command integration tests and fake worker tests deterministic without installed OCR. DO NOT: native dependency before Q2, silent empty success for unavailable backend, unbounded channels. - 4. Native macOS/Windows adapters (blocked on task 2 owner response).
OWNS:
crates/engine/src/ocr/platform.rs(new, FIRST),crates/engine/src/ocr/platform/macos.rs(new),crates/engine/src/ocr/platform/windows.rs(new),crates/engine/src/ocr/mod.rs,crates/engine/Cargo.toml(approved target-only bindings), rootCargo.toml(approved dependency versions only),Cargo.lock(approved resolution only),crates/engine/tests/ocr_native.rs(new). FILES TO OPEN: approved backend-decision.md; spec D1/D3; task 3 worker interface. GOAL: safe Rust API adapter, runtime installed language/size discovery, normalized coordinates, image orientation, explicit Windows package capability; offline recognition. Linux unsupported. No workspace crate added; layer table remains unchanged. If bindings require project unsafe or non-Rust helper, stop and ask owner, never bypass lint. TESTS: native offline printed English/Portuguese fixtures, rotated image/no-text image, installed-language absent, API image limit, runtime unavailable/package failure; report true text and boxes with tolerance, no claim of handwriting parity. VERIFY: standing engine on each approved target and native fixture evidence, not fake suite alone. DO NOT: add unapproved dependency/model; weaken Rust-only/unsafe; hidden cloud fallback.
Phase 3 — search and UI
- 5. Attachment postings and invalidation.
OWNS:
crates/index/src/search/attachment.rs(new, FIRST),crates/index/src/search/mod.rs,crates/index/src/search/doc.rs,crates/index/src/search/options.rs,crates/index/src/search/rank.rs,crates/index/src/lib.rs,crates/engine/src/ocr/mod.rs,crates/engine/src/vault/find/content_search.rs,crates/index/tests/ocr_search.rs(new),crates/engine/tests/ocr_search.rs(new). FILES TO OPEN: spec D2;crates/index/src/search/mod.rs;crates/index/src/search/doc.rs; latercrates/index/src/search/options.rsand engine search response before edit. GOAL: typed attachment insert/remove and hit location/provenance; reuse tokenizer/ranker; integrate validated completion snapshots; preserve existing note hit wire shape. Invalidate on hash/remove and exclude encrypted/locked domains before index insertion or reads; if encryption not implemented, no claim it is supported. TESTS: note and attachment matches together; no fake Markdown line offset; page/rect stable; cache reload; delete/hash change removes terms; late cancelled completion cannot reinsert; existing search tests unchanged. VERIFY: standing index/engine packages, both named OCR search integration tests. DO NOT: write extracted text into note files, return OCR text from locked domains, duplicate ranker. - 6. Attachment actions, settings and search navigation.
OWNS:
crates/ui-egui/src/views/media_view/ocr.rs(new, FIRST),crates/ui-egui/src/views/media_view/mod.rs,crates/ui-egui/src/views/media_view/pdf.rs,crates/ui-egui/src/views/image_view/mod.rs,crates/ui-egui/src/panels/search_panel.rs,crates/ui-egui/src/shell/app/window/views.rs,crates/ui-egui/src/text/views/media_view/mod.rs,crates/i18n/locales/en.toml,crates/ui-egui/tests/ocr.rs(new),crates/engine/src/prefs/ocr_config.rs(new),crates/engine/src/prefs/mod.rs,crates/engine/src/prefs/app_settings.rs,crates/engine/src/prefs/settings.rs,crates/ui-egui/src/views/settings_view/categories/core_cards.rs,crates/engine/src/ocr/mod.rs,crates/engine/src/vault/attachments.rs(successful-import scheduling hook only). FILES TO OPEN: spec D3;crates/ui-egui/src/panels/search_panel.rs;crates/ui-egui/src/views/media_view/pdf.rs; later readcrates/engine/src/prefs/maps_config.rs, owned settings/app_settings/module files andcrates/ui-egui/src/views/settings_view/categories/core_cards.rsbefore editing settings wiring. GOAL: explicit recognize/cancel/copy actions, opt-in background setting, progress and unsupported/language errors; hit opens image/PDF page and overlays boxes. Persistocr.enabled/background preference as top-levelAppSettings.ocrvia owned app_settings/settings/module files using existing maps config pattern. No default background work before consent. TESTS: kittest action sends once; disabled unsupported; Copy order; PDF/image hit correct box; progress/cancel; opt-in false schedules no import jobs; source unchanged. VERIFY: standing UI/engine + i18n; read snapshots Mocha/Latte/scale 2. DO NOT: OS recognition during paint, hardcoded strings, broad settings refactor. - 7. Acceptance and status.
OWNS:
specs/plugins-parity/attachment-ocr/acceptance.md(new, FIRST),specs/plugins-parity/roadmap.md(rank37 status),ROADMAP.md,docs/ARCHITECTURE.md,docs/CODE-MAP.md(OCR API/status only). FILES TO OPEN: spec acceptance/questions; native and fake test evidence; relevant existing docs sections. GOAL: map every criterion to evidence, explicitly report unsupported Linux/packaging/languages and outstanding approvals. TESTS: all six criteria traced; distinguish native acceptance from fake contract success. VERIFY: final standing gates. Do not execute this future task during documentation-only request, which permits writes only underspecs/plugins-parity/. DO NOT: mark feature complete before native platform fixtures/UI checks; broaden launch accuracy guarantees.