percolation-inversion-compiler 0.4.1__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.
Files changed (86) hide show
  1. percolation_inversion_compiler/__init__.py +7 -0
  2. percolation_inversion_compiler/adapters/__init__.py +39 -0
  3. percolation_inversion_compiler/adapters/domain.py +338 -0
  4. percolation_inversion_compiler/adapters/graphs.py +15 -0
  5. percolation_inversion_compiler/adapters/optimization.py +25 -0
  6. percolation_inversion_compiler/adapters/transport.py +19 -0
  7. percolation_inversion_compiler/adapters/units.py +17 -0
  8. percolation_inversion_compiler/agent/__init__.py +51 -0
  9. percolation_inversion_compiler/agent/algorithms.py +1297 -0
  10. percolation_inversion_compiler/agent/records.py +175 -0
  11. percolation_inversion_compiler/alt/__init__.py +119 -0
  12. percolation_inversion_compiler/alt/algorithms.py +1063 -0
  13. percolation_inversion_compiler/alt/records.py +553 -0
  14. percolation_inversion_compiler/bit/__init__.py +125 -0
  15. percolation_inversion_compiler/bit/algorithms.py +815 -0
  16. percolation_inversion_compiler/bit/records.py +207 -0
  17. percolation_inversion_compiler/cli.py +3606 -0
  18. percolation_inversion_compiler/core/__init__.py +179 -0
  19. percolation_inversion_compiler/core/adapter_routes.py +746 -0
  20. percolation_inversion_compiler/core/algebra.py +200 -0
  21. percolation_inversion_compiler/core/algorithms.py +104 -0
  22. percolation_inversion_compiler/core/calibration.py +243 -0
  23. percolation_inversion_compiler/core/certificates.py +129 -0
  24. percolation_inversion_compiler/core/checker.py +344 -0
  25. percolation_inversion_compiler/core/coverage.py +1336 -0
  26. percolation_inversion_compiler/core/frontier.py +103 -0
  27. percolation_inversion_compiler/core/graph.py +76 -0
  28. percolation_inversion_compiler/core/judgment.py +240 -0
  29. percolation_inversion_compiler/core/ledger.py +184 -0
  30. percolation_inversion_compiler/core/operations.py +44 -0
  31. percolation_inversion_compiler/core/order.py +207 -0
  32. percolation_inversion_compiler/core/records.py +257 -0
  33. percolation_inversion_compiler/core/status.py +115 -0
  34. percolation_inversion_compiler/data/__init__.py +1 -0
  35. percolation_inversion_compiler/data/demo/__init__.py +1 -0
  36. percolation_inversion_compiler/data/demo/agent_output.txt +1 -0
  37. percolation_inversion_compiler/data/demo/alt_admission_packet.json +201 -0
  38. percolation_inversion_compiler/data/demo/general_intake_policy.json +58 -0
  39. percolation_inversion_compiler/data/demo/manifest.json +41 -0
  40. percolation_inversion_compiler/data/demo/runtime_state.json +143 -0
  41. percolation_inversion_compiler/data/demo/runtime_step_input.json +8 -0
  42. percolation_inversion_compiler/data/snapshots/__init__.py +1 -0
  43. percolation_inversion_compiler/data/snapshots/alt.json +6073 -0
  44. percolation_inversion_compiler/data/snapshots/bit.json +543 -0
  45. percolation_inversion_compiler/data/snapshots/ecpt.json +2741 -0
  46. percolation_inversion_compiler/data/snapshots/sqot.json +2134 -0
  47. percolation_inversion_compiler/data/snapshots/trc.json +2880 -0
  48. percolation_inversion_compiler/ecology/__init__.py +184 -0
  49. percolation_inversion_compiler/ecology/algorithms.py +1621 -0
  50. percolation_inversion_compiler/ecology/connectors.py +198 -0
  51. percolation_inversion_compiler/ecology/general_intake.py +1869 -0
  52. percolation_inversion_compiler/ecology/records.py +856 -0
  53. percolation_inversion_compiler/ecpt/__init__.py +173 -0
  54. percolation_inversion_compiler/ecpt/algorithms.py +1113 -0
  55. percolation_inversion_compiler/ecpt/records.py +405 -0
  56. percolation_inversion_compiler/identity/__init__.py +45 -0
  57. percolation_inversion_compiler/identity/algorithms.py +967 -0
  58. percolation_inversion_compiler/identity/records.py +174 -0
  59. percolation_inversion_compiler/io/__init__.py +113 -0
  60. percolation_inversion_compiler/io/audit.py +219 -0
  61. percolation_inversion_compiler/io/doctor.py +372 -0
  62. percolation_inversion_compiler/io/provenance.py +228 -0
  63. percolation_inversion_compiler/io/sbom.py +109 -0
  64. percolation_inversion_compiler/io/schema.py +587 -0
  65. percolation_inversion_compiler/io/snapshots.py +159 -0
  66. percolation_inversion_compiler/io/tex.py +573 -0
  67. percolation_inversion_compiler/io/zenodo.py +173 -0
  68. percolation_inversion_compiler/py.typed +1 -0
  69. percolation_inversion_compiler/runtime/__init__.py +132 -0
  70. percolation_inversion_compiler/runtime/algorithms.py +2264 -0
  71. percolation_inversion_compiler/runtime/records.py +668 -0
  72. percolation_inversion_compiler/runtime/service.py +514 -0
  73. percolation_inversion_compiler/runtime/store.py +352 -0
  74. percolation_inversion_compiler/sqot/__init__.py +37 -0
  75. percolation_inversion_compiler/sqot/algorithms.py +213 -0
  76. percolation_inversion_compiler/sqot/records.py +130 -0
  77. percolation_inversion_compiler/trc/__init__.py +155 -0
  78. percolation_inversion_compiler/trc/algorithms.py +1004 -0
  79. percolation_inversion_compiler/trc/datacenter.py +297 -0
  80. percolation_inversion_compiler/trc/records.py +361 -0
  81. percolation_inversion_compiler-0.4.1.dist-info/METADATA +282 -0
  82. percolation_inversion_compiler-0.4.1.dist-info/RECORD +86 -0
  83. percolation_inversion_compiler-0.4.1.dist-info/WHEEL +4 -0
  84. percolation_inversion_compiler-0.4.1.dist-info/entry_points.txt +2 -0
  85. percolation_inversion_compiler-0.4.1.dist-info/licenses/LICENSE +152 -0
  86. percolation_inversion_compiler-0.4.1.dist-info/licenses/NOTICE +21 -0
@@ -0,0 +1,7 @@
1
+ """Finite certificate compiler interfaces for ECPT, BIT, TRC, SQOT, and ALT."""
2
+
3
+ from __future__ import annotations
4
+
5
+ __all__ = ["__version__"]
6
+
7
+ __version__ = "0.4.1"
@@ -0,0 +1,39 @@
1
+ """Optional adapters for scientific OSS dependencies."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from percolation_inversion_compiler.adapters.domain import (
6
+ replay_trc_physical_trace,
7
+ verify_archive_domain_evidence,
8
+ verify_ecpt_bridge_reserve,
9
+ verify_ecpt_domain_abstraction,
10
+ verify_ecpt_execution_policy,
11
+ verify_ecpt_generator_limit,
12
+ verify_ecpt_numerical_envelope,
13
+ verify_ecpt_proxy_target_contract,
14
+ verify_ecpt_speculative_channel_repair,
15
+ verify_ecpt_trace_diagnostic_projection,
16
+ verify_trc_telemetry_calibration,
17
+ )
18
+ from percolation_inversion_compiler.adapters.graphs import shortest_path_lengths
19
+ from percolation_inversion_compiler.adapters.optimization import solve_linear_release
20
+ from percolation_inversion_compiler.adapters.transport import sinkhorn_transport
21
+ from percolation_inversion_compiler.adapters.units import assert_compatible_units
22
+
23
+ __all__ = [
24
+ "assert_compatible_units",
25
+ "replay_trc_physical_trace",
26
+ "shortest_path_lengths",
27
+ "sinkhorn_transport",
28
+ "solve_linear_release",
29
+ "verify_archive_domain_evidence",
30
+ "verify_ecpt_bridge_reserve",
31
+ "verify_ecpt_domain_abstraction",
32
+ "verify_ecpt_execution_policy",
33
+ "verify_ecpt_generator_limit",
34
+ "verify_ecpt_numerical_envelope",
35
+ "verify_ecpt_proxy_target_contract",
36
+ "verify_ecpt_speculative_channel_repair",
37
+ "verify_ecpt_trace_diagnostic_projection",
38
+ "verify_trc_telemetry_calibration",
39
+ ]
@@ -0,0 +1,338 @@
1
+ """Deterministic finite domain-adapter checks for production evidence routes."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from percolation_inversion_compiler.core.checker import residual_from_reasons
6
+ from percolation_inversion_compiler.core.ledger import CoordinateKind, Ledger
7
+ from percolation_inversion_compiler.core.records import CheckResult
8
+ from percolation_inversion_compiler.core.status import ClaimStatus
9
+
10
+
11
+ def _domain_result(name: str, reasons: list[str], residual: Ledger | None = None) -> CheckResult:
12
+ residual_ledger = residual or Ledger()
13
+ residual_ledger = residual_ledger.combine(residual_from_reasons(name, reasons))
14
+ accepted = not reasons
15
+ return CheckResult(
16
+ accepted=accepted,
17
+ status=ClaimStatus.SETTLED if accepted else ClaimStatus.DIAGNOSTIC,
18
+ finite_checks_passed=accepted,
19
+ operationally_usable=accepted,
20
+ settled=accepted,
21
+ reasons=sorted(set(reasons)),
22
+ missing_obligations=[] if accepted else [f"{name}:accepted"],
23
+ residual_ledger=residual_ledger,
24
+ )
25
+
26
+
27
+ def verify_ecpt_numerical_envelope(
28
+ *,
29
+ residual: float,
30
+ residual_bound: float,
31
+ finite_horizon: int,
32
+ ) -> CheckResult:
33
+ """Check a finite ECPT numerical envelope without asserting limit behavior."""
34
+
35
+ reasons: list[str] = []
36
+ ledger = Ledger()
37
+ if finite_horizon < 0:
38
+ reasons.append("finite horizon is negative")
39
+ if residual < 0 or residual_bound < 0:
40
+ reasons.append("numerical envelope residuals must be nonnegative")
41
+ if residual > residual_bound:
42
+ reasons.append("numerical envelope residual exceeds certified bound")
43
+ ledger = ledger.add_coordinate(
44
+ "ecpt:numerical-envelope:gap",
45
+ residual - residual_bound,
46
+ kind=CoordinateKind.RESIDUAL,
47
+ )
48
+ return _domain_result("ecpt-numerical-envelope", reasons, ledger)
49
+
50
+
51
+ def verify_ecpt_generator_limit(
52
+ *,
53
+ observed_generation: float,
54
+ certified_limit: float,
55
+ residual_allowance: float = 0.0,
56
+ ) -> CheckResult:
57
+ """Check a finite generator-limit certificate."""
58
+
59
+ reasons: list[str] = []
60
+ ledger = Ledger()
61
+ if certified_limit < 0 or observed_generation < 0 or residual_allowance < 0:
62
+ reasons.append("generator limit inputs must be nonnegative")
63
+ gap = observed_generation - certified_limit - residual_allowance
64
+ if gap > 0:
65
+ reasons.append("observed generation exceeds certified limit plus residual allowance")
66
+ ledger = ledger.add_coordinate(
67
+ "ecpt:generator-limit:excess",
68
+ gap,
69
+ kind=CoordinateKind.RESIDUAL,
70
+ )
71
+ return _domain_result("ecpt-generator-limit", reasons, ledger)
72
+
73
+
74
+ def verify_ecpt_bridge_reserve(
75
+ bridge_relations: dict[str, str],
76
+ required_relations: dict[str, str],
77
+ *,
78
+ reserve: float,
79
+ minimum_reserve: float,
80
+ ) -> CheckResult:
81
+ """Check finite cross-theory bridge relations and reserve budget."""
82
+
83
+ reasons: list[str] = []
84
+ ledger = Ledger()
85
+ if reserve < 0 or minimum_reserve < 0:
86
+ reasons.append("bridge reserve inputs must be nonnegative")
87
+ missing = sorted(
88
+ key for key, target in required_relations.items() if bridge_relations.get(key) != target
89
+ )
90
+ if missing:
91
+ reasons.append("bridge reserve is missing required finite relations")
92
+ if reserve < minimum_reserve:
93
+ reasons.append("bridge reserve is below certified minimum")
94
+ ledger = ledger.add_coordinate(
95
+ "ecpt:bridge-reserve:gap",
96
+ minimum_reserve - reserve,
97
+ kind=CoordinateKind.RESIDUAL,
98
+ )
99
+ for key in missing:
100
+ ledger = ledger.add_coordinate(
101
+ f"ecpt:bridge-reserve:missing:{key}",
102
+ 1.0,
103
+ kind=CoordinateKind.RESIDUAL,
104
+ )
105
+ return _domain_result("ecpt-bridge-reserve", reasons, ledger)
106
+
107
+
108
+ def verify_ecpt_trace_diagnostic_projection(
109
+ projected_trace_ids: set[str],
110
+ accepted_trace_ids: set[str],
111
+ *,
112
+ residual: float = 0.0,
113
+ ) -> CheckResult:
114
+ """Check finite trace-diagnostic projection containment."""
115
+
116
+ reasons: list[str] = []
117
+ ledger = Ledger()
118
+ if residual < 0:
119
+ reasons.append("trace diagnostic residual must be nonnegative")
120
+ missing = sorted(projected_trace_ids - accepted_trace_ids)
121
+ if missing:
122
+ reasons.append("trace diagnostic projection contains unaccepted traces")
123
+ if residual:
124
+ ledger = ledger.add_coordinate(
125
+ "ecpt:trace-diagnostic:residual",
126
+ residual,
127
+ kind=CoordinateKind.RESIDUAL,
128
+ )
129
+ for trace_id in missing:
130
+ ledger = ledger.add_coordinate(
131
+ f"ecpt:trace-diagnostic:missing:{trace_id}",
132
+ 1.0,
133
+ kind=CoordinateKind.RESIDUAL,
134
+ )
135
+ return _domain_result("ecpt-trace-diagnostic", reasons, ledger)
136
+
137
+
138
+ def verify_ecpt_domain_abstraction(
139
+ abstraction_map: dict[str, str],
140
+ required_targets: set[str],
141
+ *,
142
+ refinement_residual: float,
143
+ residual_bound: float,
144
+ ) -> CheckResult:
145
+ """Check a finite ecology/ontology abstraction envelope."""
146
+
147
+ reasons: list[str] = []
148
+ ledger = Ledger()
149
+ if refinement_residual < 0 or residual_bound < 0:
150
+ reasons.append("domain abstraction residuals must be nonnegative")
151
+ if refinement_residual > residual_bound:
152
+ reasons.append("domain abstraction refinement residual exceeds bound")
153
+ ledger = ledger.add_coordinate(
154
+ "ecpt:domain-abstraction:residual-gap",
155
+ refinement_residual - residual_bound,
156
+ kind=CoordinateKind.RESIDUAL,
157
+ )
158
+ missing_targets = sorted(required_targets - set(abstraction_map.values()))
159
+ if missing_targets:
160
+ reasons.append("domain abstraction misses required target concepts")
161
+ for target in missing_targets:
162
+ ledger = ledger.add_coordinate(
163
+ f"ecpt:domain-abstraction:missing:{target}",
164
+ 1.0,
165
+ kind=CoordinateKind.RESIDUAL,
166
+ )
167
+ return _domain_result("ecpt-domain-abstraction", reasons, ledger)
168
+
169
+
170
+ def verify_ecpt_execution_policy(
171
+ policy_actions: set[str],
172
+ available_actions: set[str],
173
+ *,
174
+ counterfactual_residual: float,
175
+ residual_bound: float,
176
+ ) -> CheckResult:
177
+ """Check a finite execution-policy/counterfactual envelope."""
178
+
179
+ reasons: list[str] = []
180
+ ledger = Ledger()
181
+ if counterfactual_residual < 0 or residual_bound < 0:
182
+ reasons.append("execution-policy residuals must be nonnegative")
183
+ unavailable = sorted(policy_actions - available_actions)
184
+ if unavailable:
185
+ reasons.append("execution policy references unavailable actions")
186
+ if counterfactual_residual > residual_bound:
187
+ reasons.append("execution policy counterfactual residual exceeds bound")
188
+ ledger = ledger.add_coordinate(
189
+ "ecpt:execution-policy:residual-gap",
190
+ counterfactual_residual - residual_bound,
191
+ kind=CoordinateKind.RESIDUAL,
192
+ )
193
+ for action in unavailable:
194
+ ledger = ledger.add_coordinate(
195
+ f"ecpt:execution-policy:unavailable:{action}",
196
+ 1.0,
197
+ kind=CoordinateKind.RESIDUAL,
198
+ )
199
+ return _domain_result("ecpt-execution-policy", reasons, ledger)
200
+
201
+
202
+ def verify_ecpt_proxy_target_contract(
203
+ proxy_coordinates: dict[str, float],
204
+ required_coordinates: dict[str, float],
205
+ *,
206
+ mismatch_residual: float,
207
+ residual_bound: float,
208
+ ) -> CheckResult:
209
+ """Check finite proxy-target grounding coordinates."""
210
+
211
+ reasons: list[str] = []
212
+ ledger = Ledger()
213
+ if mismatch_residual < 0 or residual_bound < 0:
214
+ reasons.append("proxy-target residuals must be nonnegative")
215
+ for coordinate, floor in required_coordinates.items():
216
+ value = proxy_coordinates.get(coordinate, 0.0)
217
+ if value < floor:
218
+ reasons.append(f"proxy coordinate {coordinate} is below required floor")
219
+ ledger = ledger.add_coordinate(
220
+ f"ecpt:proxy-target:{coordinate}:gap",
221
+ floor - value,
222
+ kind=CoordinateKind.RESIDUAL,
223
+ )
224
+ if mismatch_residual > residual_bound:
225
+ reasons.append("proxy-target mismatch residual exceeds bound")
226
+ ledger = ledger.add_coordinate(
227
+ "ecpt:proxy-target:mismatch-gap",
228
+ mismatch_residual - residual_bound,
229
+ kind=CoordinateKind.RESIDUAL,
230
+ )
231
+ return _domain_result("ecpt-proxy-target", reasons, ledger)
232
+
233
+
234
+ def verify_ecpt_speculative_channel_repair(
235
+ channels: set[str],
236
+ repaired_channels: set[str],
237
+ required_channels: set[str],
238
+ *,
239
+ repair_residual: float,
240
+ residual_bound: float,
241
+ ) -> CheckResult:
242
+ """Check finite speculative-channel coverage and repair evidence."""
243
+
244
+ reasons: list[str] = []
245
+ ledger = Ledger()
246
+ if repair_residual < 0 or residual_bound < 0:
247
+ reasons.append("speculative-channel residuals must be nonnegative")
248
+ missing = sorted(required_channels - (channels | repaired_channels))
249
+ if missing:
250
+ reasons.append("speculative channel repair misses required channels")
251
+ if repair_residual > residual_bound:
252
+ reasons.append("speculative channel repair residual exceeds bound")
253
+ ledger = ledger.add_coordinate(
254
+ "ecpt:speculative-channel:residual-gap",
255
+ repair_residual - residual_bound,
256
+ kind=CoordinateKind.RESIDUAL,
257
+ )
258
+ for channel in missing:
259
+ ledger = ledger.add_coordinate(
260
+ f"ecpt:speculative-channel:missing:{channel}",
261
+ 1.0,
262
+ kind=CoordinateKind.RESIDUAL,
263
+ )
264
+ return _domain_result("ecpt-speculative-channel", reasons, ledger)
265
+
266
+
267
+ def verify_trc_telemetry_calibration(
268
+ samples: list[float],
269
+ references: list[float],
270
+ *,
271
+ tolerance: float,
272
+ ) -> CheckResult:
273
+ """Check bounded absolute calibration error over finite telemetry samples."""
274
+
275
+ reasons: list[str] = []
276
+ ledger = Ledger()
277
+ if len(samples) != len(references):
278
+ reasons.append("telemetry samples and references must have equal length")
279
+ if not samples:
280
+ reasons.append("telemetry calibration requires at least one sample")
281
+ if tolerance < 0:
282
+ reasons.append("telemetry tolerance must be nonnegative")
283
+ if not reasons:
284
+ max_error = max(
285
+ abs(sample - reference) for sample, reference in zip(samples, references, strict=True)
286
+ )
287
+ if max_error > tolerance:
288
+ reasons.append("telemetry calibration error exceeds tolerance")
289
+ ledger = ledger.add_coordinate(
290
+ "trc:telemetry-calibration:error-gap",
291
+ max_error - tolerance,
292
+ kind=CoordinateKind.RESIDUAL,
293
+ )
294
+ return _domain_result("trc-telemetry-calibration", reasons, ledger)
295
+
296
+
297
+ def replay_trc_physical_trace(
298
+ events: list[str],
299
+ expected_events: list[str],
300
+ *,
301
+ allow_prefix: bool = False,
302
+ ) -> CheckResult:
303
+ """Replay a finite physical trace against an expected transition log."""
304
+
305
+ reasons: list[str] = []
306
+ if not expected_events:
307
+ reasons.append("expected physical trace is empty")
308
+ if allow_prefix:
309
+ accepted = expected_events[: len(events)] == events
310
+ else:
311
+ accepted = events == expected_events
312
+ if not accepted:
313
+ reasons.append("physical trace does not match expected transition log")
314
+ return _domain_result("trc-physical-trace", reasons)
315
+
316
+
317
+ def verify_archive_domain_evidence(
318
+ record_domains: dict[str, str],
319
+ allowed_domains: set[str],
320
+ ) -> CheckResult:
321
+ """Check finite archive records against an explicit allowed-domain set."""
322
+
323
+ reasons: list[str] = []
324
+ if not allowed_domains:
325
+ reasons.append("archive-domain evidence has no allowed domains")
326
+ unknown = sorted(
327
+ record_id for record_id, domain in record_domains.items() if domain not in allowed_domains
328
+ )
329
+ if unknown:
330
+ reasons.append("archive records reference domains outside the certified domain set")
331
+ ledger = Ledger()
332
+ for record_id in unknown:
333
+ ledger = ledger.add_coordinate(
334
+ f"trc:archive-domain:{record_id}",
335
+ 1.0,
336
+ kind=CoordinateKind.RESIDUAL,
337
+ )
338
+ return _domain_result("trc-archive-domain", reasons, ledger)
@@ -0,0 +1,15 @@
1
+ """NetworkX-backed graph helpers kept outside the lean core."""
2
+
3
+ from __future__ import annotations
4
+
5
+
6
+ def shortest_path_lengths(edges: list[tuple[str, str]], source: str) -> dict[str, int]:
7
+ try:
8
+ import networkx as nx # type: ignore[import-untyped]
9
+ except ImportError as exc: # pragma: no cover - exercised without science extra
10
+ raise RuntimeError("Install the 'science' extra to use graph adapters.") from exc
11
+
12
+ graph = nx.DiGraph()
13
+ graph.add_edges_from(edges)
14
+ lengths = nx.single_source_shortest_path_length(graph, source)
15
+ return {str(node): int(distance) for node, distance in lengths.items()}
@@ -0,0 +1,25 @@
1
+ """Finite LP adapter for release-style certificates."""
2
+
3
+ from __future__ import annotations
4
+
5
+
6
+ def solve_linear_release(
7
+ objective: list[float],
8
+ lower_bounds: list[float],
9
+ upper_bounds: list[float],
10
+ ) -> float:
11
+ """Solve a bounded separable linear release objective.
12
+
13
+ This intentionally keeps the public adapter simple and deterministic. More
14
+ complex constrained LPs should be represented as external proof obligations
15
+ unless a full matrix certificate is supplied.
16
+ """
17
+
18
+ if len(objective) != len(lower_bounds) or len(objective) != len(upper_bounds):
19
+ raise ValueError("objective and bound vectors must have equal length")
20
+ value = 0.0
21
+ for coeff, lower, upper in zip(objective, lower_bounds, upper_bounds, strict=True):
22
+ if lower > upper:
23
+ raise ValueError("lower bound exceeds upper bound")
24
+ value += coeff * (upper if coeff >= 0 else lower)
25
+ return value
@@ -0,0 +1,19 @@
1
+ """Optimal-transport adapters."""
2
+
3
+ from __future__ import annotations
4
+
5
+
6
+ def sinkhorn_transport(
7
+ source: list[float],
8
+ target: list[float],
9
+ cost: list[list[float]],
10
+ *,
11
+ regularization: float = 1.0,
12
+ ) -> list[list[float]]:
13
+ try:
14
+ import ot # type: ignore[import-untyped]
15
+ except ImportError as exc: # pragma: no cover - exercised without ot extra
16
+ raise RuntimeError("Install the 'ot' extra to use transport adapters.") from exc
17
+
18
+ plan = ot.sinkhorn(source, target, cost, regularization)
19
+ return [[float(value) for value in row] for row in plan.tolist()]
@@ -0,0 +1,17 @@
1
+ """Pint-backed unit validation helpers."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+
8
+ def assert_compatible_units(left_unit: str, right_unit: str) -> bool:
9
+ try:
10
+ import pint
11
+ except ImportError as exc: # pragma: no cover - exercised without science extra
12
+ raise RuntimeError("Install the 'science' extra to use unit adapters.") from exc
13
+
14
+ registry: Any = pint.UnitRegistry()
15
+ left = registry.Quantity(1.0, left_unit)
16
+ right = registry.Quantity(1.0, right_unit)
17
+ return bool(left.check(right.dimensionality))
@@ -0,0 +1,51 @@
1
+ """Agent-facing shortcuts for safe PIC runtime integration."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from percolation_inversion_compiler.agent.algorithms import (
6
+ agent_feature_readiness,
7
+ agent_manifest_payload,
8
+ agent_network_readiness,
9
+ agent_safety_invariants,
10
+ build_agent_communication_guide,
11
+ build_agent_workflow_guide,
12
+ minimal_runtime_state,
13
+ minimal_runtime_step_input,
14
+ recommend_agent_next_actions,
15
+ run_agent_intake,
16
+ )
17
+ from percolation_inversion_compiler.agent.records import (
18
+ AgentCommunicationGuide,
19
+ AgentCommunicationPolicy,
20
+ AgentCommunicationStep,
21
+ AgentFeatureReadinessReport,
22
+ AgentIntakeReport,
23
+ AgentIntakeRequest,
24
+ AgentNetworkReadinessReport,
25
+ AgentNextActionReport,
26
+ AgentWorkflowGuide,
27
+ AgentWorkflowStep,
28
+ )
29
+
30
+ __all__ = [
31
+ "AgentCommunicationGuide",
32
+ "AgentCommunicationPolicy",
33
+ "AgentCommunicationStep",
34
+ "AgentFeatureReadinessReport",
35
+ "AgentIntakeReport",
36
+ "AgentIntakeRequest",
37
+ "AgentNetworkReadinessReport",
38
+ "AgentNextActionReport",
39
+ "AgentWorkflowGuide",
40
+ "AgentWorkflowStep",
41
+ "agent_feature_readiness",
42
+ "agent_manifest_payload",
43
+ "agent_network_readiness",
44
+ "agent_safety_invariants",
45
+ "build_agent_communication_guide",
46
+ "build_agent_workflow_guide",
47
+ "minimal_runtime_state",
48
+ "minimal_runtime_step_input",
49
+ "recommend_agent_next_actions",
50
+ "run_agent_intake",
51
+ ]