tigrcorn-certification 0.3.18.dev2__py3-none-any.whl → 0.3.18.dev3__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.
@@ -44,10 +44,36 @@ __all__ = [
44
44
  "validate_package_manifest_integrity",
45
45
  "validate_release_evidence",
46
46
  "write_supply_chain_release_bundle",
47
+ "certify_static",
48
+ "certify_static_main",
49
+ "export_hardening_suite_catalog",
50
+ "validate_hardening_suite_catalog",
47
51
  ]
48
52
 
49
53
 
50
54
  def __getattr__(name: str):
55
+ if name in {
56
+ "certify_static",
57
+ "certify_static_main",
58
+ }:
59
+ from .certify.static import certify_static, certify_static_main
60
+
61
+ mapping = {
62
+ "certify_static": certify_static,
63
+ "certify_static_main": certify_static_main,
64
+ }
65
+ return mapping[name]
66
+ if name in {
67
+ "export_hardening_suite_catalog",
68
+ "validate_hardening_suite_catalog",
69
+ }:
70
+ from .hardening_suites import export_hardening_suite_catalog, validate_hardening_suite_catalog
71
+
72
+ mapping = {
73
+ "export_hardening_suite_catalog": export_hardening_suite_catalog,
74
+ "validate_hardening_suite_catalog": validate_hardening_suite_catalog,
75
+ }
76
+ return mapping[name]
51
77
  if name in {
52
78
  "evaluate_release_gates",
53
79
  "assert_release_ready",
@@ -0,0 +1,5 @@
1
+ from __future__ import annotations
2
+
3
+ from .static import certify_static, certify_static_main
4
+
5
+ __all__ = ["certify_static", "certify_static_main"]
@@ -0,0 +1,118 @@
1
+ from __future__ import annotations
2
+
3
+ import argparse
4
+ import json
5
+ import sys
6
+ from pathlib import Path
7
+ from typing import Callable, Iterable
8
+
9
+ from tigrcorn_static.static import (
10
+ StaticSecurityCertificationError,
11
+ build_static_certification_evidence,
12
+ certify_static_delivery_security,
13
+ static_delivery_certification_artifact,
14
+ )
15
+
16
+ from ..artifacts import canonical_json
17
+
18
+
19
+ class StaticCertificationCommandError(ValueError):
20
+ """Raised when static certification cannot be completed."""
21
+
22
+
23
+ def build_static_certification_parser() -> argparse.ArgumentParser:
24
+ parser = argparse.ArgumentParser(prog="tigrcorn certify static")
25
+ parser.add_argument("--mount", required=True, help="Static mount directory to certify")
26
+ parser.add_argument("--profile", default="default", help="Blessed deployment profile")
27
+ parser.add_argument("--output", required=True, help="Directory where certification artifacts are written")
28
+ return parser
29
+
30
+
31
+ def certify_static(
32
+ *,
33
+ mount: str | Path,
34
+ profile: str = "default",
35
+ output: str | Path,
36
+ require_supported: Callable[[Iterable[str]], None] | None = None,
37
+ ) -> dict[str, object]:
38
+ mount_path = Path(mount)
39
+ if not mount_path.exists() or not mount_path.is_dir():
40
+ raise StaticCertificationCommandError(f"static mount does not exist or is not a directory: {mount_path}")
41
+
42
+ if require_supported is not None:
43
+ require_supported(["delivery.static"])
44
+
45
+ evidence = build_static_certification_evidence(mount_path, profile=profile)
46
+ certification = certify_static_delivery_security(evidence)
47
+ static_artifact = {
48
+ "artifact": static_delivery_certification_artifact(),
49
+ "certification": certification,
50
+ "evidence": evidence,
51
+ "mount_name": mount_path.name,
52
+ "profile": profile,
53
+ "schema_version": 1,
54
+ }
55
+ manifest = {
56
+ "artifacts": [
57
+ {
58
+ "digest": _digest(static_artifact),
59
+ "name": "static.json",
60
+ }
61
+ ],
62
+ "certification": "static",
63
+ "digest_algorithm": "sha256",
64
+ "manifest_version": 1,
65
+ "profile": profile,
66
+ }
67
+ output_path = Path(output)
68
+ output_path.mkdir(parents=True, exist_ok=True)
69
+ static_path = output_path / "static.json"
70
+ manifest_path = output_path / "manifest.json"
71
+ static_path.write_text(canonical_json(static_artifact), encoding="utf-8", newline="\n")
72
+ manifest_path.write_text(canonical_json(manifest), encoding="utf-8", newline="\n")
73
+ return {
74
+ "artifact_paths": [str(static_path), str(manifest_path)],
75
+ "mount": str(mount_path),
76
+ "output": str(output_path),
77
+ "passed": True,
78
+ "profile": profile,
79
+ }
80
+
81
+
82
+ def certify_static_main(
83
+ argv: list[str] | None = None,
84
+ *,
85
+ require_supported: Callable[[Iterable[str]], None] | None = None,
86
+ ) -> int:
87
+ parser = build_static_certification_parser()
88
+ ns = parser.parse_args(list(argv or ()))
89
+
90
+ capability_gate = None
91
+ if require_supported is not None:
92
+ capability_gate = lambda ids: require_supported(ids, profile=ns.profile) # noqa: E731
93
+ try:
94
+ result = certify_static(
95
+ mount=ns.mount,
96
+ profile=ns.profile,
97
+ output=ns.output,
98
+ require_supported=capability_gate,
99
+ )
100
+ except (StaticCertificationCommandError, StaticSecurityCertificationError, ValueError) as exc:
101
+ print(str(exc), file=sys.stderr)
102
+ return 2
103
+ print(json.dumps(result, sort_keys=True, separators=(",", ":")))
104
+ return 0
105
+
106
+
107
+ def _digest(payload: dict[str, object]) -> str:
108
+ import hashlib
109
+
110
+ return hashlib.sha256(canonical_json(payload).encode("utf-8")).hexdigest()
111
+
112
+
113
+ __all__ = [
114
+ "StaticCertificationCommandError",
115
+ "build_static_certification_parser",
116
+ "certify_static",
117
+ "certify_static_main",
118
+ ]
@@ -0,0 +1,103 @@
1
+ from __future__ import annotations
2
+
3
+ from copy import deepcopy
4
+ from typing import Any
5
+
6
+
7
+ HARDENING_SUITE_CATALOG: dict[str, dict[str, Any]] = {
8
+ "http1": {
9
+ "owner_package": "tigrcorn-protocols",
10
+ "package_tests": ["tests/test_http1_hardening_pass.py"],
11
+ "cross_cutting_tests": ["tests/test_adversarial_protocol_hardening_suites.py"],
12
+ "feature_ids": ["feat:adversarial-protocol-hardening-suites"],
13
+ "spec_ids": ["spc:2080"],
14
+ "cases": ["slowloris", "malformed_chunking", "request_smuggling", "oversized_headers", "premature_eof"],
15
+ },
16
+ "http2": {
17
+ "owner_package": "tigrcorn-protocols",
18
+ "package_tests": ["tests/test_http2_state_machine_completion.py"],
19
+ "cross_cutting_tests": ["tests/test_adversarial_protocol_hardening_suites.py"],
20
+ "feature_ids": ["feat:adversarial-protocol-hardening-suites"],
21
+ "spec_ids": ["spc:2080"],
22
+ "cases": ["rapid_reset", "continuation_flood", "stream_exhaustion", "settings_churn", "flow_control_deadlock"],
23
+ },
24
+ "http3_quic": {
25
+ "owner_package": "tigrcorn-transports",
26
+ "package_tests": ["tests/test_quic_operational_security_certification.py", "tests/test_quic_impairment_policy.py"],
27
+ "cross_cutting_tests": ["tests/test_quic_operational_security_integration.py", "tests/test_quic_recovery_live_runtime_integration.py"],
28
+ "feature_ids": ["feat:quic-operational-security-certification", "feat:adversarial-protocol-hardening-suites"],
29
+ "spec_ids": ["spc:2060", "spc:2080"],
30
+ "cases": ["packet_loss", "packet_reordering", "packet_duplication", "controlled_delay", "reliable_stream_recovery", "datagram_abandonment", "amplification_limit", "connection_migration", "cid_rotation"],
31
+ },
32
+ "websocket": {
33
+ "owner_package": "tigrcorn-protocols",
34
+ "package_tests": ["tests/test_server_websocket.py"],
35
+ "cross_cutting_tests": ["tests/test_adversarial_protocol_hardening_suites.py"],
36
+ "feature_ids": ["feat:adversarial-protocol-hardening-suites"],
37
+ "spec_ids": ["spc:2080"],
38
+ "cases": ["fragmented_control_frames", "masking_rules", "close_races", "compression_bombs"],
39
+ },
40
+ "webtransport": {
41
+ "owner_package": "tigrcorn-protocols",
42
+ "package_tests": ["tests/test_webtransport_resource_governance.py"],
43
+ "cross_cutting_tests": ["tests/test_webtransport_resource_governance_integration.py"],
44
+ "feature_ids": ["feat:webtransport-resource-governance", "feat:adversarial-protocol-hardening-suites"],
45
+ "spec_ids": ["spc:2061", "spc:2080"],
46
+ "cases": ["session_budget", "stream_budget", "datagram_budget", "drain", "reset_stop_sending"],
47
+ },
48
+ "static": {
49
+ "owner_package": "tigrcorn-static",
50
+ "package_tests": ["tests/test_static_delivery_security_certification.py"],
51
+ "cross_cutting_tests": ["tests/test_certification_command_namespace.py"],
52
+ "feature_ids": ["feat:static-delivery-security-certification", "feat:adversarial-protocol-hardening-suites"],
53
+ "spec_ids": ["spc:2062", "spc:2080"],
54
+ "cases": ["traversal", "sidecar_mismatch", "range_amplification", "content_type_ambiguity"],
55
+ },
56
+ "observability": {
57
+ "owner_package": "tigrcorn-observability",
58
+ "package_tests": ["tests/test_protocol_aware_observability.py"],
59
+ "cross_cutting_tests": ["tests/test_protocol_aware_observability_integration.py"],
60
+ "feature_ids": ["feat:protocol-aware-observability"],
61
+ "spec_ids": ["spc:2064"],
62
+ "cases": ["metric_names", "event_names", "cardinality_limits"],
63
+ },
64
+ "certification": {
65
+ "owner_package": "tigrcorn-certification",
66
+ "package_tests": ["tests/test_certification_command_namespace.py"],
67
+ "cross_cutting_tests": ["tests/test_adversarial_protocol_hardening_suites.py"],
68
+ "feature_ids": ["feat:certification-command-namespace"],
69
+ "spec_ids": ["spc:2079"],
70
+ "cases": ["command_dispatch", "artifact_shape", "leaf_import_boundary", "fail_closed"],
71
+ },
72
+ }
73
+
74
+
75
+ def export_hardening_suite_catalog() -> dict[str, Any]:
76
+ return {
77
+ "catalog": deepcopy(HARDENING_SUITE_CATALOG),
78
+ "schema_version": 1,
79
+ }
80
+
81
+
82
+ def validate_hardening_suite_catalog(catalog: dict[str, dict[str, Any]] | None = None) -> dict[str, Any]:
83
+ selected = catalog or HARDENING_SUITE_CATALOG
84
+ failures: list[str] = []
85
+ for suite_id, suite in sorted(selected.items()):
86
+ owner = suite.get("owner_package")
87
+ if not isinstance(owner, str) or not owner.startswith("tigrcorn-"):
88
+ failures.append(f"{suite_id}: owner_package must be a tigrcorn distribution")
89
+ for field in ("package_tests", "cross_cutting_tests", "feature_ids", "spec_ids", "cases"):
90
+ values = suite.get(field)
91
+ if not isinstance(values, list) or not values:
92
+ failures.append(f"{suite_id}: {field} must be a non-empty list")
93
+ for test_path in suite.get("package_tests", []) + suite.get("cross_cutting_tests", []):
94
+ if not isinstance(test_path, str) or not test_path.startswith("tests/"):
95
+ failures.append(f"{suite_id}: test path must be under tests/: {test_path!r}")
96
+ return {"failures": failures, "passed": not failures, "suite_count": len(selected)}
97
+
98
+
99
+ __all__ = [
100
+ "HARDENING_SUITE_CATALOG",
101
+ "export_hardening_suite_catalog",
102
+ "validate_hardening_suite_catalog",
103
+ ]
@@ -5,6 +5,7 @@ from .process import *
5
5
  from .helpers import *
6
6
  from .adapters import *
7
7
  from .proxies import *
8
+ from .impairment import *
8
9
  from .ports import *
9
10
  from .environment import *
10
11
  from .assertions import *
@@ -0,0 +1,55 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass, field
4
+
5
+
6
+ @dataclass(frozen=True, slots=True)
7
+ class UDPImpairmentProfile:
8
+ """Deterministic UDP impairment settings for repeatable QUIC proofs."""
9
+
10
+ drop_every: int = 0
11
+ duplicate_every: int = 0
12
+ reorder_every: int = 0
13
+ delay_seconds: float = 0.0
14
+
15
+ def __post_init__(self) -> None:
16
+ for name in ("drop_every", "duplicate_every", "reorder_every"):
17
+ if int(getattr(self, name)) < 0:
18
+ raise ValueError(f"{name} must be non-negative")
19
+ if self.delay_seconds < 0:
20
+ raise ValueError("delay_seconds must be non-negative")
21
+
22
+
23
+ @dataclass(slots=True)
24
+ class UDPImpairmentPolicy:
25
+ profile: UDPImpairmentProfile
26
+ _counts: dict[str, int] = field(default_factory=dict)
27
+ _held: dict[str, bytes] = field(default_factory=dict)
28
+
29
+ def apply(self, direction: str, payload: bytes) -> tuple[bytes, ...]:
30
+ count = self._counts.get(direction, 0) + 1
31
+ self._counts[direction] = count
32
+ if self.profile.drop_every and count % self.profile.drop_every == 0:
33
+ return ()
34
+
35
+ emitted: list[bytes] = []
36
+ held = self._held.pop(direction, None)
37
+ if self.profile.reorder_every and count % self.profile.reorder_every == 0:
38
+ self._held[direction] = bytes(payload)
39
+ if held is not None:
40
+ emitted.append(held)
41
+ return tuple(emitted)
42
+
43
+ emitted.append(bytes(payload))
44
+ if held is not None:
45
+ emitted.append(held)
46
+ if self.profile.duplicate_every and count % self.profile.duplicate_every == 0:
47
+ emitted.append(bytes(payload))
48
+ return tuple(emitted)
49
+
50
+ def flush(self, direction: str) -> tuple[bytes, ...]:
51
+ held = self._held.pop(direction, None)
52
+ return () if held is None else (held,)
53
+
54
+
55
+ __all__ = ["UDPImpairmentPolicy", "UDPImpairmentProfile"]
@@ -3,6 +3,7 @@ from __future__ import annotations
3
3
  from .imports import *
4
4
  from .helpers import *
5
5
  from .ports import _normalize_sockaddr
6
+ from .impairment import UDPImpairmentPolicy
6
7
 
7
8
  class _PacketTraceWriter:
8
9
  def __init__(self, path: Path) -> None:
@@ -124,7 +125,7 @@ class TCPRecordProxy:
124
125
 
125
126
 
126
127
  class UDPRecordProxy:
127
- def __init__(self, *, listen_host: str, listen_port: int, target_host: str, target_port: int, packet_trace_path: Path, ip_family: str = 'ipv4') -> None:
128
+ def __init__(self, *, listen_host: str, listen_port: int, target_host: str, target_port: int, packet_trace_path: Path, ip_family: str = 'ipv4', impairment: UDPImpairmentPolicy | None = None) -> None:
128
129
  family = socket.AF_INET6 if ip_family == 'ipv6' else socket.AF_INET
129
130
  self.listen_host = listen_host
130
131
  self.listen_port = listen_port
@@ -144,6 +145,14 @@ class UDPRecordProxy:
144
145
  self._stop = threading.Event()
145
146
  self._thread = threading.Thread(target=self._loop, daemon=True)
146
147
  self._last_client: tuple[str, int] | None = None
148
+ self._impairment = impairment
149
+
150
+ def _forward_payloads(self, direction: str, payload: bytes) -> tuple[bytes, ...]:
151
+ if self._impairment is None:
152
+ return (payload,)
153
+ if self._impairment.profile.delay_seconds:
154
+ time.sleep(self._impairment.profile.delay_seconds)
155
+ return self._impairment.apply(direction, payload)
147
156
 
148
157
  def start(self) -> None:
149
158
  self._thread.start()
@@ -170,10 +179,11 @@ class UDPRecordProxy:
170
179
  remote=(self.target_host, self.target_port),
171
180
  payload=payload,
172
181
  )
173
- try:
174
- self._upstream.sendto(payload, target)
175
- except OSError:
176
- continue
182
+ for forwarded in self._forward_payloads('client_to_server', payload):
183
+ try:
184
+ self._upstream.sendto(forwarded, target)
185
+ except OSError:
186
+ continue
177
187
  elif key.fileobj is self._upstream:
178
188
  try:
179
189
  payload, _addr = self._upstream.recvfrom(65535)
@@ -188,10 +198,11 @@ class UDPRecordProxy:
188
198
  remote=self._last_client,
189
199
  payload=payload,
190
200
  )
191
- try:
192
- self._downstream.sendto(payload, self._last_client)
193
- except OSError:
194
- continue
201
+ for forwarded in self._forward_payloads('server_to_client', payload):
202
+ try:
203
+ self._downstream.sendto(forwarded, self._last_client)
204
+ except OSError:
205
+ continue
195
206
  finally:
196
207
  selector.close()
197
208
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tigrcorn-certification
3
- Version: 0.3.18.dev2
3
+ Version: 0.3.18.dev3
4
4
  Summary: Certification and release-gate tooling for Tigrcorn HTTP/3, QUIC, WebSocket, WebTransport, and ASGI conformance evidence.
5
5
  Author-email: Jacob Stewart <jacob@swarmauri.com>
6
6
  License: Apache License
@@ -187,8 +187,9 @@ Classifier: Typing :: Typed
187
187
  Requires-Python: <3.15,>=3.10
188
188
  Description-Content-Type: text/markdown
189
189
  License-File: LICENSE
190
- Requires-Dist: tigrcorn-compat==0.3.18.dev2
191
- Requires-Dist: tigrcorn-runtime==0.3.18.dev2
190
+ Requires-Dist: tigrcorn-compat==0.3.18.dev3
191
+ Requires-Dist: tigrcorn-runtime==0.3.18.dev3
192
+ Requires-Dist: tigrcorn-static==0.3.18.dev3
192
193
  Requires-Dist: tomli>=2.0.0; python_version < "3.11"
193
194
  Requires-Dist: cryptography>=46.0.0
194
195
  Requires-Dist: aioquic>=1.3.0
@@ -286,7 +287,7 @@ The package exposes its supported public surface through the <code>tigrcorn_cert
286
287
 
287
288
  ## Package Graph
288
289
 
289
- [tigrcorn-core](https://pypi.org/project/tigrcorn-core/) | [tigrcorn-config](https://pypi.org/project/tigrcorn-config/) | [tigrcorn-http](https://pypi.org/project/tigrcorn-http/) | [tigrcorn-asgi](https://pypi.org/project/tigrcorn-asgi/) | [tigrcorn-contract](https://pypi.org/project/tigrcorn-contract/) | [tigrcorn-transports](https://pypi.org/project/tigrcorn-transports/) | [tigrcorn-security](https://pypi.org/project/tigrcorn-security/) | [tigrcorn-protocols](https://pypi.org/project/tigrcorn-protocols/) | [tigrcorn-static](https://pypi.org/project/tigrcorn-static/) | [tigrcorn-observability](https://pypi.org/project/tigrcorn-observability/) | [tigrcorn-runtime](https://pypi.org/project/tigrcorn-runtime/) | [tigrcorn-compat](https://pypi.org/project/tigrcorn-compat/) | [tigrcorn-certification](https://pypi.org/project/tigrcorn-certification/)
290
+ [tigrcorn-core](https://pypi.org/project/tigrcorn-core/) | [tigrcorn-quic-cc](https://pypi.org/project/tigrcorn-quic-cc/) | [tigrcorn-quic-cc-reno](https://pypi.org/project/tigrcorn-quic-cc-reno/) | [tigrcorn-config](https://pypi.org/project/tigrcorn-config/) | [tigrcorn-http](https://pypi.org/project/tigrcorn-http/) | [tigrcorn-asgi](https://pypi.org/project/tigrcorn-asgi/) | [tigrcorn-contract](https://pypi.org/project/tigrcorn-contract/) | [tigrcorn-transports](https://pypi.org/project/tigrcorn-transports/) | [tigrcorn-security](https://pypi.org/project/tigrcorn-security/) | [tigrcorn-protocols](https://pypi.org/project/tigrcorn-protocols/) | [tigrcorn-static](https://pypi.org/project/tigrcorn-static/) | [tigrcorn-observability](https://pypi.org/project/tigrcorn-observability/) | [tigrcorn-runtime](https://pypi.org/project/tigrcorn-runtime/) | [tigrcorn-compat](https://pypi.org/project/tigrcorn-compat/) | [tigrcorn-certification](https://pypi.org/project/tigrcorn-certification/)
290
291
 
291
292
  ## Best Practices
292
293
 
@@ -1,8 +1,9 @@
1
- tigrcorn_certification/__init__.py,sha256=qF7Ks2Zpme2WCdIOWeXUwOuwSSQWpfaNSrBBtyJGrpU,7523
1
+ tigrcorn_certification/__init__.py,sha256=iLEmpbSATnJ7O6QYCCREOf8iUsn-lQxpAR3pgYnzH5I,8398
2
2
  tigrcorn_certification/artifacts.py,sha256=K967bTVgOpZzr_OH18aLUZLrMruzPHjFkTiOUX2Obxg,12550
3
3
  tigrcorn_certification/certification_env.py,sha256=gnZ9kucADBPzKKckJiZ79zsTmCftVAcPWNuV_-Khc-g,18870
4
4
  tigrcorn_certification/conformance.py,sha256=ZEeLg_ctMTvhP-Zyr1k1xFHs5qBTQUTyGPOCjLlySOs,1384
5
5
  tigrcorn_certification/explicit_surfaces.py,sha256=UeQB5ozbmJInmZL-YLiLdaavhQzSMtXDMRdaecx6dhY,4998
6
+ tigrcorn_certification/hardening_suites.py,sha256=zLvv0k5bXb2v8QTkKU2F-y6SP2sTGh7JOGscfknOxP8,5423
6
7
  tigrcorn_certification/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
7
8
  tigrcorn_certification/supply_chain.py,sha256=a440IgDn2FENjE48-MMhCD2kq9O6TocbA43KM4GipgY,14637
8
9
  tigrcorn_certification/aioquic_preflight/__init__.py,sha256=q399JJr0FfyzYVJlPQb7k2eDQh2gyFKDksnUIQR9m0g,219
@@ -12,18 +13,21 @@ tigrcorn_certification/aioquic_preflight/helpers.py,sha256=rCqxxEdT9jyE_3kp2YbJA
12
13
  tigrcorn_certification/aioquic_preflight/imports.py,sha256=D65ubIap_8TsomTH7RYVgOCn7WuChINPQhZEjhky9xY,984
13
14
  tigrcorn_certification/aioquic_preflight/records.py,sha256=RADvzubi9u7bL1zcP0b4Man3oUfCFFClOKWuDbITSnA,3338
14
15
  tigrcorn_certification/aioquic_preflight/status_docs.py,sha256=KbFnbTP2cxyhKQYqUqWslBQ4vmHPoAKBMnDwRLxDgag,5961
15
- tigrcorn_certification/interop_runner/__init__.py,sha256=gxcj0H3GrKQDpqzWN7KEg-Ma_WM0INDZopRPPBLWvpM,401
16
+ tigrcorn_certification/certify/__init__.py,sha256=m7bBFFFBAIB_OBfXh_8OZOZcdAjOcmoAyDWFdyg2eIA,145
17
+ tigrcorn_certification/certify/static.py,sha256=iPm55pTkD6Hw4ZpNoWa7WLUdrwB2NMhdIVL5twFOtww,3835
18
+ tigrcorn_certification/interop_runner/__init__.py,sha256=Qn6Xv5voWpAdFeG77A3bE9hr8dp1PyvmkLNhl05TaKo,427
16
19
  tigrcorn_certification/interop_runner/adapters.py,sha256=ObHpywZ6AKjpvYCf60IoEtOCcsKII0YUTVVUV3ykABM,10196
17
20
  tigrcorn_certification/interop_runner/assertions.py,sha256=WoZ1wtOyzytRUObTpvSGY151_mJfReVM3UaAyCUmCEo,3107
18
21
  tigrcorn_certification/interop_runner/core.py,sha256=MuwI_55Ami08rIOJLrK_0eEuRvh_zIitJF3RaWPlNjE,759
19
22
  tigrcorn_certification/interop_runner/environment.py,sha256=rZovo6Ch_MV3Vj2m8pQL7yqYbYObF7paB0WNj6aFlJw,9519
20
23
  tigrcorn_certification/interop_runner/helpers.py,sha256=pSub34BNOapKeV3EHgRea4pTD0L9_vY0K1yLVGSI9NA,6554
24
+ tigrcorn_certification/interop_runner/impairment.py,sha256=4k9IM7hugKJ5ebBJt3AoBhEtUfuvCKi1XVR_sulqevQ,1915
21
25
  tigrcorn_certification/interop_runner/imports.py,sha256=vNt9MD_rERSl38raeOyyglDRR_J9E6cAv-jTXmRmXME,1397
22
26
  tigrcorn_certification/interop_runner/matrix.py,sha256=60LPxs1BAbQsBWkyBIfra5WbP7xyjMB0qzT45K0eEDI,6475
23
27
  tigrcorn_certification/interop_runner/models.py,sha256=jZ2jSjWRFAPaDRMZMblsiNaQIKDsxtOfu9fR5l69Q8Q,4261
24
28
  tigrcorn_certification/interop_runner/ports.py,sha256=50HTDT6wT02r_5KkxdvACvLOtbIVe5_aTIHju81Fl98,3003
25
29
  tigrcorn_certification/interop_runner/process.py,sha256=Bzp0C3QDt7skiycgDczGThI-sUBFKT8CNBvYqJFYZlg,1574
26
- tigrcorn_certification/interop_runner/proxies.py,sha256=rKEHaMuqXXdUpZNz6APAnQC09uBT5_wHNth-89ZvcKY,8462
30
+ tigrcorn_certification/interop_runner/proxies.py,sha256=WxjCjQ7eI9SHkvIndOrf50NjHW78eHKEhgBTyYAsdRc,9141
27
31
  tigrcorn_certification/interop_runner/qlog.py,sha256=JJRPN6n2uEiKsLxDSe8xef1ETuI48rwCCwAuG7mq-2M,5416
28
32
  tigrcorn_certification/interop_runner/runner.py,sha256=L2WM-rr7kcZ6Z50m1ueI5-OHPT4gJzXiDKXv2j_UooE,5400
29
33
  tigrcorn_certification/interop_runner/scenario.py,sha256=UDWw1REn-JlGO6z9IX4fSfYFbdEoGZbIjr8YTKR-11o,18328
@@ -49,8 +53,8 @@ tigrcorn_certification/release_gates/models.py,sha256=7SG4DDjyFKXT3QI5-uD_uMiLBB
49
53
  tigrcorn_certification/release_gates/promotion.py,sha256=7Uc-gpCI_w-fsNOX2y_9m62shj0uZV74VJnnyhqHork,4421
50
54
  tigrcorn_certification/release_gates/promotion_sections.py,sha256=5ifaqi2qvQADZeVdJy_-D5XeAfSauwDM_wtVX9efXt8,22839
51
55
  tigrcorn_certification/release_gates/supply_chain_gate.py,sha256=RMfF8pZZ9kx2mSKoGHPY4xKripMyoZ426xG_regIcyY,2013
52
- tigrcorn_certification-0.3.18.dev2.dist-info/licenses/LICENSE,sha256=xhBSirl227aDQNeQ8tk2v_yiU9nbQpJ4EZp6OtATX-s,9591
53
- tigrcorn_certification-0.3.18.dev2.dist-info/METADATA,sha256=OXpNsdrao6Gz9OKGS8mMkcH9SUjeYo5jXAorY-0tUF8,19023
54
- tigrcorn_certification-0.3.18.dev2.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
55
- tigrcorn_certification-0.3.18.dev2.dist-info/top_level.txt,sha256=FKo2THHSY3N-bEXFChxYVwG_PX1YGSk9_VSG7ePcLWc,23
56
- tigrcorn_certification-0.3.18.dev2.dist-info/RECORD,,
56
+ tigrcorn_certification-0.3.18.dev3.dist-info/licenses/LICENSE,sha256=xhBSirl227aDQNeQ8tk2v_yiU9nbQpJ4EZp6OtATX-s,9591
57
+ tigrcorn_certification-0.3.18.dev3.dist-info/METADATA,sha256=buqMf1vHD_jRDNZ_rZEsJYrlJbM4U2HobcAoeI7vt4g,19207
58
+ tigrcorn_certification-0.3.18.dev3.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
59
+ tigrcorn_certification-0.3.18.dev3.dist-info/top_level.txt,sha256=FKo2THHSY3N-bEXFChxYVwG_PX1YGSk9_VSG7ePcLWc,23
60
+ tigrcorn_certification-0.3.18.dev3.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (82.0.1)
2
+ Generator: setuptools (84.2.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5