pen-stack 6.12.0__tar.gz → 6.13.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 (526) hide show
  1. {pen_stack-6.12.0 → pen_stack-6.13.0}/CHANGELOG.md +36 -1
  2. {pen_stack-6.12.0 → pen_stack-6.13.0}/CITATION.cff +1 -1
  3. {pen_stack-6.12.0 → pen_stack-6.13.0}/PKG-INFO +1 -1
  4. pen_stack-6.13.0/benchmarks/oracle/SHA256SUMS +5 -0
  5. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/oracles/execution.yaml +8 -0
  6. pen_stack-6.13.0/configs/oracles/reliability.yaml +92 -0
  7. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/oracles/scope_cards.yaml +13 -0
  8. pen_stack-6.13.0/docs/oracle_mesh.md +64 -0
  9. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/__init__.py +1 -1
  10. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/agent/mcp_server.py +20 -0
  11. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/api/manifest.py +7 -0
  12. pen_stack-6.13.0/pen_stack/oracles/affinity.py +116 -0
  13. pen_stack-6.13.0/pen_stack/oracles/reliability.py +64 -0
  14. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/oracles/status.py +20 -7
  15. pen_stack-6.13.0/pen_stack/oracles/structure_run.py +76 -0
  16. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/server/api.py +12 -0
  17. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack.egg-info/PKG-INFO +1 -1
  18. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack.egg-info/SOURCES.txt +8 -0
  19. pen_stack-6.13.0/prereg/SHA256_LOCK_ws_oracle.json +8 -0
  20. pen_stack-6.13.0/prereg/ws_oracle.yaml +45 -0
  21. {pen_stack-6.12.0 → pen_stack-6.13.0}/pyproject.toml +1 -1
  22. {pen_stack-6.12.0 → pen_stack-6.13.0}/LICENSE +0 -0
  23. {pen_stack-6.12.0 → pen_stack-6.13.0}/MANIFEST.in +0 -0
  24. {pen_stack-6.12.0 → pen_stack-6.13.0}/README.md +0 -0
  25. {pen_stack-6.12.0 → pen_stack-6.13.0}/bench/run.py +0 -0
  26. {pen_stack-6.12.0 → pen_stack-6.13.0}/benchmarks/delivery/SHA256SUMS +0 -0
  27. {pen_stack-6.12.0 → pen_stack-6.13.0}/benchmarks/genome_writing_bench/LEADERBOARD.md +0 -0
  28. {pen_stack-6.12.0 → pen_stack-6.13.0}/benchmarks/genome_writing_bench/README.md +0 -0
  29. {pen_stack-6.12.0 → pen_stack-6.13.0}/benchmarks/genome_writing_bench/SHA256SUMS +0 -0
  30. {pen_stack-6.12.0 → pen_stack-6.13.0}/benchmarks/genome_writing_bench/SUBMISSIONS.md +0 -0
  31. {pen_stack-6.12.0 → pen_stack-6.13.0}/benchmarks/genome_writing_bench/tasks.yaml +0 -0
  32. {pen_stack-6.12.0 → pen_stack-6.13.0}/benchmarks/genome_writing_challenge/README.md +0 -0
  33. {pen_stack-6.12.0 → pen_stack-6.13.0}/benchmarks/genome_writing_challenge/SUBMISSIONS.md +0 -0
  34. {pen_stack-6.12.0 → pen_stack-6.13.0}/benchmarks/offtarget/SHA256SUMS +0 -0
  35. {pen_stack-6.12.0 → pen_stack-6.13.0}/benchmarks/position_effect/README.md +0 -0
  36. {pen_stack-6.12.0 → pen_stack-6.13.0}/benchmarks/position_effect/SHA256SUMS +0 -0
  37. {pen_stack-6.12.0 → pen_stack-6.13.0}/benchmarks/verify/SHA256SUMS +0 -0
  38. {pen_stack-6.12.0 → pen_stack-6.13.0}/benchmarks/writer_efficiency/README.md +0 -0
  39. {pen_stack-6.12.0 → pen_stack-6.13.0}/benchmarks/writer_efficiency/SHA256SUMS +0 -0
  40. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/aav_serotype_tropism.yaml +0 -0
  41. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/antipeg.yaml +0 -0
  42. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/atlas_families.yaml +0 -0
  43. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/bridge_offtarget_profile.yaml +0 -0
  44. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/calibration/preexisting_nab_independent.yaml +0 -0
  45. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/capsid_epitope_oracle.yaml +0 -0
  46. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/capsid_sequences.fasta +0 -0
  47. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/cargo_polish.yaml +0 -0
  48. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/cell_types.yaml +0 -0
  49. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/datasets.yaml +0 -0
  50. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/delivery_constraints.yaml +0 -0
  51. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/delivery_rules.yaml +0 -0
  52. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/delivery_vehicles.yaml +0 -0
  53. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/expression/modifiers.yaml +0 -0
  54. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/expression/promoters.yaml +0 -0
  55. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/gates_v3.yaml +0 -0
  56. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/genotoxicity_oracle.yaml +0 -0
  57. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/gsh_validated_heldout.yaml +0 -0
  58. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/intent_weights.yaml +0 -0
  59. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/known_unknowns.yaml +0 -0
  60. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/llm.yaml +0 -0
  61. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/metric_guide.yaml +0 -0
  62. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/mhc_epitope_oracle.yaml +0 -0
  63. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/monitor_queries.yaml +0 -0
  64. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/rules/delivery.yaml +0 -0
  65. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/rules/fold.yaml +0 -0
  66. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/rules/multiplex.yaml +0 -0
  67. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/rules/payload.yaml +0 -0
  68. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/rules/reachability.yaml +0 -0
  69. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/safety/hazard_registry.yaml +0 -0
  70. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/safety/policy.yaml +0 -0
  71. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/safety/probes.yaml +0 -0
  72. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/score_axes.yaml +0 -0
  73. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/seroprevalence.yaml +0 -0
  74. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/target_sites.yaml +0 -0
  75. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/universe_crosswalk.yaml +0 -0
  76. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/write_types.yaml +0 -0
  77. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/writer_sequences.fasta +0 -0
  78. {pen_stack-6.12.0 → pen_stack-6.13.0}/configs/wtkb_curated.yaml +0 -0
  79. {pen_stack-6.12.0 → pen_stack-6.13.0}/data/curated/bridge_offtarget_energetics.json +0 -0
  80. {pen_stack-6.12.0 → pen_stack-6.13.0}/data/curated/bridge_offtarget_profile_measured.parquet +0 -0
  81. {pen_stack-6.12.0 → pen_stack-6.13.0}/data/curated/gene_coords.parquet +0 -0
  82. {pen_stack-6.12.0 → pen_stack-6.13.0}/data/curated/unified_editor_universe.parquet +0 -0
  83. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/BACKLOG.md +0 -0
  84. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/DEPLOY.md +0 -0
  85. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/INFRA.md +0 -0
  86. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/MCP.md +0 -0
  87. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/RELEASING.md +0 -0
  88. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/REPRO.md +0 -0
  89. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/STABILITY.md +0 -0
  90. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/agent.md +0 -0
  91. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/alphagenome_feasibility.md +0 -0
  92. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/autonomy.md +0 -0
  93. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/benchmark_circularity.md +0 -0
  94. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/biosecurity.md +0 -0
  95. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/build_interface.md +0 -0
  96. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/cards/atlas.md +0 -0
  97. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/cards/durability.md +0 -0
  98. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/cards/offtarget_data.md +0 -0
  99. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/cards/position_effect_data.md +0 -0
  100. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/cards/safety.md +0 -0
  101. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/cards/writer_efficiency_data.md +0 -0
  102. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/challenge.md +0 -0
  103. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/closed_loop.md +0 -0
  104. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/co_scientist.md +0 -0
  105. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/co_scientist_loop.md +0 -0
  106. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/delivery.md +0 -0
  107. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/delivery_immunology.md +0 -0
  108. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/delivery_recommender.md +0 -0
  109. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/digital_twin.md +0 -0
  110. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/dissemination.md +0 -0
  111. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/environment.md +0 -0
  112. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/experiment_design.md +0 -0
  113. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/generative_design.md +0 -0
  114. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/immune_profiler.md +0 -0
  115. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/index.md +0 -0
  116. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/integrations.md +0 -0
  117. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/live_oracles.md +0 -0
  118. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/mechanistic_constraints.md +0 -0
  119. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/offtarget.md +0 -0
  120. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/oracles.md +0 -0
  121. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/position_effect.md +0 -0
  122. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/positioning.md +0 -0
  123. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/private_data_formats.md +0 -0
  124. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/quickstart.md +0 -0
  125. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/responsible_use.md +0 -0
  126. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/rule_spec.md +0 -0
  127. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/rules.md +0 -0
  128. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/scope.md +0 -0
  129. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/scorecard.md +0 -0
  130. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/tpe_bench.md +0 -0
  131. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/tutorials/compare-families.md +0 -0
  132. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/tutorials/score-deliverability.md +0 -0
  133. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/tutorials/where-can-i-write.md +0 -0
  134. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/tutorials/which-writer-reaches-locus.md +0 -0
  135. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/uncertainty.md +0 -0
  136. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/verify.md +0 -0
  137. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/verify_service.md +0 -0
  138. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/world_model.md +0 -0
  139. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/writer_efficiency.md +0 -0
  140. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/writer_verification.md +0 -0
  141. {pen_stack-6.12.0 → pen_stack-6.13.0}/docs/wtkb.md +0 -0
  142. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/_resources.py +0 -0
  143. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/active/__init__.py +0 -0
  144. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/active/acquire.py +0 -0
  145. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/active/design.py +0 -0
  146. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/active/validate.py +0 -0
  147. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/adapt/__init__.py +0 -0
  148. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/adapt/finetune.py +0 -0
  149. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/adapt/ingest.py +0 -0
  150. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/adapt/pipeline.py +0 -0
  151. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/adapt/recalibrate.py +0 -0
  152. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/adapt/report.py +0 -0
  153. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/agent/__init__.py +0 -0
  154. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/agent/cite.py +0 -0
  155. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/agent/co_scientist.py +0 -0
  156. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/agent/epistemic.py +0 -0
  157. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/agent/guardrails.py +0 -0
  158. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/agent/orchestrator.py +0 -0
  159. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/agent/orchestrator_live.py +0 -0
  160. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/agent/pen_agent.py +0 -0
  161. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/agent/scope.py +0 -0
  162. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/agent/tools.py +0 -0
  163. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/api/__init__.py +0 -0
  164. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/atlas/__init__.py +0 -0
  165. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/atlas/build_wtkb.py +0 -0
  166. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/atlas/crosslink.py +0 -0
  167. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/atlas/expand.py +0 -0
  168. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/atlas/guide_design.py +0 -0
  169. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/atlas/schema.py +0 -0
  170. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/atlas/scorecard.py +0 -0
  171. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/atlas/universe.py +0 -0
  172. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/atlas/variant_propose.py +0 -0
  173. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/atlas/writer_efficiency.py +0 -0
  174. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/atlas/writer_predict.py +0 -0
  175. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/atlas/writer_recommend.py +0 -0
  176. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/atlas/writer_verify.py +0 -0
  177. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/bridge/__init__.py +0 -0
  178. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/bridge/activity.py +0 -0
  179. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/bridge/cli.py +0 -0
  180. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/bridge/fold_qc.py +0 -0
  181. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/bridge/guide_qc.py +0 -0
  182. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/bridge/ingest.py +0 -0
  183. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/bridge/offtarget.py +0 -0
  184. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/bridge/offtarget_energetics.py +0 -0
  185. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/bridge/ortholog_screen.py +0 -0
  186. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/bridge/pipeline.py +0 -0
  187. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/build/__init__.py +0 -0
  188. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/build/ingest.py +0 -0
  189. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/build/protocol.py +0 -0
  190. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/build/simlab.py +0 -0
  191. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/cli.py +0 -0
  192. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/data/__init__.py +0 -0
  193. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/data/encode.py +0 -0
  194. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/data/genome.py +0 -0
  195. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/data/ingest_chromatin.py +0 -0
  196. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/data/ingest_integration.py +0 -0
  197. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/data/ingest_safety_annot.py +0 -0
  198. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/data/ingest_trip.py +0 -0
  199. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/design/__init__.py +0 -0
  200. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/design/capsid_generate.py +0 -0
  201. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/design/generate.py +0 -0
  202. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/design/pareto.py +0 -0
  203. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/design/space.py +0 -0
  204. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/design/writer_variants.py +0 -0
  205. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/env/__init__.py +0 -0
  206. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/env/genome_writing_env.py +0 -0
  207. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/env/policies.py +0 -0
  208. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/graph/__init__.py +0 -0
  209. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/graph/build.py +0 -0
  210. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/graph/cell_types.py +0 -0
  211. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/graph/ingest.py +0 -0
  212. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/graph/query.py +0 -0
  213. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/graph/schema.py +0 -0
  214. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/loop/__init__.py +0 -0
  215. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/loop/continual.py +0 -0
  216. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/loop/cycle.py +0 -0
  217. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/loop/drift.py +0 -0
  218. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/mech/__init__.py +0 -0
  219. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/mech/classify_atlas.py +0 -0
  220. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/mech/whitelist.py +0 -0
  221. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/monitor/__init__.py +0 -0
  222. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/monitor/europepmc.py +0 -0
  223. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/monitor/run.py +0 -0
  224. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/monitor/triage.py +0 -0
  225. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/oracles/__init__.py +0 -0
  226. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/oracles/cache.py +0 -0
  227. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/oracles/energetics.py +0 -0
  228. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/oracles/genome.py +0 -0
  229. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/oracles/protein_design.py +0 -0
  230. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/oracles/rna.py +0 -0
  231. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/oracles/schema.py +0 -0
  232. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/oracles/structure.py +0 -0
  233. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/oracles/vcell.py +0 -0
  234. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/planner/__init__.py +0 -0
  235. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/planner/ada_risk.py +0 -0
  236. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/planner/antipeg_oracle.py +0 -0
  237. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/planner/capsid_epitope_oracle.py +0 -0
  238. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/planner/cargo.py +0 -0
  239. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/planner/cargo_polish.py +0 -0
  240. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/planner/delivery.py +0 -0
  241. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/planner/delivery_constraints.py +0 -0
  242. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/planner/delivery_immune.py +0 -0
  243. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/planner/delivery_immunology.py +0 -0
  244. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/planner/delivery_predict.py +0 -0
  245. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/planner/delivery_vehicles.py +0 -0
  246. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/planner/genotoxicity_oracle.py +0 -0
  247. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/planner/immune_mhc2.py +0 -0
  248. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/planner/immune_profile.py +0 -0
  249. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/planner/innate_sensing.py +0 -0
  250. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/planner/multiplex.py +0 -0
  251. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/planner/optimize.py +0 -0
  252. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/planner/pipeline.py +0 -0
  253. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/planner/report.py +0 -0
  254. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/planner/router.py +0 -0
  255. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/planner/seroprevalence_oracle.py +0 -0
  256. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/planner/target_site.py +0 -0
  257. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/rag/__init__.py +0 -0
  258. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/rag/index.py +0 -0
  259. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/rag/llm.py +0 -0
  260. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/rag/qa.py +0 -0
  261. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/rules/__init__.py +0 -0
  262. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/rules/evaluators.py +0 -0
  263. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/rules/loader.py +0 -0
  264. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/rules/schema.py +0 -0
  265. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/rules/solver.py +0 -0
  266. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/rules/spec.py +0 -0
  267. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/safety/__init__.py +0 -0
  268. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/safety/audit.py +0 -0
  269. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/safety/gate.py +0 -0
  270. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/safety/policy.py +0 -0
  271. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/safety/redteam.py +0 -0
  272. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/safety/registry.py +0 -0
  273. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/safety/screen.py +0 -0
  274. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/safety/standards.py +0 -0
  275. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/score/__init__.py +0 -0
  276. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/score/recalibrate.py +0 -0
  277. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/score/therapeutic.py +0 -0
  278. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/server/__init__.py +0 -0
  279. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/twin/__init__.py +0 -0
  280. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/twin/calibrate.py +0 -0
  281. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/twin/data/__init__.py +0 -0
  282. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/twin/data/position_effect.py +0 -0
  283. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/twin/mechanistic.py +0 -0
  284. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/twin/outcome.py +0 -0
  285. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/twin/position_effect.py +0 -0
  286. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/ui/__init__.py +0 -0
  287. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/ui/app.py +0 -0
  288. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/__init__.py +0 -0
  289. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/adapt_demo.py +0 -0
  290. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/agent_eval.py +0 -0
  291. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/bench_adversarial_tasks.py +0 -0
  292. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/bench_coscientist_tasks.py +0 -0
  293. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/bench_graph_tasks.py +0 -0
  294. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/bench_rule_tasks.py +0 -0
  295. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/bench_trust_tasks.py +0 -0
  296. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/bench_writetype_tasks.py +0 -0
  297. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/blind_gsh_discovery.py +0 -0
  298. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/cargo_directionality.py +0 -0
  299. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/closed_loop.py +0 -0
  300. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/durability_baselines.py +0 -0
  301. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/experiment_design.py +0 -0
  302. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/expr_controls.py +0 -0
  303. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/forward_hypotheses.py +0 -0
  304. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/generative_design.py +0 -0
  305. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/guide_qc_demo.py +0 -0
  306. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/heldout_celltype_expr.py +0 -0
  307. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/immune_calibration.py +0 -0
  308. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/intent_specification.py +0 -0
  309. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/known_biology_expr.py +0 -0
  310. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/offtarget_energetics_eval.py +0 -0
  311. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/out_of_scope_refusal.py +0 -0
  312. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/outcome_calibration.py +0 -0
  313. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/outcome_prediction.py +0 -0
  314. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/paper3_benchmark.py +0 -0
  315. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/paper4_real_validation.py +0 -0
  316. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/paper4_validation.py +0 -0
  317. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/protocol_safety.py +0 -0
  318. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/safety_screening.py +0 -0
  319. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/selective_prediction.py +0 -0
  320. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/seq_vs_measured.py +0 -0
  321. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/target_site_controls.py +0 -0
  322. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/uncertainty_eval.py +0 -0
  323. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/ungrounded_baseline.py +0 -0
  324. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/within_locus_ranking.py +0 -0
  325. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/validate/writer_recovery.py +0 -0
  326. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/verify/__init__.py +0 -0
  327. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/verify/proof.py +0 -0
  328. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/verify/schema.py +0 -0
  329. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/verify/service.py +0 -0
  330. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/web/__init__.py +0 -0
  331. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/web/guide.py +0 -0
  332. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/web/llm.py +0 -0
  333. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/web/router.py +0 -0
  334. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/web/server.py +0 -0
  335. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/web/tools.py +0 -0
  336. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/wgenome/__init__.py +0 -0
  337. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/wgenome/chromatin_seq.py +0 -0
  338. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/wgenome/durability.py +0 -0
  339. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/wgenome/export_tracks.py +0 -0
  340. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/wgenome/features.py +0 -0
  341. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/wgenome/gsh_baseline.py +0 -0
  342. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/wgenome/mesh_features.py +0 -0
  343. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/wgenome/offtarget_assay.py +0 -0
  344. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/wgenome/offtarget_data.py +0 -0
  345. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/wgenome/offtarget_predict.py +0 -0
  346. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/wgenome/ood.py +0 -0
  347. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/wgenome/providers.py +0 -0
  348. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/wgenome/safety.py +0 -0
  349. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/wgenome/structure3d.py +0 -0
  350. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/wgenome/uncertainty.py +0 -0
  351. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack/wgenome/writability.py +0 -0
  352. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack.egg-info/dependency_links.txt +0 -0
  353. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack.egg-info/entry_points.txt +0 -0
  354. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack.egg-info/requires.txt +0 -0
  355. {pen_stack-6.12.0 → pen_stack-6.13.0}/pen_stack.egg-info/top_level.txt +0 -0
  356. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_phase0.json +0 -0
  357. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_phase1_5.json +0 -0
  358. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_phase2.json +0 -0
  359. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_phase3.json +0 -0
  360. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_a.json +0 -0
  361. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_acq.json +0 -0
  362. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_aldesign.json +0 -0
  363. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_alvalidate.json +0 -0
  364. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_atlas.json +0 -0
  365. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_b.json +0 -0
  366. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_ba.json +0 -0
  367. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_ba_v33.json +0 -0
  368. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_ba_v45.json +0 -0
  369. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_bench.json +0 -0
  370. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_c.json +0 -0
  371. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_cal.json +0 -0
  372. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_calib.json +0 -0
  373. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_challenge.json +0 -0
  374. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_chat.json +0 -0
  375. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_cite.json +0 -0
  376. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_continual.json +0 -0
  377. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_cosci2.json +0 -0
  378. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_crit.json +0 -0
  379. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_ct.json +0 -0
  380. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_d.json +0 -0
  381. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_delivery.json +0 -0
  382. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_drift.json +0 -0
  383. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_e.json +0 -0
  384. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_env.json +0 -0
  385. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_ep.json +0 -0
  386. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_epitope.json +0 -0
  387. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_expr2.json +0 -0
  388. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_f.json +0 -0
  389. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_frontend.json +0 -0
  390. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_g.json +0 -0
  391. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_gen.json +0 -0
  392. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_genotox.json +0 -0
  393. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_graph.json +0 -0
  394. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_h.json +0 -0
  395. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_hybrid.json +0 -0
  396. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_immune.json +0 -0
  397. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_immune2.json +0 -0
  398. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_ingest.json +0 -0
  399. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_innate.json +0 -0
  400. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_loop.json +0 -0
  401. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_manifest.json +0 -0
  402. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_mc.json +0 -0
  403. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_mcp.json +0 -0
  404. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_mech.json +0 -0
  405. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_mon.json +0 -0
  406. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_o.json +0 -0
  407. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_offtarget.json +0 -0
  408. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_openapi.json +0 -0
  409. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_orch.json +0 -0
  410. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_outcome.json +0 -0
  411. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_pareto.json +0 -0
  412. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_peg.json +0 -0
  413. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_plan.json +0 -0
  414. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_policy.json +0 -0
  415. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_profile.json +0 -0
  416. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_proto.json +0 -0
  417. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_r.json +0 -0
  418. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_redteam.json +0 -0
  419. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_route.json +0 -0
  420. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_screen.json +0 -0
  421. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_seroprev.json +0 -0
  422. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_simlab.json +0 -0
  423. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_twincal.json +0 -0
  424. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_uq.json +0 -0
  425. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_v.json +0 -0
  426. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_vcell.json +0 -0
  427. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_verify.json +0 -0
  428. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_writer.json +0 -0
  429. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_wv.json +0 -0
  430. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/paper1.yaml +0 -0
  431. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/paper2.yaml +0 -0
  432. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/paper3.yaml +0 -0
  433. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/paper4.yaml +0 -0
  434. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/phase0.yaml +0 -0
  435. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_a.yaml +0 -0
  436. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_acq.yaml +0 -0
  437. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_aldesign.yaml +0 -0
  438. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_alvalidate.yaml +0 -0
  439. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_atlas.yaml +0 -0
  440. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_b.yaml +0 -0
  441. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_ba.yaml +0 -0
  442. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_ba_v33.yaml +0 -0
  443. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_ba_v45.yaml +0 -0
  444. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_bench.yaml +0 -0
  445. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_c.yaml +0 -0
  446. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_cal.yaml +0 -0
  447. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_calib.yaml +0 -0
  448. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_challenge.yaml +0 -0
  449. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_chat.yaml +0 -0
  450. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_cite.yaml +0 -0
  451. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_continual.yaml +0 -0
  452. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_cosci2.yaml +0 -0
  453. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_crit.yaml +0 -0
  454. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_ct.yaml +0 -0
  455. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_d.yaml +0 -0
  456. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_delivery.yaml +0 -0
  457. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_drift.yaml +0 -0
  458. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_e.yaml +0 -0
  459. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_env.yaml +0 -0
  460. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_ep.yaml +0 -0
  461. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_epitope.yaml +0 -0
  462. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_expr2.yaml +0 -0
  463. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_f.yaml +0 -0
  464. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_frontend.yaml +0 -0
  465. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_g.yaml +0 -0
  466. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_gen.yaml +0 -0
  467. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_genotox.yaml +0 -0
  468. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_graph.yaml +0 -0
  469. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_h.yaml +0 -0
  470. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_hybrid.yaml +0 -0
  471. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_immune.yaml +0 -0
  472. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_immune2.yaml +0 -0
  473. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_ingest.yaml +0 -0
  474. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_innate.yaml +0 -0
  475. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_loop.yaml +0 -0
  476. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_manifest.yaml +0 -0
  477. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_mc.yaml +0 -0
  478. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_mcp.yaml +0 -0
  479. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_mech.yaml +0 -0
  480. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_mon.yaml +0 -0
  481. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_o.yaml +0 -0
  482. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_offtarget.yaml +0 -0
  483. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_openapi.yaml +0 -0
  484. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_orch.yaml +0 -0
  485. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_outcome.yaml +0 -0
  486. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_pareto.yaml +0 -0
  487. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_peg.yaml +0 -0
  488. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_plan.yaml +0 -0
  489. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_policy.yaml +0 -0
  490. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_profile.yaml +0 -0
  491. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_proto.yaml +0 -0
  492. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_r.yaml +0 -0
  493. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_redteam.yaml +0 -0
  494. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_route.yaml +0 -0
  495. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_screen.yaml +0 -0
  496. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_seroprev.yaml +0 -0
  497. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_simlab.yaml +0 -0
  498. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_twincal.yaml +0 -0
  499. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_uq.yaml +0 -0
  500. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_v.yaml +0 -0
  501. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_vcell.yaml +0 -0
  502. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_verify.yaml +0 -0
  503. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_writer.yaml +0 -0
  504. {pen_stack-6.12.0 → pen_stack-6.13.0}/prereg/ws_wv.yaml +0 -0
  505. {pen_stack-6.12.0 → pen_stack-6.13.0}/scripts/build_capsid_fitness.py +0 -0
  506. {pen_stack-6.12.0 → pen_stack-6.13.0}/scripts/calibrate_immune_axes.py +0 -0
  507. {pen_stack-6.12.0 → pen_stack-6.13.0}/scripts/fetch_licensed_sources.py +0 -0
  508. {pen_stack-6.12.0 → pen_stack-6.13.0}/scripts/offtarget_chromatin_incremental.py +0 -0
  509. {pen_stack-6.12.0 → pen_stack-6.13.0}/scripts/offtarget_chromatin_matched.py +0 -0
  510. {pen_stack-6.12.0 → pen_stack-6.13.0}/scripts/offtarget_chromatin_validation.py +0 -0
  511. {pen_stack-6.12.0 → pen_stack-6.13.0}/scripts/p1_build_atlas.py +0 -0
  512. {pen_stack-6.12.0 → pen_stack-6.13.0}/scripts/p1_build_durability.py +0 -0
  513. {pen_stack-6.12.0 → pen_stack-6.13.0}/scripts/p1_build_position_effect.py +0 -0
  514. {pen_stack-6.12.0 → pen_stack-6.13.0}/scripts/p1_build_writer_eff.py +0 -0
  515. {pen_stack-6.12.0 → pen_stack-6.13.0}/scripts/p1_export_tracks.py +0 -0
  516. {pen_stack-6.12.0 → pen_stack-6.13.0}/scripts/p1_safety_concordance.py +0 -0
  517. {pen_stack-6.12.0 → pen_stack-6.13.0}/scripts/p1_train_safety.py +0 -0
  518. {pen_stack-6.12.0 → pen_stack-6.13.0}/scripts/p1_validation_report.py +0 -0
  519. {pen_stack-6.12.0 → pen_stack-6.13.0}/scripts/p2_build_atlas.py +0 -0
  520. {pen_stack-6.12.0 → pen_stack-6.13.0}/scripts/p3_benchmark_report.py +0 -0
  521. {pen_stack-6.12.0 → pen_stack-6.13.0}/scripts/p4_genome_scan.py +0 -0
  522. {pen_stack-6.12.0 → pen_stack-6.13.0}/scripts/p52_build_genotox_oracle.py +0 -0
  523. {pen_stack-6.12.0 → pen_stack-6.13.0}/scripts/p53_build_epitope_oracle.py +0 -0
  524. {pen_stack-6.12.0 → pen_stack-6.13.0}/scripts/ws_b_report.py +0 -0
  525. {pen_stack-6.12.0 → pen_stack-6.13.0}/scripts/ws_c_report.py +0 -0
  526. {pen_stack-6.12.0 → pen_stack-6.13.0}/setup.cfg +0 -0
@@ -3,6 +3,40 @@
3
3
  All notable changes to PEN-STACK are documented here. This file follows
4
4
  [Keep a Changelog](https://keepachangelog.com/).
5
5
 
6
+ ## [6.13.0] - 2026-06-22 - Oracle mesh: binding-affinity dimension, per-oracle reliability, disagreement-to-uncertainty
7
+
8
+ Hardens the foundation-model oracle mesh under one result contract. Adds a binding-affinity dimension
9
+ (Boltz-2), surfaces each oracle's published reliability reported verbatim from public benchmarks, and makes
10
+ cross-oracle disagreement widen the reported interval. Every oracle output stays a candidate, never ground
11
+ truth.
12
+
13
+ ### Added
14
+ - **Binding-affinity oracle** (`pen_stack/oracles/affinity.py`). Wraps the Boltz-2 protein-ligand affinity head
15
+ (MIT, `10.1101/2025.06.14.659707`): a binder probability and a predicted affinity value with native
16
+ uncertainty taken from the model's own outputs. The head is protein-small-molecule only, so protein-protein
17
+ and protein-DNA pairs are returned as out-of-scope (extrapolating). The backend runs off the request path and
18
+ is cached; an uncached request defers (cache-or-abstain) rather than blocking or fabricating. A grounded,
19
+ in-domain example is committed: 4-hydroxytamoxifen binding the ERT2 ligand-binding domain (the inducible-writer
20
+ switch), predicted as a high-confidence binder (binder probability 0.99, complex pLDDT 0.94).
21
+ - **Per-oracle reliability registry** (`pen_stack/oracles/reliability.py`, `configs/oracles/reliability.yaml`).
22
+ Each oracle's published benchmark accuracy, reported verbatim with citation: the Boltz-2 affinity head's
23
+ FEP+ Pearson r of about 0.62 (paper-reported) is the verified anchor. These are the wrapped models' published
24
+ numbers, not a claim about this stack's accuracy and not re-computed; where a verbatim score was not verified
25
+ the value is left null with the cited benchmark as the pointer.
26
+ - **Disagreement to uncertainty.** Cross-oracle disagreement widens the reported interval (native uncertainty
27
+ plus half the cross-oracle spread); a check confirms the widening is monotonic in the spread.
28
+ - **Held-oracle runner** (`pen_stack/oracles/structure_run.py`) for the structure oracles over writer-substrate
29
+ and att-site complexes: off the request path, cache-or-abstain.
30
+ - **Oracle-Bench** (`benchmarks/oracle/`) reporting the three gates, and surfaces: `GET /api/oracles` extended
31
+ with reliability and the disagreement check, `POST /api/oracle/affinity`, MCP `oracle_query`, the manifest
32
+ `oracle_query` tool, the web Oracle Mesh page, and `docs/oracle_mesh.md`.
33
+
34
+ ### Notes
35
+ - Affinity predictions are candidates with native uncertainty, not measured binding constants; reliability is
36
+ surfaced so a confident-looking value is not over-trusted.
37
+ - The structure oracles over full complexes (AlphaFold3 / Boltz-2 / Chai-1 / Protenix) remain held: run
38
+ separately on GPU or cloud and cached, never inline on the request path.
39
+
6
40
  ## [6.12.0] - 2026-06-21 - Verification service: published rule spec, proof object, standards-aligned biosecurity
7
41
 
8
42
  Hardens `verify(design)` into a formal verification service. The rule base becomes a published, citable spec;
@@ -24,7 +58,8 @@ biosecurity gate is mapped to the community synthesis-screening standards.
24
58
  SecureDNA's pass/deny outcome, with a concordance report (8/8 concordant on the labelled probe set).
25
59
  References: Common Mechanism (Wheeler et al. 2024, `10.1089/apb.2023.0034`); SecureDNA (`arXiv:2403.14023`).
26
60
  - **Verify-Bench** (`benchmarks/verify/`) reporting the three gates, and surfaces: REST `POST /api/verify/proof`,
27
- MCP `verify_proof`, manifest tool `verify_proof`, and `docs/verify_service.md`.
61
+ MCP `verify_proof`, manifest tool `verify_proof`, the web Verify page (per-axis green/amber/red with the
62
+ violated rule, its citation, and the suggested fix), and `docs/verify_service.md`.
28
63
 
29
64
  ### Notes
30
65
  - The verdict covers legality, feasibility and biosecurity, not efficacy (efficacy stays a downstream
@@ -1,7 +1,7 @@
1
1
  cff-version: 1.2.0
2
2
  message: "If you use PEN-STACK, please cite it as below."
3
3
  title: "PEN-STACK: open infrastructure for genome writing"
4
- version: 6.12.0
4
+ version: 6.13.0
5
5
  date-released: 2026-06-20
6
6
  authors:
7
7
  - family-names: "Mahaboob Ali"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pen-stack
3
- Version: 6.12.0
3
+ Version: 6.13.0
4
4
  Summary: Open infrastructure for genome writing: the Writable Genome atlas, the Writer Atlas, and the Write Planner.
5
5
  Author-email: Anees Ahmed Mahaboob Ali <ahmedaneesm@gmail.com>
6
6
  License: MIT
@@ -0,0 +1,5 @@
1
+ 7b39e54eae68dbab180d3461c859cc1f1e481c8d0b694405e49b0f850029930b benchmarks/oracle/harness.py
2
+ 573d0e5029d222dfb93d8a1db71199ff294837a44f7e7fa793b5be3f2a0a6461 benchmarks/oracle/oracle_bench_metrics.json
3
+ d5aafb9351d5f0a93f4a3e5282fc062940a4f9ffe6b8391a4d86bdbc9e70fa29 configs/oracles/reliability.yaml
4
+ 49155d662d63ffa37e821f933a1f1b86d10f0eda0a1b038cf7dcbf5c08b54877 oracle_cache/12ce1ef95d7b45985abbc25c.json
5
+ cfbd1588311956bfaa13cc8d8bfb88debf2d4fa7c6c11586ff14c055e5cfd864 oracle_cache/9b57c9a6a632d80ac9292ee2.json
@@ -85,3 +85,11 @@ oracles:
85
85
  latency_class: long_job
86
86
  live: false
87
87
  note: "HELD, run SEPARATELY on a cloud A100. ~1-10 min. Not active now."
88
+
89
+ boltz-2-affinity: # v6.13 WS-ORACLE: the Boltz-2 affinity head (protein-ligand binding affinity)
90
+ execution: local_gpu
91
+ latency_class: long_job
92
+ live: false
93
+ note: "Boltz-2 affinity head (MIT weights). Run OFF-REQUEST as a batch on the GPU (~10-30 min incl. MSA) and
94
+ cached; the request path is cache-or-abstain and never blocks the chat. Predicts a binder probability +
95
+ affinity value for a protein + small-molecule ligand."
@@ -0,0 +1,92 @@
1
+ # PEN-STACK v6.13, WS-ORACLE: per-oracle reliability registry.
2
+ #
3
+ # These are the WRAPPED models' PUBLISHED reliability on PUBLIC benchmarks, reported VERBATIM with citation.
4
+ # They are NOT a claim about this stack's own accuracy, are NOT re-computed here, and do NOT make an oracle
5
+ # output a ground-truth measurement. Every oracle output remains a candidate / hypothesis carrying its own
6
+ # native uncertainty; reliability is surfaced so a confident-looking value is not over-trusted.
7
+ #
8
+ # Where a verbatim numeric score was not independently verified, `value` is null and the cited benchmark is the
9
+ # pointer. The registry never invents a number.
10
+ version: "1.0"
11
+ disclaimer: >
12
+ Published reliability of the wrapped foundation models on public benchmarks, reported verbatim with citation.
13
+ Not a claim about this stack's own accuracy, not re-computed here. Each oracle output is a candidate carrying
14
+ its native uncertainty. Numbers tagged "paper" are author-reported; "self-report" means not independently
15
+ verified against the official benchmark results. Where a verbatim score is not pinned, value is null and the
16
+ benchmark plus citation are given as the pointer.
17
+
18
+ oracles:
19
+ boltz-2-affinity:
20
+ - benchmark: "FEP+ (OpenFE) free-energy perturbation benchmark, held-out targets"
21
+ task: "protein-ligand binding affinity"
22
+ metric: "Pearson r vs experimental affinity"
23
+ value: 0.62
24
+ qualifier: "approximate; paper-reported"
25
+ note: "approaches physics-based FEP accuracy at ~1000x lower cost/time (a speed/cost claim, not accuracy)"
26
+ reported_by: "paper"
27
+ citation: ["10.1101/2025.06.14.659707"]
28
+ - benchmark: "CASP16 binding-affinity challenge (140 complexes)"
29
+ task: "protein-ligand binding affinity"
30
+ metric: "ranking among submitted methods"
31
+ value: null
32
+ qualifier: "self-reported first among submitted methods; not independently verified vs official CASP16 results"
33
+ reported_by: "self-report"
34
+ citation: ["10.1101/2025.06.14.659707"]
35
+ - related_public_benchmarks:
36
+ - "MF-PCBA multi-fidelity PubChem BioAssay (10.1021/acs.jcim.2c01569)"
37
+ - "Polaris / ASAP-OpenADMET antiviral challenge 2025 (10.26434/chemrxiv-2025-zd9mr)"
38
+ - "OpenFF protein-ligand-benchmark (github.com/openforcefield/protein-ligand-benchmark)"
39
+
40
+ alphafold3:
41
+ - benchmark: "CASP / CAMEO blind structure assessment; PDB held-out set"
42
+ task: "protein / protein-NA complex structure prediction"
43
+ metric: "LDDT / TM-score / DockQ by target class (see source)"
44
+ value: null
45
+ qualifier: "benchmark named; a single verbatim score is not pinned (varies strongly by target class)"
46
+ reported_by: "community/paper"
47
+ citation: ["predictioncenter.org (CASP)", "cameo3d.org (CAMEO; Haas et al. 2018, PubMed 29178137)"]
48
+
49
+ boltz-2:
50
+ - benchmark: "CASP / CAMEO; PDB held-out set (open-weights AF3-class predictor)"
51
+ task: "protein / complex structure prediction"
52
+ metric: "LDDT / TM-score (see source)"
53
+ value: null
54
+ qualifier: "benchmark named; verbatim score not pinned here"
55
+ reported_by: "paper"
56
+ citation: ["10.1101/2025.06.14.659707", "Boltz-1 10.1101/2024.11.19.624167"]
57
+
58
+ chai-1:
59
+ - benchmark: "CASP / CAMEO; PDB held-out set"
60
+ task: "protein / complex structure prediction"
61
+ metric: "LDDT / DockQ (see source)"
62
+ value: null
63
+ qualifier: "benchmark named; verbatim score not pinned here"
64
+ reported_by: "developer"
65
+ citation: ["github.com/chaidiscovery/chai-lab"]
66
+
67
+ evo2:
68
+ - benchmark: "ProteinGym (variant effect); zero-shot genomic likelihood"
69
+ task: "variant-effect / sequence likelihood"
70
+ metric: "Spearman / AUROC (see source)"
71
+ value: null
72
+ qualifier: "benchmark named; verbatim score not pinned here"
73
+ reported_by: "community"
74
+ citation: ["ProteinGym 10.1101/2023.12.07.570727"]
75
+
76
+ esm3:
77
+ - benchmark: "ProteinGym (variant effect); FLIP (fitness landscapes)"
78
+ task: "variant-effect / protein fitness"
79
+ metric: "Spearman (see source)"
80
+ value: null
81
+ qualifier: "benchmark named; verbatim score not pinned here"
82
+ reported_by: "community"
83
+ citation: ["ProteinGym 10.1101/2023.12.07.570727", "FLIP 10.1101/2021.11.09.467890"]
84
+
85
+ alphagenome:
86
+ - benchmark: "regulatory-track + variant-effect evaluation (in-distribution tracks/tissues)"
87
+ task: "regulatory genomics"
88
+ metric: "see source (per-track correlation)"
89
+ value: null
90
+ qualifier: "benchmark named; verbatim score not pinned here; valid only on trained tracks/tissues"
91
+ reported_by: "developer"
92
+ citation: ["Google DeepMind AlphaGenome"]
@@ -235,3 +235,16 @@ oracles:
235
235
  absolute expression"
236
236
  generalizes_to_unseen_loci: false
237
237
  license: "MIT (github.com/bowang-lab/scGPT; Nature Methods 10.1038/s41592-024-02201-0)"
238
+
239
+ boltz-2-affinity: # v6.13 WS-ORACLE: the Boltz-2 protein-ligand binding-affinity head
240
+ family: affinity
241
+ version: "2.2.1"
242
+ output_kind: claim # a checkable prediction (predicted, not a measured Kd); carries native uncertainty
243
+ valid_for: "protein + SMALL-MOLECULE ligand binding-affinity prediction (Boltz-2 affinity head): a binder
244
+ probability and a predicted affinity value, for ligands near the trained chemical space (e.g. a
245
+ small-molecule inducer that switches a writer, a capsid-binding small molecule, an effector drug)"
246
+ not_valid_for: "protein-protein or protein-DNA affinity (the head is protein-LIGAND only; those are
247
+ out-of-scope and flagged extrapolating); an absolute measured Kd/IC50; ligands far outside the trained
248
+ chemical space; asserting a binder WORKS in cells (every output is a hypothesis, not a measurement)"
249
+ generalizes_to_unseen_loci: true
250
+ license: "MIT (Boltz-2, 10.1101/2025.06.14.659707)"
@@ -0,0 +1,64 @@
1
+ # The oracle mesh
2
+
3
+ PEN-STACK wraps the biomolecular foundation models (AlphaGenome, Evo2, AlphaFold3, Boltz-2, Chai-1, Protenix,
4
+ ESM3, RFdiffusion, ProteinMPNN, ViennaRNA, and the bridge energetics model) behind one result contract. Every
5
+ oracle, however different internally, answers through the same `OracleResult`: a value, its provenance
6
+ (model + version), the model's own native uncertainty, and a scope card. Three invariants are encoded in the
7
+ type itself:
8
+
9
+ 1. A generative output is a candidate, never a claim. A generated sequence, structure or backbone is a proposal
10
+ that must pass writer-verification before it can enter a claim path (`as_claim()` raises on a candidate).
11
+ 2. One contract for every oracle. Provenance and the oracle's native uncertainty are always carried; every call
12
+ is cache-keyed on inputs, model and version.
13
+ 3. Scope is explicit. Each result names its scope card and carries an `extrapolating` flag, so the evidence that
14
+ these models do not generalize outside their training envelope is labelled, not hidden.
15
+
16
+ ## Binding affinity (Boltz-2)
17
+
18
+ The affinity oracle (`pen_stack.oracles.affinity`) wraps the Boltz-2 protein-ligand affinity head (Boltz-2, MIT,
19
+ DOI 10.1101/2025.06.14.659707). For a protein and a small-molecule ligand it returns a binder probability and a
20
+ predicted affinity value (a log(IC50), micromolar-scale number, lower = stronger), with native uncertainty taken
21
+ from the model's own outputs. The head is protein-small-molecule only: protein-protein and protein-DNA pairs are
22
+ returned as out-of-scope (extrapolating). Pair types in scope include the small-molecule inducer that switches a
23
+ genome writer (for example 4-hydroxytamoxifen and the ERT2 ligand-binding domain), a capsid-binding ligand, and
24
+ an effector drug.
25
+
26
+ The affinity backend is a long GPU batch (around ten to thirty minutes including the MSA), so it runs off the
27
+ request path and the result is cached. The request path is cache-or-abstain: a request with no cached run defers
28
+ (`available=False`) rather than blocking the chat or fabricating a value.
29
+
30
+ ## Per-oracle reliability
31
+
32
+ `configs/oracles/reliability.yaml` records each oracle's published reliability on public benchmarks, reported
33
+ verbatim with citation (`pen_stack.oracles.reliability`). These numbers are the wrapped model's accuracy as
34
+ reported by its authors or the community, not a claim about this stack's own accuracy and not re-computed here.
35
+ The verified anchor is the Boltz-2 affinity head's FEP+ (OpenFE) Pearson r of about 0.62 (paper-reported); its
36
+ CASP16 affinity-challenge ranking is recorded as a self-report, not independently verified. For the structure and
37
+ sequence oracles the registry names the benchmark each is evaluated on (CASP and CAMEO for structure, ProteinGym
38
+ and FLIP for variant effect) with citations, and leaves the numeric value null where a verbatim score was not
39
+ independently verified rather than inventing one.
40
+
41
+ Reliability is surfaced in `GET /api/oracles`, in the MCP `oracle_query` tool, and in the web Oracle Mesh page,
42
+ so a confident-looking value is read alongside how reliable the model that produced it actually is.
43
+
44
+ ## Disagreement to uncertainty
45
+
46
+ Where redundant numeric oracles are available (for example the structure predictors), agreement is a confidence
47
+ signal and disagreement widens the reported interval. The consensus combines the available oracles and sets the
48
+ reported native uncertainty to the largest member uncertainty plus half the cross-oracle spread. This widening is
49
+ monotonic in the spread, checked by `disagreement_widens_monotonically` and reported by Oracle-Bench.
50
+
51
+ ## Held oracles
52
+
53
+ The structure oracles (AlphaFold3 / Boltz-2 / Chai-1 / Protenix) over full writer-substrate and att-site
54
+ complexes are held: a full complex prediction is a long GPU or cloud batch run off-request and cached
55
+ (`pen_stack.oracles.structure_run`). The request path replays the cache or abstains; it never runs the long job
56
+ inline.
57
+
58
+ ## Surfaces
59
+
60
+ - `GET /api/oracles` (optional `?probe=true`): per-oracle execution, latency class, live status and published
61
+ reliability, plus the disagreement-to-interval check.
62
+ - `POST /api/oracle/affinity`: a protein-ligand binding-affinity query (cache-or-abstain).
63
+ - MCP `oracle_query`: the same, for an agent.
64
+ - Web: the Oracle Mesh page.
@@ -1,2 +1,2 @@
1
1
  """PEN-STACK v3.0 - open infrastructure for genome writing."""
2
- __version__ = "6.12.0"
2
+ __version__ = "6.13.0"
@@ -60,6 +60,26 @@ def verify_proof(design: dict) -> dict:
60
60
  return _vp(design).model_dump()
61
61
 
62
62
 
63
+ @mcp.tool()
64
+ def oracle_query(oracle: str | None = None, protein_seq: str | None = None, ligand_smiles: str | None = None,
65
+ pair_type: str = "ligand", ligand_name: str | None = None) -> dict:
66
+ """v6.13 PEN-ORACLE: query the oracle mesh under one contract. With no arguments, returns every oracle's
67
+ execution + latency + live status + PUBLISHED reliability (reported verbatim from public benchmarks, with
68
+ citation; not a claim about this stack's accuracy) and the disagreement-to-interval check. With `oracle` set,
69
+ returns that oracle's status + reliability. With `protein_seq` + `ligand_smiles`, returns a CANDIDATE
70
+ binding-affinity prediction (Boltz-2 head): a binder probability + a predicted value with native uncertainty,
71
+ cache-or-abstain; protein-protein/protein-DNA pair types are flagged extrapolating (the head is
72
+ protein-ligand only). The long GPU job never runs on the request path."""
73
+ from pen_stack.oracles.status import oracle_status, summary
74
+ if protein_seq and ligand_smiles:
75
+ from pen_stack.oracles.affinity import predict_affinity
76
+ return predict_affinity(protein_seq, ligand_smiles, pair_type=pair_type, ligand_name=ligand_name).model_dump()
77
+ st = oracle_status()
78
+ if oracle:
79
+ return {"oracle": oracle, "status": st.get(oracle), "found": oracle in st}
80
+ return {"summary": summary(), "oracles": st}
81
+
82
+
63
83
  @mcp.tool()
64
84
  def graph_query(locus: str, cargo_form: str | None = None) -> dict:
65
85
  """v4.5 world-model graph (WS-G): a multi-hop query. Returns the writer families that REACH `locus` AND
@@ -67,6 +67,13 @@ _TOOLS = [
67
67
  "NOT an in-vivo tropism claim (v6.11 PEN-DELIVER)",
68
68
  "input": "AAV VP1 capsid amino-acid sequence", "output": "predicted packaging-fitness (candidate) or abstain",
69
69
  "entrypoint": "pen_stack.planner.delivery_predict.capsid_fitness", "fabricates": False},
70
+ {"name": "oracle_query", "summary": "query the oracle mesh under one contract: per-oracle execution + latency "
71
+ "+ live status + PUBLISHED reliability (verbatim from public benchmarks, cited) + disagreement-to-interval; "
72
+ "or a CANDIDATE protein-ligand binding affinity (Boltz-2 head) with native uncertainty, cache-or-abstain "
73
+ "(v6.13 PEN-ORACLE)",
74
+ "input": "oracle name, or {protein_seq, ligand_smiles, pair_type}", "output": "oracle status + reliability, "
75
+ "or a candidate affinity (binder probability + value) or abstain; protein-protein/protein-DNA flagged OOD",
76
+ "entrypoint": "pen_stack.oracles.affinity.predict_affinity", "fabricates": False},
70
77
  ]
71
78
 
72
79
  _POLICY = ("outputs outside scope are returned as `out_of_scope` (known-unknown) or `extrapolating` (OOD) and are "
@@ -0,0 +1,116 @@
1
+ """Binding-affinity oracle (v6.13, WS-ORACLE), the Boltz-2 protein-ligand affinity head under the contract.
2
+
3
+ Boltz-2 (MIT; Passaro et al. 2025, DOI 10.1101/2025.06.14.659707) jointly predicts a complex structure and a
4
+ binding affinity for a protein with a small-molecule ligand: a binder probability (``affinity_probability_binary``)
5
+ and a predicted affinity value (``affinity_pred_value``, a log(IC50) micromolar-scale number, lower = stronger).
6
+ This oracle wraps that head under the L1 ``OracleResult`` contract:
7
+
8
+ * the prediction is a CANDIDATE / hypothesis, never a measured Kd;
9
+ * the model's own outputs supply the native uncertainty (the spread between Boltz-2's two affinity heads, or a
10
+ binder-call entropy proxy);
11
+ * the affinity head is protein-SMALL-MOLECULE only, so protein-protein and protein-DNA requests are flagged
12
+ out-of-scope (``extrapolating``);
13
+ * the backend runs OFF the request path (a GPU batch, ~10-30 min including MSA) and is cached; when no cached run
14
+ is present the request path is cache-or-abstain and never blocks.
15
+ """
16
+ from __future__ import annotations
17
+
18
+ import json
19
+ from pathlib import Path
20
+
21
+ from pen_stack.oracles import build_result, cache_get, cache_put
22
+ from pen_stack.oracles.schema import OracleResult
23
+
24
+ _MODEL = "boltz-2-affinity"
25
+
26
+ # Pair types the affinity head COVERS (protein + small-molecule ligand), with a genome-writing-relevant gloss.
27
+ _LIGAND_PAIRS = {
28
+ "inducer_switch": "a small-molecule inducer that switches a genome writer on/off (e.g. 4-OHT / ERT2)",
29
+ "capsid_ligand": "a small molecule binding a delivery capsid (stabiliser or targeting ligand)",
30
+ "effector_drug": "a drug binding a delivered effector protein",
31
+ "ligand": "a generic protein + small-molecule ligand pair",
32
+ }
33
+ # Pair types OUTSIDE the affinity head's domain (it is protein-ligand only): returned extrapolating.
34
+ _OOD_PAIRS = {
35
+ "protein_protein": "protein-protein affinity is not the Boltz-2 affinity head's domain (protein-ligand only)",
36
+ "protein_dna": "protein-DNA affinity is not the Boltz-2 affinity head's domain (protein-ligand only)",
37
+ }
38
+
39
+ _UNITS = ("Boltz-2 affinity_pred_value: log(IC50) on a micromolar scale, lower = stronger binder "
40
+ "(a prediction, not a measured Kd/IC50)")
41
+
42
+
43
+ def _inputs(protein_seq: str, ligand_smiles: str, pair_type: str) -> dict:
44
+ return {"protein_len": len(protein_seq), "protein": protein_seq.upper(),
45
+ "ligand_smiles": ligand_smiles, "pair_type": pair_type}
46
+
47
+
48
+ def predict_affinity(protein_seq: str, ligand_smiles: str, pair_type: str = "ligand",
49
+ ligand_name: str | None = None) -> OracleResult:
50
+ """Predict protein-ligand binding affinity with the Boltz-2 head; cache-replayed if present, else deferred.
51
+
52
+ ``pair_type`` in {inducer_switch, capsid_ligand, effector_drug, ligand} is in-scope; ``protein_protein`` /
53
+ ``protein_dna`` are OUT of the affinity head's domain and returned extrapolating (the head is protein-ligand).
54
+ The long GPU job is never run on the request path: an absent cached run yields a deferred result.
55
+ """
56
+ in_scope = pair_type in _LIGAND_PAIRS
57
+ extrapolating = pair_type in _OOD_PAIRS
58
+ if not in_scope and not extrapolating:
59
+ raise ValueError(f"unknown pair_type {pair_type!r}; choose from "
60
+ f"{sorted(_LIGAND_PAIRS) + sorted(_OOD_PAIRS)}")
61
+ inputs = _inputs(protein_seq, ligand_smiles, pair_type)
62
+ note0 = (_OOD_PAIRS[pair_type] if extrapolating
63
+ else "Boltz-2 affinity head; backend runs off-request on the GPU and is cached")
64
+ r = build_result("affinity", _MODEL, inputs=inputs, available=False,
65
+ in_scope=in_scope, extrapolating=extrapolating, note=note0 + "; cache-or-abstain")
66
+ hit = cache_get(r.provenance.cache_key)
67
+ if hit is not None:
68
+ note = "replayed from committed oracle cache"
69
+ if extrapolating:
70
+ note += "; OUT-OF-SCOPE pair_type for a protein-ligand head: treat as extrapolative"
71
+ if ligand_name:
72
+ note += f"; ligand={ligand_name}"
73
+ return build_result("affinity", _MODEL, inputs=inputs, value=hit.get("value"),
74
+ native_uncertainty=hit.get("native_uncertainty"),
75
+ available=True, cached=True, source="cache",
76
+ in_scope=in_scope, extrapolating=extrapolating, note=note)
77
+ return r # deferred: no cached run, and the long job never runs on the request path
78
+
79
+
80
+ def value_from_boltz_output(out_dir: str | Path) -> dict:
81
+ """Parse a Boltz-2 affinity prediction directory into the cached {value, native_uncertainty} payload.
82
+
83
+ Native uncertainty is taken from the model's own outputs: half the spread between Boltz-2's two affinity
84
+ heads when both are present, else a binder-call entropy proxy (``1 - |2p - 1|``, 0 at p in {0,1}, 1 at 0.5).
85
+ """
86
+ out = Path(out_dir)
87
+ js = sorted(p for p in out.rglob("affinity*.json"))
88
+ if not js:
89
+ raise FileNotFoundError(f"no affinity*.json under {out}")
90
+ d = json.loads(js[0].read_text(encoding="utf-8"))
91
+ val = d.get("affinity_pred_value")
92
+ prob = d.get("affinity_probability_binary")
93
+ v1, v2 = d.get("affinity_pred_value1"), d.get("affinity_pred_value2")
94
+ if v1 is not None and v2 is not None:
95
+ unc = round(abs(float(v1) - float(v2)) / 2.0, 4)
96
+ unc_src = "half the spread between the two Boltz-2 affinity heads"
97
+ elif prob is not None:
98
+ unc = round(1.0 - abs(2.0 * float(prob) - 1.0), 4)
99
+ unc_src = "binder-call entropy proxy (1 - |2p - 1|)"
100
+ else:
101
+ unc, unc_src = None, "unavailable"
102
+ value = {"affinity_pred_value": val, "binder_probability": prob, "units": _UNITS,
103
+ "heads": {"affinity_pred_value1": v1, "affinity_pred_value2": v2},
104
+ "native_uncertainty_source": unc_src, "source_file": js[0].name}
105
+ return {"value": value, "native_uncertainty": unc}
106
+
107
+
108
+ def cache_affinity_run(protein_seq: str, ligand_smiles: str, pair_type: str, out_dir: str | Path) -> str:
109
+ """Ingest an OFF-REQUEST Boltz-2 affinity run into the oracle cache, so the request path can replay it.
110
+
111
+ Returns the cache key. Called after a separate GPU batch completes; never on the request path.
112
+ """
113
+ payload = value_from_boltz_output(out_dir)
114
+ r = build_result("affinity", _MODEL, inputs=_inputs(protein_seq, ligand_smiles, pair_type), available=False)
115
+ cache_put(r.provenance.cache_key, payload)
116
+ return r.provenance.cache_key
@@ -0,0 +1,64 @@
1
+ """Per-oracle reliability registry (v6.13, WS-ORACLE) + the disagreement-to-interval monotonicity check.
2
+
3
+ Reliability here is the wrapped model's PUBLISHED accuracy on PUBLIC benchmarks, reported VERBATIM with citation
4
+ (``configs/oracles/reliability.yaml``). It is NOT recomputed here and NOT a claim about this stack's own accuracy.
5
+ Each oracle output remains a candidate carrying its own native uncertainty; reliability is surfaced precisely so a
6
+ confident-looking value is not over-trusted. Where a verbatim number was not independently verified the registry
7
+ records ``null`` plus the cited benchmark (the pointer), never a guess.
8
+
9
+ The module also exposes :func:`disagreement_widens_monotonically`, which confirms the cross-oracle consensus
10
+ mechanism (:func:`pen_stack.oracles.consensus`, native uncertainty + half the cross-oracle spread) widens the
11
+ reported interval MONOTONICALLY as the spread grows. That is the v6.13 acceptance check for the
12
+ disagreement-to-uncertainty rule.
13
+ """
14
+ from __future__ import annotations
15
+
16
+ from functools import lru_cache
17
+
18
+ from pen_stack._resources import resource
19
+
20
+
21
+ @lru_cache(maxsize=1)
22
+ def _doc() -> dict:
23
+ import yaml
24
+ return yaml.safe_load(resource("configs/oracles/reliability.yaml").read_text(encoding="utf-8"))
25
+
26
+
27
+ def reliability(oracle: str) -> list | None:
28
+ """The published-reliability records for one oracle (or None if the oracle is not in the registry)."""
29
+ return _doc()["oracles"].get(oracle)
30
+
31
+
32
+ def all_reliability() -> dict:
33
+ """The full per-oracle reliability registry."""
34
+ return _doc()["oracles"]
35
+
36
+
37
+ def disclaimer() -> str:
38
+ """The standing disclaimer: published numbers, reported verbatim, not a claim about this stack."""
39
+ return _doc()["disclaimer"].strip()
40
+
41
+
42
+ def _num_result(value: float, unc: float):
43
+ from pen_stack.oracles import build_result
44
+ return build_result("structure", "boltz-2", value=value, native_uncertainty=unc, available=True)
45
+
46
+
47
+ def disagreement_widens_monotonically(spreads: list[float] | None = None) -> dict:
48
+ """Confirm :func:`consensus` widens the reported interval monotonically with the cross-oracle spread.
49
+
50
+ For each spread ``s`` two numeric oracles are placed symmetrically about a common centre, each with the same
51
+ small native uncertainty; the consensus native uncertainty must be non-decreasing in ``s``. Returns the
52
+ measured sequence and the monotonicity verdict (the gate reports the mechanism as working or broken).
53
+ """
54
+ from pen_stack.oracles import consensus
55
+ spreads = spreads if spreads is not None else [0.0, 0.05, 0.1, 0.2, 0.4]
56
+ centre, member_unc = 0.5, 0.05
57
+ uncs: list[float] = []
58
+ for s in spreads:
59
+ members = [_num_result(centre - s / 2, member_unc), _num_result(centre + s / 2, member_unc)]
60
+ uncs.append(consensus(members, oracle="structure").native_uncertainty)
61
+ monotone = all(uncs[i + 1] >= uncs[i] - 1e-9 for i in range(len(uncs) - 1))
62
+ return {"spreads": spreads, "native_uncertainty": uncs, "monotone_nondecreasing": monotone,
63
+ "rule": "native_uncertainty = max(member native uncertainty) + 0.5 * (max - min) over the "
64
+ "available numeric oracles"}
@@ -87,14 +87,20 @@ def _is_live(model: str, card: dict, probe: bool) -> tuple[bool, str]:
87
87
 
88
88
 
89
89
  def oracle_status(probe: bool = False) -> dict:
90
- """Per-oracle execution + latency_class + live status. `probe=True` pings the local model servers (adds a
91
- short network check); default is config-level only. The assistant uses this to warn the user about cost."""
90
+ """Per-oracle execution + latency_class + live status + published reliability. `probe=True` pings the local
91
+ model servers (adds a short network check); default is config-level only. Reliability is the wrapped model's
92
+ PUBLISHED benchmark accuracy, reported verbatim with citation, never a claim about this stack's accuracy."""
93
+ try:
94
+ from pen_stack.oracles.reliability import all_reliability
95
+ rel = all_reliability()
96
+ except Exception: # noqa: BLE001
97
+ rel = {}
92
98
  out = {}
93
99
  for model, card in execution_map().items():
94
100
  live, why = _is_live(model, card, probe)
95
101
  out[model] = {"execution": card.get("execution"), "latency_class": card.get("latency_class"),
96
102
  "live": live, "status": why, "note": card.get("note", ""),
97
- "server": card.get("server")}
103
+ "server": card.get("server"), "reliability": rel.get(model)}
98
104
  return out
99
105
 
100
106
 
@@ -104,7 +110,14 @@ def summary() -> dict:
104
110
  live = sorted(m for m, s in st.items() if s["live"])
105
111
  held = sorted(m for m, s in st.items() if s["execution"] == "cloud_a100")
106
112
  deferred = sorted(m for m, s in st.items() if s["execution"] == "deferred")
107
- return {"live": live, "held_cloud": held, "deferred": deferred,
108
- "latency_classes": {m: s["latency_class"] for m, s in st.items()},
109
- "note": ("Live oracles answer in seconds, ~2 min; held cloud jobs (AF3/Boltz/Chai/Protenix) are run "
110
- "separately and never block; deferred outcomes are known-unknowns, never fabricated.")}
113
+ out = {"live": live, "held_cloud": held, "deferred": deferred,
114
+ "latency_classes": {m: s["latency_class"] for m, s in st.items()},
115
+ "note": ("Live oracles answer in seconds, ~2 min; held cloud jobs (AF3/Boltz/Chai/Protenix) are run "
116
+ "separately and never block; deferred outcomes are known-unknowns, never fabricated.")}
117
+ try:
118
+ from pen_stack.oracles.reliability import disagreement_widens_monotonically, disclaimer
119
+ out["reliability_note"] = disclaimer()
120
+ out["disagreement_to_interval"] = disagreement_widens_monotonically()
121
+ except Exception: # noqa: BLE001
122
+ pass
123
+ return out
@@ -0,0 +1,76 @@
1
+ """Off-request structure-oracle runner (v6.13, WS-ORACLE) over named genome-writing complexes.
2
+
3
+ The structure oracles (AlphaFold3 / Boltz-2 / Chai-1 / Protenix) are held: a full complex prediction is a long
4
+ GPU / cloud batch, so it runs OFF the request path and the result is cached; the request path only ever replays
5
+ the cache or abstains (:func:`pen_stack.oracles.structure.consistency`). This module names the writer-substrate /
6
+ att-site complexes the substrate cares about, exposes a cache-or-abstain :func:`get` over the cross-oracle
7
+ consistency, and an :func:`ingest_boltz_confidence` hook that folds a completed off-request Boltz run's confidence
8
+ (pLDDT / pTM) into the cache so the request path can replay it.
9
+ """
10
+ from __future__ import annotations
11
+
12
+ import json
13
+ from pathlib import Path
14
+
15
+ from pen_stack.oracles import build_result, cache_put
16
+ from pen_stack.oracles.schema import OracleResult
17
+ from pen_stack.oracles.structure import consistency, predict_structure
18
+
19
+ # Named complexes relevant to genome writing. Sequences are supplied at call time; these entries describe what a
20
+ # held off-request run would target. `kind` records why a structure oracle is or is not the right tool.
21
+ _COMPLEXES = {
22
+ "ert2_4oht": {
23
+ "description": "ERT2 ligand-binding domain (human ESR1, UniProt P03372 res 305-554) with "
24
+ "4-hydroxytamoxifen, the inducible-writer chemical switch",
25
+ "kind": "protein_ligand"},
26
+ "bxb1_attb": {
27
+ "description": "Bxb1 serine integrase engaging its attB DNA target",
28
+ "kind": "protein_dna"},
29
+ "prime_editor_target": {
30
+ "description": "Prime editor (Cas9 nickase-RT fusion) engaging its primed genomic target",
31
+ "kind": "protein_dna"},
32
+ }
33
+
34
+
35
+ def complexes() -> dict:
36
+ """The registry of named writer-substrate / att-site complexes a held structure run would target."""
37
+ return dict(_COMPLEXES)
38
+
39
+
40
+ def get(protein_seq: str, models: list[str] | None = None) -> OracleResult:
41
+ """Cross-oracle structure consistency for a complex's protein, cache-or-abstain (never runs the long job).
42
+
43
+ Replays committed structure-oracle caches and combines them; divergence widens the interval. When no backend
44
+ has been run off-request and cached, the consensus is unavailable (a deferred result), never fabricated.
45
+ """
46
+ return consistency(protein_seq, models)
47
+
48
+
49
+ def single(protein_seq: str, model: str = "boltz-2") -> OracleResult:
50
+ """One structure oracle's confidence for a sequence (cache-replayed if present, else deferred)."""
51
+ return predict_structure(protein_seq, model)
52
+
53
+
54
+ def ingest_boltz_confidence(protein_seq: str, out_dir: str | Path, model: str = "boltz-2") -> str:
55
+ """Fold a completed OFF-REQUEST Boltz run's confidence into the structure cache, keyed as ``predict_structure``.
56
+
57
+ Reads Boltz's ``confidence_*.json`` (``complex_plddt`` on a 0-1 scale) and caches a pLDDT-like value with
58
+ native uncertainty ``1 - pLDDT``, so :func:`predict_structure` (and thus :func:`get`) replays it. Returns the
59
+ cache key. Called after a separate GPU batch completes; never on the request path.
60
+ """
61
+ out = Path(out_dir)
62
+ cj = sorted(p for p in out.rglob("confidence*.json"))
63
+ if not cj:
64
+ raise FileNotFoundError(f"no confidence*.json under {out}")
65
+ d = json.loads(cj[0].read_text(encoding="utf-8"))
66
+ plddt = d.get("complex_plddt")
67
+ if plddt is None:
68
+ raise KeyError(f"complex_plddt absent in {cj[0].name}")
69
+ plddt = float(plddt)
70
+ if plddt > 1.0: # some writers report 0-100; normalise to 0-1
71
+ plddt = plddt / 100.0
72
+ inputs = {"seq_len": len(protein_seq), "seq": protein_seq.upper(), "model": model}
73
+ key = build_result("structure", model, inputs=inputs, available=False).provenance.cache_key
74
+ cache_put(key, {"value": round(plddt, 4), "native_uncertainty": round(1.0 - plddt, 4),
75
+ "ptm": d.get("ptm"), "iptm": d.get("iptm"), "source_file": cj[0].name})
76
+ return key
@@ -238,6 +238,18 @@ def offtarget_assay_endpoint(writer_family: str):
238
238
  return recommend_assay(writer_family)
239
239
 
240
240
 
241
+ @app.post("/oracle/affinity", tags=["v6.13 oracle"])
242
+ def oracle_affinity_endpoint(req: dict):
243
+ """v6.13 PEN-ORACLE protein-ligand binding-affinity (Boltz-2 head) under the oracle contract. Body:
244
+ {protein_seq, ligand_smiles, pair_type?, ligand_name?}. Returns a CANDIDATE affinity (binder probability +
245
+ predicted value) with native uncertainty, cache-or-abstain; protein-protein/protein-DNA pair types are
246
+ flagged extrapolating (the head is protein-ligand only). Never runs the long job on the request path."""
247
+ from pen_stack.oracles.affinity import predict_affinity
248
+ r = predict_affinity(req.get("protein_seq", ""), req.get("ligand_smiles", ""),
249
+ pair_type=req.get("pair_type", "ligand"), ligand_name=req.get("ligand_name"))
250
+ return r.model_dump()
251
+
252
+
241
253
  @app.post("/delivery", tags=["v6.11 delivery"])
242
254
  def delivery_endpoint(req: dict):
243
255
  """v6.11 PEN-DELIVER cross-modality delivery recommender. Body: {cargo_form, cargo_bp?, target_tissue?,