uofa 0.7.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. uofa-0.7.0.dist-info/METADATA +731 -0
  2. uofa-0.7.0.dist-info/RECORD +166 -0
  3. uofa-0.7.0.dist-info/WHEEL +4 -0
  4. uofa-0.7.0.dist-info/entry_points.txt +2 -0
  5. uofa-0.7.0.dist-info/licenses/LICENSE +202 -0
  6. uofa-0.7.0.dist-info/licenses/NOTICE +36 -0
  7. uofa_cli/__init__.py +19 -0
  8. uofa_cli/__main__.py +7 -0
  9. uofa_cli/_data/fixtures/demo/manifest.json +19 -0
  10. uofa_cli/_data/fixtures/demo/passage.txt +13 -0
  11. uofa_cli/_data/fixtures/demo/uofa-demo-cou1.jsonld +33 -0
  12. uofa_cli/_data/fixtures/verify/expected.json +40 -0
  13. uofa_cli/_data/fixtures/verify/passage.txt +9 -0
  14. uofa_cli/_data/repo/keys/research.pub +3 -0
  15. uofa_cli/_data/repo/packs/README.md +214 -0
  16. uofa_cli/_data/repo/packs/core/pack.json +14 -0
  17. uofa_cli/_data/repo/packs/core/rules/uofa_weakener.rules +645 -0
  18. uofa_cli/_data/repo/packs/core/shapes/uofa_shacl.ttl +519 -0
  19. uofa_cli/_data/repo/packs/core/source_taxonomies.json +215 -0
  20. uofa_cli/_data/repo/packs/core/templates/uofa-complete-skeleton.jsonld +102 -0
  21. uofa_cli/_data/repo/packs/core/templates/uofa-minimal-skeleton.jsonld +32 -0
  22. uofa_cli/_data/repo/packs/core/templates/uofa-template.xlsx +0 -0
  23. uofa_cli/_data/repo/packs/nasa-7009b/examples/aerospace/aero-evidence-cou1.zip +0 -0
  24. uofa_cli/_data/repo/packs/nasa-7009b/examples/aerospace/aero-evidence-cou2.zip +0 -0
  25. uofa_cli/_data/repo/packs/nasa-7009b/examples/aerospace/uofa-aero-cou1-nasa7009b.jsonld +337 -0
  26. uofa_cli/_data/repo/packs/nasa-7009b/examples/aerospace/uofa-aero-cou2-nasa7009b.jsonld +386 -0
  27. uofa_cli/_data/repo/packs/nasa-7009b/examples/starters/uofa-aero-fatigue-minimal.jsonld +33 -0
  28. uofa_cli/_data/repo/packs/nasa-7009b/examples/starters/uofa-aero-hpt-blade-thermal-gaps.xlsx +0 -0
  29. uofa_cli/_data/repo/packs/nasa-7009b/pack.json +14 -0
  30. uofa_cli/_data/repo/packs/nasa-7009b/prompts/nasa_7009b_extract_prompt.txt +161 -0
  31. uofa_cli/_data/repo/packs/nasa-7009b/rules/nasa_7009b_weakener.rules +133 -0
  32. uofa_cli/_data/repo/packs/nasa-7009b/shapes/nasa_7009b_shapes.ttl +79 -0
  33. uofa_cli/_data/repo/packs/nasa-7009b/templates/nasa-7009b-template.xlsx +0 -0
  34. uofa_cli/_data/repo/packs/vv40/examples/morrison/cou1/uofa-morrison-cou1.jsonld +188 -0
  35. uofa_cli/_data/repo/packs/vv40/examples/morrison/cou2/uofa-morrison-cou2.jsonld +280 -0
  36. uofa_cli/_data/repo/packs/vv40/examples/morrison/slide-assets/cou1-cou2-diff-report-screenshot.png +0 -0
  37. uofa_cli/_data/repo/packs/vv40/examples/morrison/slide-assets/cou1-cou2-diff-report.txt +70 -0
  38. uofa_cli/_data/repo/packs/vv40/examples/morrison/slide-assets/cou1-weakener-report-screenshot.png +0 -0
  39. uofa_cli/_data/repo/packs/vv40/examples/morrison/slide-assets/cou1-weakener-report.txt +58 -0
  40. uofa_cli/_data/repo/packs/vv40/examples/morrison/slide-assets/cou2-weakener-report-screenshot.png +0 -0
  41. uofa_cli/_data/repo/packs/vv40/examples/morrison/slide-assets/cou2-weakener-report.txt +35 -0
  42. uofa_cli/_data/repo/packs/vv40/examples/nagaraja/cou1/uofa-nagaraja-cou1.jsonld +229 -0
  43. uofa_cli/_data/repo/packs/vv40/examples/starters/uofa-structural-bridge-minimal.jsonld +33 -0
  44. uofa_cli/_data/repo/packs/vv40/pack.json +14 -0
  45. uofa_cli/_data/repo/packs/vv40/prompts/vv40_extract_prompt.txt +127 -0
  46. uofa_cli/_data/repo/packs/vv40/shapes/vv40_shapes.ttl +69 -0
  47. uofa_cli/_data/repo/packs/vv40/templates/uofa-starter-filled.xlsx +0 -0
  48. uofa_cli/_data/repo/packs/vv40/templates/vv40-template.xlsx +0 -0
  49. uofa_cli/_data/repo/spec/README.md +24 -0
  50. uofa_cli/_data/repo/spec/context/v0.1.jsonld +73 -0
  51. uofa_cli/_data/repo/spec/context/v0.2.jsonld +87 -0
  52. uofa_cli/_data/repo/spec/context/v0.3.jsonld +276 -0
  53. uofa_cli/_data/repo/spec/context/v0.4.jsonld +346 -0
  54. uofa_cli/_data/repo/spec/context/v0.5.jsonld +412 -0
  55. uofa_cli/_data/repo/spec/schemas/uofa.schema.json +568 -0
  56. uofa_cli/_data/repo/spec/schemas/uofa_shacl.ttl +519 -0
  57. uofa_cli/_engine/.gitkeep +0 -0
  58. uofa_cli/_engine/uofa-weakener-engine-0.1.0.jar +0 -0
  59. uofa_cli/adversarial/__init__.py +13 -0
  60. uofa_cli/adversarial/circularity.py +131 -0
  61. uofa_cli/adversarial/classifier.py +859 -0
  62. uofa_cli/adversarial/generator.py +863 -0
  63. uofa_cli/adversarial/hash_utils.py +37 -0
  64. uofa_cli/adversarial/model_costs.py +32 -0
  65. uofa_cli/adversarial/prep_review.py +405 -0
  66. uofa_cli/adversarial/prompts/__init__.py +214 -0
  67. uofa_cli/adversarial/prompts/aleatory.py +142 -0
  68. uofa_cli/adversarial/prompts/base.py +234 -0
  69. uofa_cli/adversarial/prompts/clarissa_machinery.py +156 -0
  70. uofa_cli/adversarial/prompts/compound.py +152 -0
  71. uofa_cli/adversarial/prompts/consistency.py +324 -0
  72. uofa_cli/adversarial/prompts/contextual.py +241 -0
  73. uofa_cli/adversarial/prompts/d1_undermining.py +81 -0
  74. uofa_cli/adversarial/prompts/d2_rebutting.py +80 -0
  75. uofa_cli/adversarial/prompts/d3_undercutting_inference.py +268 -0
  76. uofa_cli/adversarial/prompts/d3_undercutting_model.py +89 -0
  77. uofa_cli/adversarial/prompts/epistemic.py +275 -0
  78. uofa_cli/adversarial/prompts/evidence_validity.py +278 -0
  79. uofa_cli/adversarial/prompts/logical_fallacies.py +147 -0
  80. uofa_cli/adversarial/prompts/multi_target.py +186 -0
  81. uofa_cli/adversarial/prompts/negative_controls.py +343 -0
  82. uofa_cli/adversarial/prompts/ontological.py +145 -0
  83. uofa_cli/adversarial/prompts/paraphrase.py +98 -0
  84. uofa_cli/adversarial/prompts/provenance.py +84 -0
  85. uofa_cli/adversarial/prompts/requirements_engineering.py +198 -0
  86. uofa_cli/adversarial/prompts/structural.py +129 -0
  87. uofa_cli/adversarial/reporter.py +528 -0
  88. uofa_cli/adversarial/runner.py +568 -0
  89. uofa_cli/adversarial/skeleton.py +416 -0
  90. uofa_cli/adversarial/spec_loader.py +594 -0
  91. uofa_cli/adversarial/tool_schema.py +288 -0
  92. uofa_cli/cli.py +141 -0
  93. uofa_cli/commands/__init__.py +1 -0
  94. uofa_cli/commands/adversarial.py +208 -0
  95. uofa_cli/commands/catalog.py +135 -0
  96. uofa_cli/commands/check.py +311 -0
  97. uofa_cli/commands/demo.py +157 -0
  98. uofa_cli/commands/diff.py +470 -0
  99. uofa_cli/commands/explain.py +253 -0
  100. uofa_cli/commands/extract_cmd.py +273 -0
  101. uofa_cli/commands/import_excel.py +145 -0
  102. uofa_cli/commands/init.py +231 -0
  103. uofa_cli/commands/keygen.py +23 -0
  104. uofa_cli/commands/migrate.py +79 -0
  105. uofa_cli/commands/packs.py +105 -0
  106. uofa_cli/commands/rules.py +612 -0
  107. uofa_cli/commands/schema.py +695 -0
  108. uofa_cli/commands/setup.py +293 -0
  109. uofa_cli/commands/shacl.py +134 -0
  110. uofa_cli/commands/sign.py +66 -0
  111. uofa_cli/commands/validate.py +126 -0
  112. uofa_cli/commands/verify.py +118 -0
  113. uofa_cli/document_reader.py +206 -0
  114. uofa_cli/eval_scoring.py +104 -0
  115. uofa_cli/excel_constants.py +171 -0
  116. uofa_cli/excel_mapper.py +270 -0
  117. uofa_cli/excel_reader.py +536 -0
  118. uofa_cli/excel_writer.py +352 -0
  119. uofa_cli/explain.py +58 -0
  120. uofa_cli/integrity.py +167 -0
  121. uofa_cli/interpretation/__init__.py +122 -0
  122. uofa_cli/interpretation/cache.py +221 -0
  123. uofa_cli/interpretation/cli.py +164 -0
  124. uofa_cli/interpretation/context.py +497 -0
  125. uofa_cli/interpretation/degrade.py +245 -0
  126. uofa_cli/interpretation/dispatcher.py +126 -0
  127. uofa_cli/interpretation/envelope.py +150 -0
  128. uofa_cli/interpretation/formatters.py +431 -0
  129. uofa_cli/interpretation/functions/__init__.py +27 -0
  130. uofa_cli/interpretation/functions/contextualize.py +149 -0
  131. uofa_cli/interpretation/functions/cross.py +149 -0
  132. uofa_cli/interpretation/functions/explain.py +486 -0
  133. uofa_cli/interpretation/functions/group.py +254 -0
  134. uofa_cli/interpretation/functions/narrative.py +168 -0
  135. uofa_cli/interpretation/pipeline.py +294 -0
  136. uofa_cli/interpretation/templates/diff/explain.jinja2 +91 -0
  137. uofa_cli/interpretation/templates/rules/contextualize.jinja2 +80 -0
  138. uofa_cli/interpretation/templates/rules/cross.jinja2 +85 -0
  139. uofa_cli/interpretation/templates/rules/explain.jinja2 +164 -0
  140. uofa_cli/interpretation/templates/rules/group.jinja2 +88 -0
  141. uofa_cli/interpretation/templates/rules/narrative.jinja2 +70 -0
  142. uofa_cli/interpretation/templates/shacl/contextualize.jinja2 +64 -0
  143. uofa_cli/interpretation/templates/shacl/explain.jinja2 +77 -0
  144. uofa_cli/interpretation/templates/shacl/group.jinja2 +73 -0
  145. uofa_cli/interpretation/templates.py +112 -0
  146. uofa_cli/llm/__init__.py +103 -0
  147. uofa_cli/llm/backend.py +156 -0
  148. uofa_cli/llm/config.py +287 -0
  149. uofa_cli/llm/errors.py +97 -0
  150. uofa_cli/llm/litellm_backend.py +551 -0
  151. uofa_cli/llm/mock_backend.py +129 -0
  152. uofa_cli/llm_extractor.py +621 -0
  153. uofa_cli/output.py +193 -0
  154. uofa_cli/paths.py +371 -0
  155. uofa_cli/readers/__init__.py +3 -0
  156. uofa_cli/readers/csv_reader.py +78 -0
  157. uofa_cli/readers/docx_reader.py +62 -0
  158. uofa_cli/readers/pdf_reader.py +46 -0
  159. uofa_cli/readers/text_reader.py +41 -0
  160. uofa_cli/readers/xlsx_reader.py +104 -0
  161. uofa_cli/setup_bundle.py +359 -0
  162. uofa_cli/setup_install.py +398 -0
  163. uofa_cli/setup_state.py +231 -0
  164. uofa_cli/setup_uninstall.py +114 -0
  165. uofa_cli/setup_verify.py +195 -0
  166. uofa_cli/shacl_friendly.py +246 -0
@@ -0,0 +1,731 @@
1
+ Metadata-Version: 2.4
2
+ Name: uofa
3
+ Version: 0.7.0
4
+ Summary: CLI for creating, validating, and signing Unit of Assurance evidence packages for computational modeling and simulation credibility
5
+ Project-URL: Homepage, https://crediblesimulation.com
6
+ Project-URL: Repository, https://github.com/cloudronin/uofa
7
+ Project-URL: Documentation, https://github.com/cloudronin/uofa/blob/main/docs/onboarding.md
8
+ Project-URL: Issues, https://github.com/cloudronin/uofa/issues
9
+ Author: Vishnu Viswanathan
10
+ License-Expression: Apache-2.0
11
+ License-File: LICENSE
12
+ License-File: NOTICE
13
+ Keywords: computational-modeling,credibility,digital-signature,evidence-packaging,json-ld,shacl,simulation,validation,verification,vv40
14
+ Classifier: Development Status :: 3 - Alpha
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Intended Audience :: Science/Research
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Topic :: Scientific/Engineering
23
+ Classifier: Topic :: Software Development :: Quality Assurance
24
+ Requires-Python: >=3.10
25
+ Requires-Dist: cryptography
26
+ Requires-Dist: pyshacl
27
+ Requires-Dist: rdflib
28
+ Requires-Dist: tomli; python_version < '3.11'
29
+ Provides-Extra: corpus
30
+ Requires-Dist: msoffcrypto-tool>=5.4.0; extra == 'corpus'
31
+ Requires-Dist: openpyxl>=3.1.0; extra == 'corpus'
32
+ Requires-Dist: reportlab>=4.0.0; extra == 'corpus'
33
+ Provides-Extra: excel
34
+ Requires-Dist: openpyxl; extra == 'excel'
35
+ Provides-Extra: export
36
+ Requires-Dist: weasyprint>=60; extra == 'export'
37
+ Provides-Extra: extract
38
+ Requires-Dist: chardet>=5.0.0; extra == 'extract'
39
+ Requires-Dist: jinja2>=3.1; extra == 'extract'
40
+ Requires-Dist: litellm>=1.30.0; extra == 'extract'
41
+ Requires-Dist: openpyxl>=3.1.0; extra == 'extract'
42
+ Requires-Dist: pdfplumber>=0.10.0; extra == 'extract'
43
+ Requires-Dist: python-docx>=1.1.0; extra == 'extract'
44
+ Requires-Dist: pyyaml>=6.0; extra == 'extract'
45
+ Requires-Dist: requests>=2.31; extra == 'extract'
46
+ Provides-Extra: test
47
+ Requires-Dist: pytest; extra == 'test'
48
+ Description-Content-Type: text/markdown
49
+
50
+ # Unit of Assurance (UofA) — v0.5.2
51
+
52
+ ![validate examples](https://github.com/cloudronin/uofa/actions/workflows/validate.yml/badge.svg)
53
+ [![License: Apache 2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
54
+
55
+ The **Unit of Assurance** is the smallest independently verifiable bundle of credibility evidence for computational modeling and simulation (CM&S). It packages the **credibility decision** — who judged what, against what criteria, using what evidence, with what result — as a signed, provenance-linked, machine-verifiable engineering artifact.
56
+
57
+ ## Conference Attendees: Run the 30-Second Demo
58
+
59
+ ```bash
60
+ pip install uofa
61
+ uofa demo
62
+ ```
63
+
64
+ The bundled fixture exercises the full C1 (signature + integrity) +
65
+ C2 (SHACL) + C3 (Jena rule engine) pipeline against a small pre-computed
66
+ UofA artifact — no Java install, no LLM runtime, no internet required.
67
+ Use it to verify "yes, this tool actually does what the speaker claimed"
68
+ in under a minute.
69
+
70
+ When you're ready to encode your own evidence, see the Quick Start below.
71
+
72
+ ## Quick Start: Create Your Own UofA
73
+
74
+ [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/cloudronin/uofa?quickstart=1)
75
+
76
+ **No install required** — click the button above to open a ready-to-use environment with Python, Java, and the `uofa` CLI pre-installed.
77
+
78
+ Or run locally:
79
+
80
+ ```bash
81
+ # 1. Install the uofa CLI (one command — bundles Python deps, the rule
82
+ # engine JAR, and an OpenJDK 17 JRE inside the wheel; no Java or Maven
83
+ # install required).
84
+ pip install uofa
85
+
86
+ # 2. Import from Excel (fastest on-ramp for practitioners)
87
+ uofa import my-assessment.xlsx --sign --key keys/research.key --check
88
+
89
+ # — OR — scaffold from a JSON-LD template
90
+ uofa init my-project
91
+ # Edit my-project/my-project-cou1.jsonld — fill in your project details
92
+ uofa sign my-project/my-project-cou1.jsonld --key my-project/keys/my-project.key
93
+ uofa check my-project/my-project-cou1.jsonld
94
+ ```
95
+
96
+ Platform wheels are published for macOS (arm64 + x86_64), Linux (x86_64 +
97
+ aarch64), and Windows (x86_64). The `uofa[extract]` extra adds the LLM-
98
+ backed prose-to-UofA pipeline; see `uofa setup --help` for one-time runtime
99
+ installation.
100
+
101
+ **New to UofA?** See the [Onboarding Guide](docs/onboarding.md) for a step-by-step walkthrough, or study the [Morrison demo](#live-demo-morrison-blood-pump-fda-vv-40-case-study) below.
102
+
103
+ ---
104
+
105
+ ## Why UofA?
106
+
107
+ UofA exists because the credibility frameworks are not the problem. ASME V&V 40, NASA-STD-7009B, and the FDA's 2023 guidance on CM&S credibility provide clear instructions for *how to assess* simulation credibility. The problem is the **last mile**: there is no standardized construct for packaging, transmitting, and verifying the *evidence and decisions* those assessments produce.
108
+
109
+ The result is predictable. Credibility decisions live in prose PDFs. Evidence is scattered across tools. Provenance is partial. Audit packaging is manual. And reviewers catch quality gaps by intuition rather than automation.
110
+
111
+ UofA addresses this through three contributions:
112
+
113
+ | Contribution | What it does | Mechanism |
114
+ |---|---|---|
115
+ | **C1 — Decision as artifact** | Captures the credibility decision as a portable, tool-independent object with provenance lineage and integrity guarantees | JSON-LD + PROV-DM + SHA-256 hash + ed25519 digital signatures |
116
+ | **C2 — Completeness enforcement** | Defines what a UofA must contain at each rigor level and enforces it as a computable constraint | SHACL profiles (Minimal / Complete) with format-validated integrity fields |
117
+ | **C3 — Quality gates** | Detects substantive credibility gaps — missing UQ, orphan claims, acceptance criteria gaps — including compound risks that no individual query can find | Jena forward-chaining rule engine with compound inference |
118
+
119
+ ---
120
+
121
+ ## Live Demo: Morrison Blood Pump (FDA V&V 40 Case Study)
122
+
123
+ The `packs/vv40/examples/morrison/` directory contains complete, working UofA evidence packages built from [Morrison et al. (2019)](https://doi.org/10.1097/MAT.0000000000000996) — an FDA OSEL co-authored V&V 40 credibility assessment for a centrifugal blood pump. This is the most widely cited V&V 40 worked example.
124
+
125
+ **What the demo shows:**
126
+
127
+ ```
128
+ Morrison prose assessment → UofA structured evidence package
129
+ "model deemed credible" JSON-LD with 13 V&V 40 factors,
130
+ scattered across 10 pages provenance chain, integrity hash,
131
+ of journal article machine-verifiable in 30 seconds
132
+ ```
133
+
134
+ **Run it yourself:**
135
+
136
+ ```bash
137
+ pip install uofa # bundles the rule engine JAR + an OpenJDK 17 JRE
138
+
139
+ # Run the full C1 + C2 + C3 pipeline in one command
140
+ uofa check packs/vv40/examples/morrison/cou1/uofa-morrison-cou1.jsonld
141
+ ```
142
+
143
+ That single command runs three checks:
144
+
145
+ | Step | Command | What it does |
146
+ |---|---|---|
147
+ | C2 | `uofa shacl FILE` | SHACL Complete profile validation — all required fields present |
148
+ | C1 | `uofa verify FILE` | SHA-256 hash + ed25519 signature verification — content untampered |
149
+ | C3 | `uofa rules FILE` | Jena rule engine — 23 forward-chaining rules (21 core + 2 compound) detect quality gaps |
150
+
151
+ The bundled JAR + JRE inside the wheel mean no Maven, no separate Java
152
+ install, and no `--build` flag is needed. Source-tree contributors can
153
+ still build the JAR via `cd src/weakener-engine && mvn package` and run from
154
+ their own checkout — the bundled JRE only activates inside an installed
155
+ wheel.
156
+
157
+ **What the rule engine finds on Morrison COU1 at v0.5.2 (24 weakeners across 9 patterns):**
158
+
159
+ | Pattern | Severity | Hits | What it detects |
160
+ |---|---|---|---|
161
+ | W-EP-01 | Critical | 1 | Orphan claim — no evidence chain to supporting data |
162
+ | W-EP-02 | High | 3 | Broken provenance — validation results with no generation activity |
163
+ | W-AL-01 | High | 3 | Missing uncertainty quantification on validation results |
164
+ | W-AR-05 | High | 3 | Comparator absence — results not linked to reference entities |
165
+ | W-CON-01 | High | 6 | Accepted decision with factors lacking both requiredLevel and achievedLevel |
166
+ | W-CON-04 | Medium | 1 | Complete profile with no sensitivity analysis linked |
167
+ | W-ON-02 | High | 1 | COU lacks both applicability constraint and operating envelope |
168
+ | ⚡ COMPOUND-01 | Critical | 5 | Risk escalation — Critical + High weakeners coexist on same UofA |
169
+ | ⚡ COMPOUND-03 | High | 1 | Assurance level override — declared "Medium" but Critical gaps exist |
170
+
171
+ The v0.5.2 catalog includes 23 core weakener patterns spanning epistemic, aleatoric, ontological, structural, consistency, provenance, and argumentation categories. Run `uofa catalog` to list the full set. The Morrison COU1 example fires 9 of those 23 (7 Level-1 rules plus 2 compound rules).
172
+
173
+ The ⚡ compound rules fire on the output of the core rules — this is chained forward-chaining inference that standalone SPARQL queries cannot produce. Same model, same data, same rules: the rule engine reasons about the *interactions* between gaps, not just the gaps themselves.
174
+
175
+ ---
176
+
177
+ ## COU Divergence: `uofa diff`
178
+
179
+ Morrison contains two Contexts of Use assessing the same CFD model:
180
+
181
+ - **COU1** (CPB, Class II, Model Risk Level 2) → Decision: **Accepted**
182
+ - **COU2** (VAD, Class III, Model Risk Level 5) → Decision: **Not accepted**
183
+
184
+ Same model. Same experimental data. Different credibility requirements driven by different model risk. The `uofa diff` command surfaces this divergence automatically:
185
+
186
+ ```bash
187
+ uofa diff packs/vv40/examples/morrison/cou1/uofa-morrison-cou1.jsonld \
188
+ packs/vv40/examples/morrison/cou2/uofa-morrison-cou2.jsonld
189
+ ```
190
+
191
+ ```
192
+ ════════════════════════════════════════════════════════
193
+ COU Divergence Analysis
194
+ ════════════════════════════════════════════════════════
195
+
196
+ COU A COU B
197
+ Name COU1: Cardiopulmonary bypass use (Class II) COU2: Ventricular assist device use (Class III)
198
+ Device class Class II Class III
199
+ Model risk level MRL 2 MRL 5
200
+ Decision Accepted Not accepted
201
+ Assurance level Medium Low
202
+ Weakeners 9 6
203
+
204
+ ══ Weakener Patterns (10) ══
205
+ ┌────────────────────────────────────────────────────────────────┐
206
+ │ Pattern │ Severity │ COU A │ COU B │ Status │
207
+ ├──────────────┼────────────┼─────────┼─────────┼──────────────┤
208
+ │ W-AL-01 │ [High] │ ✓ │ ✗ │ ◆ divergent │
209
+ │ W-AL-02 │ [Medium] │ ✗ │ ✓ │ ◆ divergent │
210
+ │ W-AR-05 │ [High] │ ✓ │ ✗ │ ◆ divergent │
211
+ │ W-CON-01 │ [High] │ ✓ │ ✗ │ ◆ divergent │
212
+ │ W-CON-04 │ [Medium] │ ✓ │ ✓ │ same │
213
+ │ W-EP-01 │ [Critical] │ ✓ │ ✗ │ ◆ divergent │
214
+ │ W-EP-02 │ [High] │ ✓ │ ✗ │ ◆ divergent │
215
+ │ W-EP-04 │ [High] │ ✗ │ ✓ │ ◆ divergent │
216
+ │ W-ON-02 │ [High] │ ✓ │ ✓ │ same │
217
+ │ W-PROV-01 │ [Critical] │ ✗ │ ✓ │ ◆ divergent │
218
+ └──────────────┴────────────┴─────────┴─────────┴──────────────┘
219
+
220
+ ══ Compound Patterns (2) ══
221
+ ┌────────────────────────────────────────────────────────────────┐
222
+ │ Pattern │ Severity │ COU A │ COU B │ Status │
223
+ ├──────────────┼────────────┼─────────┼─────────┼──────────────┤
224
+ │ COMPOUND-01 │ [Critical] │ ✓ │ ✓ │ same │
225
+ │ COMPOUND-03 │ [High] │ ✓ │ ✗ │ ◆ divergent │
226
+ └──────────────┴────────────┴─────────┴─────────┴──────────────┘
227
+
228
+ ══ Summary ══
229
+ COU A (COU1: Cardiopulmonary bypass use (Class II)):
230
+ [Critical] 2
231
+ [High] 6
232
+ [Medium] 1
233
+ COU B (COU2: Ventricular assist device use (Class III)):
234
+ [Critical] 2
235
+ [High] 2
236
+ [Medium] 2
237
+
238
+ 9 divergence(s) detected
239
+
240
+ ══ Divergence Explanations ══
241
+
242
+ [High] COMPOUND-03 — only in COU A
243
+ COU1: Cardiopulmonary bypass use (Class II): Assurance level is not Low, yet Critical weakeners exist — stated assurance level may be overstated.
244
+ COU2: Ventricular assist device use (Class III): pattern does not fire.
245
+
246
+ [High] W-AL-01 — only in COU A
247
+ COU1: Cardiopulmonary bypass use (Class II): Validation result has no uncertainty quantification — aleatory uncertainty is uncharacterized.
248
+ COU2: Ventricular assist device use (Class III): pattern does not fire.
249
+
250
+ [High] W-AR-05 — only in COU A
251
+ COU1: Cardiopulmonary bypass use (Class II): Validation result has no comparedAgainst link — comparator data source is absent.
252
+ COU2: Ventricular assist device use (Class III): pattern does not fire.
253
+
254
+ [High] W-CON-01 — only in COU A
255
+ COU1: Cardiopulmonary bypass use (Class II): Decision is Accepted but a credibility factor has neither requiredLevel nor achievedLevel — the acceptance rests on an unestablished factor.
256
+ COU2: Ventricular assist device use (Class III): pattern does not fire.
257
+
258
+ [Critical] W-EP-01 — only in COU A
259
+ COU1: Cardiopulmonary bypass use (Class II): Claim has no prov:wasDerivedFrom link to evidence — provenance chain is broken.
260
+ COU2: Ventricular assist device use (Class III): pattern does not fire.
261
+
262
+ [High] W-EP-02 — only in COU A
263
+ COU1: Cardiopulmonary bypass use (Class II): Validation result has no prov:wasGeneratedBy — generation activity is missing.
264
+ COU2: Ventricular assist device use (Class III): pattern does not fire.
265
+
266
+ [Medium] W-AL-02 — only in COU B
267
+ COU2: Ventricular assist device use (Class III): Uncertainty quantification is reported but no sensitivity analysis is linked — the drivers of uncertainty are undocumented.
268
+ COU1: Cardiopulmonary bypass use (Class II): pattern does not fire.
269
+
270
+ [High] W-EP-04 — only in COU B
271
+ COU2: Ventricular assist device use (Class III): Credibility factor is not assessed but model risk level exceeds 2 — unassessed factors at elevated risk weaken the credibility argument.
272
+ COU1: Cardiopulmonary bypass use (Class II): pattern does not fire.
273
+
274
+ [Critical] W-PROV-01 — only in COU B
275
+ COU2: Ventricular assist device use (Class III): Provenance chain terminates at a node that has no upstream derivation/generation/use edge and is not marked uofa:isFoundationalEvidence=true — chain is incomplete.
276
+ COU1: Cardiopulmonary bypass use (Class II): pattern does not fire.
277
+ ```
278
+
279
+ The output has four sections: **identity block** (side-by-side COU metadata), **weakener profile table** (✓/✗ presence with divergence markers), **summary counts** (per-severity breakdown), and **divergence explanations** (from the `description` field on each WeakenerAnnotation — generated by the rule engine, not hardcoded in the diff command).
280
+
281
+ Compound patterns (COMPOUND-*) are separated into their own sub-table when present, since they fire on the output of Level 1 rules.
282
+
283
+ This divergence is invisible in the prose paper. It becomes machine-visible in the UofA. That's C1: the credibility *decision* — not just the evidence — captured as a first-class artifact.
284
+
285
+ ---
286
+
287
+ ## Live Demo: HPT Blade CHT (NASA-STD-7009B, Aerospace)
288
+
289
+ The `packs/nasa-7009b/examples/aerospace/` directory contains a parallel NASA-STD-7009B case study — an HPT turbine-blade conjugate heat transfer CFD model assessed for two operating points:
290
+
291
+ - **COU1** (take-off transient, MRL 3) → Decision: **Accepted with conditions**
292
+ - **COU2** (cruise steady-state, MRL 4) → Decision: **Not accepted**
293
+
294
+ Same CFD model, same cascade-rig validation data, re-purposed for a different operating regime — reproducing the Morrison divergence mechanism in aerospace. The bundles ship as zipped evidence folders (10 docs each — narrative DOCX, CFX solver settings, cascade CSVs, board minutes, decision rationale PDFs), so you can exercise the full `extract → import → rules` pipeline end-to-end on real input.
295
+
296
+ **End-to-end roundtrip on COU1:**
297
+
298
+ ```bash
299
+ # 1. Extract: LLM reads 10 evidence documents, produces a pre-filled 19-factor xlsx
300
+ uofa extract tests/fixtures/extract/aero-evidence-cou1 \
301
+ --pack nasa-7009b --model ollama/qwen3.5:4b -o /tmp/aero-cou1.xlsx
302
+
303
+ # 2. Import: convert the xlsx to signed JSON-LD
304
+ uofa import /tmp/aero-cou1.xlsx --pack nasa-7009b -o /tmp/aero-cou1.jsonld
305
+
306
+ # 3. Rules: run the Jena weakener engine, write the reasoned jsonld
307
+ uofa rules /tmp/aero-cou1.jsonld --pack nasa-7009b \
308
+ --format jsonld -o /tmp/aero-cou1-reasoned.jsonld --build
309
+ ```
310
+
311
+ The pack ships pre-computed reasoned outputs so you can skip to the interesting part:
312
+
313
+ ```bash
314
+ # COU1 (Accepted) — W-AR-02 fires on narrative-stated level gaps
315
+ uofa rules packs/nasa-7009b/examples/aerospace/uofa-aero-cou1-nasa7009b.jsonld --pack nasa-7009b
316
+
317
+ # COU2 (Not Accepted) — W-AR-02 stays at zero despite 4+ not-assessed factors
318
+ uofa rules packs/nasa-7009b/examples/aerospace/uofa-aero-cou2-nasa7009b.jsonld --pack nasa-7009b
319
+ ```
320
+
321
+ **The divergence:**
322
+
323
+ | Pattern | COU1 (Accepted) | COU2 (Not Accepted) |
324
+ |---|---|---|
325
+ | **W-AR-02** (accept-despite-gap) | **4 fires** on level gaps | **0 fires** (hard gate) |
326
+ | W-EP-04 (not-assessed at MRL>2) | 1 | 4 |
327
+ | COMPOUND-01 (Critical + High) | 6 | 5 |
328
+ | W-NASA-02/03/06 (missing evidence linkage) | 1 each | 1 each |
329
+ | Total weakeners | 17 | 20 |
330
+ | Distinct patterns | 9 | 8 |
331
+
332
+ **Why this matters:** W-AR-02 (the rebutting-defeater rule) fires *only* when a decision says `Accepted` AND any factor has `achievedLevel < requiredLevel`. Flipping the decision to `Not accepted` disarms every instance of this rule — even though COU2 actually has *more* credibility gaps than COU1. That's the C3 rule engine correctly modeling the argument: a not-accepted decision has no "contradictory result ignored" to defeat. The same mechanism is visible in Morrison; here it repeats in aerospace.
333
+
334
+ **Reproduce the accuracy numbers:**
335
+
336
+ ```bash
337
+ # Factor F1 + weakener gate scoring, logs to dev/tools/scripts/extract_accuracy_log.jsonl
338
+ python dev/tools/scripts/score_extraction.py --pack nasa-7009b --case cou1 \
339
+ --model ollama/qwen3.5:4b --prompt-version v3-nasa-aero
340
+ python dev/tools/scripts/score_extraction.py --pack nasa-7009b --case cou2 \
341
+ --model ollama/qwen3.5:4b --prompt-version v3-nasa-aero
342
+ ```
343
+
344
+ The scorer runs `extract → import → rules` end-to-end and asserts gates from `tests/fixtures/extract/ground_truth/aero-cou{1,2}-nasa7009b.json`. The hard gate for COU2 is `W-AR-02 count == 0`; if it ever fires, either the extracted decision outcome isn't `"Not accepted"` or the rule engine is mis-matching. Most recent live run: COU1 F1 = 0.97, COU2 F1 = 0.85, both weakener gates pass.
345
+
346
+ ---
347
+
348
+ ## Standards Alignment
349
+
350
+ UofA is grounded in existing standards rather than inventing new ones:
351
+
352
+ - **ASME V&V 40-2018** — Credibility factors, model risk framework, and the Context of Use (COU) concept that drives per-factor assessment
353
+ - **FDA 2023 Final Guidance on CM&S Credibility** — Regulatory expectations for credibility evidence in medical device submissions
354
+ - **NASA-STD-7009B** — CMS credibility assessment standard for models and simulations
355
+ - **W3C PROV-DM / PROV-O** — Provenance data model for artifact lineage
356
+ - **W3C SHACL** — Shapes Constraint Language for RDF graph validation
357
+ - **JSON-LD 1.1** — Linked data serialization that stays human-readable
358
+
359
+ ---
360
+
361
+ ## Integrity Verification
362
+
363
+ Every UofA carries a real cryptographic hash and digital signature — not placeholders.
364
+
365
+ | Level | What it checks | Mechanism |
366
+ |---|---|---|
367
+ | **Format gate** | Hash and signature are well-formed | SHACL `sh:pattern` regex on both Minimal and Complete profiles |
368
+ | **Content verification** | Hash matches the canonical document content | `uofa verify` recomputes SHA-256 from JSON canonical form |
369
+ | **Cryptographic signature** | Document was signed by the declared authority | ed25519 signature verification against the repo public key |
370
+
371
+ ```bash
372
+ # Mint a sealed UofA (sign after edits)
373
+ uofa sign packs/vv40/examples/morrison/cou1/uofa-morrison-cou1.jsonld --key keys/research.key
374
+
375
+ # Verify integrity
376
+ uofa verify packs/vv40/examples/morrison/cou1/uofa-morrison-cou1.jsonld
377
+ ```
378
+
379
+ Placeholder strings (e.g., `sha256:placeholder...`) now **fail** SHACL validation. This is deliberate — a UofA claiming ProfileComplete must carry a real hash.
380
+
381
+ ---
382
+
383
+ ## The Jena Rule Engine (C3)
384
+
385
+ Quality gap detection uses [Apache Jena](https://jena.apache.org/) forward-chaining rules, not just SPARQL queries. The rule engine operates in two levels:
386
+
387
+ **Level 1 — Core detection rules** (21 patterns in v0.5.2) match structural patterns against the evidence graph. Categories include epistemic (W-EP-*), aleatoric (W-AL-*), ontological (W-ON-*), structural (W-SI-*), consistency (W-CON-*), provenance (W-PROV-*), and argumentation (W-AR-*). Run `uofa catalog` for the full list with descriptions.
388
+
389
+ **Level 2 — Compound inference rules** (2 active in v0.5.2) fire on the output of Level 1 rules:
390
+
391
+ | Rule | What it detects |
392
+ |---|---|
393
+ | COMPOUND-01 | Critical + High weakeners coexist → escalated compound risk |
394
+ | COMPOUND-03 | Declared assurance level contradicts detected Critical gaps |
395
+
396
+ COMPOUND-02 ships in the rules file but is currently commented out pending v0.6 design review; `uofa catalog` filters it from listing output.
397
+
398
+ The compound rules are the key differentiator versus SPARQL. They reason about the *interactions* between gaps — something that requires chained forward-chaining inference. As of v0.5.2, all weakener rules (including previously Python-implemented W-CON-02, W-CON-05, W-PROV-01) evaluate in a single Jena forward-chaining pass, enabling compound rules to reason over the full weakener set.
399
+
400
+ ---
401
+
402
+ ## Plain-language explanations: `--explain` (v0.6.0)
403
+
404
+ `uofa rules`, `check`, `diff`, and `shacl` accept an `--explain` flag that
405
+ adds a plain-language interpretation block to the structured output. The
406
+ deterministic analysis remains the source of truth; the explanation is a
407
+ human-readable layer for regulatory affairs and validation engineers.
408
+
409
+ ```bash
410
+ uofa rules my-package.jsonld --explain
411
+ uofa rules my-package.jsonld --explain --explain-max-items 3
412
+ uofa rules my-package.jsonld --explain --explain-format json
413
+ ```
414
+
415
+ Default backend is bundled Ollama (qwen3.5:4b, local-only, free). For
416
+ higher quality or larger context, configure a remote backend in
417
+ `uofa.toml` or override per invocation:
418
+
419
+ ```bash
420
+ uofa rules my-package.jsonld --explain \
421
+ --explain-backend anthropic \
422
+ --explain-model claude-sonnet-5-2026
423
+ # requires ANTHROPIC_API_KEY in environment
424
+ ```
425
+
426
+ Results are cached at `~/.uofa/cache/explain.db` — a second invocation
427
+ on the same input completes in <100 ms. Standalone re-interpretation of
428
+ cached output: `uofa explain --from-file cache.json`.
429
+
430
+ Full documentation:
431
+
432
+ - **[docs/explain.md](docs/explain.md)** — usage, output formats, caching, limitations
433
+ - **[docs/llm-config.md](docs/llm-config.md)** — `[llm]` section, supported backends, precedence
434
+ - **[docs/security.md](docs/security.md)** — API key handling, threat model
435
+
436
+ ---
437
+
438
+ ## Profiles
439
+
440
+ UofA uses a two-tier profile system. **Minimal** captures the bare evidence package. **Complete** adds the full credibility assessment.
441
+
442
+ ### Minimal Profile
443
+
444
+ The minimum viable UofA. Suitable for evidence capture during live pipeline execution or as a lightweight audit artifact.
445
+
446
+ | Property | Type | Purpose |
447
+ |---|---|---|
448
+ | `bindsRequirement` | IRI | The requirement this UofA substantiates |
449
+ | `hasContextOfUse` | IRI | The V&V 40 Context of Use for this assessment |
450
+ | `hasValidationResult` | IRI | At least one validation result |
451
+ | `hasDecisionRecord` | IRI | The credibility decision (accepted/rejected + rationale) |
452
+ | `generatedAtTime` | xsd:dateTime | When this UofA was created |
453
+ | `hash` | string | Content hash (format-validated: `sha256:<64 hex chars>`) |
454
+ | `signature` | string | Digital signature (format-validated: `ed25519:<hex>`) |
455
+
456
+ ### Complete Profile
457
+
458
+ Extends Minimal with full V&V 40 credibility assessment, provenance chain, and quality metrics. Required for regulatory submissions and formal credibility arguments.
459
+
460
+ Everything in Minimal, plus:
461
+
462
+ | Property | Type | Purpose |
463
+ |---|---|---|
464
+ | `bindsModel` | IRI | The computational model assessed |
465
+ | `bindsDataset` | IRI | The dataset(s) used in validation |
466
+ | `wasDerivedFrom` | IRI | Provenance link to parent artifact |
467
+ | `wasAttributedTo` | IRI | Responsible actor or organization |
468
+ | `hasCredibilityFactor` | CredibilityFactor[] | Per-factor assessment (V&V 40 Table 5-1) |
469
+ | `hasWeakener` | WeakenerAnnotation[] | *(optional)* Detected quality gaps |
470
+ | `credibilityIndex` | xsd:decimal [0–1] | Overall credibility score |
471
+ | `traceCompleteness` | xsd:decimal [0–1] | Provenance chain completeness |
472
+ | `verificationCoverage` | xsd:decimal [0–1] | Verification evidence coverage |
473
+ | `validationCoverage` | xsd:decimal [0–1] | Validation evidence coverage |
474
+ | `uncertaintyCIWidth` | xsd:decimal [≥0] | Uncertainty confidence interval width |
475
+ | `assuranceLevel` | string | `Low` / `Medium` / `High` |
476
+ | `criteriaSet` | IRI | Reference criteria set (e.g., `ASME-VV40-2018`) |
477
+
478
+ ### CredibilityFactor
479
+
480
+ Each factor maps to one row in V&V 40 Table 5-1 or NASA-STD-7009B:
481
+
482
+ | Property | Constraint | Purpose |
483
+ |---|---|---|
484
+ | `factorType` | Factor name from the active pack's taxonomy | Which credibility factor is being assessed |
485
+ | `factorStandard` | String (e.g., `"ASME-VV40-2018"`, `"NASA-STD-7009B"`) | Which standard defines this factor |
486
+ | `assessmentPhase` | `"capability"` or `"results"` *(NASA-STD-7009B only)* | NASA CAS assessment phase |
487
+ | `requiredLevel` | Integer (1–5 for V&V 40, 0–4 for NASA-7009B) | Target credibility level for this COU |
488
+ | `achievedLevel` | Integer (1–5 for V&V 40, 0–4 for NASA-7009B) | Actual credibility level achieved |
489
+ | `hasEvidence` | IRI or IRI[] *(optional)* | Links to backing evidence entities |
490
+
491
+ ### WeakenerAnnotation
492
+
493
+ Quality gap annotations detected by the Jena rule engine (C3). Optional — a UofA with zero weakeners is valid (and desirable).
494
+
495
+ | Property | Constraint | Purpose |
496
+ |---|---|---|
497
+ | `patternId` | Format: `W-XX-NN` or `COMPOUND-NN` | Catalog ID from the weakener pattern taxonomy |
498
+ | `severity` | `Critical` / `High` / `Medium` / `Low` | Impact severity |
499
+ | `affectedNode` | IRI | The specific graph node flagged by this pattern |
500
+ | `description` | string *(optional)* | Human-readable explanation of why this weakener fires |
501
+
502
+ ---
503
+
504
+ ## Working with Your Own UofA
505
+
506
+ The `uofa` CLI provides commands for every step of the workflow:
507
+
508
+ ```bash
509
+ # Extract credibility data from evidence documents with an LLM (pre-fills a pack xlsx)
510
+ uofa extract path/to/evidence/ --pack nasa-7009b --model ollama/qwen3.5:4b -o out.xlsx
511
+
512
+ # Import from a practitioner-filled Excel workbook (fastest on-ramp)
513
+ uofa import assessment.xlsx --sign --key keys/your.key --check
514
+
515
+ # Full pipeline (C1 + C2 + C3) on your file
516
+ uofa check path/to/your-uofa.jsonld
517
+
518
+ # Individual steps
519
+ uofa shacl path/to/your-uofa.jsonld # C2: SHACL validation
520
+ uofa verify path/to/your-uofa.jsonld # C1: Hash + signature check
521
+ uofa rules path/to/your-uofa.jsonld # C3: Jena weakener detection (text summary)
522
+ uofa rules FILE --format jsonld -o reasoned.jsonld # C3: write reasoned JSON-LD with weakener annotations
523
+
524
+ # Sign with your own key
525
+ uofa sign path/to/your-uofa.jsonld --key keys/your.key
526
+
527
+ # Scaffold a new project from a JSON-LD template
528
+ uofa init my-new-project
529
+
530
+ # Validate all examples in the repo
531
+ uofa validate
532
+
533
+ # Compare weakener profiles across two COUs
534
+ uofa diff uofa-cou1.jsonld uofa-cou2.jsonld
535
+
536
+ # List installed domain packs
537
+ uofa packs
538
+
539
+ # Use a specific domain pack
540
+ uofa check path/to/your-uofa.jsonld --pack vv40
541
+
542
+ # Use multiple packs (e.g., V&V 40 + NASA-STD-7009B)
543
+ uofa check path/to/your-uofa.jsonld --pack vv40 --pack nasa-7009b
544
+
545
+ # Migrate a v0.3 file to v0.4
546
+ uofa migrate path/to/old-file.jsonld
547
+
548
+ # Generate import constants from SHACL (after schema changes)
549
+ uofa schema --emit python
550
+ ```
551
+
552
+ See the [Onboarding Guide](docs/onboarding.md) for a full walkthrough.
553
+
554
+ ---
555
+
556
+ ## Adversarial Generation (research instrument)
557
+
558
+ `uofa adversarial generate` synthesizes JSON-LD evidence packages that target specific weakener patterns, then validates them against SHACL. The tool is an **instrument** for empirically characterizing rule coverage — it feeds the methodology section of Chapter 3 and the September 2026 JVVUQ paper. Synthetic packages are flagged and refused by `uofa sign` and `uofa verify` so they can never be mistaken for real evidence.
559
+
560
+ ```bash
561
+ pip install -e '.[extract]' # one-time: adds litellm + pyyaml
562
+ export ANTHROPIC_API_KEY=sk-ant-... # generation defaults to claude-opus-4-7
563
+
564
+ # Generate 5 synthetic packages targeting W-AR-05 (comparator absence / mismatch)
565
+ uofa adversarial generate \
566
+ --spec dev/specs/confirm_existing/w_ar_05.yaml \
567
+ --out build/adversarial/w_ar_05/
568
+
569
+ # Dry-run: render the prompt without calling the LLM
570
+ uofa adversarial generate --spec dev/specs/confirm_existing/w_ar_05.yaml --out /tmp/dry --dry-run
571
+
572
+ # Run the full Phase 1 acceptance script
573
+ bash tests/adversarial/test_acceptance.sh
574
+ ```
575
+
576
+ Every generated package carries an `adversarialProvenance` block (spec id, prompt template version, generation model, timestamp, target weakener) and a `provenanceBlockHash` that `uofa verify` recomputes to detect tampering with the synthetic flag. `--strict-circularity` refuses to run when the generation model matches the configured extract model; `--allow-circular-model` is an explicit opt-in for debugging runs.
577
+
578
+ Spec file format and the full design are documented in [UofA_Adversarial_Gen_Spec_v1.1.md](../Requirements/UofA_Adversarial_Gen_Spec_v1.1.md). Phase 1 ships the W-AR-05 (D3 undercutting) template; the registry in `src/uofa_cli/adversarial/prompts/__init__.py` scales to additional weakener patterns by adding keys.
579
+
580
+ ---
581
+
582
+ ## Domain Packs
583
+
584
+ SHACL shapes, Jena rules, templates, and extraction prompts are organized into **domain packs** under `packs/`. The `core` pack ships with standards-agnostic credibility assessment rules (23 weakener patterns as of v0.5.2, up from 12 in v0.4). The `vv40` pack provides the ASME V&V 40-2018 factor taxonomy (13 factors), and the `nasa-7009b` pack provides the NASA-STD-7009B factor taxonomy (19 factors, including 6 NASA-only lifecycle factors).
585
+
586
+ ```bash
587
+ $ uofa packs
588
+ ════════════════════════════════════════════════════════
589
+ Installed packs
590
+ ════════════════════════════════════════════════════════
591
+ core v0.5.0 Core credibility assessment rules. Standards-agnostic. (any factors, 23 patterns) [always loaded]
592
+ nasa-7009b v0.5.0 NASA-STD-7009B credibility assessment factors (19 factors: 1... (19 factors, 6 patterns)
593
+ vv40 v0.5.0 ASME V&V 40-2018 credibility factor taxonomy (13 factors). (13 factors, 0 patterns) [active]
594
+ ```
595
+
596
+ The `--pack` flag on any command switches the active pack(s). Multiple packs can be specified to combine factor taxonomies and rules. The default is `--pack vv40` for backward compatibility. Per-project rules files next to the input file still take precedence over the pack default. See [`packs/README.md`](packs/README.md) for the full pack contract and instructions for creating domain packs.
597
+
598
+ ---
599
+
600
+ ## Excel Import: The Practitioner On-Ramp
601
+
602
+ Simulation engineers fill an Excel workbook, run one command, and get a signed, validated JSON-LD evidence package. The import pipeline handles URI generation, factor standard assignment, provenance tracking, and optional signing + validation in a single invocation.
603
+
604
+ ```bash
605
+ pip install -e '.[excel]' # one-time: adds openpyxl dependency
606
+
607
+ # Import from Excel → JSON-LD, sign, and validate in one step
608
+ uofa import my-assessment.xlsx --sign --key keys/research.key --check --pack vv40
609
+ ```
610
+
611
+ The Excel template has 5 sheets: **Assessment Summary**, **Model & Data**, **Validation Results**, **Credibility Factors**, and **Decision**. Each pack provides a pre-populated template with locked factor names and dropdown validation. See `packs/vv40/templates/uofa-starter-filled.xlsx` for a complete filled example.
612
+
613
+ | Feature | Detail |
614
+ |---|---|
615
+ | **VV40 support** | 13 V&V 40 factors, levels 1-5, `factorStandard: "ASME-VV40-2018"` |
616
+ | **NASA-STD-7009B** | 19 factors (13 shared + 6 NASA-only), levels 0-4, `assessmentPhase` auto-assigned |
617
+ | **Evidence types** | `ValidationResult`, `ReviewActivity`, `ProcessAttestation`, `DeploymentRecord`, `InputPedigreeLink` |
618
+ | **Provenance** | `ImportActivity` entry with timestamp, source file, and tool version |
619
+ | **Error messages** | Sheet name + cell reference (e.g., `[Credibility Factors!C7] Required Level must be 1-5`) |
620
+ | **SHACL-synced** | Factor names, level ranges, and enums are generated from SHACL shapes via `uofa schema --emit python` |
621
+
622
+ ---
623
+
624
+ ## Prerequisites
625
+
626
+ **Zero-install option:** [Open in GitHub Codespaces](https://codespaces.new/cloudronin/uofa?quickstart=1) — everything is pre-installed.
627
+
628
+ **Local install:**
629
+
630
+ ```bash
631
+ pip install -e '.[excel]' # installs uofa CLI + all Python deps + openpyxl for Excel import
632
+ ```
633
+
634
+ | Tool | Version | Purpose |
635
+ |---|---|---|
636
+ | Python 3.10+ | Installed via `pip install -e .` | SHACL validation + integrity verification |
637
+ | openpyxl | Installed via `pip install -e '.[excel]'` | Excel import (`uofa import`) |
638
+ | Java 17+ | OpenJDK or equivalent | Jena rule engine (C3 only) |
639
+ | Maven 3.8+ | `mvn package` | Build the Jena fat JAR (C3 only) |
640
+
641
+ Java and Maven are only required for the Jena rule engine (C3). Use `uofa check FILE --skip-rules` if Java is not available. openpyxl is only required for `uofa import`; all other commands work without it.
642
+
643
+ ---
644
+
645
+ ## Architecture: One UofA per Context of Use
646
+
647
+ UofA models credibility assessment at the **COU level**, not the individual factor level. Each UofA packages the complete credibility decision for one Context of Use — including all per-factor assessments as embedded CredibilityFactor nodes and any detected quality gaps as WeakenerAnnotation nodes.
648
+
649
+ ```
650
+ Morrison Blood Pump Assessment
651
+ ├── morrison/cou1/uofa-morrison-cou1.jsonld (ProfileComplete)
652
+ │ COU1: CPB Use (Class II) — Model Risk Level 2
653
+ │ ├── hasContextOfUse → COU1 node
654
+ │ ├── bindsRequirement → hemolysis safety requirement
655
+ │ ├── bindsModel → ANSYS CFX v.15.0 + Eulerian HI model
656
+ │ ├── bindsDataset → [PIV data, hemolysis in vitro data]
657
+ │ ├── hasValidationResult → [mesh convergence, PIV velocity, hemolysis comparison]
658
+ │ ├── hasCredibilityFactor → [13 V&V 40 factors: 7 assessed + 6 not-assessed]
659
+ │ ├── hasWeakener → [W-EP-01, W-EP-02 (3×), W-AL-01 (3×), W-AR-05 (3×), W-CON-01 (6×), W-CON-04, W-ON-02] + [COMPOUND-01 (5×), COMPOUND-03]
660
+ │ ├── hasDecisionRecord → "Accepted for COU1"
661
+ │ ├── hash → sha256:<real hash>
662
+ │ ├── signature → ed25519:<real signature>
663
+ │ └── wasDerivedFrom → Morrison DOI
664
+ │
665
+ └── morrison/cou2/uofa-morrison-cou2.jsonld (ProfileComplete)
666
+ COU2: VAD Use (Class III) — Model Risk Level 5
667
+ ├── hasCredibilityFactor → [13 V&V 40 factors: 7 assessed + 6 not-assessed]
668
+ ├── hasWeakener → [W-PROV-01 (7×), W-EP-04 (6×), W-ON-02, W-AL-02, W-CON-04] + [COMPOUND-01 (2×)]
669
+ └── At MRL 5 the risk-driven catalog shifts: W-PROV-01 dominates COU2 (7 provenance-chain orphans),
670
+ W-EP-04 fires 6× on not-assessed factors, and two of W-PROV-01's Criticals coexist with High
671
+ weakeners on `cou2` — triggering 2 COMPOUND-01 cascades that were unreachable pre-v0.5.2.
672
+ ```
673
+
674
+ Shared entities (model, datasets, pump geometry) are referenced by IRI, not duplicated. The divergence between COU1 and COU2 weakener profiles is the central analytical demonstration.
675
+
676
+ ---
677
+
678
+ ## Research Context
679
+
680
+ UofA is the subject of a Doctor of Engineering praxis at George Washington University. The evaluation uses two FDA case studies:
681
+
682
+ - **Tier 1 (Retrospective):** Morrison et al. (2019) — FDA generic centrifugal blood pump V&V 40 credibility assessment. Re-expressed as UofA evidence packages with real cryptographic integrity. Full 13-factor assessment (7 assessed, 6 not-assessed) with risk-driven divergence across the v0.5.2 catalog:
683
+
684
+ - **Morrison COU1** (MRL 2, Accepted): 24 weakeners including 6 Critical (1 W-EP-01 orphan claim plus 5 COMPOUND-01 cascades from coexisting Critical and High weakeners), 17 High (W-CON-01 on 6 factors with missing level assertions under the Accepted decision, plus W-AL-01, W-AR-05, W-EP-02, W-ON-02), and 1 Medium (W-CON-04 structural gap).
685
+
686
+ - **Morrison COU2** (MRL 5, Not Accepted): 18 weakeners including 9 Critical (7 W-PROV-01 provenance-chain orphans plus 2 COMPOUND-01 cascades), 7 High (6 W-EP-04 on unassessed factors at elevated model risk, 1 W-ON-02), and 2 Medium.
687
+
688
+ The cross-COU divergence (9 pattern-level divergences between COU1 and COU2) is the central analytical demonstration: same model, same data, different credibility requirements driven by different model risk produce measurably different credibility evidence profiles.
689
+ - **Tier 2 (Prospective):** FDA VICTRE pipeline — live computational workflow instrumented to generate UofAs during execution rather than from retrospective documents.
690
+ - **Tier 3 (Exploratory):** Multi-component stress test on VICTRE — simulates change events to test continuous re-issuance and hierarchical credibility composition.
691
+
692
+ Early findings — including the aerospace companion case study ([HPT Blade CHT, NASA-STD-7009B](#live-demo-hpt-blade-cht-nasa-std-7009b-aerospace)) that reproduces the Morrison COU1/COU2 divergence mechanism in a turbomachinery domain — will be presented at [NAFEMS Americas 2026](https://www.nafems.org/events/nafems/2026/nafems-americas-conference/) (May 27–29, St. Charles, MO).
693
+
694
+ ---
695
+
696
+ ## Design Principles
697
+
698
+ | Principle | Meaning |
699
+ |---|---|
700
+ | **Minimal** | Small JSON-LD document, human-readable, one file per COU |
701
+ | **Semantic** | Aligns with PROV-O, V&V 40, and domain ontologies |
702
+ | **Verifiable** | Real SHA-256 hashes + ed25519 signatures + SHACL validation |
703
+ | **Composable** | UofAs form nodes in system-level assurance graphs via `wasDerivedFrom` |
704
+ | **Tool-agnostic** | Works with any simulation tool, MBSE platform, or ML pipeline |
705
+ | **Hide the plumbing** | Practitioners see completeness reports and gap alerts, not triples and SPARQL |
706
+
707
+ ---
708
+
709
+ ## License
710
+
711
+ Apache License, Version 2.0 — see [LICENSE](LICENSE) for the full text and
712
+ [NOTICE](NOTICE) for bundled-software attributions.
713
+
714
+ The full project (UofA ontology, JSON-LD context, SHACL shapes, reference
715
+ examples, Jena rule implementations, and the CLI) is licensed under
716
+ Apache 2.0. Bundled third-party components retain their own licenses
717
+ as enumerated in `NOTICE` (e.g., OpenJDK GPLv2-CE, Ollama MIT).
718
+
719
+ ---
720
+
721
+ ## Contributing
722
+
723
+ Contributions are welcome, especially real-world UofA examples from practitioners working with CM&S credibility assessment. If you are preparing a CM&S-supported regulatory submission and want to explore UofA packaging for your evidence, please reach out.
724
+
725
+ For contributors looking to add features or fix bugs:
726
+
727
+ - [**Repo layout**](docs/repo-layout.md) — top-level orientation; quick reference for finding code, specs, schemas, outputs, and tooling. Disambiguates `spec/` (the v0.5 schema) vs `dev/specs/` (adversarial spec YAMLs).
728
+ - [**Onboarding Guide**](docs/onboarding.md) — combined quick-start + architecture + contributor guide. Covers CLI design, subcommand patterns, test structure, and step-by-step instructions for adding new commands, weakener rules, and schema changes.
729
+ - [**Phase 2.5 tooling**](dev/tools/phase2_5/README.md) — the metric-gated catalog refinement loop + per-rule corpus regen tools (referenced by recent versions v0.5.7 → v0.5.15.1).
730
+
731
+ **Website:** [crediblesimulation.com](https://crediblesimulation.com)