Fixes the storage/query layer of the bug-fix backlog from PR #327.
Slice 2 of 4 (split by architectural layer for reviewability).
Bug fixes — storage
- ST-1: BlazegraphStore parity gate. The adapter-parity-extra.test
intentionally fails red when BLAZEGRAPH_URL is missing so a green
pass cannot lie about parity coverage. Production blazegraph.ts
hardened to surface engine errors clearly instead of silently
falling back to a stub.
- ST-2: AES-GCM-SIV deterministic nonce derivation in private-store.
Previous nonce derivation could collide for repeated plaintexts on
the same key, breaking SIV's misuse-resistance guarantee.
- ST-12: Typed-literal round-trip preservation in oxigraph.ts (and
blazegraph.ts parity). xsd:dateTime / xsd:integer / xsd:decimal
values now round-trip with their explicit datatype IRIs intact;
previously they were narrowed to xsd:string on read.
Bug fixes — query
- Q-1: minTrust enforcement in DKGQueryEngine. The threshold was
documented but never actually filtered results below it; queries
could return assets from nodes the operator had explicitly
configured as untrusted.
- sparql-guard.ts: query-form detection now correctly distinguishes
SELECT / CONSTRUCT / ASK / DESCRIBE before applying form-specific
guards. Previously CONSTRUCT and DESCRIBE could bypass the
read-only guard meant for SELECT.
CI — Blazegraph service container (.github/workflows/ci.yml)
The storage shard now boots a real lyrasis/blazegraph:2.1.5 container
and provisions two quads-mode namespaces:
- dkgq → conformance / general storage suite (DROP-ALL tests)
- dkgq-parity → adapter-parity-extra (real Oxigraph ↔ Blazegraph parity)
Two namespaces (not one) because vitest parallelises files but
serialises tests within a file: pointing the parity suite at the
SAME namespace as the conformance suite let the latter's DROP ALL
fire mid-parity and wipe the parity fixture. Isolating per file
gives each suite exclusive ownership.
Quads mode is required (not Blazegraph's default triples mode),
otherwise GRAPH <…> { … } clauses are silently dropped on insert
and deleteByPattern over-deletes by collapsing all triples into
the default graph.
continue-on-error on the namespace-creation step so a failed boot
surfaces as the storage suite's missing-engine error (preserving the
"no false positives" contract — silently passing without a real
engine is impossible).
Tests
- private-store-key-resolution.test.ts (new, +895 lines): exercises
the full key derivation matrix that ST-2 hardened.
- query-extra.test.ts (+1153 lines): expanded coverage of minTrust
enforcement and per-cg trust isolation.
- sparql-form-detection.test.ts (new, +400 lines): regression
fixtures for the form-detection guard.
- adapter-parity.test.ts / adapter-parity-extra.test.ts: now exercise
both adapters against real engines.
- vitest.setup.ts (new): per-file storage adapter setup so the
parallel runners don't fight over namespace state.
Coverage ratchet
- tornadoStorageCoverage 57/52/39/53 → 85/81/63/79.
Sequencing: this is PR 2 of 4. Independent off main; PR 1 (#331)
carries contracts+chain, PRs 3-4 will carry operator-surface and
data-pipeline. Original umbrella branch parked at fix_tests-overflow.
Made-with: Cursor
Summary
PR 2 of 4 in the split of #327. Each slice is a single architectural layer to keep reviews tractable.
This PR carries the storage/query layer: RDF correctness, AES-GCM-SIV nonce hardening, SPARQL guard fixes, and the CI infrastructure to run real Blazegraph parity tests.
Changes by category
Storage bug fixes
Query bug fixes
CI — Blazegraph service container
The storage shard now boots a real `lyrasis/blazegraph:2.1.5` container and provisions two quads-mode namespaces:
Two namespaces (not one) because vitest parallelises files but serialises tests within a file: pointing the parity suite at the SAME namespace as the conformance suite let the latter's `DROP ALL` fire mid-parity and wipe the parity fixture.
Quads mode is required (not Blazegraph's default triples mode), otherwise `GRAPH <…> { … }` clauses are silently dropped on insert.
Tests added
Coverage ratchet
Sequencing context
This is slice 2 of 4 from the #327 split:
Test plan
Made with Cursor