Skip to content

feat(knowable-from): wire schema_ddl_hint via surrealql-hint feature + ADR-023#33

Merged
AdaWorldAPI merged 1 commit into
mainfrom
claude/wire-schema-ddl-hint-and-adr-023
Jun 5, 2026
Merged

feat(knowable-from): wire schema_ddl_hint via surrealql-hint feature + ADR-023#33
AdaWorldAPI merged 1 commit into
mainfrom
claude/wire-schema-ddl-hint-and-adr-023

Conversation

@AdaWorldAPI

Copy link
Copy Markdown
Owner

Summary

Two thematic threads bundled — the framing principle (ADR-023: IR-as-wire-truth) and its receipt (the registry now carries the producer's Class IR projected into SurrealQL DDL).

1. The schema_ddl_hint loop closes

PR #25 introduced KnowableFromStore::register(class_identity, schema_ddl_hint: Option<&str>) with the docstring claim "so the registry is self-describing". PR #32 landed emit_surrealql_ddl. This PR wires the two together.

Mechanism — opt-in feature flag (keeps the lightweight default):

# Cargo.toml
[features]
surrealql-hint = ["dep:ogar-adapter-surrealql"]

[dependencies]
ogar-adapter-surrealql = { path = "...", optional = true }
// register_class_knowable_from body — when feature ON:
let ddl = ogar_adapter_surrealql::emit_surrealql_ddl(std::slice::from_ref(class));
store.register(class_identity, Some(ddl.as_str()))
// When feature OFF: store.register(class_identity, None)  — unchanged

Tests (both paths, conditionally compiled):

Test Feature Asserts
default_path_passes_none_for_schema_ddl_hint OFF calls[0].1.is_none()
surrealql_hint_feature_renders_ddl_into_registry ON DDL contains DEFINE TABLE Account SCHEMAFULL; + DEFINE FIELD email ON Account TYPE string;

Existing register_simple_class_returns_store_version made axis-agnostic on the hint (dedicated tests above cover each feature path).

2. ADR-023 — IR-as-wire-truth

New ADR in docs/ARCHITECTURAL-DECISIONS-2026-06-04.md. Pins the framing principle ADR-022 (The Firewall) has implicitly relied on but hadn't named.

The aphorism: Elixir AST is input dialect; the canonical IR is wire truth.

Generalizes to any source dialect — Elixir quoted form, SurrealQL DDL, Ruby AR macros, Odoo Python models.Model, ClickHouse CREATE TABLE, OWL TTL triples — all are input dialects lifted into the canonical IR (Class/Attribute/Association/EnumDecl/ActionDef/KausalSpec/Identity (NiblePath)).

Consequences pinned in the ADR:

  • Content-addressing primitive: Same IR → same hash → same actor routing key → same Lance row → same audit dimension.
  • Adapters pluggable, IR fixed: New source dialects ship as new adapter crates (ogar-adapter-surrealql, ogar-adapter-ttl planned, ogar-from-elixir, ogar-from-ecto proposed). The Class IR doesn't change; only the lift code does.
  • Round-trip is the adapter contract — demonstrated by PR feat(ogar-adapter-surrealql): AST -> Class walk (closes ADR-017) #32 for SurrealQL DDL.
  • schema_ddl_hint loop closes here — this PR IS the receipt.
  • Cross-session triangulation receipt: bardioc PR docs: SurrealQL AST as universal adapter — feasibility, beauty, brutal honesty #19's substrate-b-shadow::EdgeDecoder<E> IS the pattern materialized in runtime-side code; its decoders return ActionInvocation regardless of source dialect.

Change policy: adding a new source dialect (new adapter crate) is routine; changing the IR is substrate-wide — requires Option<…> backward-compat default, round-trip preservation in all adapters, and runtime-session consultation.

ADR-023 generalizes ADR-016's claim ("SurrealQL DDL AST is not the universal IR") from SurrealQL to all source dialects.

3. CI floor extended

- name: cargo test -p ogar-knowable-from --features surrealql-hint
  run: cargo test -p ogar-knowable-from --features surrealql-hint

Same crate-scoped pattern as #32's surrealdb-parser step. Both feature-gated test steps now part of the CI floor.

Verification

$ cargo test --workspace  (default, no feature)
test result: ok. 10 passed; 0 failed (ogar-knowable-from feature-off path)

$ cargo test -p ogar-knowable-from --features surrealql-hint
test result: ok. 10 passed; 0 failed (feature-on path)

$ cargo check --workspace --all-targets
Finished

PII abort-guard (word-boundary): CLEAN on all four touched files.

Position in the queue

Per docs/RDF-OWL-ALIGNMENT.md §10 + the queue refresh after bardioc #19:

https://claude.ai/code/session_01PBTGaPCSnnt6u3pjXpbLwY

…+ ADR-023

Two thematic things bundled — the framing principle (ADR-023:
IR-as-wire-truth) and its receipt (the registry now carries the
producer's `Class` IR projected into SurrealQL DDL).

# 1. The schema_ddl_hint loop closure

PR #25 introduced `KnowableFromStore::register(class_identity,
schema_ddl_hint: Option<&str>)` with the docstring claim *"so the
registry is self-describing"*. PR #32 landed `emit_surrealql_ddl`.
This PR wires the two together:

  - New optional feature `surrealql-hint` on `ogar-knowable-from`.
  - When ON: `register_class_knowable_from` renders the DDL via
    `ogar_adapter_surrealql::emit_surrealql_ddl(std::slice::from_ref
    (class))` and passes `Some(ddl)` to `store.register`.
  - When OFF (default): `None` is passed, preserving the lightweight
    path (no adapter dep pulled in).

Cargo.toml — optional dep + feature:

    surrealql-hint = ["dep:ogar-adapter-surrealql"]
    ogar-adapter-surrealql = { path = "...", optional = true }

Tests (both paths, conditionally compiled):
  - `default_path_passes_none_for_schema_ddl_hint` (feature-off):
    asserts `calls[0].1.is_none()`.
  - `surrealql_hint_feature_renders_ddl_into_registry`
    (feature-on): asserts the registry received DDL containing
    `DEFINE TABLE Account SCHEMAFULL;` + `DEFINE FIELD email ON
    Account TYPE string;`.

Plus: existing `register_simple_class_returns_store_version` made
axis-agnostic on the hint (the hint axis now has dedicated tests for
each feature path).

# 2. ADR-023 — IR-as-wire-truth

New ADR in `docs/ARCHITECTURAL-DECISIONS-2026-06-04.md`. Pins the
framing principle that ADR-022 (The Firewall) has implicitly relied
on but hadn't named: source-language ASTs (Elixir quoted form,
SurrealQL DDL, Ruby AR macro tree, Odoo Python, ClickHouse CREATE
TABLE, OWL TTL triples) are *input dialects*; the canonical OGAR IR
(`Class`/`Attribute`/`Association`/`EnumDecl`/`ActionDef`/
`KausalSpec`/`Identity` (`NiblePath`)) is *wire truth*.

The aphorism: "Elixir AST is input dialect; the canonical IR is
wire truth." Generalizes to any source dialect.

Consequences pinned:
  - Same IR -> same hash -> same actor routing -> same Lance row ->
    same audit dimension. Content-addressing primitive.
  - Adapters pluggable, IR fixed.
  - Round-trip is the adapter contract.
  - `schema_ddl_hint` loop closes here (this PR is the receipt).
  - Cross-session triangulation: bardioc PR #19's
    `substrate-b-shadow::EdgeDecoder<E>` IS the pattern in code —
    its decoders return `ActionInvocation` regardless of source.

Change policy: adding a new source dialect (new adapter crate) is
routine; changing the IR is substrate-wide (requires Option<…>
backward-compat default + round-trip preservation in all adapters
+ runtime-session consultation).

# 3. CI floor extended

`.github/workflows/ci.yml` adds:

    cargo test -p ogar-knowable-from --features surrealql-hint

Same crate-scoped pattern as #32's `surrealdb-parser` step.

# Verification

  - `cargo test --workspace` (default) -> clean (10/10 for
    ogar-knowable-from on the feature-off path).
  - `cargo test -p ogar-knowable-from --features surrealql-hint`
    -> 10/10 (the feature-on test now lands and the feature-off
    test is cfg'd out).
  - `cargo check --workspace --all-targets` -> clean.

PII abort-guard (word-boundary): CLEAN on all four touched files.

https://claude.ai/code/session_01PBTGaPCSnnt6u3pjXpbLwY

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3bdfdc54ac

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

// gets wired into the call site.
#[cfg(feature = "surrealql-hint")]
{
let ddl = ogar_adapter_surrealql::emit_surrealql_ddl(std::slice::from_ref(class));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Escape OGAR class names before emitting DDL hints

When surrealql-hint is enabled this now renders a DDL hint for every registered Class, but register_class_knowable_from accepts OGAR class names such as sale.order via the documented ogit-erp/sale.order identity path. Those names are not safe SurrealQL bare identifiers, and emit_surrealql_ddl currently formats them directly as DEFINE TABLE {class.name}, so enabling this feature for Odoo-style classes stores an invalid schema hint instead of a self-describing registry entry. Please normalize or quote identifiers before passing the hint, or only enable the hint for classes already known to be SurrealQL identifier-safe.

Useful? React with 👍 / 👎.

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