Milestone 0.8 — C ABI preview¶
Status: complete
Outcome: run representative existing C consumers against an auditable Oxiland
compatibility library, with Fjall behind a sealed durable-store adapter
Depends on: 0.6 safe API accounting (independent of 0.7 Python)
Blocks: 0.9 C compatibility and optional storage adapters
Release evidence: docs/reports/0.8.md
This is the executable specification for 0.8. The roadmap defines the release outcome; this document defines the work packages and acceptance criteria. Design detail: 0.8-cabi.md, storage-backend-expansion.md. Decisions: ADR-022, ADR-023.
User-visible result¶
At the end of 0.8, a caller can:
- open durable Fjall stores through a sealed adapter while
Model::open(path)remains the Fjall-compatible shortcut; - select backends through typed
OpenOptionsand a shared registry (Rust, CLI, Python, C), with known-disabled backends distinct from unknown names; - link a C program against
oxiland-capiheaders/pkg-configand run a Redland-shaped workflow: world → memory or Fjall storage → model CRUD → Turtle parse/serialize → ASK/SELECT; - rely on opaque-handle ownership, panic containment, and sanitizer-clean CI for the preview symbol allowlist.
Frozen C preview allowlist¶
| Area | Symbols |
|---|---|
| World | librdf_new_world, librdf_free_world, librdf_world_open |
| Storage | librdf_new_storage, librdf_free_storage, librdf_storage_open |
| Model | librdf_new_model, librdf_free_model, librdf_model_add_statement, librdf_model_remove_statement, librdf_model_contains_statement, librdf_model_size, librdf_model_find_statements |
| Terms | librdf_new_uri, librdf_free_uri, librdf_new_node_from_uri_string, librdf_new_node_from_literal, librdf_free_node, librdf_new_statement_from_nodes, librdf_free_statement |
| Stream | librdf_stream_end, librdf_stream_next, librdf_stream_get_object, librdf_free_stream |
| Parser | librdf_new_parser, librdf_free_parser, librdf_parser_check_name, librdf_parser_parse_string_into_model |
| Serializer | librdf_new_serializer, librdf_free_serializer, librdf_serializer_check_name, librdf_serializer_serialize_model_to_string |
| Query | librdf_new_query, librdf_free_query, librdf_model_query_execute, librdf_query_results_is_boolean, librdf_query_results_get_boolean, librdf_query_results_is_bindings, librdf_query_results_finished, librdf_query_results_next, librdf_query_results_get_binding_name, librdf_query_results_get_binding_value, librdf_query_results_get_bindings_count, librdf_free_query_results |
| Alloc | librdf_free_memory |
Unsupported preview symbols return NULL / nonzero failure with a documented limitation. Full symbol closure is 0.9.
Non-goals¶
- Complete C symbol inventory with no unexplained gaps (0.9)
- ABI layout/calling guarantees for existing Redland binaries (0.9)
- Downstream Redland bindings/apps matrix (0.9)
- Optional adapters: redb, RocksDB, SQLite, LMDB (0.9; 0.8 records a redb spike)
- Public user-supplied
DurableBackendtrait (pre-0.10 ADR) - FFI fuzz corpus as a hard release gate
Work package sequence¶
| ID | Package | Depends on |
|---|---|---|
| WP-08-00 | Milestone + design + inventory C-field schema | — |
| WP-08-01 | Accept ADR-022 + ADR-023 | WP-08-00 |
| WP-08-02 | Sealed DurableStore + Fjall extraction |
WP-08-01 |
| WP-08-03 | Backend conformance harness (memory + fjall) | WP-08-02 |
| WP-08-04 | Backend registry across Rust / CLI / Python | WP-08-02 |
| WP-08-05 | oxiland-capi scaffold, panic/allocator, headers |
WP-08-01 |
| WP-08-06 | Preview symbols: world/model/terms/CRUD/streams | WP-08-05, WP-08-04 |
| WP-08-07 | Preview symbols: parse/serialize + ASK/SELECT | WP-08-06 |
| WP-08-08 | Representative C program + sanitizer/symbol CI | WP-08-07 |
| WP-08-09 | C inventory accounting + redb spike record | WP-08-03, WP-08-08 |
| WP-08-10 | Docs, parity, report, 0.8.0 release | all |
Evidence gates¶
- A representative unmodified Redland-shaped C program compiles and runs.
- Sanitizers find no leaks, use-after-free, or callback lifetime defects on CAPI paths.
- Exported-symbol allowlist checks run in CI.
- Every exported pointer type has allocation, aliasing, and destruction tests.
- Null, invalid UTF-8, callback re-entry, and double-free defenses are tested.
- No
unsafeblock lacks a local safety argument. - Format-v1 and storage transaction suites pass through the common backend conformance harness.
- The default build remains free of native C/C++ storage dependencies.
- ADR-022 and ADR-023 are accepted; preview limitations are documented.
Exit checklist¶
- ADR-022 and ADR-023 accepted
- Sealed Fjall adapter + conformance harness
- Backend registry on Rust / CLI / Python / C
-
oxiland-capibuilds (cdylib+staticlib) with headers/pkg-config - Preview allowlist implemented and tested
- Representative C example + sanitizer/symbol CI
- Inventory
redland-1.0.17-oxiland-0.8.jsonwith C ABI fields -
docs/reports/0.8.mdcomplete -
PARITY.md/ROADMAP.mdmark 0.8 complete -
0.8.0release checklist ready (docs/reports/0.8.0-release.md; tagging still open)