Skip to content

fix(ogar-vocab): codex P1+P2 — curated codebook registry, PascalCase round-trip#61

Merged
AdaWorldAPI merged 1 commit into
mainfrom
claude/codebook-curated-table-no-hash
Jun 19, 2026
Merged

fix(ogar-vocab): codex P1+P2 — curated codebook registry, PascalCase round-trip#61
AdaWorldAPI merged 1 commit into
mainfrom
claude/codebook-curated-table-no-hash

Conversation

@AdaWorldAPI

Copy link
Copy Markdown
Owner

Two codex findings on the merged PR #60 — both valid, both fixed

P1: lossy hash → curated registry table

The 16-bit FNV-1a XOR-fold has real collisions. Codex named canonical_concept_id("outcome") == canonical_concept_id("handle_out") == 33032; verified locally. The integration contract is explicit (docs/INTEGRATION-MAP.md:92-93):

ClassId / entity_type is minted uniquely by the registry and is never a content hash.

Replaced the hash with a curated const CODEBOOK table assigning each promoted concept a unique u16:

const CODEBOOK: &[(&str, u16)] = &[
    ("project",             0x0001),
    ("project_work_item",   0x0002),
    ("billable_work_entry", 0x0003),
];

canonical_concept_id now returns Option<u16>Some for promoted concepts, None for everything else. No silent hash collisions possible. codebook_has_no_duplicate_ids_or_zero pins the registry contract.

P2: PascalCase canonical-class names didn't round-trip

billable_work_entry().name == "BillableWorkEntry" (PascalCase). The resolver lowercased to "billableworkentry" and fell through to lexical, producing a different id than "billable_work_entry". Same for ProjectWorkItem and Project. OGAR's own canonical class names didn't share their own codebook id.

Added PascalCase + lowercase-concat aliases ("billableworkentry", "projectworkitem") into the promoted-invariant arms; added an explicit Project/Projects arm (was relying on lexical). Now ogar_codebook("BillableWorkEntry") == ogar_codebook("billable_work_entry") == ogar_codebook("TimeEntry") == ogar_codebook("account.analytic.line").

API changes (all internal — PR #60's API was 1 day old)

  • canonical_concept_id(&str) -> Option<u16>
  • ogar_codebook(&str) -> Option<u16>
  • LabelDTO::from_alias(label) -> Option<Self>
  • Class::canonical_id(&self) -> Option<u16> (signature unchanged; inner derivation .and_then over the table)

Tests pin both fixes

  • codebook_has_no_duplicate_ids_or_zero — registry invariant.
  • canonical_concept_id_returns_some_for_promoted_none_for_unknown — explicit None for "outcome" and "handle_out" (the codex P1 collision).
  • ogar_codebook_maps_curator_labels_to_canonical_id — adds "BillableWorkEntry" and "ProjectWorkItem" PascalCase round-trip.
  • label_dto_carries_local_label_and_shared_codebook_id — adds the same + LabelDTO::from_alias("user") is None.
  • class_canonical_id_round_trips_through_codebookcanonical_concept set to a non-promoted value returns None (no synthesised hash).
  • Real-corpus tests: drop the Some(...) wrap since the codebook fns now return Option.

ogar-vocab 28 · ogar-from-ruff 24 · ogar-from-rails 7 real-corpus · clippy clean.

🤖 Generated with Claude Code

…round-trip

Two codex findings on the merged PR #60 commit e780241. Both real, both fixed.

P1 (registry, not hash):
The 16-bit FNV-1a XOR-fold has real collisions — codex named
canonical_concept_id('outcome') == canonical_concept_id('handle_out')
== 33032; verified locally. The integration contract
(docs/INTEGRATION-MAP.md:92-93) is explicit: 'ClassId / entity_type is
minted uniquely by the registry and is never a content hash'.
Replace the hash with a curated const CODEBOOK table assigning each
promoted canonical concept a unique u16 (project = 1, project_work_item
= 2, billable_work_entry = 3). canonical_concept_id now returns
Option<u16>: Some for promoted concepts, None for everything else (no
silent hash collision possible).

P2 (PascalCase round-trip):
billable_work_entry().name is 'BillableWorkEntry' (PascalCase). The
existing resolver lowercased to 'billableworkentry' and fell through
to lexical, producing a DIFFERENT id than 'billable_work_entry'. Same
for ProjectWorkItem / Project. OGAR's own canonical class names didn't
round-trip to their own codebook id. Added PascalCase + lowercase-
concat aliases ('billableworkentry', 'projectworkitem', 'BillableWork-
Entry'/'billable_work_entry', etc.) into the promoted-invariant arms;
also explicit Project arm (was relying on lexical).

API changes (all internal — PR #60's API was 1 day old):
- canonical_concept_id(&str) -> Option<u16>  (was u16)
- ogar_codebook(&str) -> Option<u16>          (was u16)
- LabelDTO::from_alias(label) -> Option<Self> (was Self)
- Class::canonical_id(&self) -> Option<u16>   (unchanged signature;
  inner derivation now and_then over the table)

Test updates:
- codebook_has_no_duplicate_ids_or_zero pins the registry contract.
- canonical_concept_id_returns_some_for_promoted_none_for_unknown pins
  the 'unknown returns None, no hash' behaviour explicitly against
  'outcome' and 'handle_out'.
- ogar_codebook_maps_curator_labels_to_canonical_id adds Pascal-Case
  round-trip ('BillableWorkEntry' -> bwe id; 'ProjectWorkItem' -> pwi).
- label_dto_carries_local_label_and_shared_codebook_id adds the same.
- class_canonical_id_round_trips_through_codebook adds None for
  non-promoted canonical_concept ('totally_unknown').
- ogar-from-rails real-corpus assertions drop the Some(...) wrap since
  canonical_concept_id / ogar_codebook already return Option.

ogar-vocab 28, ogar-from-ruff 24, ogar-from-rails 7 real-corpus green;
clippy clean.
@AdaWorldAPI AdaWorldAPI merged commit 832fb71 into main Jun 19, 2026
1 check passed
AdaWorldAPI pushed a commit to AdaWorldAPI/lance-graph that referenced this pull request Jun 19, 2026
…xPolicy / CommercialDocument / BillingParty / CurrencyPolicy / PaymentRecord (CanonicalConcept enum 1→6)

Operator "continue with opensource-billing <> odoo" (2026-06-19). Each
concept promotion is gated by ≥2-curator evidence on the real
harvested corpora (OSB ndjson fixture + workspace Odoo manifest), not
pre-emptively added.

New shared helper:
- declared_classes(triples, ns) — returns class IRIs surfaced as
  (class, rdf:type, ogit:ObjectType). Filters out method/field IRIs.

5 sibling lexical-shape detectors:
- classes_matching_commercial_document_shape_canonical
  Ends-with(invoice|move|order) AND NOT contains("line"). Surfaces
  Invoice + account_move. Filters out InvoiceLineItem / account_move_line
  (those are CommercialLineItem, not Document).
- classes_matching_tax_policy_shape_canonical
  Ends-with("tax"). Surfaces Tax + account_tax. Excludes TaxGroup /
  account_tax_group (lowercased "taxgroup" / "account_tax_group"
  don't end with "tax").
- classes_matching_billing_party_shape_canonical
  Ends-with(client|customer|partner). Surfaces Client + res_partner.
- classes_matching_currency_policy_shape_canonical
  Ends-with("currency"). Surfaces Currency + res_currency.
- classes_matching_payment_record_shape_canonical
  Ends-with("payment"). Surfaces Payment + account_payment (also
  CreditPayment as expected sub-type; downstream ranking picks
  primary).

5 corpus-driven tests matching operator's naming convention:
- open_source_billing_invoice_and_odoo_account_move_overlap_as_commercial_document
- open_source_billing_tax_and_odoo_tax_overlap_as_tax_policy
- open_source_billing_client_and_odoo_res_partner_overlap_as_billing_party
- open_source_billing_currency_and_odoo_res_currency_overlap_as_currency_policy
- open_source_billing_payment_and_odoo_account_payment_overlap_as_payment_record

Each loads the OSB ndjson fixture (1195 triples) + workspace Odoo
manifest (2.8 MB) and asserts the expected class IRI appears on each
side via lexical shape on declared OGIT ObjectTypes.

Plus all 14 prior tests still green → 19/19 total.

Scope discipline:
- Lexical class-shape is the minimal viable detector. Structural
  refinement (incoming OGIT canonical relations FROM line-items for
  TaxPolicy; outgoing has_many to line-items for CommercialDocument)
  is the natural follow-up — not added pre-emptively.
- CanonicalConcept enum at 6 variants: CommercialLineItem,
  CommercialDocument, TaxPolicy, BillingParty, PaymentRecord,
  CurrencyPolicy. SalesOrder / SalesOrderLine / ProductOffering /
  FulfillmentFlow / InventoryMovement / ProjectWorkItem /
  BillableWorkEntry stay deferred — operator smoke target B needs a
  Spree harvest; target C needs Project::TimeEntry + materialization
  rules.

Cross-repo alignment with AdaWorldAPI/OGAR#61: the merged PR
introduced const CODEBOOK: &[(&str, u16)] minting stable u16
ClassIds for promoted canonical concepts (today: project,
project_work_item, billable_work_entry). The ar_shape CanonicalConcept
enum is the upstream candidate set — concepts get promoted into
OGAR's CODEBOOK once they clear the ≥2-curator gate AND OGAR-side
review. Each new variant in this commit is a candidate row for a
future OGAR CODEBOOK assignment.

EPIPHANIES E-OGAR-AR-SHAPE-SMOKE-4 prepended.

Cross-refs:
- crates/lance-graph-ontology/src/ar_shape.rs (5 detectors +
  declared_classes helper + 5 tests; 19/19 green)
- E-OGAR-AR-SHAPE-SMOKE-3 (OGIT canonical predecessor)
- E-OGAR-AR-SHAPE-SMOKE-2 (predicate-vocabulary divergence finding)
- E-OGAR-AR-SHAPE-SMOKE-1 (hand-fixture predecessor)
- AdaWorldAPI/OGAR#61 (upstream u16 CODEBOOK registry — candidate
  promotion target for each ar_shape::CanonicalConcept variant)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xzyc27Nx3f8WC5KzwfWfjx
AdaWorldAPI pushed a commit to AdaWorldAPI/lance-graph that referenced this pull request Jun 19, 2026
…xPolicy / CommercialDocument / BillingParty / CurrencyPolicy / PaymentRecord (CanonicalConcept enum 1→6)

Operator "continue with opensource-billing <> odoo" (2026-06-19). Each
concept promotion is gated by ≥2-curator evidence on the real
harvested corpora (OSB ndjson fixture + workspace Odoo manifest), not
pre-emptively added.

New shared helper:
- declared_classes(triples, ns) — returns class IRIs surfaced as
  (class, rdf:type, ogit:ObjectType). Filters out method/field IRIs.

5 sibling lexical-shape detectors:
- classes_matching_commercial_document_shape_canonical
  Ends-with(invoice|move|order) AND NOT contains("line"). Surfaces
  Invoice + account_move. Filters out InvoiceLineItem / account_move_line
  (those are CommercialLineItem, not Document).
- classes_matching_tax_policy_shape_canonical
  Ends-with("tax"). Surfaces Tax + account_tax. Excludes TaxGroup /
  account_tax_group (lowercased "taxgroup" / "account_tax_group"
  don't end with "tax").
- classes_matching_billing_party_shape_canonical
  Ends-with(client|customer|partner). Surfaces Client + res_partner.
- classes_matching_currency_policy_shape_canonical
  Ends-with("currency"). Surfaces Currency + res_currency.
- classes_matching_payment_record_shape_canonical
  Ends-with("payment"). Surfaces Payment + account_payment (also
  CreditPayment as expected sub-type; downstream ranking picks
  primary).

5 corpus-driven tests matching operator's naming convention:
- open_source_billing_invoice_and_odoo_account_move_overlap_as_commercial_document
- open_source_billing_tax_and_odoo_tax_overlap_as_tax_policy
- open_source_billing_client_and_odoo_res_partner_overlap_as_billing_party
- open_source_billing_currency_and_odoo_res_currency_overlap_as_currency_policy
- open_source_billing_payment_and_odoo_account_payment_overlap_as_payment_record

Each loads the OSB ndjson fixture (1195 triples) + workspace Odoo
manifest (2.8 MB) and asserts the expected class IRI appears on each
side via lexical shape on declared OGIT ObjectTypes.

Plus all 14 prior tests still green → 19/19 total.

Scope discipline:
- Lexical class-shape is the minimal viable detector. Structural
  refinement (incoming OGIT canonical relations FROM line-items for
  TaxPolicy; outgoing has_many to line-items for CommercialDocument)
  is the natural follow-up — not added pre-emptively.
- CanonicalConcept enum at 6 variants: CommercialLineItem,
  CommercialDocument, TaxPolicy, BillingParty, PaymentRecord,
  CurrencyPolicy. SalesOrder / SalesOrderLine / ProductOffering /
  FulfillmentFlow / InventoryMovement / ProjectWorkItem /
  BillableWorkEntry stay deferred — operator smoke target B needs a
  Spree harvest; target C needs Project::TimeEntry + materialization
  rules.

Cross-repo alignment with AdaWorldAPI/OGAR#61: the merged PR
introduced const CODEBOOK: &[(&str, u16)] minting stable u16
ClassIds for promoted canonical concepts (today: project,
project_work_item, billable_work_entry). The ar_shape CanonicalConcept
enum is the upstream candidate set — concepts get promoted into
OGAR's CODEBOOK once they clear the ≥2-curator gate AND OGAR-side
review. Each new variant in this commit is a candidate row for a
future OGAR CODEBOOK assignment.

EPIPHANIES E-OGAR-AR-SHAPE-SMOKE-4 prepended.

Cross-refs:
- crates/lance-graph-ontology/src/ar_shape.rs (5 detectors +
  declared_classes helper + 5 tests; 19/19 green)
- E-OGAR-AR-SHAPE-SMOKE-3 (OGIT canonical predecessor)
- E-OGAR-AR-SHAPE-SMOKE-2 (predicate-vocabulary divergence finding)
- E-OGAR-AR-SHAPE-SMOKE-1 (hand-fixture predecessor)
- AdaWorldAPI/OGAR#61 (upstream u16 CODEBOOK registry — candidate
  promotion target for each ar_shape::CanonicalConcept variant)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xzyc27Nx3f8WC5KzwfWfjx
AdaWorldAPI pushed a commit to AdaWorldAPI/lance-graph that referenced this pull request Jun 19, 2026
…xPolicy / CommercialDocument / BillingParty / CurrencyPolicy / PaymentRecord (CanonicalConcept enum 1→6)

Operator "continue with opensource-billing <> odoo" (2026-06-19). Each
concept promotion is gated by ≥2-curator evidence on the real
harvested corpora (OSB ndjson fixture + workspace Odoo manifest), not
pre-emptively added.

New shared helper:
- declared_classes(triples, ns) — returns class IRIs surfaced as
  (class, rdf:type, ogit:ObjectType). Filters out method/field IRIs.

5 sibling lexical-shape detectors:
- classes_matching_commercial_document_shape_canonical
  Ends-with(invoice|move|order) AND NOT contains("line"). Surfaces
  Invoice + account_move. Filters out InvoiceLineItem / account_move_line
  (those are CommercialLineItem, not Document).
- classes_matching_tax_policy_shape_canonical
  Ends-with("tax"). Surfaces Tax + account_tax. Excludes TaxGroup /
  account_tax_group (lowercased "taxgroup" / "account_tax_group"
  don't end with "tax").
- classes_matching_billing_party_shape_canonical
  Ends-with(client|customer|partner). Surfaces Client + res_partner.
- classes_matching_currency_policy_shape_canonical
  Ends-with("currency"). Surfaces Currency + res_currency.
- classes_matching_payment_record_shape_canonical
  Ends-with("payment"). Surfaces Payment + account_payment (also
  CreditPayment as expected sub-type; downstream ranking picks
  primary).

5 corpus-driven tests matching operator's naming convention:
- open_source_billing_invoice_and_odoo_account_move_overlap_as_commercial_document
- open_source_billing_tax_and_odoo_tax_overlap_as_tax_policy
- open_source_billing_client_and_odoo_res_partner_overlap_as_billing_party
- open_source_billing_currency_and_odoo_res_currency_overlap_as_currency_policy
- open_source_billing_payment_and_odoo_account_payment_overlap_as_payment_record

Each loads the OSB ndjson fixture (1195 triples) + workspace Odoo
manifest (2.8 MB) and asserts the expected class IRI appears on each
side via lexical shape on declared OGIT ObjectTypes.

Plus all 14 prior tests still green → 19/19 total.

Scope discipline:
- Lexical class-shape is the minimal viable detector. Structural
  refinement (incoming OGIT canonical relations FROM line-items for
  TaxPolicy; outgoing has_many to line-items for CommercialDocument)
  is the natural follow-up — not added pre-emptively.
- CanonicalConcept enum at 6 variants: CommercialLineItem,
  CommercialDocument, TaxPolicy, BillingParty, PaymentRecord,
  CurrencyPolicy. SalesOrder / SalesOrderLine / ProductOffering /
  FulfillmentFlow / InventoryMovement / ProjectWorkItem /
  BillableWorkEntry stay deferred — operator smoke target B needs a
  Spree harvest; target C needs Project::TimeEntry + materialization
  rules.

Cross-repo alignment with AdaWorldAPI/OGAR#61: the merged PR
introduced const CODEBOOK: &[(&str, u16)] minting stable u16
ClassIds for promoted canonical concepts (today: project,
project_work_item, billable_work_entry). The ar_shape CanonicalConcept
enum is the upstream candidate set — concepts get promoted into
OGAR's CODEBOOK once they clear the ≥2-curator gate AND OGAR-side
review. Each new variant in this commit is a candidate row for a
future OGAR CODEBOOK assignment.

EPIPHANIES E-OGAR-AR-SHAPE-SMOKE-4 prepended.

Cross-refs:
- crates/lance-graph-ontology/src/ar_shape.rs (5 detectors +
  declared_classes helper + 5 tests; 19/19 green)
- E-OGAR-AR-SHAPE-SMOKE-3 (OGIT canonical predecessor)
- E-OGAR-AR-SHAPE-SMOKE-2 (predicate-vocabulary divergence finding)
- E-OGAR-AR-SHAPE-SMOKE-1 (hand-fixture predecessor)
- AdaWorldAPI/OGAR#61 (upstream u16 CODEBOOK registry — candidate
  promotion target for each ar_shape::CanonicalConcept variant)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xzyc27Nx3f8WC5KzwfWfjx
AdaWorldAPI pushed a commit to AdaWorldAPI/lance-graph that referenced this pull request Jun 20, 2026
…xPolicy / CommercialDocument / BillingParty / CurrencyPolicy / PaymentRecord (CanonicalConcept enum 1→6)

Operator "continue with opensource-billing <> odoo" (2026-06-19). Each
concept promotion is gated by ≥2-curator evidence on the real
harvested corpora (OSB ndjson fixture + workspace Odoo manifest), not
pre-emptively added.

New shared helper:
- declared_classes(triples, ns) — returns class IRIs surfaced as
  (class, rdf:type, ogit:ObjectType). Filters out method/field IRIs.

5 sibling lexical-shape detectors:
- classes_matching_commercial_document_shape_canonical
  Ends-with(invoice|move|order) AND NOT contains("line"). Surfaces
  Invoice + account_move. Filters out InvoiceLineItem / account_move_line
  (those are CommercialLineItem, not Document).
- classes_matching_tax_policy_shape_canonical
  Ends-with("tax"). Surfaces Tax + account_tax. Excludes TaxGroup /
  account_tax_group (lowercased "taxgroup" / "account_tax_group"
  don't end with "tax").
- classes_matching_billing_party_shape_canonical
  Ends-with(client|customer|partner). Surfaces Client + res_partner.
- classes_matching_currency_policy_shape_canonical
  Ends-with("currency"). Surfaces Currency + res_currency.
- classes_matching_payment_record_shape_canonical
  Ends-with("payment"). Surfaces Payment + account_payment (also
  CreditPayment as expected sub-type; downstream ranking picks
  primary).

5 corpus-driven tests matching operator's naming convention:
- open_source_billing_invoice_and_odoo_account_move_overlap_as_commercial_document
- open_source_billing_tax_and_odoo_tax_overlap_as_tax_policy
- open_source_billing_client_and_odoo_res_partner_overlap_as_billing_party
- open_source_billing_currency_and_odoo_res_currency_overlap_as_currency_policy
- open_source_billing_payment_and_odoo_account_payment_overlap_as_payment_record

Each loads the OSB ndjson fixture (1195 triples) + workspace Odoo
manifest (2.8 MB) and asserts the expected class IRI appears on each
side via lexical shape on declared OGIT ObjectTypes.

Plus all 14 prior tests still green → 19/19 total.

Scope discipline:
- Lexical class-shape is the minimal viable detector. Structural
  refinement (incoming OGIT canonical relations FROM line-items for
  TaxPolicy; outgoing has_many to line-items for CommercialDocument)
  is the natural follow-up — not added pre-emptively.
- CanonicalConcept enum at 6 variants: CommercialLineItem,
  CommercialDocument, TaxPolicy, BillingParty, PaymentRecord,
  CurrencyPolicy. SalesOrder / SalesOrderLine / ProductOffering /
  FulfillmentFlow / InventoryMovement / ProjectWorkItem /
  BillableWorkEntry stay deferred — operator smoke target B needs a
  Spree harvest; target C needs Project::TimeEntry + materialization
  rules.

Cross-repo alignment with AdaWorldAPI/OGAR#61: the merged PR
introduced const CODEBOOK: &[(&str, u16)] minting stable u16
ClassIds for promoted canonical concepts (today: project,
project_work_item, billable_work_entry). The ar_shape CanonicalConcept
enum is the upstream candidate set — concepts get promoted into
OGAR's CODEBOOK once they clear the ≥2-curator gate AND OGAR-side
review. Each new variant in this commit is a candidate row for a
future OGAR CODEBOOK assignment.

EPIPHANIES E-OGAR-AR-SHAPE-SMOKE-4 prepended.

Cross-refs:
- crates/lance-graph-ontology/src/ar_shape.rs (5 detectors +
  declared_classes helper + 5 tests; 19/19 green)
- E-OGAR-AR-SHAPE-SMOKE-3 (OGIT canonical predecessor)
- E-OGAR-AR-SHAPE-SMOKE-2 (predicate-vocabulary divergence finding)
- E-OGAR-AR-SHAPE-SMOKE-1 (hand-fixture predecessor)
- AdaWorldAPI/OGAR#61 (upstream u16 CODEBOOK registry — candidate
  promotion target for each ar_shape::CanonicalConcept variant)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xzyc27Nx3f8WC5KzwfWfjx
AdaWorldAPI pushed a commit to AdaWorldAPI/lance-graph that referenced this pull request Jun 20, 2026
…xPolicy / CommercialDocument / BillingParty / CurrencyPolicy / PaymentRecord (CanonicalConcept enum 1→6)

Operator "continue with opensource-billing <> odoo" (2026-06-19). Each
concept promotion is gated by ≥2-curator evidence on the real
harvested corpora (OSB ndjson fixture + workspace Odoo manifest), not
pre-emptively added.

New shared helper:
- declared_classes(triples, ns) — returns class IRIs surfaced as
  (class, rdf:type, ogit:ObjectType). Filters out method/field IRIs.

5 sibling lexical-shape detectors:
- classes_matching_commercial_document_shape_canonical
  Ends-with(invoice|move|order) AND NOT contains("line"). Surfaces
  Invoice + account_move. Filters out InvoiceLineItem / account_move_line
  (those are CommercialLineItem, not Document).
- classes_matching_tax_policy_shape_canonical
  Ends-with("tax"). Surfaces Tax + account_tax. Excludes TaxGroup /
  account_tax_group (lowercased "taxgroup" / "account_tax_group"
  don't end with "tax").
- classes_matching_billing_party_shape_canonical
  Ends-with(client|customer|partner). Surfaces Client + res_partner.
- classes_matching_currency_policy_shape_canonical
  Ends-with("currency"). Surfaces Currency + res_currency.
- classes_matching_payment_record_shape_canonical
  Ends-with("payment"). Surfaces Payment + account_payment (also
  CreditPayment as expected sub-type; downstream ranking picks
  primary).

5 corpus-driven tests matching operator's naming convention:
- open_source_billing_invoice_and_odoo_account_move_overlap_as_commercial_document
- open_source_billing_tax_and_odoo_tax_overlap_as_tax_policy
- open_source_billing_client_and_odoo_res_partner_overlap_as_billing_party
- open_source_billing_currency_and_odoo_res_currency_overlap_as_currency_policy
- open_source_billing_payment_and_odoo_account_payment_overlap_as_payment_record

Each loads the OSB ndjson fixture (1195 triples) + workspace Odoo
manifest (2.8 MB) and asserts the expected class IRI appears on each
side via lexical shape on declared OGIT ObjectTypes.

Plus all 14 prior tests still green → 19/19 total.

Scope discipline:
- Lexical class-shape is the minimal viable detector. Structural
  refinement (incoming OGIT canonical relations FROM line-items for
  TaxPolicy; outgoing has_many to line-items for CommercialDocument)
  is the natural follow-up — not added pre-emptively.
- CanonicalConcept enum at 6 variants: CommercialLineItem,
  CommercialDocument, TaxPolicy, BillingParty, PaymentRecord,
  CurrencyPolicy. SalesOrder / SalesOrderLine / ProductOffering /
  FulfillmentFlow / InventoryMovement / ProjectWorkItem /
  BillableWorkEntry stay deferred — operator smoke target B needs a
  Spree harvest; target C needs Project::TimeEntry + materialization
  rules.

Cross-repo alignment with AdaWorldAPI/OGAR#61: the merged PR
introduced const CODEBOOK: &[(&str, u16)] minting stable u16
ClassIds for promoted canonical concepts (today: project,
project_work_item, billable_work_entry). The ar_shape CanonicalConcept
enum is the upstream candidate set — concepts get promoted into
OGAR's CODEBOOK once they clear the ≥2-curator gate AND OGAR-side
review. Each new variant in this commit is a candidate row for a
future OGAR CODEBOOK assignment.

EPIPHANIES E-OGAR-AR-SHAPE-SMOKE-4 prepended.

Cross-refs:
- crates/lance-graph-ontology/src/ar_shape.rs (5 detectors +
  declared_classes helper + 5 tests; 19/19 green)
- E-OGAR-AR-SHAPE-SMOKE-3 (OGIT canonical predecessor)
- E-OGAR-AR-SHAPE-SMOKE-2 (predicate-vocabulary divergence finding)
- E-OGAR-AR-SHAPE-SMOKE-1 (hand-fixture predecessor)
- AdaWorldAPI/OGAR#61 (upstream u16 CODEBOOK registry — candidate
  promotion target for each ar_shape::CanonicalConcept variant)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xzyc27Nx3f8WC5KzwfWfjx
AdaWorldAPI pushed a commit to AdaWorldAPI/lance-graph that referenced this pull request Jun 21, 2026
…xPolicy / CommercialDocument / BillingParty / CurrencyPolicy / PaymentRecord (CanonicalConcept enum 1→6)

Operator "continue with opensource-billing <> odoo" (2026-06-19). Each
concept promotion is gated by ≥2-curator evidence on the real
harvested corpora (OSB ndjson fixture + workspace Odoo manifest), not
pre-emptively added.

New shared helper:
- declared_classes(triples, ns) — returns class IRIs surfaced as
  (class, rdf:type, ogit:ObjectType). Filters out method/field IRIs.

5 sibling lexical-shape detectors:
- classes_matching_commercial_document_shape_canonical
  Ends-with(invoice|move|order) AND NOT contains("line"). Surfaces
  Invoice + account_move. Filters out InvoiceLineItem / account_move_line
  (those are CommercialLineItem, not Document).
- classes_matching_tax_policy_shape_canonical
  Ends-with("tax"). Surfaces Tax + account_tax. Excludes TaxGroup /
  account_tax_group (lowercased "taxgroup" / "account_tax_group"
  don't end with "tax").
- classes_matching_billing_party_shape_canonical
  Ends-with(client|customer|partner). Surfaces Client + res_partner.
- classes_matching_currency_policy_shape_canonical
  Ends-with("currency"). Surfaces Currency + res_currency.
- classes_matching_payment_record_shape_canonical
  Ends-with("payment"). Surfaces Payment + account_payment (also
  CreditPayment as expected sub-type; downstream ranking picks
  primary).

5 corpus-driven tests matching operator's naming convention:
- open_source_billing_invoice_and_odoo_account_move_overlap_as_commercial_document
- open_source_billing_tax_and_odoo_tax_overlap_as_tax_policy
- open_source_billing_client_and_odoo_res_partner_overlap_as_billing_party
- open_source_billing_currency_and_odoo_res_currency_overlap_as_currency_policy
- open_source_billing_payment_and_odoo_account_payment_overlap_as_payment_record

Each loads the OSB ndjson fixture (1195 triples) + workspace Odoo
manifest (2.8 MB) and asserts the expected class IRI appears on each
side via lexical shape on declared OGIT ObjectTypes.

Plus all 14 prior tests still green → 19/19 total.

Scope discipline:
- Lexical class-shape is the minimal viable detector. Structural
  refinement (incoming OGIT canonical relations FROM line-items for
  TaxPolicy; outgoing has_many to line-items for CommercialDocument)
  is the natural follow-up — not added pre-emptively.
- CanonicalConcept enum at 6 variants: CommercialLineItem,
  CommercialDocument, TaxPolicy, BillingParty, PaymentRecord,
  CurrencyPolicy. SalesOrder / SalesOrderLine / ProductOffering /
  FulfillmentFlow / InventoryMovement / ProjectWorkItem /
  BillableWorkEntry stay deferred — operator smoke target B needs a
  Spree harvest; target C needs Project::TimeEntry + materialization
  rules.

Cross-repo alignment with AdaWorldAPI/OGAR#61: the merged PR
introduced const CODEBOOK: &[(&str, u16)] minting stable u16
ClassIds for promoted canonical concepts (today: project,
project_work_item, billable_work_entry). The ar_shape CanonicalConcept
enum is the upstream candidate set — concepts get promoted into
OGAR's CODEBOOK once they clear the ≥2-curator gate AND OGAR-side
review. Each new variant in this commit is a candidate row for a
future OGAR CODEBOOK assignment.

EPIPHANIES E-OGAR-AR-SHAPE-SMOKE-4 prepended.

Cross-refs:
- crates/lance-graph-ontology/src/ar_shape.rs (5 detectors +
  declared_classes helper + 5 tests; 19/19 green)
- E-OGAR-AR-SHAPE-SMOKE-3 (OGIT canonical predecessor)
- E-OGAR-AR-SHAPE-SMOKE-2 (predicate-vocabulary divergence finding)
- E-OGAR-AR-SHAPE-SMOKE-1 (hand-fixture predecessor)
- AdaWorldAPI/OGAR#61 (upstream u16 CODEBOOK registry — candidate
  promotion target for each ar_shape::CanonicalConcept variant)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xzyc27Nx3f8WC5KzwfWfjx
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants