Skip to content

Preserve literal objects when exporting unbound statements - #821

Merged
WaylandYang merged 1 commit into
deeplethe:devfrom
Maya-Kid:codex/preserve-unbound-rdf
Sep 20, 2026
Merged

WaylandYang merged 1 commit into
deeplethe:devfrom
Maya-Kid:codex/preserve-unbound-rdf

Conversation

@Maya-Kid

@Maya-Kid Maya-Kid commented Sep 20, 2026

Copy link
Copy Markdown
Contributor

Problem

An open statement can have a literal object without an ontology predicate. For example, 设备 A —状态→ "待复检" is stored and read by export::facts_page, but its RDF statement has no rdf:object: emit_fact constructed literal objects inside predicate_id.map(...).

Reproduced on dev@91469de through the authenticated HTTP export route against PostgreSQL, as well as the serializer regression.

Change

Construct the literal when object_value exists, using the optional predicate only to look up its datatype. Unbound values use the existing conservative xsd:string representation. Bound datatypes, entity objects, and the current-assertion gate retain their behavior. No predicate or ordinary assertion is invented for an unbound statement.

Validation

Linux, Rust 1.98.1, dedicated PostgreSQL 16/pgvector container, UTOPIA_TEST_REQUIRE_DB=1 and UTOPIA_TEST_REQUIRE_PDFTOTEXT=1:

  • Baseline: cargo test --locked -p utopia-server unbound_literal_objects — both tests fail specifically on the missing object.
  • Fixed: the same 2 tests pass. Removing only the production fix makes both fail again.
  • RDF suite: 16 tests pass, including parsed Turtle/JSON-LD equality, escaping, empty/zero/false/null values, live/retracted statements, absent objects, and bound datatype controls.
  • Authenticated HTTP export reads a statement inserted through insert_open_statement, retains its evidence, and leaves business rows, evidence, and queued jobs unchanged.
  • cargo fmt --all --check, workspace Clippy with -D warnings, workspace tests, and workspace build pass.
  • Workspace tests: 942 passed, 0 failed, 1 explicitly ignored live-public-HTTPS test.
  • Frontend frozen install, 91 tests, and build pass.

Scope and compatibility

Only emit_fact changes in production. No schema, SQL, worker, alignment, or write-path change. The baseline includes #820; its relation-rule design is unaffected. Existing external exports are not rewritten and must be regenerated to recover omitted values. Other RDF omissions remain outside this fix.

Combined regression verification

All five independent fixes merge cleanly onto the same dev baseline. On the combined Linux branch, format, workspace Clippy, build and the full test suite pass (952 passed, 0 failed, 1 explicitly ignored live-public-HTTPS test). A shared authenticated RDF fixture verifies unbound values, subsecond history and explicit ontology links together in Turtle and JSON-LD. Removing each fix individually makes its regression fail again; restoring all fixes returns the full suite to 952 passing tests. No database migration or historical rewrite is included.

Signed-off-by: dada-yan <BinjunYann@gmail.com>
@WaylandYang
WaylandYang merged commit cbf4969 into deeplethe:dev Sep 20, 2026
4 checks passed
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