feat(csv): #499 Phase 1 — add 12 relational/AIF columns to Virtues prod CSV - #590
Merged
Merged
Conversation
…od CSV Append-only prod-write: 12 new columns to Cards/Fallacies/Argumentum Virtues - Taxonomy.csv (66 -> 78 cols), populated from the 12 validated annotation CSVs in docs/taxonomy/ (joined by virtue_pk == pk). De-gated by jsboige (interactive 2026-06-23, "GO" on docs/taxonomy/499-virtues-parity-closure.md); dispatched by ai-01 as Phase 1 of the #499 deep-queue (data write; OWL code = Phase 2 PR). Columns added (verbatim Fallacies names, after link_fa col 66): crossLink_PredatesOn, crossLink_Denounces, crossLink_Leverages, crossLink_Allows, crossLink_Opposes, crossLink_Inverts, crossLink_Mirrors, crossLink_IsRelatedTo, AIF_skosDirectRef, AIF_skosExceptionRef, AIF_skosOther, AIF_skosMappingType 3 of 12 populated for 222 rows (the real Virtue nodes): crossLink_Opposes (semicolon-list of opposed Fallacy PKs) AIF_skosDirectRef (Walton scheme label) AIF_skosMappingType (FR prose critical question, comma-quoted) 9 cols structurally empty by design (Virtue->Fallacy is solely "Opposes"; Exceptions/Other are Fallacy attributes). pk=0 (taxonomy root) left empty. ADDITIVE PROOF: existing 66 cols byte-identical before/after (0 value drift across 223x66 = 14518 cells). Line-append only; existing content untouched. Guard: aborted if raw CRLF-line count != 223 (embedded-newline safety). Verified: 223 rows x 78 cols, 3 target cols filled 222/222, 9 structural empties 0 non-empty, crossLink_Opposes 60 distinct Fallacy PKs all resolve in Fallacies corpus (0 dangling). UTF-8 no-BOM, CRLF preserved, 998061 bytes (+30898). Phase 2 (separate code PR): ArgumentVirtueClassMap mapping + OwlAdapter Virtues pass. No code changed in Phase 1. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
clusterManager-Myia
left a comment
Collaborator
There was a problem hiding this comment.
[NanoClaw] — data-integrity review (RFC4180 parse of all 223 rows, old-master vs head blob)
✅ PASS — no data loss.
- Schema 66 → 78 cols; every one of the 223 data rows parses to exactly 78 fields (no ragged rows).
- The existing 66 columns are byte-identical across all rows (verified field-by-field). No unintended edits, no truncation.
- Header prefix preserved; 12 new cols:
crossLink_{PredatesOn,Denounces,Leverages,Allows,Opposes,Inverts,Mirrors,IsRelatedTo},AIF_skos{DirectRef,ExceptionRef,Other},AIF_skosMappingType. - Join integrity matches the PR's ground-truth table: populated cols show 222/223 non-empty = the 222 annotation rows; the single orphan prod row (no matching
virtue_pk) is correctly left empty. - No secrets / no control-char corruption in the new blob.
crossLink_Opposes (222, 147 distinct), AIF_skosDirectRef (222, 14 distinct), AIF_skosMappingType (222, 222 distinct). The other 9 are empty across all rows. Given Phase 2 = OWL/crossLink propagation (separate PR) the empty crossLink_* set is plausibly expected — worth an explicit 👀 that these are "source annotations had no data for those relations," not a silent join gap. If only those 3 had source data today, the change is internally consistent.
No merge-blocking issues. Phase-1 prod-write looks structurally sound.
Merged
5 tasks
jsboige
added a commit
that referenced
this pull request
Jun 24, 2026
…corpus, aif:goodTenorOf) (#592) * feat(ontology): #499 Phase 2 — map 12 relational/AIF columns on Virtue entity Phase 2 ClassMap: map the 12 columns appended to the Virtues prod CSV in #590 (66->78) onto Virtue / VirtueClassMap -- the entity that loads the prod CSV (CsvType = typeof(Virtue), AssetConverterConfig.cs) and feeds the OWL/mindmap pipeline (ParallelVirtueDocumentCreatorConfigBase<Virtue>). Entity-target correction: ai-01's dispatch named ArgumentVirtueClassMap, but ArgumentVirtue is only the AutoMapper ArgumentVirtue->Fallacy projection target (MappingProfile.cs) -- it is NOT a CSV loader. The prod Virtues CSV + downstream pipeline operate on Virtue. Flagged to ai-01 (the two entities are near-identical; the naming conflates them in the dispatch and in CLAUDE.md). All 12 columns .Optional() -- 9 structurally empty by design, 3 populated for the 222 real Virtue nodes (pk=0 root left empty): crossLink_PredatesOn..IsRelatedTo (x8) -- only crossLink_Opposes populated (semicolon list of prevented Fallacy PKs) AIF_skosDirectRef/ExceptionRef/Other/MappingType (x4) -- DirectRef + MappingType populated (Walton scheme label + FR-prose critical question) Tests (+2 in VirtueClassMapRegressionTests): - Maps499RelationalAndAifColumns: populated row mirrors prod pk=71 (crossLink_Opposes=681;690, AIF_skosDirectRef=Argument from Sign, AIF_skosMappingType=FR prose RFC4180-quoted for its internal comma); 9 structural empties map to "" (CsvHelper empty-cell behavior, not null). - 499ColumnsAbsent_DoesNotThrow: Optional contract -- a header missing the relational block loads without throwing (property null, not throw). Suite: 533 -> 535 passed, 0 failed, 5 skipped. Phase 2 part 2 (OwlAdapter Virtues OWL pass) follows in this branch once the 2 flagged design adaptations are confirmed with ai-01: 1. AIF: Virtue AIF_skosMappingType is FR prose (not a skos:*Match enum token), so the Fallacies switch cannot fire -> adapt to skos:relatedMatch + annotation. 2. crossLink_Opposes is cross-corpus (Virtue->Fallacy PKs); Fallacy concept URIs derive from TextEn, not PK -> the Virtues pass must load the Fallacies corpus to resolve PK->URI for the 0-dangling DoD. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat(ontology): #499 Phase 2 Part 2 — VirtueOwlGeneratorConfig (mono-corpus OWL pass) Create the Virtues OWL/SKOS generator from scratch (mirroring OwlGeneratorConfig / OwlDocumentConfig for Fallacies) and wire it into the pipeline alongside the Fallacies pass. Emits argumentum_virtues.owl: a concept scheme with the 7-family hierarchy (skos:narrower via Path/Depth, same GetParent shape as Fallacies), one concept per Virtue node (prefLabel/description FR+EN on Title*/Description*), and a custom AIF object property aif:goodTenorOf linking each Virtue to its Walton argumentation scheme. Design decisions (jsboige interactive 2026-06-24): - AIF predicate = custom `aif:goodTenorOf` (DeclareObjectProperty), NOT a skos:*Match token. The Virtue AIF_skosMappingType column holds the FR-prose critical question, not a skos enum token, so the Fallacies switch over AIFSkosMappingType cannot fire (design adaptation 1). The prose is carried as an rdfs:comment annotation. - The AIF namespace already exists in the Fallacies pass (ExternalReferenceOntologyNamespaceURI = http://www.arg.dundee.ac.uk/aif#) — no new namespace introduced; aif:goodTenorOf resolves in the Dundee AIF ontology. - Cross-corpus Virtue↔Fallacy links (crossLink_Opposes PK→URI resolution) DEFERRED to Phase 3. Resolving Fallacy PKs requires loading the Fallacies corpus (concept URIs derive from GetId(TextEn), not PK) — new architecture beyond this single-dataset pass. This pass is strictly mono-corpus Virtues. Wiring (AssetConverterConfig.cs): - new VirtueOwlGeneratorConfig property (instantiated, default Enabled=true). - invoked in the OwlGenerator mode block (both sync + async branches), parallel to OwlGeneratorConfig.Apply. Tests (+5 in VirtueOwlGenerationContractTests): GetId mirrors the Fallacies IRI transform (byte-identical, asserted on the same proven inputs A-B/A, B/Appel à l'autorité); generator defaults lock the ontology identity (document name / VirtuesTaxonomy dataset / namespace / AIF namespace); aif:goodTenorOf URI construction pinned for Phase 3 reuse. Verified: build 0 errors, 0 new warnings; suite 535 → 540 passed / 0 failed / 5 skipped. 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>
jsboige
added a commit
that referenced
this pull request
Jun 28, 2026
…ster, #601 guardrail) (#604) Add VirtueMindMapFRFrozenCharacterizationTests — a Golden-Master suite pinning the CURRENT behaviour that Virtues mind map node text renders French for all 8 release languages (Fallacies are localized 8-lang, pinned by MindMapLocalizationRegressionTests). This is an executable snapshot of the 2-layer gap traced in investigation #601 (merged 71033f8), NOT a regression test of desired behaviour: - Layer B (config): the single Virtue-targeting MindMapLocalization entry is a stale stub that only rewrites the tree-root literal "Vertus", for 4 of 7 target languages (en/ru/pt/es; ar/fa/zh absent). - Layer A (entity): Virtue exposes no TitleAr/TitleFa/TitleZh (CSV columns from #590/#595 exist but are invisible to the mind map), and Virtue.Text hard- delegates to TitleFr. Three guardrail sections, each GREEN today and expected to FAIL when the 3-step fix documented in #601 lands (entity ar/fa/zh props + {item.TitleFr} expression + mirrored config table). At that point flip the assertions to the localized expectation rather than deleting them — the failure is the signal the gap closed. The test-writing process surfaced a precision my investigation missed: nameof(VirtueMindMapDocumentConfig.TitleExpression) returns the bare "TitleExpression", which is SHARED with the Fallacy text entry — so the entry must be located by its unique "Vertus" conversion, not by nameof (documented in the helper XML doc). Additive only: no production code or existing test modified. 0 write under Cards/ (release freeze). Dispatch ai-01 2026-06-27 primary (characterization test, GO). Co-authored-by: Your <your.email@example.com> Co-authored-by: Claude-Code <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
#499 Phase 1 — prod-write: append 12 relational/AIF columns to the Virtues prod CSV (
Cards/Fallacies/Argumentum Virtues - Taxonomy.csv, 66 → 78 cols), populated from the 12 validated annotation CSVs indocs/taxonomy/(joined byvirtue_pk == pk).De-gated by jsboige (interactive 2026-06-23, "GO" on
docs/taxonomy/499-virtues-parity-closure.md); dispatched by ai-01 as Phase 1 of the #499 deep-queue. Data-only (the OWL code propagation = Phase 2, separate PR).Ground-truth re-verified on current master
f432455e(spec #580 claims held exactly)virtue_pk/ dupspk=0taxonomy root — correctly left out)The 12 columns (verbatim Fallacies names, appended after
link_facol 66)crossLink_Opposes(Fallacy PK semicolon-list),AIF_skosDirectRef(Walton scheme label),AIF_skosMappingType(FR prose critical question).pk=0(root) left empty.Additive proof (the critical invariant)
Existing 66 columns are byte-identical before/after — 0 value drift across 223 × 66 = 14 518 cells. The write is a line-append (12 new cells per line); existing content untouched. Guard: the script aborts if raw CRLF-line count ≠ 223 (embedded-newline safety).
Verification
pk=0empty ✓crossLink_Opposes→ 0 dangling (all resolve in the Fallacies corpusPKcolumn) ✓crossLink_Opposes=[681;690],AIF_skosDirectRef=[Argument from Sign],AIF_skosMappingType=[Les résultats sont-ils correctement calculés, reproductibles et cohérents… ?](FR prose comma correctly quoted) ✓git diff --stat: 224 ins / 224 del (every line gets 12 cols appended; existing cells unchanged within each line) ✓Phase 2 (separate code PR — NOT this one)
ArgumentVirtueClassMapmapping of the 12 new columns +OwlAdapterVirtues pass (currently Fallacies-only). No code changed in Phase 1.🤖 Worker po-2024 · #499 Phase 1 prod-write · 12 additive cols (3 populated ×222) · additive-proof 0 drift · crossLink 0 dangling · 533 tests pass · Phase 2 (OWL code) next