# Validation summary — pbo 0.1.0

Re-run 2026-09-15 from the bundled ontology skill scripts. Release state: **release_candidate**.

## Deterministic project validation (`validate_project.py`)

| Gate | Result |
|---|---|
| Required files present | pass |
| YAML / JSON / JSONL / Turtle parse errors | 0 |
| Accepted terms | 486 (93 classes, 75 object properties, 37 datatype properties, 24 schemes, 257 concepts) |
| Accepted axioms | 190 |
| Label and definition coverage of custom RDF terms | 100 % (205 terms) |
| Term evidence-or-rationale coverage | 100 % |
| Axiom evidence-or-rationale coverage | 100 % |
| Evidence references to unknown sources | 0 |
| Undeclared custom predicates | 0 |
| Core CQ query coverage | 9 / 9 |
| Errors | 0 |
| Warnings | 26 |

All 26 warnings are `PROPERTY_DOMAIN` / `PROPERTY_RANGE` notices for properties that intentionally omit a global domain or range because they apply to several unrelated classes (`hasRisk`, `hasMetricValue`, `hasParticipation`, `concernsAsset`, `allocatesOutgoing`, `appliesIn`, `governedBy`, `underRegime`, and similar). The omission is recorded in DEC-009 and the per-class constraints live in `shapes.ttl`.

## Competency-question tests (`run_cq_tests.py`)

15 / 15 pass with `entailment: none` against `instances.ttl` plus `ontology.ttl` and `taxonomy.ttl`. Each query has an explicit `row_count` expectation; expectations were set after inspecting the result rows, not from the count alone. Negative and boundary cases covered by fixtures: expired and pending authorisations (CQ-015), conflicting yield claims (CQ-011), the owner-occupier 1–3-room partial-coverage threshold and the 4+ full-coverage threshold (CQ-002), gross versus triple-net outgoings (CQ-010), and a corporate-lease agreement with `fixedRent true` alongside subleases with `fixedRent false` (CQ-003).

## SHACL (`run_shacl.py`, pySHACL via `uv run`)

Data graph `instances.ttl`, shapes `shapes.ttl`, ontology graph `ontology.ttl` + `taxonomy.ttl`, inference `rdfs`. **Conforms: true.** No negative-fixture file is bundled; critical constraints were exercised by hand during authoring (missing `authorisationStatus`, a `HeadLease` without `fixedRent true`, a `MetricValue` without `numericValue`) but those cases are not retained as an automated regression fixture. Adding `fixtures/negative.ttl` is the first recommended improvement.

## Semantic atlas (`validate_atlas.py`, `render_check.py`)

`documentation/semantic-atlas.md`: 197 Mermaid blocks, all balanced; 100 % lexical coverage of classes, object properties, datatype properties, SKOS schemes, SHACL node shapes, competency questions, sources, evidence and decisions. Render check: 197 / 197 blocks rendered under both ELK and Dagre layouts, no failures.

## Not executed

- **OWL DL reasoning.** No reasoner (HermiT, ELK, Pellet-compatible) was run. Disjointness axioms and the four restrictions are therefore syntactically checked only. The release policy sets `require_external_reasoner: false`.
- **Semantic expert review** of class-versus-role, is-a-versus-part-of and event-versus-property choices beyond the modeller's own review recorded in `decisions.yaml`.
- **Verification of synthesis-only legal and tax claims** against primary legislation (ISSUE-005, ISSUE-006).

## Regression policy

Any change to `build/build_model.py`, `instances.ttl`, `shapes.ttl` or `queries/` must re-run the four commands in `README.md` and keep all 15 CQ tests, SHACL conformance and atlas coverage green before the version is bumped.
