test(ontology): #204 OwlAdapter regression — 🔴 BUG FOUND: all readers return empty (RDFResource.Equals(Uri) type-mismatch) - #480
Conversation
…eturn empty (RDFResource.Equals(Uri) type-mismatch) Dispatch 3a0d2l-continue primaire (j1jfoi). NEW additive file (+16 tests, 313 lines). Baseline 202 -> 218 / 0 fail / 5 skip.⚠️ BUG FOUND (not greenwashed): every self-retrieval reader in OwlAdapter compares RDFResource.Equals(Uri) / RDFResource.Equals(string) — RDFResource.Equals(object) requires the arg to BE an RDFResource, so it returns FALSE by type-mismatch on every call. Affected readers ALL return empty/false: - GetConcepts, GetResourcesByType, GetTopConcepts - HasAnnotation, CheckIsNarrowerConcept - GetConceptPreferredLabels, GetConceptDocumentation - GetExactMatchConcepts/CloseMatch/RelatedMatch - CheckHasClass (cls.GetIRI().Equals(resource.URI) — same root cause, .URI is System.Uri) Production impact: Tests/OwlOntologyValidationTests.cs (the post-gen validation module, NOT an xUnit suite) relies on these readers. ValidateMultilingualAnnotations and ValidateAIFMappings early-return "no concepts -> skip -> PASS" (silent false-pass). ValidateOwlOntologyStructure logs all 4 errors and FAILs. So OWL validation is currently unreliable. Root cause confirmed empirically (Diag_RDFResource_Equals_String_Is_False_By_Type_Mismatch): RDFResource.Equals(string) -> false (type mismatch) RDFResource.Equals(RDFResource with same URI) -> true (what readers SHOULD use) RDFResource.ToString() == uriString -> true (correct string basis) Tests structured as: (A) [BUG] characterization — 8 tests pin the BROKEN behavior (.Should().BeEmpty() / .BeFalse()). When OwlAdapter is fixed, these flip red->green become proper round-trip assertions. (B) root-cause probe — pins RDFSharp Equals semantics so the cause is undeniable. (C) write-path + serialization — 7 tests verify the WRITE side works correctly (the ontology graph IS built in memory; ToFileAsync produces valid RDF/XML — that's why #133 ships a non-empty ontology despite the readers being broken). Verified by direct graph inspection (.ToString() comparison), NOT the broken readers. No fix applied — OwlAdapter.cs is out of scope (test-only dispatch; fix is ai-01's call and may intersect #444/#457 reserved files). The file gives the fix author a ready regression suite. No existing file modified. Baseline additive (202->218). Deterministic, key-free, release-independent. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
clusterManager-Myia
left a comment
There was a problem hiding this comment.
[NanoClaw]
Solid regression suite. A few notes:
The bug characterization is excellent. Pinning broken behavior with explicit [BUG] tags and Should().BeEmpty() assertions (rather than greenwashing) is exactly the right approach. The root-cause probe (Diag_RDFResource_Equals_String_Is_False_By_Type_Mismatch) makes the fix obvious and undeniable.
Write-path tests (section C) are well-designed — verifying via direct graph inspection (.ToString() comparison) bypasses the broken readers, so these won't flip when the fix lands. Good defensive design.
Minor observations:
- The class-level XML doc (~50 lines) is very thorough but could be trimmed — much of it duplicates what the individual test doc comments already say. Consider keeping the key context (BUG root cause, test structure overview) and moving the detailed reader-by-reader breakdown to the PR description where it already exists.
ToFileAsync(...).Wait()blocks the thread. Since this is a test it's acceptable, butawait ...with an async test method would be cleaner and avoid potential deadlocks under certain sync contexts.DocumentConcept_Unknown_Type_Throwssits in section C (write-path) but is really an edge-case/guard test. Consider a separate section or at least a comment grouping it with the BUG tests, since it validates a defensive code path rather than the write side.
Recommendation: LGTM — merge as-is. The test coverage is additive, well-structured, and the bug documentation is precise enough that the OwlAdapter fix author can land the ~6-line change with confidence using these as a regression suite.
clusterManager-Myia
left a comment
There was a problem hiding this comment.
[NanoClaw]
Thorough regression test file. Read the full 313-line diff -- here are the specifics.
Section B -- Root cause probe (1 test)
Diag_RDFResource_Equals_String_Is_False_By_Type_Mismatch is clean and compelling. Three assertions in sequence: (1) Equals(string) is false -- the bug, (2) Equals(RDFResource) is true -- what readers should do, (3) ToString() == uriString is true -- the workaround basis. Assertions are NOT flipped. The test directly pins the RDFSharp semantics the PR body describes at lines 333-391 of OwlAdapter.cs. Good probe -- makes the fix obvious to whoever picks up the OwlAdapter work.
Section A -- BUG characterization (8 tests)
All 8 tests follow the same pattern: write data, read via the broken reader, assert empty/false. Cross-checked every assertion against the PR body claims:
BUG_GetConcepts_Returns_Empty: writes 3 concepts, assertsBeEmpty-- correct.BUG_GetResourcesByType: asserts both Concept and ConceptScheme return empty -- correct.BUG_GetTopConcepts: writes 2 top concepts, asserts empty -- correct.BUG_HasAnnotation: writes ConceptScheme, asserts false -- correct.BUG_CheckIsNarrowerConcept: writes narrower relationship, asserts false -- correct. Comment correctly notes the try/except fallback also suffers the same bug.BUG_GetConceptPreferredLabels: writes prefLabel, asserts empty -- correct.BUG_GetConceptDocumentation: writes definition, asserts empty -- correct.BUG_GetExactMatchConcepts: writes exactMatch, asserts empty -- correct.
All assertions match the documented broken behavior. None are flipped. The naming convention [BUG]_Method_Result_Under_Condition is clear and consistent with the claimed failure mode.
One note: BUG_GetResourcesByType asserts two empty results in a single test. This is fine for characterization but will need splitting when flipped to green assertions, since a fix might resolve one reader path but not the other. Minor -- the fix author can address it.
Section C -- Write-path + serialization (7 tests)
Write-path tests correctly bypass the broken readers by using direct graph inspection: onto.AnnotationAxioms.OfType<OWLAnnotationAssertion>() with .ToString() string comparison. This is the right approach -- it proves the graph is populated independently of the broken read path.
Constructor_Produces_An_Adapter: basic sanity, fine.DeclareConcept_Appends_AnnotationAxioms: verifies rdf:type=skos:Concept axiom in the graph. Checks property, subject, and value IRIs via ToString(). Solid.DeclareNarrowerConcepts_Appends_Both_Directional_Axioms: verifies both skos:narrower and skos:broader. Good coverage of the reciprocal write.AnnotateConceptPreferredLabel: verifies the prefLabel axiom exists with a non-null ValueLiteral. Correctly only asserts property+subject (not the literal value rendering, which is OWLSharp-internal).BUG_CheckHasClass_Returns_False: hybrid test -- verifies both the write side (DeclarationAxioms non-empty) AND the broken read side (CheckHasClass returns false). Effective.DocumentConcept_Unknown_Type_Throws: edge case for invalid enum.Should().Throw<ArgumentOutOfRangeException>(). Good defensive test.ToFileAsync_Writes_A_Non_Empty_OWL2XML_File: end-to-end serialization with temp file, try/finally cleanup, asserts non-empty and contains RDF/XML markers. One note: uses.Wait()instead ofawait(sync-over-async). This is a known xUnit limitation with[Fact]returning void -- not a bug, but worth noting that[Fact]+.GetAwaiter().GetResult()or switching to[Fact]withasync Taskreturn type would be slightly safer against deadlocks.
Test structure and hygiene
- xUnit
[Fact]attributes, FluentAssertions throughout, consistent helper methods (NewAdapter,Res,Lit). Clean. - Test namespace (
Argumentum.AssetConverter.Tests.Ontology) is correct for the project structure. http://argumentum.test/onto#namespace -- clearly non-production. Good.- Temp file in
ToFileAsyncuses Guid for uniqueness and has try/finally cleanup. Proper. - No hardcoded secrets, credentials, or API keys. Clean.
Summary
This is well-crafted characterization work. The 8 BUG tests correctly pin the broken behavior (not flipped), the root-cause probe is undeniable, and the write-path tests genuinely verify graph population without depending on the broken readers. The PR delivers exactly what it claims: a regression suite ready for the fix author. Recommend merging as-is.
Nit: BUG_GetResourcesByType combines two assertion paths in one test -- consider splitting when flipping to green. And ToFileAsync could use async Task return instead of .Wait() to avoid potential sync-context deadlocks, though this is low-risk in a test runner.
…SHelper silent-empty fallback (#481) Fixes the bug surfaced by PR #480 (OwlAdapter readers returning empty). Root cause was deeper than the .URI type-mismatch: RDFResource.Equals uses runtime-type comparison (GetType()), so even RDFResource.Equals(fresh RDFResource) is false when the stored IRI is a subtype — only GetIRI().Equals works. Switched all 14 reader comparison sites to .ToString() equality (the URI-as-string basis the write-path tests already proved correct, agnostic to RDFResource subtype). Also completes the "incomplete SKOSHelper bypass" flagged on the dashboard: CheckIsNarrowerConcept / GetExactMatch/Close/RelatedMatch had try/catch fallbacks that only triggered on exception, but SKOSHelper returns false/empty SILENTLY — so the (now-correct) fallback scanner was never reached. Changed fallback to trigger on empty/false result too, not just exception. Tests: section-(A) [BUG] characterization suite from #480 flipped to proper round-trip assertions (now the regression suite for this fix). Full suite 218 pass / 0 fail / 5 skip (baseline preserved). Production impact: Tests/OwlOntologyValidationTests.cs (post-gen OWL validator, not xUnit) was silently false-passing "no concepts → skip → PASS" on annotation and AIF checks because GetResourcesByType(Concept) returned empty. Now resolves correctly → validation becomes reliable (unblocks trustworthy #133 OWL publication). Co-authored-by: Your <your.email@example.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…ad (dispatch 4rkh1s secondaire) (#482) * fix(ontology): #204 OwlAdapter readers — RDFResource.ToString() + SKOSHelper silent-empty fallback Fixes the bug surfaced by PR #480 (OwlAdapter readers returning empty). Root cause was deeper than the .URI type-mismatch: RDFResource.Equals uses runtime-type comparison (GetType()), so even RDFResource.Equals(fresh RDFResource) is false when the stored IRI is a subtype — only GetIRI().Equals works. Switched all 14 reader comparison sites to .ToString() equality (the URI-as-string basis the write-path tests already proved correct, agnostic to RDFResource subtype). Also completes the "incomplete SKOSHelper bypass" flagged on the dashboard: CheckIsNarrowerConcept / GetExactMatch/Close/RelatedMatch had try/catch fallbacks that only triggered on exception, but SKOSHelper returns false/empty SILENTLY — so the (now-correct) fallback scanner was never reached. Changed fallback to trigger on empty/false result too, not just exception. Tests: section-(A) [BUG] characterization suite from #480 flipped to proper round-trip assertions (now the regression suite for this fix). Full suite 218 pass / 0 fail / 5 skip (baseline preserved). Production impact: Tests/OwlOntologyValidationTests.cs (post-gen OWL validator, not xUnit) was silently false-passing "no concepts → skip → PASS" on annotation and AIF checks because GetResourcesByType(Concept) returned empty. Now resolves correctly → validation becomes reliable (unblocks trustworthy #133 OWL publication). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * test(ontology): #204 OwlValidator live-path — silent false-pass is dead (dispatch 4rkh1s secondaire) NEW additive file: OwlValidatorLivePathTests.cs (+5 tests). Dispatch `4rkh1s` secondaire — prove the production OWL validation path is LIVE after the #481 reader fix. The production validator `Tests/OwlOntologyValidationTests.cs` (runtime validator invoked by `OwlValidatorConfig.Apply`, NOT an xUnit suite) had a silent false-pass: ValidateMultilingualAnnotations and ValidateAIFMappings early-return `true` ("No concepts to validate — skipping") when GetResourcesByType(Concept) was empty. Before #481 that reader ALWAYS returned empty, so the validators reported PASS regardless of whether annotations/AIF mappings existed. These tests drive the REAL production validator via reflection (its `_ontology` field is private; the validation methods are public). They prove: - (1) annotated concepts → validator inspects them and reports genuine PASS (not the skip-path); - (2) UNannotated concepts → validator now FAILS (the annotation check actually ran and found the missing labels/definitions) — the dead silent false-pass is gone; - (3) the GetResourcesByType(Concept) predicate the validators branch on resolves non-empty. Tests: 223 pass / 0 fail / 5 skip (218 + 5). Deterministic, key-free, release-independent. No existing file modified. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Your <your.email@example.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…ch 4rkh1s tertiaire) (#483) * fix(ontology): #204 OwlAdapter readers — RDFResource.ToString() + SKOSHelper silent-empty fallback Fixes the bug surfaced by PR #480 (OwlAdapter readers returning empty). Root cause was deeper than the .URI type-mismatch: RDFResource.Equals uses runtime-type comparison (GetType()), so even RDFResource.Equals(fresh RDFResource) is false when the stored IRI is a subtype — only GetIRI().Equals works. Switched all 14 reader comparison sites to .ToString() equality (the URI-as-string basis the write-path tests already proved correct, agnostic to RDFResource subtype). Also completes the "incomplete SKOSHelper bypass" flagged on the dashboard: CheckIsNarrowerConcept / GetExactMatch/Close/RelatedMatch had try/catch fallbacks that only triggered on exception, but SKOSHelper returns false/empty SILENTLY — so the (now-correct) fallback scanner was never reached. Changed fallback to trigger on empty/false result too, not just exception. Tests: section-(A) [BUG] characterization suite from #480 flipped to proper round-trip assertions (now the regression suite for this fix). Full suite 218 pass / 0 fail / 5 skip (baseline preserved). Production impact: Tests/OwlOntologyValidationTests.cs (post-gen OWL validator, not xUnit) was silently false-passing "no concepts → skip → PASS" on annotation and AIF checks because GetResourcesByType(Concept) returned empty. Now resolves correctly → validation becomes reliable (unblocks trustworthy #133 OWL publication). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * test(ontology): #204 OwlValidator live-path — silent false-pass is dead (dispatch 4rkh1s secondaire) NEW additive file: OwlValidatorLivePathTests.cs (+5 tests). Dispatch `4rkh1s` secondaire — prove the production OWL validation path is LIVE after the #481 reader fix. The production validator `Tests/OwlOntologyValidationTests.cs` (runtime validator invoked by `OwlValidatorConfig.Apply`, NOT an xUnit suite) had a silent false-pass: ValidateMultilingualAnnotations and ValidateAIFMappings early-return `true` ("No concepts to validate — skipping") when GetResourcesByType(Concept) was empty. Before #481 that reader ALWAYS returned empty, so the validators reported PASS regardless of whether annotations/AIF mappings existed. These tests drive the REAL production validator via reflection (its `_ontology` field is private; the validation methods are public). They prove: - (1) annotated concepts → validator inspects them and reports genuine PASS (not the skip-path); - (2) UNannotated concepts → validator now FAILS (the annotation check actually ran and found the missing labels/definitions) — the dead silent false-pass is gone; - (3) the GetResourcesByType(Concept) predicate the validators branch on resolves non-empty. Tests: 223 pass / 0 fail / 5 skip (218 + 5). Deterministic, key-free, release-independent. No existing file modified. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * test(utility): #204 UtilityExtensions layout math + path gate (dispatch 4rkh1s tertiaire) NEW additive file: UtilityExtensionsLayoutTests.cs (+24 tests). Dispatch `4rkh1s` tertiaire — cover a documented-fragile, deterministic, key-free area with ZERO existing coverage (grep confirms no test references ToJaggedArray/UtilityExtensions/PathIsUrl). (1) ToJaggedArray<T> — grid layout math. Pins rowLength = ceil(count/columns), the trailing short row (remainder only, no padding — a padding regression would inject phantom blank cards into final grid rows), row-major fill order (a transpose regression scrambles positions), and the ToJaggedArray→Flatten inverse round-trip. This is the same class of geometry the coordinator flagged ("count the geometry, not just the text"). (2) PathIsUrl — the asset-path gate. Pins that the relative paths CLAUDE.md documents as the root cause of "white/empty cards" (../../Cards/..., ../, bare, Windows C:\, Unix /var/) are NOT URLs (so the caller knows to rewrite them to absolute GitHub URLs), that http/https ARE URLs, that null/empty/whitespace return false, and that whitespace-padded URLs still resolve. Tests: 246 pass / 0 fail / 5 skip (223 + 24). Deterministic, key-free, release-independent. No existing file modified. AssetConverterConfig.cs / DatasetUpdaterRootConfig.cs / FallaciesLocalizationTests.cs untouched (reserved #444 β/γ po-2023). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Your <your.email@example.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…lent-false-pass bug (#486) Loads the committed generated ontology (docs/ontology/argumentum.owl, the real OwlDocumentConfig.CreateOwlDocument output) and runs the production validation path against it. This completes the #133 e2e proof that #482 (synthetic in-memory adapters) started — and surfaces a SECOND silent-false-pass bug the #480→#481→#482 lane missed because it only exercised the in-memory path. ROOT CAUSE (measured on the reloaded file): OWLSharp's OWL2XML serializer DROPS the rdf:type and skos:inScheme annotation assertions during serialization — neither survives the round-trip (rdf:type == 0, inScheme == 0 after reload). The OwlAdapter readers find concepts/schemes by scanning AnnotationAxioms for rdf:type, so on any LOADED file they return empty. OwlOntologyValidationTests.ValidateMultilingualAnnotations and .ValidateAIFMappings then hit their `if (concepts.Count == 0) return true;` guard and report PASS without inspecting anything. The real content IS present (2816 prefLabels, 10 AIF matches, 1510 class declarations) — the validator simply cannot see it. So #133's "confidence restored" premise does NOT hold for the production load-and-validate path: the silent false-pass is still alive there, for a different root cause than the #480 RDFResource type-mismatch. 4 characterization tests (all green, pinning current broken behavior): 1. rdf:type==0 and inScheme==0 after round-trip (prefLabel survives as contrast). 2. GetResourcesByType(Concept/ConceptScheme) returns empty on the loaded file. 3. The reloaded ontology DOES contain real content (prefLabel>1000, matches>0, classDecls>1000) — reader defect, not data defect. 4. Production validator returns TRUE for annotation + AIF checks on the loaded ontology — the silent false-pass, decisively pinned. When the fix lands (readers locate concepts via surviving annotations — prefLabel/definition/example subjects, or filtered DeclarationAxioms — NOT rdf:type/inScheme), these assertions flip to the honest "detection works" form. The fix is a prod behavior change with release-gate implications → coordinator scope; this PR surfaces it rather than shipping a unilateral prod change. Deterministic, key-free, release-independent. NEW additive file — nothing modified. Co-authored-by: Your <your.email@example.com> Co-authored-by: Claude <noreply@anthropic.com>
…nt-false-pass dead (#489) The #481 reader fix only covered the IN-MEMORY path. On a LOADED ontology (rdf:type + skos:inScheme dropped from the reloaded AnnotationAxioms by OWLSharp's OWL2XML round-trip), GetResourcesByType(Concept)/GetConcepts returned empty -> ValidateMultilingualAnnotations/ValidateAIFMappings hit their `concepts.Count == 0 -> return true` guard -> PASS without inspecting (the 2nd silent-false-pass, characterized by #486). Verified reloaded breakdown (probed on the real generated ontology): prefLabel=2816, definition=2816, example=2816, narrower/broader=1407, broadMatch=57, closeMatch=10, narrowMatch=3, hasTopConcept=1; rdf:type=0, inScheme=0 among AnnotationAxioms. Fix is READ-PATH ONLY (serializer untouched, per dispatch scope). When the rdf:type scan is empty, locate entities via the surviving SKOS annotations: - skos:Concept -> distinct subjects of skos:prefLabel (~1305 resolved) - skos:ConceptScheme -> subject of skos:hasTopConcept In-memory path preserved (rdf:type present -> early-return, no fallback), so the #482 in-memory live-path proofs still hold. Concepts deduped by URI string (not RDFResource.Equals) to avoid the equality bug class of #480. OwlE2EGenerationValidationTests (#486) flipped from bug-characterization to a genuine-pass regression suite: (1) rdf:type/inScheme drop still real (now benign), prefLabel survives (2) readers now resolve concepts (>1000) + scheme (NotBeEmpty) (3) real content now resolvable (>1000 distinct concept subjects) (4) prod validator genuinely inspects + passes (skip guard unreachable) Tests: Ontology namespace 25/25 green; full suite 259 passed / 0 failed / 5 skipped (no regression). Dispatch msg-...irkf5i primaire, base 4ac52e2. Read-path only: no write/serialize, no CSV/template/config touched. Co-authored-by: Your <your.email@example.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
/#133 (#495) Unit-isolation of the OWL2XML round-trip SURVIVOR fallback in OwlAdapter. The #489 read-path fix (e2e-pinned on the real 5MB ontology by OwlE2EGenerationValidationTests) made the production validators stop silent-false-passing when OWLSharp drops rdf:type on reload. But the survivor fallback branch (OwlAdapter.cs ~424-441) was unit-uncovered: OwlAdapterRegressionTests (#480/#481) builds ontologies WITH rdf:type (DeclareConcept), so GetResourcesByType always early-returns on the type scan and NEVER reaches the fallback. 7 additive tests on synthetic survivor-only ontologies (no DeclareConcept -> no rdf:type; only prefLabel/hasTopConcept that survive the round-trip), pinning what the e2e cannot: - Concept dedup: 3 concepts x fr+en prefLabel (6 assertions) -> 3 distinct subjects (the GetAnnotationSubjectsByProperty .Distinct() contract) - ConceptScheme via hasTopConcept SUBJECT (exact pin, not coarse NotBeEmpty) - Unknown type -> empty (fallback does not over-resolve) - rdf:type present -> type-scan governs, fallback SKIPPED. Decisive proof the fix did not change in-memory semantics; the e2e cannot test this because the real file has zero rdf:type - GetConcepts() survivor tail (distinct path from GetResourcesByType) - AIF exactMatch + closeMatch annotation-scan fallback Verified: 7/7 new tests green; full suite 282 passed / 0 failed / 5 skipped. Test-only, 0 prod change, 0 gate risk. Co-authored-by: Your <your.email@example.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
What
NEW additive file
Ontology/OwlAdapterRegressionTests.cs(+16 tests, 313 lines). Baseline 202 → 218 / 0 fail / 5 skip. The Ontology subsystem had zero xUnit coverage before this (the production-sideTests/OwlOntologyValidationTests.csis a post-gen module, not a test suite).🔴 BUG FOUND (not greenwashed)
Every self-retrieval reader in
OwlAdapteris broken — they all silently return empty/false. Root cause: the comparisonRDFResource.Equals(someUri)wheresomeUriis aSystem.Uri(or string).RDFResource.Equals(object)requires the argument to be anRDFResource— so it returns false by type-mismatch on every call.Confirmed empirically in
Diag_RDFResource_Equals_String_Is_False_By_Type_Mismatch:RDFResource.Equals(string)→ false (type mismatch) ← what the readers doRDFResource.Equals(RDFResource with same URI)→ true ← what they should doRDFResource.ToString() == uriString→ true ← the correct string basisAffected readers (all return empty/false):
GetAnnotationSubjectsa.ValueIRI.Equals(typeResource.URI)GetAnnotationObjects(GetTopConcepts)property.URI)GetResourceAnnotationsa.SubjectIRI.Equals(subject.URI)GetLiteralAnnotationsa.SubjectIRI.Equals(subject.URI)HasAnnotationa.ValueIRI.Equals(value.URI)+a.SubjectIRI.Equals(subject.URI)CheckIsNarrowerConceptfallback.Equals(...URI)CheckHasClasscls.GetIRI().Equals(resource.URI)Production impact:
Generation/Converters/Argumentum.AssetConverter/Tests/OwlOntologyValidationTests.csis the post-generation OWL validation module and it calls these readers heavily:ValidateMultilingualAnnotations→GetResourcesByType(Concept)returns empty → early-returns "no concepts → skip → PASS" (silent false-pass)ValidateAIFMappings→ same silent false-passValidateOwlOntologyStructure→ logs all 4 errors (no ConceptScheme, no Concept, no topConcepts, no narrower) → FAILsSo OWL validation is currently unreliable. #133 (OWL publication) ships a non-empty ontology because the write path + serialization work (verified in section C), but the validators can't actually inspect it.
Why no fix in this PR
OwlAdapter.csis out of scope for this test-only dispatch (may intersect #444/#457 reserved files; fix is ai-01's call). Instead, this PR delivers the ready-to-go regression suite: the fix author changes the comparisons toa.ValueIRI.Equals(new RDFResource(value.URI.ToString()))(or.ToString()-based), and the 8[BUG]_*tests flip red→green into proper round-trip assertions.Test structure (16 tests)
Section A — [BUG] characterization (8 tests): pin the BROKEN behavior. Each
.Should().BeEmpty()/.BeFalse()with a[BUG]reason. When fixed, these become.Should().HaveCount(...)/.BeTrue().Section B — root-cause probe (1 test): pins the exact RDFSharp
Equalssemantics so the cause is undeniable and the fix is obvious.Section C — write-path + serialization (7 tests): verify the WRITE side works (the graph IS correctly built in memory;
ToFileAsyncproduces valid RDF/XML — that's why #133 ships non-empty despite broken readers). Verified by direct graph inspection (.ToString()comparison), NOT via the broken readers. So a fix can't accidentally regress the write side.DoD
[BUG]tests assert the broken behavior, not a flipped assertion)Recommendation to ai-01
[BUG]issue / fix PR forOwlAdapter.csread methods — the fix is mechanical (6 comparison sites), and this PR's section-A tests become its regression suite.🤖 Worker po-2024 on dispatch
j1jfoi(primaire). Verdict QA visuelle = ai-01.Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com