counterdex 0.3.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 (216) hide show
  1. counterdex-0.3.0/MANIFEST.in +5 -0
  2. counterdex-0.3.0/PKG-INFO +210 -0
  3. counterdex-0.3.0/README.md +193 -0
  4. counterdex-0.3.0/counterdex/__init__.py +39 -0
  5. counterdex-0.3.0/counterdex/__main__.py +116 -0
  6. counterdex-0.3.0/counterdex/analytical.py +116 -0
  7. counterdex-0.3.0/counterdex/application.py +345 -0
  8. counterdex-0.3.0/counterdex/arithmetic.py +115 -0
  9. counterdex-0.3.0/counterdex/baseline.py +119 -0
  10. counterdex-0.3.0/counterdex/bridge.py +268 -0
  11. counterdex-0.3.0/counterdex/capabilities.py +73 -0
  12. counterdex-0.3.0/counterdex/checked.py +225 -0
  13. counterdex-0.3.0/counterdex/errors.py +28 -0
  14. counterdex-0.3.0/counterdex/exact.py +248 -0
  15. counterdex-0.3.0/counterdex/followup.py +173 -0
  16. counterdex-0.3.0/counterdex/historical.py +252 -0
  17. counterdex-0.3.0/counterdex/identity.py +20 -0
  18. counterdex-0.3.0/counterdex/interpretation.py +23 -0
  19. counterdex-0.3.0/counterdex/models.py +338 -0
  20. counterdex-0.3.0/counterdex/native_packet.py +255 -0
  21. counterdex-0.3.0/counterdex/numerical.py +118 -0
  22. counterdex-0.3.0/counterdex/pipeline.py +81 -0
  23. counterdex-0.3.0/counterdex/replay.py +143 -0
  24. counterdex-0.3.0/counterdex/replay_baseline.py +112 -0
  25. counterdex-0.3.0/counterdex/replay_numeric.py +164 -0
  26. counterdex-0.3.0/counterdex/resource.py +43 -0
  27. counterdex-0.3.0/counterdex/search.py +276 -0
  28. counterdex-0.3.0/counterdex.egg-info/PKG-INFO +210 -0
  29. counterdex-0.3.0/counterdex.egg-info/SOURCES.txt +214 -0
  30. counterdex-0.3.0/counterdex.egg-info/dependency_links.txt +1 -0
  31. counterdex-0.3.0/counterdex.egg-info/entry_points.txt +2 -0
  32. counterdex-0.3.0/counterdex.egg-info/top_level.txt +1 -0
  33. counterdex-0.3.0/docs/ANALYTIC_ARGUMENT.md +88 -0
  34. counterdex-0.3.0/docs/APPLICATION_MAPPING.md +205 -0
  35. counterdex-0.3.0/docs/BRIDGE.md +294 -0
  36. counterdex-0.3.0/docs/CURRENT_INTEGRATION_REVIEW.md +148 -0
  37. counterdex-0.3.0/docs/DECISION_EXAMPLE.md +151 -0
  38. counterdex-0.3.0/docs/DECISION_LOOP_QUALIFICATION.md +212 -0
  39. counterdex-0.3.0/docs/INTEGRATED_SOURCE_LOOP_REVIEW.md +118 -0
  40. counterdex-0.3.0/docs/INTEGRATION.md +211 -0
  41. counterdex-0.3.0/docs/OWNER2_BRIDGE_ADOPTION.md +662 -0
  42. counterdex-0.3.0/docs/OWNER5_NATIVE_ACCEPTANCE.md +242 -0
  43. counterdex-0.3.0/docs/RELEASE_0_3_0.md +87 -0
  44. counterdex-0.3.0/docs/RESULT_SEMANTICS.md +154 -0
  45. counterdex-0.3.0/docs/REVIEW.md +69 -0
  46. counterdex-0.3.0/docs/VALIDATION.md +363 -0
  47. counterdex-0.3.0/docs/review-evidence/5507519/README.md +28 -0
  48. counterdex-0.3.0/docs/review-evidence/f713635/README.md +42 -0
  49. counterdex-0.3.0/fixtures/archive/0.2.0-bridge/README.md +13 -0
  50. counterdex-0.3.0/fixtures/archive/0.2.0-bridge/hero-baseline.response.json +1 -0
  51. counterdex-0.3.0/fixtures/archive/0.2.0-bridge/hero-design.anchors.json +1 -0
  52. counterdex-0.3.0/fixtures/archive/0.2.0-bridge/hero-design.native.json +1 -0
  53. counterdex-0.3.0/fixtures/archive/initial-published-release/README.md +19 -0
  54. counterdex-0.3.0/fixtures/archive/initial-published-release/canonicalization_golden.json +1 -0
  55. counterdex-0.3.0/fixtures/archive/initial-published-release/checked_no_separation.anchors.json +1 -0
  56. counterdex-0.3.0/fixtures/archive/initial-published-release/checked_no_separation.bundle.json +1 -0
  57. counterdex-0.3.0/fixtures/archive/initial-published-release/checked_no_separation.replay.json +1 -0
  58. counterdex-0.3.0/fixtures/archive/initial-published-release/checked_no_separation.request.json +1 -0
  59. counterdex-0.3.0/fixtures/archive/initial-published-release/checked_success.anchors.json +1 -0
  60. counterdex-0.3.0/fixtures/archive/initial-published-release/checked_success.bundle.json +1 -0
  61. counterdex-0.3.0/fixtures/archive/initial-published-release/checked_success.replay.json +1 -0
  62. counterdex-0.3.0/fixtures/archive/initial-published-release/checked_success.request.json +1 -0
  63. counterdex-0.3.0/fixtures/archive/initial-published-release/manifest.json +1 -0
  64. counterdex-0.3.0/fixtures/archive/initial-published-release/new_datum_excludes_both.anchors.json +1 -0
  65. counterdex-0.3.0/fixtures/archive/initial-published-release/new_datum_excludes_both.bundle.json +1 -0
  66. counterdex-0.3.0/fixtures/archive/initial-published-release/new_datum_excludes_both.replay.json +1 -0
  67. counterdex-0.3.0/fixtures/archive/initial-published-release/new_datum_excludes_both.request.json +1 -0
  68. counterdex-0.3.0/fixtures/archive/initial-published-release/numerical_invalid_range.anchors.json +1 -0
  69. counterdex-0.3.0/fixtures/archive/initial-published-release/numerical_invalid_range.bundle.json +1 -0
  70. counterdex-0.3.0/fixtures/archive/initial-published-release/numerical_invalid_range.replay.json +1 -0
  71. counterdex-0.3.0/fixtures/archive/initial-published-release/numerical_invalid_range.request.json +1 -0
  72. counterdex-0.3.0/fixtures/archive/initial-published-release/numerical_no_useful.anchors.json +1 -0
  73. counterdex-0.3.0/fixtures/archive/initial-published-release/numerical_no_useful.bundle.json +1 -0
  74. counterdex-0.3.0/fixtures/archive/initial-published-release/numerical_no_useful.replay.json +1 -0
  75. counterdex-0.3.0/fixtures/archive/initial-published-release/numerical_no_useful.request.json +1 -0
  76. counterdex-0.3.0/fixtures/archive/initial-published-release/numerical_partial.anchors.json +1 -0
  77. counterdex-0.3.0/fixtures/archive/initial-published-release/numerical_partial.bundle.json +1 -0
  78. counterdex-0.3.0/fixtures/archive/initial-published-release/numerical_partial.replay.json +1 -0
  79. counterdex-0.3.0/fixtures/archive/initial-published-release/numerical_partial.request.json +1 -0
  80. counterdex-0.3.0/fixtures/archive/initial-published-release/numerical_success.anchors.json +1 -0
  81. counterdex-0.3.0/fixtures/archive/initial-published-release/numerical_success.bundle.json +1 -0
  82. counterdex-0.3.0/fixtures/archive/initial-published-release/numerical_success.replay.json +1 -0
  83. counterdex-0.3.0/fixtures/archive/initial-published-release/numerical_success.request.json +1 -0
  84. counterdex-0.3.0/fixtures/canonicalization_golden.json +1 -0
  85. counterdex-0.3.0/fixtures/checked_no_separation.anchors.json +1 -0
  86. counterdex-0.3.0/fixtures/checked_no_separation.bundle.json +1 -0
  87. counterdex-0.3.0/fixtures/checked_no_separation.replay.json +1 -0
  88. counterdex-0.3.0/fixtures/checked_no_separation.request.json +1 -0
  89. counterdex-0.3.0/fixtures/checked_success.anchors.json +1 -0
  90. counterdex-0.3.0/fixtures/checked_success.bundle.json +1 -0
  91. counterdex-0.3.0/fixtures/checked_success.replay.json +1 -0
  92. counterdex-0.3.0/fixtures/checked_success.request.json +1 -0
  93. counterdex-0.3.0/fixtures/decision/alternate-baseline.anchors.json +1 -0
  94. counterdex-0.3.0/fixtures/decision/alternate-baseline.display.json +1 -0
  95. counterdex-0.3.0/fixtures/decision/alternate-baseline.native.json +1 -0
  96. counterdex-0.3.0/fixtures/decision/alternate-baseline.replay-request.json +1 -0
  97. counterdex-0.3.0/fixtures/decision/alternate-baseline.replay.json +1 -0
  98. counterdex-0.3.0/fixtures/decision/alternate-baseline.request.json +1 -0
  99. counterdex-0.3.0/fixtures/decision/alternate-baseline.response.json +1 -0
  100. counterdex-0.3.0/fixtures/decision/alternate-design.anchors.json +1 -0
  101. counterdex-0.3.0/fixtures/decision/alternate-design.display.json +1 -0
  102. counterdex-0.3.0/fixtures/decision/alternate-design.native.json +1 -0
  103. counterdex-0.3.0/fixtures/decision/alternate-design.replay-request.json +1 -0
  104. counterdex-0.3.0/fixtures/decision/alternate-design.replay.json +1 -0
  105. counterdex-0.3.0/fixtures/decision/alternate-design.request.json +1 -0
  106. counterdex-0.3.0/fixtures/decision/alternate-design.response.json +1 -0
  107. counterdex-0.3.0/fixtures/decision/decision-summary.json +1 -0
  108. counterdex-0.3.0/fixtures/decision/fixed-pair-6h-only.anchors.json +1 -0
  109. counterdex-0.3.0/fixtures/decision/fixed-pair-6h-only.bundle.json +1 -0
  110. counterdex-0.3.0/fixtures/decision/fixed-pair-6h-only.display.json +1 -0
  111. counterdex-0.3.0/fixtures/decision/fixed-pair-6h-only.engine-input.json +1 -0
  112. counterdex-0.3.0/fixtures/decision/fixed-pair-6h-only.replay.json +1 -0
  113. counterdex-0.3.0/fixtures/decision/fixed-pair-8h.anchors.json +1 -0
  114. counterdex-0.3.0/fixtures/decision/fixed-pair-8h.bundle.json +1 -0
  115. counterdex-0.3.0/fixtures/decision/fixed-pair-8h.display.json +1 -0
  116. counterdex-0.3.0/fixtures/decision/fixed-pair-8h.engine-input.json +1 -0
  117. counterdex-0.3.0/fixtures/decision/fixed-pair-8h.replay.json +1 -0
  118. counterdex-0.3.0/fixtures/decision/fixed-pair-wide-allowance.anchors.json +1 -0
  119. counterdex-0.3.0/fixtures/decision/fixed-pair-wide-allowance.bundle.json +1 -0
  120. counterdex-0.3.0/fixtures/decision/fixed-pair-wide-allowance.display.json +1 -0
  121. counterdex-0.3.0/fixtures/decision/fixed-pair-wide-allowance.engine-input.json +1 -0
  122. counterdex-0.3.0/fixtures/decision/fixed-pair-wide-allowance.replay.json +1 -0
  123. counterdex-0.3.0/fixtures/decision/hero-baseline.anchors.json +1 -0
  124. counterdex-0.3.0/fixtures/decision/hero-baseline.display.json +1 -0
  125. counterdex-0.3.0/fixtures/decision/hero-baseline.native.json +1 -0
  126. counterdex-0.3.0/fixtures/decision/hero-baseline.replay-request.json +1 -0
  127. counterdex-0.3.0/fixtures/decision/hero-baseline.replay.json +1 -0
  128. counterdex-0.3.0/fixtures/decision/hero-baseline.request.json +1 -0
  129. counterdex-0.3.0/fixtures/decision/hero-baseline.response.json +1 -0
  130. counterdex-0.3.0/fixtures/decision/hero-both-excluded.anchors.json +1 -0
  131. counterdex-0.3.0/fixtures/decision/hero-both-excluded.display.json +1 -0
  132. counterdex-0.3.0/fixtures/decision/hero-both-excluded.native.json +1 -0
  133. counterdex-0.3.0/fixtures/decision/hero-both-excluded.replay-request.json +1 -0
  134. counterdex-0.3.0/fixtures/decision/hero-both-excluded.replay.json +1 -0
  135. counterdex-0.3.0/fixtures/decision/hero-both-excluded.request.json +1 -0
  136. counterdex-0.3.0/fixtures/decision/hero-both-excluded.response.json +1 -0
  137. counterdex-0.3.0/fixtures/decision/hero-design.anchors.json +1 -0
  138. counterdex-0.3.0/fixtures/decision/hero-design.display.json +1 -0
  139. counterdex-0.3.0/fixtures/decision/hero-design.native.json +1 -0
  140. counterdex-0.3.0/fixtures/decision/hero-design.replay-request.json +1 -0
  141. counterdex-0.3.0/fixtures/decision/hero-design.replay.json +1 -0
  142. counterdex-0.3.0/fixtures/decision/hero-design.request.json +1 -0
  143. counterdex-0.3.0/fixtures/decision/hero-design.response.json +1 -0
  144. counterdex-0.3.0/fixtures/decision/hero-outside-survives.anchors.json +1 -0
  145. counterdex-0.3.0/fixtures/decision/hero-outside-survives.display.json +1 -0
  146. counterdex-0.3.0/fixtures/decision/hero-outside-survives.native.json +1 -0
  147. counterdex-0.3.0/fixtures/decision/hero-outside-survives.replay-request.json +1 -0
  148. counterdex-0.3.0/fixtures/decision/hero-outside-survives.replay.json +1 -0
  149. counterdex-0.3.0/fixtures/decision/hero-outside-survives.request.json +1 -0
  150. counterdex-0.3.0/fixtures/decision/hero-outside-survives.response.json +1 -0
  151. counterdex-0.3.0/fixtures/decision/hero-own-time-recheck.anchors.json +1 -0
  152. counterdex-0.3.0/fixtures/decision/hero-own-time-recheck.display.json +1 -0
  153. counterdex-0.3.0/fixtures/decision/hero-own-time-recheck.native.json +1 -0
  154. counterdex-0.3.0/fixtures/decision/hero-own-time-recheck.replay-request.json +1 -0
  155. counterdex-0.3.0/fixtures/decision/hero-own-time-recheck.replay.json +1 -0
  156. counterdex-0.3.0/fixtures/decision/hero-own-time-recheck.request.json +1 -0
  157. counterdex-0.3.0/fixtures/decision/hero-own-time-recheck.response.json +1 -0
  158. counterdex-0.3.0/fixtures/decision/hero-reference-survives.anchors.json +1 -0
  159. counterdex-0.3.0/fixtures/decision/hero-reference-survives.display.json +1 -0
  160. counterdex-0.3.0/fixtures/decision/hero-reference-survives.native.json +1 -0
  161. counterdex-0.3.0/fixtures/decision/hero-reference-survives.replay-request.json +1 -0
  162. counterdex-0.3.0/fixtures/decision/hero-reference-survives.replay.json +1 -0
  163. counterdex-0.3.0/fixtures/decision/hero-reference-survives.request.json +1 -0
  164. counterdex-0.3.0/fixtures/decision/hero-reference-survives.response.json +1 -0
  165. counterdex-0.3.0/fixtures/decision/manifest.json +1 -0
  166. counterdex-0.3.0/fixtures/manifest.json +1 -0
  167. counterdex-0.3.0/fixtures/new_datum_excludes_both.anchors.json +1 -0
  168. counterdex-0.3.0/fixtures/new_datum_excludes_both.bundle.json +1 -0
  169. counterdex-0.3.0/fixtures/new_datum_excludes_both.replay.json +1 -0
  170. counterdex-0.3.0/fixtures/new_datum_excludes_both.request.json +1 -0
  171. counterdex-0.3.0/fixtures/numerical_invalid_range.anchors.json +1 -0
  172. counterdex-0.3.0/fixtures/numerical_invalid_range.bundle.json +1 -0
  173. counterdex-0.3.0/fixtures/numerical_invalid_range.replay.json +1 -0
  174. counterdex-0.3.0/fixtures/numerical_invalid_range.request.json +1 -0
  175. counterdex-0.3.0/fixtures/numerical_no_useful.anchors.json +1 -0
  176. counterdex-0.3.0/fixtures/numerical_no_useful.bundle.json +1 -0
  177. counterdex-0.3.0/fixtures/numerical_no_useful.replay.json +1 -0
  178. counterdex-0.3.0/fixtures/numerical_no_useful.request.json +1 -0
  179. counterdex-0.3.0/fixtures/numerical_partial.anchors.json +1 -0
  180. counterdex-0.3.0/fixtures/numerical_partial.bundle.json +1 -0
  181. counterdex-0.3.0/fixtures/numerical_partial.replay.json +1 -0
  182. counterdex-0.3.0/fixtures/numerical_partial.request.json +1 -0
  183. counterdex-0.3.0/fixtures/numerical_success.anchors.json +1 -0
  184. counterdex-0.3.0/fixtures/numerical_success.bundle.json +1 -0
  185. counterdex-0.3.0/fixtures/numerical_success.replay.json +1 -0
  186. counterdex-0.3.0/fixtures/numerical_success.request.json +1 -0
  187. counterdex-0.3.0/fixtures/repro/README.md +42 -0
  188. counterdex-0.3.0/fixtures/repro/hero-baseline.anchors.json +1 -0
  189. counterdex-0.3.0/fixtures/repro/hero-baseline.native.json +1 -0
  190. counterdex-0.3.0/fixtures/repro/hero-baseline.request.json +1 -0
  191. counterdex-0.3.0/fixtures/repro/implementation.json +1 -0
  192. counterdex-0.3.0/fixtures/repro/replay.py +23 -0
  193. counterdex-0.3.0/pyproject.toml +32 -0
  194. counterdex-0.3.0/scripts/check_application_schema.py +92 -0
  195. counterdex-0.3.0/scripts/generate_decision_fixtures.py +501 -0
  196. counterdex-0.3.0/scripts/generate_fixtures.py +90 -0
  197. counterdex-0.3.0/scripts/supervise_bridge.py +144 -0
  198. counterdex-0.3.0/setup.cfg +4 -0
  199. counterdex-0.3.0/tests/check_canonical.mjs +18 -0
  200. counterdex-0.3.0/tests/helpers.py +65 -0
  201. counterdex-0.3.0/tests/test_analytical.py +136 -0
  202. counterdex-0.3.0/tests/test_application.py +551 -0
  203. counterdex-0.3.0/tests/test_arithmetic.py +128 -0
  204. counterdex-0.3.0/tests/test_baseline.py +282 -0
  205. counterdex-0.3.0/tests/test_bridge.py +840 -0
  206. counterdex-0.3.0/tests/test_checked.py +239 -0
  207. counterdex-0.3.0/tests/test_cli.py +161 -0
  208. counterdex-0.3.0/tests/test_exact.py +136 -0
  209. counterdex-0.3.0/tests/test_followup.py +258 -0
  210. counterdex-0.3.0/tests/test_historical.py +309 -0
  211. counterdex-0.3.0/tests/test_models.py +405 -0
  212. counterdex-0.3.0/tests/test_numerical.py +171 -0
  213. counterdex-0.3.0/tests/test_replay.py +348 -0
  214. counterdex-0.3.0/tests/test_replay_numeric.py +142 -0
  215. counterdex-0.3.0/tests/test_search.py +270 -0
  216. counterdex-0.3.0/tests/test_supervisor.py +243 -0
@@ -0,0 +1,5 @@
1
+ recursive-include docs *.md
2
+ recursive-include fixtures *.json
3
+ recursive-include fixtures *.md *.py
4
+ recursive-include tests *.py *.mjs
5
+ recursive-include scripts *.py
@@ -0,0 +1,210 @@
1
+ Metadata-Version: 2.4
2
+ Name: counterdex
3
+ Version: 0.3.0
4
+ Summary: Bounded candidate discovery, exact historical checks and measurement decisions
5
+ Project-URL: Homepage, https://github.com/Arnav-M10/DrBean-hp26
6
+ Project-URL: Documentation, https://github.com/Arnav-M10/DrBean-hp26/tree/main/packages/groundwork_adapter/docs
7
+ Project-URL: Source, https://github.com/Arnav-M10/DrBean-hp26/tree/main/packages/groundwork_adapter
8
+ Project-URL: Issues, https://github.com/Arnav-M10/DrBean-hp26/issues
9
+ Keywords: scientific-inference,counterexamples,exact-arithmetic,experiment-design,kinetics
10
+ Classifier: Intended Audience :: Science/Research
11
+ Classifier: Programming Language :: Python :: 3 :: Only
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: Implementation :: CPython
14
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
15
+ Requires-Python: <3.12,>=3.11
16
+ Description-Content-Type: text/markdown
17
+
18
+ # Counterdex
19
+
20
+ **Check a parameter claim against measurements, find a competing explanation, and
21
+ compare what to measure next.** Counterdex is a Python library and command-line
22
+ tool for bounded scientific investigation with portable, freshly replayable
23
+ evidence. It uses only the Python standard library and makes no network or model
24
+ provider calls.
25
+
26
+ Version **0.3.0** supports one model:
27
+
28
+ ```text
29
+ C(t) = A · (exp(−ke · t) − exp(−ka · t))
30
+ A > 0, 0 < ke < ka
31
+ ```
32
+
33
+ Time is in hours, concentration in mg/L, and rates in inverse hours. The admitted
34
+ initial conditions are `x(0)=1` and `c(0)=0`. Exact scientific execution and replay
35
+ are qualified on **CPython 3.11**.
36
+
37
+ ## What Counterdex does
38
+
39
+ - **Discover competing candidates.** Search a bounded rate grid with amplitude
40
+ screening, then independently check retained exact parameter vectors against
41
+ every included measurement and its declared hard allowance. A compatible
42
+ vector strictly outside a **closed** claimed interval is a counterexample;
43
+ either endpoint is inside the claim.
44
+ - **Compare a selected pair.** Evaluate researcher-supplied feasible measurement
45
+ times and a declared future allowance. Numerical guidance stays numerical.
46
+ Checked separation requires two freshly compatible candidates and a strictly
47
+ positive exact separation margin. Touching bands do not separate.
48
+ - **Review a new reading.** Recheck the original candidates using an appended
49
+ actual, transcribed or hypothetical observation at its own declared time and
50
+ allowance. Preserve the parent evidence and candidate vectors rather than
51
+ silently searching for replacements.
52
+ - **Replay evidence independently of the application.** Check native bytes,
53
+ complete lineage and exact input bindings against separately supplied expected
54
+ identities, then recompute the scientific checks with the matching prepared
55
+ package.
56
+
57
+ No counterexample found means **inconclusive**, never “claim proved.” Excluding
58
+ one or both selected candidates does not exclude every other model. A successful
59
+ replay confirms the recorded calculation under its declared scope; it does not
60
+ upgrade an inconclusive result or establish the truth of the physical model.
61
+
62
+ ## Install
63
+
64
+ Create a CPython 3.11 environment:
65
+
66
+ ```sh
67
+ python3.11 -m venv .counterdex-env
68
+ .counterdex-env/bin/python -m pip install --no-deps "counterdex==0.3.0"
69
+ .counterdex-env/bin/python -m counterdex capabilities
70
+ ```
71
+
72
+ The distribution, Python import and console command are all named `counterdex`.
73
+ The package has **no runtime dependencies**. Build and publication tools are
74
+ separate development dependencies. Python 3.12/3.13 applications should invoke a
75
+ separately prepared CPython 3.11 scientific process rather than relax the
76
+ package's Python requirement.
77
+
78
+ ## Try a complete native replay
79
+
80
+ This example uses synthetic measurements, a retained counterexample and its
81
+ separately stored anchors. Download the two public fixture files into a new
82
+ folder; the replay itself is offline and requires no repository checkout:
83
+
84
+ ```sh
85
+ mkdir counterdex-demo
86
+ cd counterdex-demo
87
+ curl --fail --location --output hero-baseline.native.json \
88
+ https://raw.githubusercontent.com/Arnav-M10/DrBean-hp26/b60e9d997cdc262e50107953bafc422398435297/packages/groundwork_adapter/fixtures/repro/hero-baseline.native.json
89
+ curl --fail --location --output hero-baseline.anchors.json \
90
+ https://raw.githubusercontent.com/Arnav-M10/DrBean-hp26/b60e9d997cdc262e50107953bafc422398435297/packages/groundwork_adapter/fixtures/repro/hero-baseline.anchors.json
91
+ ../.counterdex-env/bin/python -I -m counterdex replay-native \
92
+ hero-baseline.native.json --anchors hero-baseline.anchors.json
93
+ ```
94
+
95
+ For this fixture the result has `verification: "valid"`,
96
+ `expected_binding: "matches"`, `replay: "passed"`, and scientific outcome
97
+ `"certified_counterexample"`. It checks two compatible exact vectors, including
98
+ one strictly outside the reviewed closed claim. It is synthetic evidence, not an
99
+ acquired experiment or an application approval.
100
+
101
+ For real work, obtain expected anchors through the reviewer's trusted channel.
102
+ Replacing both an artifact and its anchors does not prove authorship or honest
103
+ data collection. Old evidence needs its matching prepared source; Counterdex
104
+ never installs or imports a version chosen by an evidence packet.
105
+
106
+ ## Python API
107
+
108
+ After downloading the two files above, the same fresh replay is available from
109
+ Python:
110
+
111
+ ```sh
112
+ ../.counterdex-env/bin/python -I - <<'PY'
113
+ import json
114
+ from pathlib import Path
115
+ from counterdex import replay_packet
116
+
117
+ result = replay_packet(
118
+ Path("hero-baseline.native.json").read_bytes(),
119
+ expected=json.loads(Path("hero-baseline.anchors.json").read_text()),
120
+ )
121
+ print({key: result[key] for key in ("verification", "expected_binding", "replay")})
122
+ print(result["outcome"]["scientific_outcome"])
123
+ PY
124
+ ```
125
+
126
+ The public API also exposes:
127
+
128
+ | Entry point | Purpose |
129
+ | --- | --- |
130
+ | `normalize_problem`, `normalize_design`, `normalize_times` | Validate exact scientific projections without changing their reviewed meaning. |
131
+ | `create_baseline` | Discover and check candidates for a reviewed historical problem. |
132
+ | `replay_baseline` | Recompute historical compatibility and outside-claim checks. |
133
+ | `create_suggestion` | Compare a frozen pair under the reviewed design scope. |
134
+ | `replay_bundle` | Replay a standalone pair-design bundle. |
135
+ | `replay_packet` | Replay an application-bound native packet and its required lineage. |
136
+ | `capabilities` | Report supported operations and runtime qualification; this is not a verdict on supplied data. |
137
+ | `ExecutionContext`, `AdapterError` | Provide cooperative execution limits and typed failures. |
138
+
139
+ See the [scientific input contract](https://github.com/Arnav-M10/DrBean-hp26/blob/b60e9d997cdc262e50107953bafc422398435297/packages/groundwork_adapter/docs/INTEGRATION.md)
140
+ for complete input shapes and identities. Scientific scalar inputs use exact
141
+ rational strings, not JSON floating-point numbers. Row order, excluded rows,
142
+ notes and provenance participate in the problem identity. Candidate vectors,
143
+ feasible times, allowance provenance, policies and limits participate in the
144
+ design identity.
145
+
146
+ ## Command line and application integration
147
+
148
+ ```sh
149
+ .counterdex-env/bin/python -m counterdex --help
150
+ ```
151
+
152
+ Run the command above from the directory where the environment was created.
153
+ Commands include `capabilities`, `baseline`, `replay-baseline`, `run`, `replay`,
154
+ `bridge`, and `replay-native`; each command has `--help`. Evidence-producing CLI
155
+ commands require an explicit output path and refuse to overwrite an existing
156
+ file.
157
+
158
+ The bounded JSON subprocess bridge offers `handshake`, `admission`,
159
+ `investigate`, `design`, `review`, `recheck`, and `replay` operations. In
160
+ particular, `recheck` binds a separately reviewed observation proposal and its
161
+ revised inputs to the original baseline or design packet. Read the
162
+ [bridge contract](https://github.com/Arnav-M10/DrBean-hp26/blob/b60e9d997cdc262e50107953bafc422398435297/packages/groundwork_adapter/docs/BRIDGE.md)
163
+ and [exact application mapping](https://github.com/Arnav-M10/DrBean-hp26/blob/b60e9d997cdc262e50107953bafc422398435297/packages/groundwork_adapter/docs/APPLICATION_MAPPING.md)
164
+ for request schemas, approved limits, lineage and the POSIX parent-supervision
165
+ example. Those technical documents retain dated integration notes; the library
166
+ scope and release information on this page describe this distribution.
167
+
168
+ Counterdex checks mathematics and scope bindings. The calling application owns
169
+ authentication, human review, approval, durable storage, provider consent and hard
170
+ process supervision. Workflow IDs alone confer no authority. A new measurement
171
+ design or changed assumptions need fresh application review and approval. Native
172
+ bytes and the accepted report should be published together after checking their
173
+ exact bindings.
174
+
175
+ The Dr. Bean application coordinates this workflow using its own backend and
176
+ Deep Agents integration. They are separate from the Counterdex distribution;
177
+ installing this library does not start a server, configure an AI provider or
178
+ supply a browser verifier.
179
+
180
+ ## Scientific limits
181
+
182
+ This release does not establish global identifiability, search completeness,
183
+ physical truth, model adequacy, instrument precision, a global design optimum,
184
+ or a confidence interval. Hard allowances are reviewed bounds, not automatically
185
+ inferred statistical uncertainties. The exact checker uses a fixed rational
186
+ exponential-enclosure rule for the admitted analytic template. An unresolved
187
+ enclosure is not evidence of incompatibility.
188
+
189
+ Generic ODE families, interventions, resets, shared offsets, correlated errors
190
+ and nonlinear observables are unsupported. Native replay is qualified on
191
+ CPython 3.11; in-browser mathematical replay is not qualified. Pair separation
192
+ concerns only the two named candidates and approved feasible times. Numerical
193
+ scores cannot be promoted to checked guarantees.
194
+
195
+ The public package preserves existing schema identifiers, hash domains and
196
+ proof/selection-policy identifiers as compatibility data. Archived evidence
197
+ retains its original bytes and source requirements.
198
+
199
+ ## Documentation and source
200
+
201
+ - [Counterdex 0.3.0 release notes](https://github.com/Arnav-M10/DrBean-hp26/blob/main/packages/groundwork_adapter/docs/RELEASE_0_3_0.md)
202
+ - [Result semantics and permitted claims](https://github.com/Arnav-M10/DrBean-hp26/blob/b60e9d997cdc262e50107953bafc422398435297/packages/groundwork_adapter/docs/RESULT_SEMANTICS.md)
203
+ - [Exact analytic argument](https://github.com/Arnav-M10/DrBean-hp26/blob/b60e9d997cdc262e50107953bafc422398435297/packages/groundwork_adapter/docs/ANALYTIC_ARGUMENT.md)
204
+ - [Synthetic discovery, design and follow-up examples](https://github.com/Arnav-M10/DrBean-hp26/tree/b60e9d997cdc262e50107953bafc422398435297/packages/groundwork_adapter/fixtures/decision)
205
+ - [Portable replay packet](https://github.com/Arnav-M10/DrBean-hp26/tree/b60e9d997cdc262e50107953bafc422398435297/packages/groundwork_adapter/fixtures/repro)
206
+ - [Repository and issue tracker](https://github.com/Arnav-M10/DrBean-hp26)
207
+
208
+ The source distribution includes tests, technical documentation, synthetic
209
+ fixtures and the parent-supervision example. The wheel supplies the scientific
210
+ runtime. The repository package directory is `packages/groundwork_adapter/`.
@@ -0,0 +1,193 @@
1
+ # Counterdex
2
+
3
+ **Check a parameter claim against measurements, find a competing explanation, and
4
+ compare what to measure next.** Counterdex is a Python library and command-line
5
+ tool for bounded scientific investigation with portable, freshly replayable
6
+ evidence. It uses only the Python standard library and makes no network or model
7
+ provider calls.
8
+
9
+ Version **0.3.0** supports one model:
10
+
11
+ ```text
12
+ C(t) = A · (exp(−ke · t) − exp(−ka · t))
13
+ A > 0, 0 < ke < ka
14
+ ```
15
+
16
+ Time is in hours, concentration in mg/L, and rates in inverse hours. The admitted
17
+ initial conditions are `x(0)=1` and `c(0)=0`. Exact scientific execution and replay
18
+ are qualified on **CPython 3.11**.
19
+
20
+ ## What Counterdex does
21
+
22
+ - **Discover competing candidates.** Search a bounded rate grid with amplitude
23
+ screening, then independently check retained exact parameter vectors against
24
+ every included measurement and its declared hard allowance. A compatible
25
+ vector strictly outside a **closed** claimed interval is a counterexample;
26
+ either endpoint is inside the claim.
27
+ - **Compare a selected pair.** Evaluate researcher-supplied feasible measurement
28
+ times and a declared future allowance. Numerical guidance stays numerical.
29
+ Checked separation requires two freshly compatible candidates and a strictly
30
+ positive exact separation margin. Touching bands do not separate.
31
+ - **Review a new reading.** Recheck the original candidates using an appended
32
+ actual, transcribed or hypothetical observation at its own declared time and
33
+ allowance. Preserve the parent evidence and candidate vectors rather than
34
+ silently searching for replacements.
35
+ - **Replay evidence independently of the application.** Check native bytes,
36
+ complete lineage and exact input bindings against separately supplied expected
37
+ identities, then recompute the scientific checks with the matching prepared
38
+ package.
39
+
40
+ No counterexample found means **inconclusive**, never “claim proved.” Excluding
41
+ one or both selected candidates does not exclude every other model. A successful
42
+ replay confirms the recorded calculation under its declared scope; it does not
43
+ upgrade an inconclusive result or establish the truth of the physical model.
44
+
45
+ ## Install
46
+
47
+ Create a CPython 3.11 environment:
48
+
49
+ ```sh
50
+ python3.11 -m venv .counterdex-env
51
+ .counterdex-env/bin/python -m pip install --no-deps "counterdex==0.3.0"
52
+ .counterdex-env/bin/python -m counterdex capabilities
53
+ ```
54
+
55
+ The distribution, Python import and console command are all named `counterdex`.
56
+ The package has **no runtime dependencies**. Build and publication tools are
57
+ separate development dependencies. Python 3.12/3.13 applications should invoke a
58
+ separately prepared CPython 3.11 scientific process rather than relax the
59
+ package's Python requirement.
60
+
61
+ ## Try a complete native replay
62
+
63
+ This example uses synthetic measurements, a retained counterexample and its
64
+ separately stored anchors. Download the two public fixture files into a new
65
+ folder; the replay itself is offline and requires no repository checkout:
66
+
67
+ ```sh
68
+ mkdir counterdex-demo
69
+ cd counterdex-demo
70
+ curl --fail --location --output hero-baseline.native.json \
71
+ https://raw.githubusercontent.com/Arnav-M10/DrBean-hp26/b60e9d997cdc262e50107953bafc422398435297/packages/groundwork_adapter/fixtures/repro/hero-baseline.native.json
72
+ curl --fail --location --output hero-baseline.anchors.json \
73
+ https://raw.githubusercontent.com/Arnav-M10/DrBean-hp26/b60e9d997cdc262e50107953bafc422398435297/packages/groundwork_adapter/fixtures/repro/hero-baseline.anchors.json
74
+ ../.counterdex-env/bin/python -I -m counterdex replay-native \
75
+ hero-baseline.native.json --anchors hero-baseline.anchors.json
76
+ ```
77
+
78
+ For this fixture the result has `verification: "valid"`,
79
+ `expected_binding: "matches"`, `replay: "passed"`, and scientific outcome
80
+ `"certified_counterexample"`. It checks two compatible exact vectors, including
81
+ one strictly outside the reviewed closed claim. It is synthetic evidence, not an
82
+ acquired experiment or an application approval.
83
+
84
+ For real work, obtain expected anchors through the reviewer's trusted channel.
85
+ Replacing both an artifact and its anchors does not prove authorship or honest
86
+ data collection. Old evidence needs its matching prepared source; Counterdex
87
+ never installs or imports a version chosen by an evidence packet.
88
+
89
+ ## Python API
90
+
91
+ After downloading the two files above, the same fresh replay is available from
92
+ Python:
93
+
94
+ ```sh
95
+ ../.counterdex-env/bin/python -I - <<'PY'
96
+ import json
97
+ from pathlib import Path
98
+ from counterdex import replay_packet
99
+
100
+ result = replay_packet(
101
+ Path("hero-baseline.native.json").read_bytes(),
102
+ expected=json.loads(Path("hero-baseline.anchors.json").read_text()),
103
+ )
104
+ print({key: result[key] for key in ("verification", "expected_binding", "replay")})
105
+ print(result["outcome"]["scientific_outcome"])
106
+ PY
107
+ ```
108
+
109
+ The public API also exposes:
110
+
111
+ | Entry point | Purpose |
112
+ | --- | --- |
113
+ | `normalize_problem`, `normalize_design`, `normalize_times` | Validate exact scientific projections without changing their reviewed meaning. |
114
+ | `create_baseline` | Discover and check candidates for a reviewed historical problem. |
115
+ | `replay_baseline` | Recompute historical compatibility and outside-claim checks. |
116
+ | `create_suggestion` | Compare a frozen pair under the reviewed design scope. |
117
+ | `replay_bundle` | Replay a standalone pair-design bundle. |
118
+ | `replay_packet` | Replay an application-bound native packet and its required lineage. |
119
+ | `capabilities` | Report supported operations and runtime qualification; this is not a verdict on supplied data. |
120
+ | `ExecutionContext`, `AdapterError` | Provide cooperative execution limits and typed failures. |
121
+
122
+ See the [scientific input contract](https://github.com/Arnav-M10/DrBean-hp26/blob/b60e9d997cdc262e50107953bafc422398435297/packages/groundwork_adapter/docs/INTEGRATION.md)
123
+ for complete input shapes and identities. Scientific scalar inputs use exact
124
+ rational strings, not JSON floating-point numbers. Row order, excluded rows,
125
+ notes and provenance participate in the problem identity. Candidate vectors,
126
+ feasible times, allowance provenance, policies and limits participate in the
127
+ design identity.
128
+
129
+ ## Command line and application integration
130
+
131
+ ```sh
132
+ .counterdex-env/bin/python -m counterdex --help
133
+ ```
134
+
135
+ Run the command above from the directory where the environment was created.
136
+ Commands include `capabilities`, `baseline`, `replay-baseline`, `run`, `replay`,
137
+ `bridge`, and `replay-native`; each command has `--help`. Evidence-producing CLI
138
+ commands require an explicit output path and refuse to overwrite an existing
139
+ file.
140
+
141
+ The bounded JSON subprocess bridge offers `handshake`, `admission`,
142
+ `investigate`, `design`, `review`, `recheck`, and `replay` operations. In
143
+ particular, `recheck` binds a separately reviewed observation proposal and its
144
+ revised inputs to the original baseline or design packet. Read the
145
+ [bridge contract](https://github.com/Arnav-M10/DrBean-hp26/blob/b60e9d997cdc262e50107953bafc422398435297/packages/groundwork_adapter/docs/BRIDGE.md)
146
+ and [exact application mapping](https://github.com/Arnav-M10/DrBean-hp26/blob/b60e9d997cdc262e50107953bafc422398435297/packages/groundwork_adapter/docs/APPLICATION_MAPPING.md)
147
+ for request schemas, approved limits, lineage and the POSIX parent-supervision
148
+ example. Those technical documents retain dated integration notes; the library
149
+ scope and release information on this page describe this distribution.
150
+
151
+ Counterdex checks mathematics and scope bindings. The calling application owns
152
+ authentication, human review, approval, durable storage, provider consent and hard
153
+ process supervision. Workflow IDs alone confer no authority. A new measurement
154
+ design or changed assumptions need fresh application review and approval. Native
155
+ bytes and the accepted report should be published together after checking their
156
+ exact bindings.
157
+
158
+ The Dr. Bean application coordinates this workflow using its own backend and
159
+ Deep Agents integration. They are separate from the Counterdex distribution;
160
+ installing this library does not start a server, configure an AI provider or
161
+ supply a browser verifier.
162
+
163
+ ## Scientific limits
164
+
165
+ This release does not establish global identifiability, search completeness,
166
+ physical truth, model adequacy, instrument precision, a global design optimum,
167
+ or a confidence interval. Hard allowances are reviewed bounds, not automatically
168
+ inferred statistical uncertainties. The exact checker uses a fixed rational
169
+ exponential-enclosure rule for the admitted analytic template. An unresolved
170
+ enclosure is not evidence of incompatibility.
171
+
172
+ Generic ODE families, interventions, resets, shared offsets, correlated errors
173
+ and nonlinear observables are unsupported. Native replay is qualified on
174
+ CPython 3.11; in-browser mathematical replay is not qualified. Pair separation
175
+ concerns only the two named candidates and approved feasible times. Numerical
176
+ scores cannot be promoted to checked guarantees.
177
+
178
+ The public package preserves existing schema identifiers, hash domains and
179
+ proof/selection-policy identifiers as compatibility data. Archived evidence
180
+ retains its original bytes and source requirements.
181
+
182
+ ## Documentation and source
183
+
184
+ - [Counterdex 0.3.0 release notes](https://github.com/Arnav-M10/DrBean-hp26/blob/main/packages/groundwork_adapter/docs/RELEASE_0_3_0.md)
185
+ - [Result semantics and permitted claims](https://github.com/Arnav-M10/DrBean-hp26/blob/b60e9d997cdc262e50107953bafc422398435297/packages/groundwork_adapter/docs/RESULT_SEMANTICS.md)
186
+ - [Exact analytic argument](https://github.com/Arnav-M10/DrBean-hp26/blob/b60e9d997cdc262e50107953bafc422398435297/packages/groundwork_adapter/docs/ANALYTIC_ARGUMENT.md)
187
+ - [Synthetic discovery, design and follow-up examples](https://github.com/Arnav-M10/DrBean-hp26/tree/b60e9d997cdc262e50107953bafc422398435297/packages/groundwork_adapter/fixtures/decision)
188
+ - [Portable replay packet](https://github.com/Arnav-M10/DrBean-hp26/tree/b60e9d997cdc262e50107953bafc422398435297/packages/groundwork_adapter/fixtures/repro)
189
+ - [Repository and issue tracker](https://github.com/Arnav-M10/DrBean-hp26)
190
+
191
+ The source distribution includes tests, technical documentation, synthetic
192
+ fixtures and the parent-supervision example. The wheel supplies the scientific
193
+ runtime. The repository package directory is `packages/groundwork_adapter/`.
@@ -0,0 +1,39 @@
1
+ """Counterdex scientific adapter. Expensive/producer entry points load lazily."""
2
+ from .errors import AdapterError
3
+ from .identity import VERSION as __version__
4
+ from .models import normalize_design, normalize_problem, normalize_times
5
+ from .resource import ExecutionContext
6
+
7
+
8
+ def create_suggestion(*args, **kwargs):
9
+ from .pipeline import create_suggestion as implementation
10
+ return implementation(*args, **kwargs)
11
+
12
+
13
+ def replay_bundle(*args, **kwargs):
14
+ from .replay import replay_bundle as implementation
15
+ return implementation(*args, **kwargs)
16
+
17
+
18
+ def capabilities():
19
+ from .capabilities import capabilities as implementation
20
+ return implementation()
21
+
22
+
23
+ def create_baseline(*args, **kwargs):
24
+ from .baseline import create_baseline as implementation
25
+ return implementation(*args, **kwargs)
26
+
27
+
28
+ def replay_baseline(*args, **kwargs):
29
+ from .replay_baseline import replay_baseline as implementation
30
+ return implementation(*args, **kwargs)
31
+
32
+
33
+ def replay_packet(*args, **kwargs):
34
+ from .native_packet import replay_packet as implementation
35
+ return implementation(*args, **kwargs)
36
+
37
+
38
+ __all__ = ["AdapterError", "ExecutionContext", "normalize_design", "normalize_problem", "normalize_times",
39
+ "create_suggestion", "replay_bundle", "create_baseline", "replay_baseline", "replay_packet", "capabilities"]
@@ -0,0 +1,116 @@
1
+ """Local commands; supplied evidence can never select a path, URL, or import."""
2
+ import argparse
3
+ import os
4
+ from pathlib import Path
5
+ import sys
6
+ import tempfile
7
+
8
+ from .errors import AdapterError
9
+ from .exact import canonical_bytes, strict_json_loads
10
+ from .models import fields
11
+
12
+
13
+ def _read(path: str, maximum: int = 4 * 1024 * 1024) -> bytes:
14
+ with Path(path).open("rb") as stream:
15
+ data = stream.read(maximum + 1)
16
+ if len(data) > maximum:
17
+ raise AdapterError("resource_exhaustion", "Input file exceeds the admitted byte limit.")
18
+ return data
19
+
20
+
21
+ def _write_complete(path: str, content: bytes) -> None:
22
+ """Link a fully written same-filesystem file without replacing a destination."""
23
+ destination = Path(path)
24
+ temporary = None
25
+ try:
26
+ with tempfile.NamedTemporaryFile(dir=destination.parent, prefix=".counterdex-", delete=False) as output:
27
+ temporary = Path(output.name)
28
+ output.write(content)
29
+ output.flush()
30
+ os.fsync(output.fileno())
31
+ os.link(temporary, destination)
32
+ finally:
33
+ if temporary is not None:
34
+ temporary.unlink(missing_ok=True)
35
+
36
+
37
+ def main(argv: list[str] | None = None) -> int:
38
+ parser = argparse.ArgumentParser(description="Counterdex bounded scientific adapter")
39
+ commands = parser.add_subparsers(dest="command", required=True)
40
+ commands.add_parser("capabilities", help="Print qualified scientific capability metadata")
41
+ commands.add_parser("bridge", help="Read one bounded application request from stdin and write one response")
42
+ baseline = commands.add_parser("baseline", help="Discover and exactly check candidates for a reviewed historical problem")
43
+ baseline.add_argument("request")
44
+ baseline.add_argument("--output", required=True)
45
+ historical = commands.add_parser("replay-baseline", help="Fresh exact historical replay")
46
+ historical.add_argument("bundle")
47
+ native = commands.add_parser("replay-native", help="Replay an application-bound native packet and its full lineage")
48
+ native.add_argument("bundle")
49
+ native.add_argument("--anchors", required=True)
50
+ run = commands.add_parser("run", help="Run a frozen scientific request (approval is the caller's responsibility)")
51
+ run.add_argument("request")
52
+ run.add_argument("--output", required=True)
53
+ replay = commands.add_parser("replay", help="Fresh exact replay against separately supplied trust anchors")
54
+ replay.add_argument("bundle")
55
+ for command in (run, replay, baseline, historical):
56
+ command.add_argument("--anchors", help="Separate trusted local identity file; never selected by evidence")
57
+ command.add_argument("--expected-problem")
58
+ run.add_argument("--expected-design")
59
+ replay.add_argument("--expected-suggestion")
60
+ historical.add_argument("--expected-baseline")
61
+ historical.add_argument("--expected-scenario")
62
+ args = parser.parse_args(argv)
63
+ try:
64
+ if args.command == "bridge":
65
+ from .bridge import main as bridge_main
66
+ return bridge_main()
67
+ if args.command == "capabilities":
68
+ from .capabilities import capabilities
69
+ result = capabilities()
70
+ elif args.command == "replay-native":
71
+ from .native_packet import replay_packet
72
+ result = replay_packet(_read(args.bundle), expected=strict_json_loads(_read(args.anchors, 4096)))
73
+ else:
74
+ anchors = strict_json_loads(_read(args.anchors, 4096), max_bytes=4096) if args.anchors else {}
75
+ allowed = {"problem_digest", "baseline_digest", "scenario_id"} if args.command in ("baseline", "replay-baseline") else {"problem_digest", "design_digest", "suggestion_digest"}
76
+ if not isinstance(anchors, dict) or set(anchors) - allowed:
77
+ raise AdapterError("invalid_input", "Unexpected trust-anchor fields.")
78
+ expected_problem = args.expected_problem or anchors.get("problem_digest")
79
+ if args.command == "baseline":
80
+ from .baseline import create_baseline
81
+ request = fields(strict_json_loads(_read(args.request)), {"problem", "scenario_id", "workflow", "search_settings"}, "request")
82
+ content = create_baseline(request["problem"], expected_problem_digest=expected_problem,
83
+ scenario_id=request["scenario_id"], workflow=request["workflow"], settings=request["search_settings"])
84
+ _write_complete(args.output, content)
85
+ result = {"output": args.output, "artifact_bytes": len(content), "baseline_digest": strict_json_loads(content)["baseline_digest"]}
86
+ elif args.command == "replay-baseline":
87
+ from .replay_baseline import replay_baseline
88
+ result = replay_baseline(_read(args.bundle), expected_problem_digest=expected_problem,
89
+ expected_baseline_digest=args.expected_baseline or anchors.get("baseline_digest"),
90
+ expected_scenario_id=args.expected_scenario or anchors.get("scenario_id"))
91
+ elif args.command == "run":
92
+ from .pipeline import create_suggestion
93
+ request = fields(strict_json_loads(_read(args.request)), {"problem", "design", "workflow"}, "request")
94
+ content = create_suggestion(request["problem"], request["design"], workflow=request["workflow"],
95
+ expected_problem_digest=expected_problem,
96
+ expected_design_digest=args.expected_design or anchors.get("design_digest"))
97
+ # User-specified destination only; never replace an existing file.
98
+ _write_complete(args.output, content)
99
+ result = {"output": args.output, "artifact_bytes": len(content),
100
+ "suggestion_digest": strict_json_loads(content)["suggestion_digest"]}
101
+ else:
102
+ from .replay import replay_bundle
103
+ result = replay_bundle(_read(args.bundle), expected_problem_digest=expected_problem,
104
+ expected_suggestion_digest=args.expected_suggestion or anchors.get("suggestion_digest"))
105
+ sys.stdout.buffer.write(canonical_bytes(result) + b"\n")
106
+ return 0 if result.get("replay") != "failed" else 1
107
+ except AdapterError as error:
108
+ sys.stderr.buffer.write(canonical_bytes({"error": error.to_dict()}) + b"\n")
109
+ return 2
110
+ except OSError:
111
+ sys.stderr.buffer.write(canonical_bytes({"error": {"code": "local_io_failure", "message": "Could not read or exclusively create the supplied local file."}}) + b"\n")
112
+ return 2
113
+
114
+
115
+ if __name__ == "__main__":
116
+ raise SystemExit(main())