Open-FDD Haystack projection profile — ofdd_haystack_projection_v1
Status: C3 audit repair (#1123 / #1001) implements strict export from native
openfdd_semantic_meta_v1 via GET …/mapping/haystack.ttl (defs pin
haystack-defs-ttl-4.0.0 — official multi-library Turtle). Passing this document alone does not
establish full Haystack server interoperability, FDD readiness, or a live SPARQL service.
This profile names the strict Haystack RDF interchange Open-FDD will target
in wave C3+. It is separate from today’s native package inventory exports
(openfdd_data_model_v1 JSON and openfdd_data_model_v2 Turtle under
urn:openfdd:ns#).
Requirements source: openfdd_agent_spec/HAYSTACK_RDF_ROLLOUT.md
(HR-01–HR-12).
Compatibility layers (do not conflate)
| Layer | Meaning | C1 status |
|---|---|---|
| RDF syntax | Parseable Turtle/JSON-LD | Native TTL is valid RDF; not yet strict Haystack |
| Haystack semantics | Terms resolve to pinned ph defs; markers/refs valid |
Not claimed for package TTL |
| Site mapping completeness | Roles, topology, units sufficient for FDD | Package inventory + diagnostics |
| FDD readiness | DataFusion roles populated | Existing SQL path |
| Graph/API services | Central scoped dataset + SPARQL | Dataset H8 + template SPARQL/bindings H9 shipped; #1002 still needs H10+ consumers |
Pinned vocabulary
| Prefix | Base IRI | Pin policy |
|---|---|---|
ph |
https://project-haystack.org/def/ph/4.0.0# |
Official normalized defs artifact defs.ttl (SHA in scripts/fixtures/haystack_rdf/defs/defs.pin.json) |
phIoT |
https://project-haystack.org/def/phIoT/4.0.0# |
Same pin — sites, equips, points, refs |
phScience |
https://project-haystack.org/def/phScience/4.0.0# |
Same pin — phenomena / quantities (e.g. air, temp) |
ofdd |
urn:openfdd:ns# |
Open-FDD native inventory + FDD selection / engineering extensions only |
Pin id: haystack-defs-ttl-4.0.0. The RDF doc page’s illustrative 4.0
prefix is not the pin. Symbols are case-sensitive (heatPump, not heatpump).
Instance mapping (strict projection)
Follow Haystack RDF instance rules:
- Sites, equips, points are distinct resources with Haystack classes from
the owning library (
phIoT:site,phIoT:equip,phIoT:point, …). - Marker / class tags attach via
ph:hasTagto the correct library IRI — never invent a marker because a SQL role exists. - Point metadata uses standard
ph:dis,ph:unit,ph:kind,ph:tzandphIoT:hiswhere present. Numeric tag-value units remain a documented gap. - References use
phIoT:siteRef/phIoT:equipRef/phIoT:airRefonly with validated targets and explicit relation evidence (equipRef≠ generic parent). - Named IRIs under
urn:openfdd:site/…are the interchange identity for this profile (not blank-node labels). Point identity preferspoint_idover CSV column. - Never mint Open-FDD extension terms inside Haystack IRIs. Use
urn:openfdd:ns#for FDD selection / exclusions / provenance.
Unknown tags and intentional exclusions
- Tags without a pinned def are excluded from the strict projection and listed in a projection report (omitted term, source column/id, reason).
- Source facts remain in native metadata (JSON sidecars / persisted revision).
- Ambiguous SQL roles and operator FDD exclusions retain valid semantic points;
FDD selection is reported separately (
ofdd:fddSelection/ofdd:fddExcluded).
Units: value vs point metadata
Haystack RDF leaves some unit-on-value semantics as evolving spec work. This profile distinguishes:
| Concept | Strict Haystack projection | Native Open-FDD metadata |
|---|---|---|
Point unit def |
Emit when known and def-backed | Store on point record |
| Numeric reading | Value + compatible unit when spec allows | Parquet historian (canonical telemetry) |
| Unknown unit | Omit typed strict literal; report unknown_unit |
Retain unit_status: unknown and vendor text |
Do not infer unit from column name suffixes or split SQL role strings.
Uncertainty and FDD selection (HR-05)
These states stay explicit in native exports:
- Ambiguous roles — multiple columns mapped to one SQL role without selection evidence.
- Missing topology — e.g. stamped VAV without confirmed
parent_ahu. - Duplicate legitimate sensors — multiple valid Haystack points; FDD policy chooses inputs separately.
Strict projection must not pick the first column or promote inferred parents
to fact edges. Package TTL today already skips parent_ahu_source=inferred
(DM-04); strict Haystack inherits that rule.
Authority and revisions (HR-07 preview)
One authoritative native revision per tenant/site. JSON, Turtle, and graph views are derived from that revision. C2 adds persistence; C3 adds strict projection. See ADR — data model graph.
Strict vs native export
| Export | Schema / profile | Purpose |
|---|---|---|
| Native JSON | openfdd_data_model_v1 |
Full inventory + diagnostics for agents/UI |
| Native TTL | openfdd_data_model_v2 (Turtle) |
Compact RDF view of roles/unmapped columns |
| Strict Haystack TTL/JSON | ofdd_haystack_projection_v1 |
Interchange with pinned ph semantics (C3+) |
Field-level mapping: data-model JSON/RDF crosswalk.
Synthetic conformance fixtures
Independent answers (not exporter output):
scripts/fixtures/haystack_rdf/ — see README there.
Related
- RDF vocabulary notes (DM-10 narrow) — legacy edge grid
- Data model TTL export — native package TTL
- Consumer route matrix