Outcome

outcome-MITIGATED — strict kill-condition clause 2 met (“annotation lost in any codegen step” — gen-typescript + gen-json-schema drop annotations entirely); spirit kill-condition clause 3 NOT met (Catala scope-binding works end-to-end via YAML-direct shim). 3-of-5 validation layers PASS / 2-of-5 FAIL. Functional path validated.

Key findings

  • 5-layer validation table summary:

    • LAYER 1 LinkML YAML annotation authoring — PASS (annotations: + extensions: blocks both syntactically supported)
    • LAYER 2 gen-pydantic --meta fullPASS (annotations preserved class-level via linkml_meta: ClassVar[LinkMLMeta] + attribute-level via Field.json_schema_extra['linkml_meta']['annotations']; PensionAsset.linkml_meta.root['annotations'] returns full dict at runtime)
    • LAYER 3 gen-typescriptFAIL (annotations dropped entirely; tested 4 alternatives --metadata/--no-metadata/--include-induced-slots/extensions:-block — all identical output; only description: survives as JSDoc)
    • LAYER 4 gen-json-schemaFAIL (annotations dropped entirely; only description: survives)
    • LAYER 5 Catala-via-shim — PASS (YAML-direct scope_binding_shim.py filters classes by inherit:phase_activation_status + inherit:phase_activation_target_phase; scope_binding_emitter.py emits per-phase .catala_en files; catala 1.1.0 typecheck --no-stdlib succeeds for both phase-1 + phase-1.5+ emissions)
  • The architecturally-correct working configuration (per post-S2.5 enriched alternatives-first discipline; 5 alternatives surfaced before settling): YAML-as-canonical metadata carrier + gen-pydantic --meta full for runtime + Python shim for Catala scope-binding. TS + JSON-Schema annotation-drop is deliberate LinkML 1.10 separation between annotation-bearing surfaces (YAML, Pydantic — for metadata + tooling) and data-validation surfaces (TS, JSON Schema — for runtime data shape). Not a defect; a design choice.

  • OntoUML standards-track narrative PRESERVED — fallback (collapse to plain boolean slot_usage: { active: false }) NOT NEEDED. ε.ι Layer 2 holds at lock-time without the standards-track-collapse penalty.

  • Plan defect noted: plan §2 Task 3 Step 3’s --include-annotations=True flag does NOT exist in LinkML 1.10.0 gen-pydantic. Real flag is --meta full. Plan v1.3 patch candidate at Phase E Task 13 lock-time.

  • Year-2+ uplift candidates (lands at lock-time only):

    1. Sidecar *.metadata.json via ~10-line Python shim if browser-side OntoUML metadata access becomes load-bearing
    2. LinkML 1.11.x/2.0 upgrade if it adds custom-annotation propagation to non-Python codegens
  • NEW richard-task candidate (logged in T-file §5; will land formally at Phase E Task 13 lock-time): extend frontmatter pin-drift hook at ~/testatetech/scripts/check-frontmatter-pins.py to validate annotations: block schema (e.g. require inherit:phase_activation_status{active, deferred, retired} + inherit:phase_activation_target_phase ∈ enumeration).

  • Methodological pattern: post-S2.5 alternatives-first discipline successfully applied — surfaced 5 alternatives (--meta full, --metadata/--no-metadata/--include-induced-slots, extensions:-block, --no-stdlib for Catala) before settling on architecturally-correct path. Unlike S2 → S2.5 where a follow-up spike was needed, S3 settles in-spike because YAML-as-canonical IS the architecturally-correct pattern, not a stopgap.

  • Codification candidate feedback_kill_condition_strict_vs_spirit_reading_via_outcome_MITIGATED: maturity vocabulary outcome-MITIGATED correctly handles the strict-vs-spirit kill-condition reading — strict says “any clause met → KILL”; spirit asks “does the functional purpose work?” — and the maturity tag carries that distinction without forcing a binary KILL/VALIDATED choice.

Cross-references

  • T-file: ~/off-github/library/projects/inherit/T-spike-eps-iota-S3-ontouml-linkml-2026-05-02.md (off-repo; not in git)
  • arch-state row: inherit-v2-architecture-state.md v3.19 §11 + Changelog v3.19 row
  • Q-003 row: 2026-04-29-multi-phase-audit/answered-questions/Q-003-zeta-asset-taxonomy-CCO-BFO-rooted-9-classes-locked.md v1.4 §10
  • Plan: docs-strategy/docs/superpowers/plans/2026-05-02-zeta-q3-eps-iota-derisking-spikes.md §2 Task 3
  • Sibling spikes: S1 VALIDATED (v6.6 SEED audit), S2 MITIGATED (schema-automator broken), S2.5 VALIDATED (owlready2 rescue Layer 1)

Phase-2 status post-spike

ε.ι 10-spike suite: 3 of 10 spikes complete (S1 VALIDATED + S2 MITIGATED → S2.5 VALIDATED + S3 MITIGATED). 7 remaining: S4 UK&W NRB pipeline / S5 FIBO SSSOM / S6 AM-CDM precedent / S7 Mondo precedent / S8 Catala HMRC golden / S9 OntoGPT F1 (likely subsumed by S4) / S10 partner conversation Mon 11 May. ε.ι lockable signal: net positive — 4 spikes done, all confirm or strengthen ε.ι Layer 1 + Layer 2 viability without need for fallback collapses.

  • feedback_universal_production_pipeline_sequence — Rich-directive 2026-05-02 BST canonical 3-layer SEED→LLM-REFINE→partner-REVIEW
  • project_zeta_q3_eps_iota_S1_2026_05_02 — sibling S1 VALIDATED outcome
  • project_zeta_q3_eps_iota_S2_2026_05_02 — sibling S2 MITIGATED (schema-automator broken)
  • project_zeta_q3_eps_iota_S2_5_owlready2_rescue_2026_05_02 — sibling S2.5 VALIDATED (owlready2 rescue; established alternatives-first discipline that S3 followed)
  • feedback_iri_verification_before_lock — discipline applied (OntoUML stereotype IRIs verified at w3id.org/ontouml/ namespace)
  • feedback_actively_use_t_files_in_scorecard_authoring — verbatim error excerpts captured in T-file §2
  • feedback_bold_front_loaded_synthesis_preference — applied to verdict reasoning (kill-condition strict-vs-spirit; refused to collapse OntoUML to fallback boolean)