zeromodel-artifacts 1.1.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.
- zeromodel/artifacts/__init__.py +120 -0
- zeromodel/artifacts/adapted_report_persistence.py +91 -0
- zeromodel/artifacts/adapter.py +30 -0
- zeromodel/artifacts/aggregate.py +795 -0
- zeromodel/artifacts/canonicalization.py +13 -0
- zeromodel/artifacts/compatibility_schema.py +93 -0
- zeromodel/artifacts/compiled_artifact.py +518 -0
- zeromodel/artifacts/core_artifact_persistence.py +95 -0
- zeromodel/artifacts/ref.py +44 -0
- zeromodel/artifacts/report_adapter_contract_persistence.py +78 -0
- zeromodel/artifacts/report_compiler.py +254 -0
- zeromodel/artifacts/report_decode.py +82 -0
- zeromodel/artifacts/report_dto.py +493 -0
- zeromodel/artifacts/report_errors.py +13 -0
- zeromodel/artifacts/report_loading.py +94 -0
- zeromodel/artifacts/score_semantics.py +16 -0
- zeromodel/artifacts/store.py +156 -0
- zeromodel_artifacts-1.1.0.dist-info/METADATA +118 -0
- zeromodel_artifacts-1.1.0.dist-info/RECORD +21 -0
- zeromodel_artifacts-1.1.0.dist-info/WHEEL +5 -0
- zeromodel_artifacts-1.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from zeromodel.artifacts.adapted_report_persistence import (
|
|
4
|
+
ADAPTED_REPORT_ARTIFACT_KIND,
|
|
5
|
+
load_adapted_report,
|
|
6
|
+
store_adapted_report,
|
|
7
|
+
)
|
|
8
|
+
from zeromodel.artifacts.adapter import ReportAdapter
|
|
9
|
+
from zeromodel.artifacts.aggregate import (
|
|
10
|
+
CompiledReportClosureReceiptDTO,
|
|
11
|
+
ResolvedCompiledReportAggregateDTO,
|
|
12
|
+
build_compiled_report_closure_receipt,
|
|
13
|
+
load_compiled_report_aggregate,
|
|
14
|
+
load_compiled_report_vpm,
|
|
15
|
+
validate_compiled_report_aggregate,
|
|
16
|
+
)
|
|
17
|
+
from zeromodel.artifacts.canonicalization import canonical_json_bytes, sha256_digest
|
|
18
|
+
from zeromodel.artifacts.compatibility_schema import (
|
|
19
|
+
compute_compatibility_schema_id,
|
|
20
|
+
compute_report_semantics_id,
|
|
21
|
+
)
|
|
22
|
+
from zeromodel.artifacts.compiled_artifact import (
|
|
23
|
+
CellBindingDTO,
|
|
24
|
+
CompiledReportArtifactDTO,
|
|
25
|
+
CoreArtifactRefs,
|
|
26
|
+
)
|
|
27
|
+
from zeromodel.artifacts.core_artifact_persistence import (
|
|
28
|
+
LAYOUT_RECIPE_ARTIFACT_KIND,
|
|
29
|
+
SCORE_TABLE_ARTIFACT_KIND,
|
|
30
|
+
VPM_ARTIFACT_ARTIFACT_KIND,
|
|
31
|
+
load_layout_recipe,
|
|
32
|
+
load_score_table,
|
|
33
|
+
load_vpm_artifact,
|
|
34
|
+
store_layout_recipe,
|
|
35
|
+
store_score_table,
|
|
36
|
+
store_vpm_artifact,
|
|
37
|
+
)
|
|
38
|
+
from zeromodel.artifacts.ref import ARTIFACT_REF_VERSION, ArtifactRef, is_sha256_digest
|
|
39
|
+
from zeromodel.artifacts.report_adapter_contract_persistence import (
|
|
40
|
+
REPORT_ADAPTER_CONTRACT_ARTIFACT_KIND,
|
|
41
|
+
load_report_adapter_contract,
|
|
42
|
+
store_report_adapter_contract,
|
|
43
|
+
)
|
|
44
|
+
from zeromodel.artifacts.report_compiler import compile_report
|
|
45
|
+
from zeromodel.artifacts.report_dto import (
|
|
46
|
+
AdaptedDimensionDTO,
|
|
47
|
+
AdaptedReportDTO,
|
|
48
|
+
AdaptedSubjectDTO,
|
|
49
|
+
AdaptedValueDTO,
|
|
50
|
+
ReportAdapterContractDTO,
|
|
51
|
+
ReportFindingRefDTO,
|
|
52
|
+
SourceBindingDTO,
|
|
53
|
+
)
|
|
54
|
+
from zeromodel.artifacts.report_errors import (
|
|
55
|
+
ReportAdaptationError,
|
|
56
|
+
ReportCompilationError,
|
|
57
|
+
)
|
|
58
|
+
from zeromodel.artifacts.report_loading import load_compiled_report_artifact
|
|
59
|
+
from zeromodel.artifacts.score_semantics import ScoreSemantics
|
|
60
|
+
from zeromodel.artifacts.store import (
|
|
61
|
+
ArtifactIntegrityError,
|
|
62
|
+
ArtifactManifestConflictError,
|
|
63
|
+
ArtifactNotFoundError,
|
|
64
|
+
ArtifactResolver,
|
|
65
|
+
ArtifactStore,
|
|
66
|
+
InMemoryArtifactStore,
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
__all__ = [
|
|
70
|
+
"ADAPTED_REPORT_ARTIFACT_KIND",
|
|
71
|
+
"ARTIFACT_REF_VERSION",
|
|
72
|
+
"LAYOUT_RECIPE_ARTIFACT_KIND",
|
|
73
|
+
"REPORT_ADAPTER_CONTRACT_ARTIFACT_KIND",
|
|
74
|
+
"SCORE_TABLE_ARTIFACT_KIND",
|
|
75
|
+
"VPM_ARTIFACT_ARTIFACT_KIND",
|
|
76
|
+
"AdaptedDimensionDTO",
|
|
77
|
+
"AdaptedReportDTO",
|
|
78
|
+
"AdaptedSubjectDTO",
|
|
79
|
+
"AdaptedValueDTO",
|
|
80
|
+
"ArtifactIntegrityError",
|
|
81
|
+
"ArtifactManifestConflictError",
|
|
82
|
+
"ArtifactNotFoundError",
|
|
83
|
+
"ArtifactRef",
|
|
84
|
+
"ArtifactResolver",
|
|
85
|
+
"ArtifactStore",
|
|
86
|
+
"CellBindingDTO",
|
|
87
|
+
"CompiledReportArtifactDTO",
|
|
88
|
+
"CompiledReportClosureReceiptDTO",
|
|
89
|
+
"CoreArtifactRefs",
|
|
90
|
+
"InMemoryArtifactStore",
|
|
91
|
+
"ReportAdaptationError",
|
|
92
|
+
"ReportAdapter",
|
|
93
|
+
"ReportAdapterContractDTO",
|
|
94
|
+
"ReportCompilationError",
|
|
95
|
+
"ReportFindingRefDTO",
|
|
96
|
+
"ResolvedCompiledReportAggregateDTO",
|
|
97
|
+
"ScoreSemantics",
|
|
98
|
+
"SourceBindingDTO",
|
|
99
|
+
"build_compiled_report_closure_receipt",
|
|
100
|
+
"canonical_json_bytes",
|
|
101
|
+
"compile_report",
|
|
102
|
+
"compute_compatibility_schema_id",
|
|
103
|
+
"compute_report_semantics_id",
|
|
104
|
+
"is_sha256_digest",
|
|
105
|
+
"load_adapted_report",
|
|
106
|
+
"load_compiled_report_aggregate",
|
|
107
|
+
"load_compiled_report_artifact",
|
|
108
|
+
"load_compiled_report_vpm",
|
|
109
|
+
"load_layout_recipe",
|
|
110
|
+
"load_report_adapter_contract",
|
|
111
|
+
"load_score_table",
|
|
112
|
+
"load_vpm_artifact",
|
|
113
|
+
"sha256_digest",
|
|
114
|
+
"store_adapted_report",
|
|
115
|
+
"store_layout_recipe",
|
|
116
|
+
"store_report_adapter_contract",
|
|
117
|
+
"store_score_table",
|
|
118
|
+
"store_vpm_artifact",
|
|
119
|
+
"validate_compiled_report_aggregate",
|
|
120
|
+
]
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"""Persist and reload `AdaptedReportDTO` as a first-class artifact.
|
|
2
|
+
|
|
3
|
+
Before this module, `AdaptedReportDTO` only ever existed as a discarded
|
|
4
|
+
local Python object inside `compile_report()`: the compiled report named it
|
|
5
|
+
by digest (`adapted_report_id`) but nothing made that digest resolvable
|
|
6
|
+
after the process exited. Raw values, per-value confidence, per-value
|
|
7
|
+
importance, source bindings, and parent-report lineage - none of which the
|
|
8
|
+
VPM matrix preserves completely - were unrecoverable once compilation
|
|
9
|
+
finished. This module closes that gap using the same decode-and-verify
|
|
10
|
+
pattern as `core_artifact_persistence.py`: resolve canonical bytes,
|
|
11
|
+
recompute the digest, require it to equal the requested ref's
|
|
12
|
+
`artifact_id`, decode, and reconstruct via `AdaptedReportDTO.__post_init__`
|
|
13
|
+
- never trusting a store's manifest as authoritative.
|
|
14
|
+
|
|
15
|
+
Canonical format: the stored payload is exactly
|
|
16
|
+
`adapted_report_signing_payload(adapted_report)` - the same payload
|
|
17
|
+
`AdaptedReportDTO.adapted_report_id` is computed over, with the
|
|
18
|
+
self-referential id field excluded. Because `ArtifactStore.put()` computes
|
|
19
|
+
`ref.artifact_id` as `sha256_digest(canonical_bytes)` over that same
|
|
20
|
+
payload, `ref.artifact_id == adapted_report.adapted_report_id` always
|
|
21
|
+
holds - the artifact-store identity and the DTO's own content identity are
|
|
22
|
+
the same digest, not two independent layers that happen to agree.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
from __future__ import annotations
|
|
26
|
+
|
|
27
|
+
import json
|
|
28
|
+
|
|
29
|
+
from zeromodel.artifacts.canonicalization import canonical_json_bytes, sha256_digest
|
|
30
|
+
from zeromodel.artifacts.ref import ArtifactRef
|
|
31
|
+
from zeromodel.artifacts.report_decode import (
|
|
32
|
+
decode_attributes,
|
|
33
|
+
decode_dimension,
|
|
34
|
+
decode_subject,
|
|
35
|
+
decode_value,
|
|
36
|
+
)
|
|
37
|
+
from zeromodel.artifacts.report_dto import (
|
|
38
|
+
AdaptedReportDTO,
|
|
39
|
+
adapted_report_signing_payload,
|
|
40
|
+
)
|
|
41
|
+
from zeromodel.artifacts.report_errors import ReportCompilationError
|
|
42
|
+
from zeromodel.artifacts.store import ArtifactResolver, ArtifactStore
|
|
43
|
+
|
|
44
|
+
ADAPTED_REPORT_ARTIFACT_KIND = "zeromodel.artifacts.adapted-report/v1"
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def store_adapted_report(
|
|
48
|
+
adapted_report: AdaptedReportDTO, *, store: ArtifactStore
|
|
49
|
+
) -> ArtifactRef:
|
|
50
|
+
canonical_bytes = canonical_json_bytes(
|
|
51
|
+
adapted_report_signing_payload(adapted_report)
|
|
52
|
+
)
|
|
53
|
+
ref = store.put(ADAPTED_REPORT_ARTIFACT_KIND, canonical_bytes, manifest=None)
|
|
54
|
+
if ref.artifact_id != adapted_report.adapted_report_id:
|
|
55
|
+
raise ReportCompilationError(
|
|
56
|
+
"stored adapted-report digest does not match adapted_report_id "
|
|
57
|
+
f"(stored={ref.artifact_id}, adapted_report_id={adapted_report.adapted_report_id})"
|
|
58
|
+
)
|
|
59
|
+
return ref
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def load_adapted_report(
|
|
63
|
+
ref: ArtifactRef, *, resolver: ArtifactResolver
|
|
64
|
+
) -> AdaptedReportDTO:
|
|
65
|
+
if ref.artifact_kind != ADAPTED_REPORT_ARTIFACT_KIND:
|
|
66
|
+
raise ReportCompilationError(
|
|
67
|
+
f"load_adapted_report requires artifact_kind={ADAPTED_REPORT_ARTIFACT_KIND!r}, "
|
|
68
|
+
f"got {ref.artifact_kind!r}"
|
|
69
|
+
)
|
|
70
|
+
canonical_bytes = resolver.resolve_canonical_bytes(ref)
|
|
71
|
+
actual_digest = sha256_digest(canonical_bytes)
|
|
72
|
+
if actual_digest != ref.artifact_id:
|
|
73
|
+
raise ReportCompilationError(
|
|
74
|
+
f"resolved canonical bytes for {ref.artifact_id} do not hash to the requested id "
|
|
75
|
+
f"(got {actual_digest})"
|
|
76
|
+
)
|
|
77
|
+
payload = json.loads(canonical_bytes)
|
|
78
|
+
|
|
79
|
+
return AdaptedReportDTO(
|
|
80
|
+
adapted_report_id=ref.artifact_id,
|
|
81
|
+
report_id=payload["report_id"],
|
|
82
|
+
report_kind=payload["report_kind"],
|
|
83
|
+
adapter_contract_id=payload["adapter_contract_id"],
|
|
84
|
+
compatibility_id=payload["compatibility_id"],
|
|
85
|
+
subjects=tuple(decode_subject(item) for item in payload["subjects"]),
|
|
86
|
+
dimensions=tuple(decode_dimension(item) for item in payload["dimensions"]),
|
|
87
|
+
values=tuple(decode_value(item) for item in payload["values"]),
|
|
88
|
+
parent_report_ids=tuple(payload["parent_report_ids"]),
|
|
89
|
+
attributes=decode_attributes(payload["attributes"]),
|
|
90
|
+
spec_version=payload["spec_version"],
|
|
91
|
+
)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""The adapter protocol - the ingress boundary for domain reports.
|
|
2
|
+
|
|
3
|
+
Concrete adapters live in the external application (e.g.
|
|
4
|
+
`writer.integrations.zeromodel.AIArtifactReportAdapter`), never in this
|
|
5
|
+
package. An adapter must not write directly to an `ArtifactStore`,
|
|
6
|
+
construct rendered images, or calculate artifact identity itself - it only
|
|
7
|
+
translates one typed domain report into a neutral `AdaptedReportDTO`;
|
|
8
|
+
`compile_report` (see `report_compiler.py`) owns validation and identity.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
from typing import Generic, Protocol, TypeVar, runtime_checkable
|
|
14
|
+
|
|
15
|
+
from zeromodel.artifacts.report_dto import AdaptedReportDTO, ReportAdapterContractDTO
|
|
16
|
+
|
|
17
|
+
ReportT = TypeVar("ReportT", contravariant=True)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@runtime_checkable
|
|
21
|
+
class ReportAdapter(Protocol, Generic[ReportT]):
|
|
22
|
+
"""Domain-owned translation from one typed report into neutral ZeroModel form."""
|
|
23
|
+
|
|
24
|
+
def contract(self) -> ReportAdapterContractDTO:
|
|
25
|
+
"""Return the stable contract governing this adapter's translation."""
|
|
26
|
+
...
|
|
27
|
+
|
|
28
|
+
def adapt(self, report: ReportT) -> AdaptedReportDTO:
|
|
29
|
+
"""Convert one domain report into the neutral ZeroModel report form."""
|
|
30
|
+
...
|