Skip to content

Commit dd1c30d

Browse files
authored
Merge pull request #172 from AdaWorldAPI/claude/ocr-pdf-plan-mints
ogar-vocab: mint the 0x08 OCR PDF-to-text plan concepts (0x0805..0x0809)
2 parents 2e346ea + fd8528a commit dd1c30d

2 files changed

Lines changed: 129 additions & 8 deletions

File tree

crates/ogar-class-view/src/lib.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ use ogar_vocab::{
7777
automation_trigger,
7878
billable_work_entry,
7979
billing_party,
80+
blob,
8081
bone,
8182
canonical_concept_id,
8283
charset,
@@ -98,6 +99,7 @@ use ogar_vocab::{
9899
mars_software,
99100
medication,
100101
network_layer,
102+
ocr_renderer,
101103
osm_changeset,
102104
osm_element_tag,
103105
osm_gpx_trace,
@@ -108,6 +110,8 @@ use ogar_vocab::{
108110
osm_user,
109111
osm_way,
110112
osm_way_node,
113+
page_image,
114+
page_layout,
111115
patient,
112116
payment_record,
113117
pricelist,
@@ -141,6 +145,7 @@ use ogar_vocab::{
141145
recoder,
142146
skeleton,
143147
tax_policy,
148+
textline,
144149
treatment,
145150
unicharset,
146151
unit_of_measure,
@@ -200,6 +205,11 @@ fn all_canonical_classes() -> Vec<(&'static str, Class)> {
200205
("recoder", recoder()),
201206
("charset", charset()),
202207
("network_layer", network_layer()),
208+
("textline", textline()),
209+
("blob", blob()),
210+
("page_layout", page_layout()),
211+
("page_image", page_image()),
212+
("ocr_renderer", ocr_renderer()),
203213
// ── 0x09XX — health (OGIT Healthcare) ──
204214
("patient", patient()),
205215
("diagnosis", diagnosis()),

crates/ogar-vocab/src/lib.rs

Lines changed: 119 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1203,6 +1203,14 @@ const CODEBOOK: &[(&str, u16)] = &[
12031203
("recoder", 0x0802),
12041204
("charset", 0x0803),
12051205
("network_layer", 0x0804),
1206+
// PDF→text plan mints (tesseract-rs `pdf-to-text-ocr-v1.md` Phase 0 D0.3;
1207+
// the plan IS the emit-seam declaration — each row names its consumer
1208+
// phase, honoring the mint-on-emit guard rather than pre-minting blind).
1209+
("textline", 0x0805),
1210+
("blob", 0x0806),
1211+
("page_layout", 0x0807),
1212+
("page_image", 0x0808),
1213+
("ocr_renderer", 0x0809),
12061214
// ── 0x09XX — Health domain (clinical / patient / care) ──
12071215
// medcare-rs Healthcare-namespace promotion (Northstar T9). The 7
12081216
// entities the OGIT `NTO/Healthcare/entities/` TTL ships, projected
@@ -1678,6 +1686,25 @@ pub mod class_ids {
16781686
/// ruff→OGAR network harvest lands here). Wire-declared first in the
16791687
/// lance-graph contract mirror; this is the authoritative OGAR counterpart.
16801688
pub const NETWORK_LAYER: u16 = 0x0804;
1689+
/// `textline` (`0x0805`) — a segmented text line: box + baseline, the unit
1690+
/// the LSTM line recognizer consumes and the word/box extract references
1691+
/// (plan Phases 1B + 3E; the line images `RecognizeLine` reads).
1692+
pub const TEXTLINE: u16 = 0x0805;
1693+
/// `blob` (`0x0806`) — a connected-component blob container (Tesseract
1694+
/// `C_BLOB`/`BLOBNBOX` kind), the page-segmentation substrate (plan
1695+
/// Phase 3B/3D). Content (outlines/pixels) stays in content stores.
1696+
pub const BLOB: u16 = 0x0806;
1697+
/// `page_layout` (`0x0807`) — the layout-analysis result container:
1698+
/// blocks / columns / reading order over one page (plan Phase 3F/4A).
1699+
pub const PAGE_LAYOUT: u16 = 0x0807;
1700+
/// `page_image` (`0x0808`) — a rasterized page container (decoded +
1701+
/// grey/binary normalized), the OCR input kind (plan Phase 2).
1702+
pub const PAGE_IMAGE: u16 = 0x0808;
1703+
/// `ocr_renderer` (`0x0809`) — an output-rendering KIND (txt / tsv /
1704+
/// hOCR / searchable-PDF), one slot; the concrete format is the
1705+
/// classid custom-low half, mirroring the `network_layer` pattern
1706+
/// (plan Phase 4B-D).
1707+
pub const OCR_RENDERER: u16 = 0x0809;
16811708

16821709
// ── 0x09XX — health domain (medcare-rs Healthcare namespace) ──
16831710

@@ -1878,6 +1905,11 @@ pub mod class_ids {
18781905
("recoder", RECODER),
18791906
("charset", CHARSET),
18801907
("network_layer", NETWORK_LAYER),
1908+
("textline", TEXTLINE),
1909+
("blob", BLOB),
1910+
("page_layout", PAGE_LAYOUT),
1911+
("page_image", PAGE_IMAGE),
1912+
("ocr_renderer", OCR_RENDERER),
18811913
// 0x09XX — health
18821914
("patient", PATIENT),
18831915
("diagnosis", DIAGNOSIS),
@@ -1986,7 +2018,7 @@ pub mod class_ids {
19862018
// lance-graph mirror is rebuilt against it.
19872019
assert_eq!(
19882020
ALL.len(),
1989-
79,
2021+
84,
19902022
"class_ids::ALL count changed — update this pin AND the \
19912023
lance-graph mirror COUNT_FUSE (crates/lance-graph-ogar/src/lib.rs) \
19922024
in the same PR",
@@ -2808,11 +2840,16 @@ pub fn all_promoted_classes() -> Vec<Class> {
28082840
// `osint_system` / `osint_person` mints); no calls follow — OGAR
28092841
// vocabulary carries no OSINT concept names, see the CODEBOOK
28102842
// 0x07XX section note.
2811-
// 0x08XX — OCR arm (4 container kinds), in class_ids::ALL order.
2843+
// 0x08XX — OCR arm (9 container kinds), in class_ids::ALL order.
28122844
unicharset(),
28132845
recoder(),
28142846
charset(),
28152847
network_layer(),
2848+
textline(),
2849+
blob(),
2850+
page_layout(),
2851+
page_image(),
2852+
ocr_renderer(),
28162853
// 0x09XX — health arm (7 OGIT Healthcare concepts), in
28172854
// class_ids::ALL order.
28182855
patient(),
@@ -3828,6 +3865,69 @@ pub fn network_layer() -> Class {
38283865
c
38293866
}
38303867

3868+
/// Textline (`0x0805`) — a segmented text line (box + baseline), the unit the
3869+
/// LSTM line recognizer consumes (plan Phases 1B + 3E).
3870+
#[must_use]
3871+
pub fn textline() -> Class {
3872+
let mut c = Class::new("Textline");
3873+
c.language = Language::Unknown;
3874+
c.canonical_concept = Some("textline".to_string());
3875+
let mut baseline_y = Attribute::new("baseline_y");
3876+
baseline_y.type_name = Some("i32".to_string());
3877+
c.attributes = vec![baseline_y];
3878+
c.associations = vec![family_edge("belongs_to", "PageLayout")];
3879+
c
3880+
}
3881+
3882+
/// Blob (`0x0806`) — a connected-component blob container (Tesseract
3883+
/// `C_BLOB`/`BLOBNBOX` kind), the page-segmentation substrate (plan Phase 3B/3D).
3884+
#[must_use]
3885+
pub fn blob() -> Class {
3886+
let mut c = Class::new("Blob");
3887+
c.language = Language::Unknown;
3888+
c.canonical_concept = Some("blob".to_string());
3889+
c.associations = vec![family_edge("belongs_to", "Textline")];
3890+
c
3891+
}
3892+
3893+
/// PageLayout (`0x0807`) — the layout-analysis result container: blocks /
3894+
/// columns / reading order over one page (plan Phase 3F/4A).
3895+
#[must_use]
3896+
pub fn page_layout() -> Class {
3897+
let mut c = Class::new("PageLayout");
3898+
c.language = Language::Unknown;
3899+
c.canonical_concept = Some("page_layout".to_string());
3900+
c.associations = vec![family_edge("derived_from", "PageImage")];
3901+
c
3902+
}
3903+
3904+
/// PageImage (`0x0808`) — a rasterized page container (decoded + grey/binary
3905+
/// normalized), the OCR input kind (plan Phase 2).
3906+
#[must_use]
3907+
pub fn page_image() -> Class {
3908+
let mut c = Class::new("PageImage");
3909+
c.language = Language::Unknown;
3910+
c.canonical_concept = Some("page_image".to_string());
3911+
let mut depth = Attribute::new("depth");
3912+
depth.type_name = Some("u8".to_string());
3913+
c.attributes = vec![depth];
3914+
c
3915+
}
3916+
3917+
/// OcrRenderer (`0x0809`) — an output-rendering KIND (txt / tsv / hOCR /
3918+
/// searchable-PDF), one slot; the concrete format is the classid custom-low
3919+
/// half, mirroring the `network_layer` pattern (plan Phase 4B-D).
3920+
#[must_use]
3921+
pub fn ocr_renderer() -> Class {
3922+
let mut c = Class::new("OcrRenderer");
3923+
c.language = Language::Unknown;
3924+
c.canonical_concept = Some("ocr_renderer".to_string());
3925+
let mut format = Attribute::new("format");
3926+
format.type_name = Some("u8".to_string());
3927+
c.attributes = vec![format];
3928+
c
3929+
}
3930+
38313931
// ─────────────────────────────────────────────────────────────────────
38323932
// 0x09XX — Health domain (OGIT Healthcare). The reusable Active-Record
38333933
// shape for the clinical concepts. `diagnosis` (0x0902) is the worked
@@ -5258,17 +5358,28 @@ mod tests {
52585358
}
52595359
// Counts line up with the codebook blocks.
52605360
assert_eq!(concepts_in_domain(ConceptDomain::Health).count(), 7);
5261-
// 0x08XX OCR: the four container KINDS (unicharset/recoder/charset/
5262-
// network_layer). Content (the 112 unichars, code tables) never becomes
5263-
// concepts — see the CODEBOOK 0x08XX section note (Osint zero-rows
5264-
// precedent).
5265-
assert_eq!(concepts_in_domain(ConceptDomain::Ocr).count(), 4);
5361+
// 0x08XX OCR: the nine container KINDS (unicharset/recoder/charset/
5362+
// network_layer + the PDF→text plan mints textline/blob/page_layout/
5363+
// page_image/ocr_renderer). Content (the 112 unichars, code tables,
5364+
// blob outlines) never becomes concepts — see the CODEBOOK 0x08XX
5365+
// section note (Osint zero-rows precedent).
5366+
assert_eq!(concepts_in_domain(ConceptDomain::Ocr).count(), 9);
52665367
let ocr: Vec<&str> = concepts_in_domain(ConceptDomain::Ocr)
52675368
.map(|(name, _)| name)
52685369
.collect();
52695370
assert_eq!(
52705371
ocr,
5271-
["unicharset", "recoder", "charset", "network_layer"],
5372+
[
5373+
"unicharset",
5374+
"recoder",
5375+
"charset",
5376+
"network_layer",
5377+
"textline",
5378+
"blob",
5379+
"page_layout",
5380+
"page_image",
5381+
"ocr_renderer",
5382+
],
52725383
"OCR domain set drift — re-sync the consumer coverage gate",
52735384
);
52745385
assert_eq!(concepts_in_domain(ConceptDomain::HR).count(), 4);

0 commit comments

Comments
 (0)