validibot-shared 0.7.3__tar.gz → 0.8.0__tar.gz

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 (26) hide show
  1. {validibot_shared-0.7.3 → validibot_shared-0.8.0}/PKG-INFO +8 -8
  2. {validibot_shared-0.7.3 → validibot_shared-0.8.0}/README.md +6 -6
  3. {validibot_shared-0.7.3 → validibot_shared-0.8.0}/pyproject.toml +2 -2
  4. {validibot_shared-0.7.3 → validibot_shared-0.8.0}/tests/test_evidence_manifest.py +33 -0
  5. {validibot_shared-0.7.3 → validibot_shared-0.8.0}/validibot_shared/energyplus/models.py +14 -6
  6. {validibot_shared-0.7.3 → validibot_shared-0.8.0}/validibot_shared/evidence/manifest.py +20 -0
  7. {validibot_shared-0.7.3 → validibot_shared-0.8.0}/.gitignore +0 -0
  8. {validibot_shared-0.7.3 → validibot_shared-0.8.0}/LICENSE +0 -0
  9. {validibot_shared-0.7.3 → validibot_shared-0.8.0}/NOTICE +0 -0
  10. {validibot_shared-0.7.3 → validibot_shared-0.8.0}/tests/__init__.py +0 -0
  11. {validibot_shared-0.7.3 → validibot_shared-0.8.0}/tests/test_energyplus_envelopes.py +0 -0
  12. {validibot_shared-0.7.3 → validibot_shared-0.8.0}/tests/test_energyplus_models.py +0 -0
  13. {validibot_shared-0.7.3 → validibot_shared-0.8.0}/tests/test_fmu_envelopes.py +0 -0
  14. {validibot_shared-0.7.3 → validibot_shared-0.8.0}/tests/test_fmu_models.py +0 -0
  15. {validibot_shared-0.7.3 → validibot_shared-0.8.0}/tests/test_package_init.py +0 -0
  16. {validibot_shared-0.7.3 → validibot_shared-0.8.0}/tests/test_validations_envelopes.py +0 -0
  17. {validibot_shared-0.7.3 → validibot_shared-0.8.0}/validibot_shared/__init__.py +0 -0
  18. {validibot_shared-0.7.3 → validibot_shared-0.8.0}/validibot_shared/energyplus/__init__.py +0 -0
  19. {validibot_shared-0.7.3 → validibot_shared-0.8.0}/validibot_shared/energyplus/envelopes.py +0 -0
  20. {validibot_shared-0.7.3 → validibot_shared-0.8.0}/validibot_shared/evidence/__init__.py +0 -0
  21. {validibot_shared-0.7.3 → validibot_shared-0.8.0}/validibot_shared/fmu/__init__.py +0 -0
  22. {validibot_shared-0.7.3 → validibot_shared-0.8.0}/validibot_shared/fmu/envelopes.py +0 -0
  23. {validibot_shared-0.7.3 → validibot_shared-0.8.0}/validibot_shared/fmu/models.py +0 -0
  24. {validibot_shared-0.7.3 → validibot_shared-0.8.0}/validibot_shared/py.typed +0 -0
  25. {validibot_shared-0.7.3 → validibot_shared-0.8.0}/validibot_shared/validations/__init__.py +0 -0
  26. {validibot_shared-0.7.3 → validibot_shared-0.8.0}/validibot_shared/validations/envelopes.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: validibot-shared
3
- Version: 0.7.3
3
+ Version: 0.8.0
4
4
  Summary: Shared library for data interchange between Validibot and validator containers
5
5
  Project-URL: Homepage, https://validibot.com
6
6
  Project-URL: Documentation, https://docs.validibot.com
@@ -27,14 +27,14 @@ Requires-Python: >=3.10
27
27
  Requires-Dist: pydantic<3.0,>=2.13
28
28
  Provides-Extra: dev
29
29
  Requires-Dist: pytest==9.0.3; extra == 'dev'
30
- Requires-Dist: ruff==0.15.12; extra == 'dev'
30
+ Requires-Dist: ruff==0.15.14; extra == 'dev'
31
31
  Description-Content-Type: text/markdown
32
32
 
33
33
  <div align="center">
34
34
 
35
35
  # Validibot Shared
36
36
 
37
- **Shared Pydantic models for Validibot Advanced Validator containers**
37
+ **Shared Pydantic models for Validibot validator backends**
38
38
 
39
39
  [![PyPI version](https://badge.fury.io/py/validibot-shared.svg)](https://pypi.org/project/validibot-shared/)
40
40
  [![Python versions](https://img.shields.io/pypi/pyversions/validibot-shared.svg)](https://pypi.org/project/validibot-shared/)
@@ -106,7 +106,7 @@ poetry add validibot-shared
106
106
  ### Requirements
107
107
 
108
108
  - Python 3.10 or later
109
- - Pydantic 2.8.0 or later
109
+ - Pydantic 2.13 or later (< 3.0)
110
110
 
111
111
  ## Core Concepts
112
112
 
@@ -132,7 +132,7 @@ Validibot uses an "envelope" pattern for validator communication. Every validati
132
132
 
133
133
  ▼ JSON
134
134
  ┌─────────────────────────────────────────────────────────────────┐
135
- Validator Container
135
+ Validator Backend Container
136
136
  │ (EnergyPlus, FMU, etc.) │
137
137
  │ │
138
138
  │ 1. Parses input envelope │
@@ -399,13 +399,13 @@ This library is one component of the Validibot open-source data validation platf
399
399
  │ validibot-cli │ │ validibot-validator-backends │ │ validibot-shared │
400
400
  │ │ │ │ │ (this repo) │
401
401
  │ Terminal access │ │ EnergyPlus™, FMU │ │ │
402
- │ to API │ │ containers │ │ Pydantic models │
402
+ │ to API │ │ validator backends │ │ Pydantic models │
403
403
  │ │ │ │ │ │ (shared contract) │
404
404
  └─────────────────┘ └──────────────┼───────────────┘ └─────────────────────┘
405
405
  │ ▲
406
406
  └──────────────────────────┘
407
- validators import shared
408
- models for type safety
407
+ backends import shared
408
+ models for type safety
409
409
  ```
410
410
 
411
411
  ## Development
@@ -2,7 +2,7 @@
2
2
 
3
3
  # Validibot Shared
4
4
 
5
- **Shared Pydantic models for Validibot Advanced Validator containers**
5
+ **Shared Pydantic models for Validibot validator backends**
6
6
 
7
7
  [![PyPI version](https://badge.fury.io/py/validibot-shared.svg)](https://pypi.org/project/validibot-shared/)
8
8
  [![Python versions](https://img.shields.io/pypi/pyversions/validibot-shared.svg)](https://pypi.org/project/validibot-shared/)
@@ -74,7 +74,7 @@ poetry add validibot-shared
74
74
  ### Requirements
75
75
 
76
76
  - Python 3.10 or later
77
- - Pydantic 2.8.0 or later
77
+ - Pydantic 2.13 or later (< 3.0)
78
78
 
79
79
  ## Core Concepts
80
80
 
@@ -100,7 +100,7 @@ Validibot uses an "envelope" pattern for validator communication. Every validati
100
100
 
101
101
  ▼ JSON
102
102
  ┌─────────────────────────────────────────────────────────────────┐
103
- Validator Container
103
+ Validator Backend Container
104
104
  │ (EnergyPlus, FMU, etc.) │
105
105
  │ │
106
106
  │ 1. Parses input envelope │
@@ -367,13 +367,13 @@ This library is one component of the Validibot open-source data validation platf
367
367
  │ validibot-cli │ │ validibot-validator-backends │ │ validibot-shared │
368
368
  │ │ │ │ │ (this repo) │
369
369
  │ Terminal access │ │ EnergyPlus™, FMU │ │ │
370
- │ to API │ │ containers │ │ Pydantic models │
370
+ │ to API │ │ validator backends │ │ Pydantic models │
371
371
  │ │ │ │ │ │ (shared contract) │
372
372
  └─────────────────┘ └──────────────┼───────────────┘ └─────────────────────┘
373
373
  │ ▲
374
374
  └──────────────────────────┘
375
- validators import shared
376
- models for type safety
375
+ backends import shared
376
+ models for type safety
377
377
  ```
378
378
 
379
379
  ## Development
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "validibot-shared"
7
- version = "0.7.3"
7
+ version = "0.8.0"
8
8
  description = "Shared library for data interchange between Validibot and validator containers"
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
@@ -35,7 +35,7 @@ classifiers = [
35
35
  dependencies = ["pydantic>=2.13,<3.0"]
36
36
 
37
37
  [project.optional-dependencies]
38
- dev = ["pytest==9.0.3", "ruff==0.15.12"]
38
+ dev = ["pytest==9.0.3", "ruff==0.15.14"]
39
39
 
40
40
  [project.urls]
41
41
  Homepage = "https://validibot.com"
@@ -131,6 +131,39 @@ class TestOptionalFields:
131
131
  manifest = EvidenceManifest(**_minimal_manifest_kwargs())
132
132
  assert manifest.steps == []
133
133
 
134
+ # ── Manifest source field ───────────────────────────────────
135
+ #
136
+ # ``source`` documents which auth channel produced the run. It's
137
+ # additive and optional — older producers set None, newer
138
+ # producers populate it from the authenticated route (NOT from a
139
+ # client header). The schema-version contract still reads ``v1``
140
+ # because the change is purely additive.
141
+ def test_source_defaults_to_none(self):
142
+ """Older producers and producers that don't track source leave it None."""
143
+ manifest = EvidenceManifest(**_minimal_manifest_kwargs())
144
+ assert manifest.source is None
145
+
146
+ def test_source_can_be_populated(self):
147
+ """Newer producers populate source from the authenticated route."""
148
+ manifest = EvidenceManifest(
149
+ **_minimal_manifest_kwargs(),
150
+ source="X402_AGENT",
151
+ )
152
+ assert manifest.source == "X402_AGENT"
153
+
154
+ def test_source_addition_preserves_v1_schema(self):
155
+ """Manifests carrying ``source`` still report schema_version v1.
156
+
157
+ Adding an optional field is explicitly an additive change per
158
+ the schema-versioning policy in ``manifest.py``. Bumping to v2
159
+ would only be required for breaking changes.
160
+ """
161
+ manifest = EvidenceManifest(
162
+ **_minimal_manifest_kwargs(),
163
+ source="MCP",
164
+ )
165
+ assert manifest.schema_version == "validibot.evidence.v1"
166
+
134
167
 
135
168
  # ──────────────────────────────────────────────────────────────────────
136
169
  # StepValidatorRecord — semantic_digest can be None for legacy validators
@@ -116,14 +116,22 @@ class EnergyPlusSimulationMetrics(BaseModel):
116
116
  peak_electric_demand_w: NonNegFloat | None = None
117
117
 
118
118
  # ==========================================================================
119
- # Building Characteristics (from IDF/SQL)
119
+ # Building Characteristics (simulation-derived)
120
+ #
121
+ # Per ADR-2026-05-22 (provenance rule): only simulation-derived metrics
122
+ # belong here. IDF-text-derived facts (idf_version, zone_count,
123
+ # north_axis_deg) are step inputs populated by the validator's parser
124
+ # and live in the i.* CEL namespace, not in this output envelope.
120
125
  # ==========================================================================
121
126
 
122
- # Total conditioned floor area
123
- floor_area_m2: NonNegFloat | None = None
124
-
125
- # Number of thermal zones
126
- zone_count: NonNegInt | None = None
127
+ # Total conditioned floor area as computed by EnergyPlus from the
128
+ # geometry the area EnergyPlus actually simulates conditioning
129
+ # for, which may differ from the design floor area input the
130
+ # author supplied. The name says "simulated" + "conditioned" to
131
+ # distinguish it from inputs the IDF declares; per ADR-2026-05-22
132
+ # the rename from the legacy ``floor_area_m2`` lands with this
133
+ # shared-package release.
134
+ simulated_conditioned_area_m2: NonNegFloat | None = None
127
135
 
128
136
  # ==========================================================================
129
137
  # Window / Envelope (from EnergyPlus output variables)
@@ -251,6 +251,26 @@ class EvidenceManifest(BaseModel):
251
251
  default_factory=ManifestPayloadDigests,
252
252
  description="Session A: empty. Session B: input + output hashes.",
253
253
  )
254
+ # The auth channel that initiated the run. Pinning it in the
255
+ # manifest lets verifiers answer "what surface produced this
256
+ # run?" without consulting the producer database (the run row
257
+ # may be purged under DO_NOT_STORE retention). Optional because
258
+ # (a) older producers persist runs without populating
259
+ # ``source``, and (b) the field is additive — a missing value
260
+ # preserves the v1 schema-version contract. Producers MUST
261
+ # derive this from the authenticated route, NEVER from a
262
+ # caller-controlled header.
263
+ source: str | None = Field(
264
+ default=None,
265
+ description=(
266
+ "Run source identifier — one of LAUNCH_PAGE, API, MCP, "
267
+ "X402_AGENT, CLI, SCHEDULE. Derived from the "
268
+ "authenticated route on the producer side and propagated "
269
+ "into the manifest verbatim. None when the run was "
270
+ "captured before P2 #2 shipped or by a producer that does "
271
+ "not yet emit the field."
272
+ ),
273
+ )
254
274
 
255
275
 
256
276
  __all__ = [