pen-stack 6.10.3__tar.gz → 6.10.4__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 (502) hide show
  1. {pen_stack-6.10.3 → pen_stack-6.10.4}/CHANGELOG.md +24 -0
  2. {pen_stack-6.10.3 → pen_stack-6.10.4}/CITATION.cff +1 -1
  3. {pen_stack-6.10.3 → pen_stack-6.10.4}/PKG-INFO +2 -2
  4. {pen_stack-6.10.3 → pen_stack-6.10.4}/README.md +1 -1
  5. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/DEVIATIONS_AND_DISCLOSURES.md +1 -1
  6. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/cards/offtarget_data.md +10 -4
  7. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/__init__.py +1 -1
  8. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/wgenome/offtarget_data.py +15 -3
  9. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/wgenome/offtarget_predict.py +5 -4
  10. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack.egg-info/PKG-INFO +2 -2
  11. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack.egg-info/SOURCES.txt +1 -0
  12. {pen_stack-6.10.3 → pen_stack-6.10.4}/pyproject.toml +1 -1
  13. pen_stack-6.10.4/scripts/offtarget_chromatin_incremental.py +148 -0
  14. {pen_stack-6.10.3 → pen_stack-6.10.4}/LICENSE +0 -0
  15. {pen_stack-6.10.3 → pen_stack-6.10.4}/MANIFEST.in +0 -0
  16. {pen_stack-6.10.3 → pen_stack-6.10.4}/bench/run.py +0 -0
  17. {pen_stack-6.10.3 → pen_stack-6.10.4}/benchmarks/genome_writing_bench/LEADERBOARD.md +0 -0
  18. {pen_stack-6.10.3 → pen_stack-6.10.4}/benchmarks/genome_writing_bench/README.md +0 -0
  19. {pen_stack-6.10.3 → pen_stack-6.10.4}/benchmarks/genome_writing_bench/SHA256SUMS +0 -0
  20. {pen_stack-6.10.3 → pen_stack-6.10.4}/benchmarks/genome_writing_bench/SUBMISSIONS.md +0 -0
  21. {pen_stack-6.10.3 → pen_stack-6.10.4}/benchmarks/genome_writing_bench/tasks.yaml +0 -0
  22. {pen_stack-6.10.3 → pen_stack-6.10.4}/benchmarks/genome_writing_challenge/README.md +0 -0
  23. {pen_stack-6.10.3 → pen_stack-6.10.4}/benchmarks/genome_writing_challenge/SUBMISSIONS.md +0 -0
  24. {pen_stack-6.10.3 → pen_stack-6.10.4}/benchmarks/offtarget/SHA256SUMS +0 -0
  25. {pen_stack-6.10.3 → pen_stack-6.10.4}/benchmarks/position_effect/README.md +0 -0
  26. {pen_stack-6.10.3 → pen_stack-6.10.4}/benchmarks/position_effect/SHA256SUMS +0 -0
  27. {pen_stack-6.10.3 → pen_stack-6.10.4}/benchmarks/writer_efficiency/README.md +0 -0
  28. {pen_stack-6.10.3 → pen_stack-6.10.4}/benchmarks/writer_efficiency/SHA256SUMS +0 -0
  29. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/antipeg.yaml +0 -0
  30. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/atlas_families.yaml +0 -0
  31. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/bridge_offtarget_profile.yaml +0 -0
  32. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/calibration/preexisting_nab_independent.yaml +0 -0
  33. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/capsid_epitope_oracle.yaml +0 -0
  34. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/capsid_sequences.fasta +0 -0
  35. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/cargo_polish.yaml +0 -0
  36. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/cell_types.yaml +0 -0
  37. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/datasets.yaml +0 -0
  38. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/delivery_constraints.yaml +0 -0
  39. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/delivery_rules.yaml +0 -0
  40. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/delivery_vehicles.yaml +0 -0
  41. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/expression/modifiers.yaml +0 -0
  42. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/expression/promoters.yaml +0 -0
  43. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/gates_v3.yaml +0 -0
  44. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/genotoxicity_oracle.yaml +0 -0
  45. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/gsh_validated_heldout.yaml +0 -0
  46. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/intent_weights.yaml +0 -0
  47. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/known_unknowns.yaml +0 -0
  48. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/llm.yaml +0 -0
  49. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/metric_guide.yaml +0 -0
  50. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/mhc_epitope_oracle.yaml +0 -0
  51. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/monitor_queries.yaml +0 -0
  52. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/oracles/execution.yaml +0 -0
  53. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/oracles/scope_cards.yaml +0 -0
  54. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/rules/delivery.yaml +0 -0
  55. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/rules/fold.yaml +0 -0
  56. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/rules/multiplex.yaml +0 -0
  57. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/rules/payload.yaml +0 -0
  58. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/rules/reachability.yaml +0 -0
  59. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/safety/hazard_registry.yaml +0 -0
  60. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/safety/policy.yaml +0 -0
  61. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/safety/probes.yaml +0 -0
  62. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/score_axes.yaml +0 -0
  63. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/seroprevalence.yaml +0 -0
  64. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/target_sites.yaml +0 -0
  65. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/universe_crosswalk.yaml +0 -0
  66. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/write_types.yaml +0 -0
  67. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/writer_sequences.fasta +0 -0
  68. {pen_stack-6.10.3 → pen_stack-6.10.4}/configs/wtkb_curated.yaml +0 -0
  69. {pen_stack-6.10.3 → pen_stack-6.10.4}/data/curated/bridge_offtarget_energetics.json +0 -0
  70. {pen_stack-6.10.3 → pen_stack-6.10.4}/data/curated/bridge_offtarget_profile_measured.parquet +0 -0
  71. {pen_stack-6.10.3 → pen_stack-6.10.4}/data/curated/gene_coords.parquet +0 -0
  72. {pen_stack-6.10.3 → pen_stack-6.10.4}/data/curated/unified_editor_universe.parquet +0 -0
  73. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/BACKLOG.md +0 -0
  74. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/DEPLOY.md +0 -0
  75. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/INFRA.md +0 -0
  76. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/MCP.md +0 -0
  77. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/RELEASING.md +0 -0
  78. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/REPRO.md +0 -0
  79. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/STABILITY.md +0 -0
  80. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/agent.md +0 -0
  81. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/alphagenome_feasibility.md +0 -0
  82. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/autonomy.md +0 -0
  83. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/benchmark_circularity.md +0 -0
  84. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/biosecurity.md +0 -0
  85. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/build_interface.md +0 -0
  86. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/cards/atlas.md +0 -0
  87. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/cards/durability.md +0 -0
  88. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/cards/position_effect_data.md +0 -0
  89. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/cards/safety.md +0 -0
  90. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/cards/writer_efficiency_data.md +0 -0
  91. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/challenge.md +0 -0
  92. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/closed_loop.md +0 -0
  93. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/co_scientist.md +0 -0
  94. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/co_scientist_loop.md +0 -0
  95. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/delivery.md +0 -0
  96. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/delivery_immunology.md +0 -0
  97. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/digital_twin.md +0 -0
  98. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/dissemination.md +0 -0
  99. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/environment.md +0 -0
  100. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/experiment_design.md +0 -0
  101. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/generative_design.md +0 -0
  102. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/immune_profiler.md +0 -0
  103. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/index.md +0 -0
  104. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/integrations.md +0 -0
  105. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/live_oracles.md +0 -0
  106. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/mechanistic_constraints.md +0 -0
  107. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/offtarget.md +0 -0
  108. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/oracles.md +0 -0
  109. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/position_effect.md +0 -0
  110. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/positioning.md +0 -0
  111. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/private_data_formats.md +0 -0
  112. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/quickstart.md +0 -0
  113. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/responsible_use.md +0 -0
  114. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/rules.md +0 -0
  115. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/scope.md +0 -0
  116. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/scorecard.md +0 -0
  117. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/tpe_bench.md +0 -0
  118. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/tutorials/compare-families.md +0 -0
  119. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/tutorials/score-deliverability.md +0 -0
  120. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/tutorials/where-can-i-write.md +0 -0
  121. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/tutorials/which-writer-reaches-locus.md +0 -0
  122. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/uncertainty.md +0 -0
  123. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/verify.md +0 -0
  124. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/world_model.md +0 -0
  125. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/writer_efficiency.md +0 -0
  126. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/writer_verification.md +0 -0
  127. {pen_stack-6.10.3 → pen_stack-6.10.4}/docs/wtkb.md +0 -0
  128. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/_resources.py +0 -0
  129. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/active/__init__.py +0 -0
  130. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/active/acquire.py +0 -0
  131. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/active/design.py +0 -0
  132. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/active/validate.py +0 -0
  133. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/adapt/__init__.py +0 -0
  134. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/adapt/finetune.py +0 -0
  135. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/adapt/ingest.py +0 -0
  136. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/adapt/pipeline.py +0 -0
  137. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/adapt/recalibrate.py +0 -0
  138. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/adapt/report.py +0 -0
  139. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/agent/__init__.py +0 -0
  140. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/agent/cite.py +0 -0
  141. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/agent/co_scientist.py +0 -0
  142. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/agent/epistemic.py +0 -0
  143. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/agent/guardrails.py +0 -0
  144. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/agent/mcp_server.py +0 -0
  145. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/agent/orchestrator.py +0 -0
  146. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/agent/orchestrator_live.py +0 -0
  147. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/agent/pen_agent.py +0 -0
  148. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/agent/scope.py +0 -0
  149. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/agent/tools.py +0 -0
  150. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/api/__init__.py +0 -0
  151. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/api/manifest.py +0 -0
  152. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/atlas/__init__.py +0 -0
  153. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/atlas/build_wtkb.py +0 -0
  154. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/atlas/crosslink.py +0 -0
  155. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/atlas/expand.py +0 -0
  156. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/atlas/guide_design.py +0 -0
  157. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/atlas/schema.py +0 -0
  158. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/atlas/scorecard.py +0 -0
  159. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/atlas/universe.py +0 -0
  160. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/atlas/variant_propose.py +0 -0
  161. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/atlas/writer_efficiency.py +0 -0
  162. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/atlas/writer_predict.py +0 -0
  163. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/atlas/writer_recommend.py +0 -0
  164. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/atlas/writer_verify.py +0 -0
  165. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/bridge/__init__.py +0 -0
  166. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/bridge/activity.py +0 -0
  167. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/bridge/cli.py +0 -0
  168. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/bridge/fold_qc.py +0 -0
  169. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/bridge/guide_qc.py +0 -0
  170. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/bridge/ingest.py +0 -0
  171. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/bridge/offtarget.py +0 -0
  172. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/bridge/offtarget_energetics.py +0 -0
  173. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/bridge/ortholog_screen.py +0 -0
  174. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/bridge/pipeline.py +0 -0
  175. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/build/__init__.py +0 -0
  176. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/build/ingest.py +0 -0
  177. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/build/protocol.py +0 -0
  178. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/build/simlab.py +0 -0
  179. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/cli.py +0 -0
  180. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/data/__init__.py +0 -0
  181. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/data/encode.py +0 -0
  182. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/data/genome.py +0 -0
  183. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/data/ingest_chromatin.py +0 -0
  184. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/data/ingest_integration.py +0 -0
  185. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/data/ingest_safety_annot.py +0 -0
  186. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/data/ingest_trip.py +0 -0
  187. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/design/__init__.py +0 -0
  188. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/design/generate.py +0 -0
  189. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/design/pareto.py +0 -0
  190. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/design/space.py +0 -0
  191. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/design/writer_variants.py +0 -0
  192. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/env/__init__.py +0 -0
  193. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/env/genome_writing_env.py +0 -0
  194. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/env/policies.py +0 -0
  195. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/graph/__init__.py +0 -0
  196. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/graph/build.py +0 -0
  197. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/graph/cell_types.py +0 -0
  198. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/graph/ingest.py +0 -0
  199. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/graph/query.py +0 -0
  200. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/graph/schema.py +0 -0
  201. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/loop/__init__.py +0 -0
  202. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/loop/continual.py +0 -0
  203. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/loop/cycle.py +0 -0
  204. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/loop/drift.py +0 -0
  205. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/mech/__init__.py +0 -0
  206. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/mech/classify_atlas.py +0 -0
  207. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/mech/whitelist.py +0 -0
  208. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/monitor/__init__.py +0 -0
  209. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/monitor/europepmc.py +0 -0
  210. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/monitor/run.py +0 -0
  211. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/monitor/triage.py +0 -0
  212. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/oracles/__init__.py +0 -0
  213. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/oracles/cache.py +0 -0
  214. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/oracles/energetics.py +0 -0
  215. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/oracles/genome.py +0 -0
  216. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/oracles/protein_design.py +0 -0
  217. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/oracles/rna.py +0 -0
  218. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/oracles/schema.py +0 -0
  219. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/oracles/status.py +0 -0
  220. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/oracles/structure.py +0 -0
  221. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/oracles/vcell.py +0 -0
  222. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/planner/__init__.py +0 -0
  223. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/planner/ada_risk.py +0 -0
  224. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/planner/antipeg_oracle.py +0 -0
  225. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/planner/capsid_epitope_oracle.py +0 -0
  226. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/planner/cargo.py +0 -0
  227. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/planner/cargo_polish.py +0 -0
  228. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/planner/delivery.py +0 -0
  229. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/planner/delivery_constraints.py +0 -0
  230. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/planner/delivery_immunology.py +0 -0
  231. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/planner/delivery_vehicles.py +0 -0
  232. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/planner/genotoxicity_oracle.py +0 -0
  233. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/planner/immune_mhc2.py +0 -0
  234. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/planner/immune_profile.py +0 -0
  235. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/planner/innate_sensing.py +0 -0
  236. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/planner/multiplex.py +0 -0
  237. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/planner/optimize.py +0 -0
  238. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/planner/pipeline.py +0 -0
  239. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/planner/report.py +0 -0
  240. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/planner/router.py +0 -0
  241. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/planner/seroprevalence_oracle.py +0 -0
  242. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/planner/target_site.py +0 -0
  243. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/rag/__init__.py +0 -0
  244. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/rag/index.py +0 -0
  245. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/rag/llm.py +0 -0
  246. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/rag/qa.py +0 -0
  247. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/rules/__init__.py +0 -0
  248. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/rules/evaluators.py +0 -0
  249. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/rules/loader.py +0 -0
  250. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/rules/schema.py +0 -0
  251. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/rules/solver.py +0 -0
  252. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/safety/__init__.py +0 -0
  253. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/safety/audit.py +0 -0
  254. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/safety/gate.py +0 -0
  255. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/safety/policy.py +0 -0
  256. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/safety/redteam.py +0 -0
  257. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/safety/registry.py +0 -0
  258. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/safety/screen.py +0 -0
  259. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/score/__init__.py +0 -0
  260. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/score/recalibrate.py +0 -0
  261. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/score/therapeutic.py +0 -0
  262. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/server/__init__.py +0 -0
  263. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/server/api.py +0 -0
  264. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/twin/__init__.py +0 -0
  265. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/twin/calibrate.py +0 -0
  266. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/twin/data/__init__.py +0 -0
  267. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/twin/data/position_effect.py +0 -0
  268. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/twin/mechanistic.py +0 -0
  269. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/twin/outcome.py +0 -0
  270. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/twin/position_effect.py +0 -0
  271. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/ui/__init__.py +0 -0
  272. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/ui/app.py +0 -0
  273. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/__init__.py +0 -0
  274. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/adapt_demo.py +0 -0
  275. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/agent_eval.py +0 -0
  276. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/bench_adversarial_tasks.py +0 -0
  277. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/bench_coscientist_tasks.py +0 -0
  278. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/bench_graph_tasks.py +0 -0
  279. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/bench_rule_tasks.py +0 -0
  280. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/bench_trust_tasks.py +0 -0
  281. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/bench_writetype_tasks.py +0 -0
  282. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/blind_gsh_discovery.py +0 -0
  283. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/cargo_directionality.py +0 -0
  284. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/closed_loop.py +0 -0
  285. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/durability_baselines.py +0 -0
  286. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/experiment_design.py +0 -0
  287. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/expr_controls.py +0 -0
  288. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/forward_hypotheses.py +0 -0
  289. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/generative_design.py +0 -0
  290. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/guide_qc_demo.py +0 -0
  291. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/heldout_celltype_expr.py +0 -0
  292. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/immune_calibration.py +0 -0
  293. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/intent_specification.py +0 -0
  294. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/known_biology_expr.py +0 -0
  295. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/offtarget_energetics_eval.py +0 -0
  296. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/out_of_scope_refusal.py +0 -0
  297. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/outcome_calibration.py +0 -0
  298. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/outcome_prediction.py +0 -0
  299. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/paper3_benchmark.py +0 -0
  300. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/paper4_real_validation.py +0 -0
  301. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/paper4_validation.py +0 -0
  302. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/protocol_safety.py +0 -0
  303. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/safety_screening.py +0 -0
  304. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/selective_prediction.py +0 -0
  305. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/seq_vs_measured.py +0 -0
  306. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/target_site_controls.py +0 -0
  307. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/uncertainty_eval.py +0 -0
  308. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/ungrounded_baseline.py +0 -0
  309. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/within_locus_ranking.py +0 -0
  310. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/validate/writer_recovery.py +0 -0
  311. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/verify/__init__.py +0 -0
  312. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/verify/schema.py +0 -0
  313. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/verify/service.py +0 -0
  314. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/web/__init__.py +0 -0
  315. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/web/guide.py +0 -0
  316. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/web/llm.py +0 -0
  317. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/web/router.py +0 -0
  318. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/web/server.py +0 -0
  319. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/web/tools.py +0 -0
  320. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/wgenome/__init__.py +0 -0
  321. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/wgenome/chromatin_seq.py +0 -0
  322. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/wgenome/durability.py +0 -0
  323. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/wgenome/export_tracks.py +0 -0
  324. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/wgenome/features.py +0 -0
  325. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/wgenome/gsh_baseline.py +0 -0
  326. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/wgenome/mesh_features.py +0 -0
  327. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/wgenome/offtarget_assay.py +0 -0
  328. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/wgenome/ood.py +0 -0
  329. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/wgenome/providers.py +0 -0
  330. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/wgenome/safety.py +0 -0
  331. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/wgenome/structure3d.py +0 -0
  332. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/wgenome/uncertainty.py +0 -0
  333. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack/wgenome/writability.py +0 -0
  334. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack.egg-info/dependency_links.txt +0 -0
  335. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack.egg-info/entry_points.txt +0 -0
  336. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack.egg-info/requires.txt +0 -0
  337. {pen_stack-6.10.3 → pen_stack-6.10.4}/pen_stack.egg-info/top_level.txt +0 -0
  338. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_phase0.json +0 -0
  339. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_phase1_5.json +0 -0
  340. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_phase2.json +0 -0
  341. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_phase3.json +0 -0
  342. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_a.json +0 -0
  343. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_acq.json +0 -0
  344. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_aldesign.json +0 -0
  345. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_alvalidate.json +0 -0
  346. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_atlas.json +0 -0
  347. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_b.json +0 -0
  348. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_ba.json +0 -0
  349. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_ba_v33.json +0 -0
  350. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_ba_v45.json +0 -0
  351. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_bench.json +0 -0
  352. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_c.json +0 -0
  353. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_cal.json +0 -0
  354. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_calib.json +0 -0
  355. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_challenge.json +0 -0
  356. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_chat.json +0 -0
  357. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_cite.json +0 -0
  358. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_continual.json +0 -0
  359. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_cosci2.json +0 -0
  360. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_crit.json +0 -0
  361. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_ct.json +0 -0
  362. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_d.json +0 -0
  363. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_drift.json +0 -0
  364. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_e.json +0 -0
  365. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_env.json +0 -0
  366. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_ep.json +0 -0
  367. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_epitope.json +0 -0
  368. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_expr2.json +0 -0
  369. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_f.json +0 -0
  370. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_frontend.json +0 -0
  371. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_g.json +0 -0
  372. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_gen.json +0 -0
  373. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_genotox.json +0 -0
  374. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_graph.json +0 -0
  375. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_h.json +0 -0
  376. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_hybrid.json +0 -0
  377. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_immune.json +0 -0
  378. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_immune2.json +0 -0
  379. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_ingest.json +0 -0
  380. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_innate.json +0 -0
  381. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_loop.json +0 -0
  382. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_manifest.json +0 -0
  383. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_mc.json +0 -0
  384. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_mcp.json +0 -0
  385. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_mech.json +0 -0
  386. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_mon.json +0 -0
  387. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_o.json +0 -0
  388. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_offtarget.json +0 -0
  389. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_openapi.json +0 -0
  390. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_orch.json +0 -0
  391. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_outcome.json +0 -0
  392. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_pareto.json +0 -0
  393. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_peg.json +0 -0
  394. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_plan.json +0 -0
  395. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_policy.json +0 -0
  396. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_profile.json +0 -0
  397. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_proto.json +0 -0
  398. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_r.json +0 -0
  399. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_redteam.json +0 -0
  400. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_route.json +0 -0
  401. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_screen.json +0 -0
  402. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_seroprev.json +0 -0
  403. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_simlab.json +0 -0
  404. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_twincal.json +0 -0
  405. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_uq.json +0 -0
  406. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_v.json +0 -0
  407. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_vcell.json +0 -0
  408. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_writer.json +0 -0
  409. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/SHA256_LOCK_ws_wv.json +0 -0
  410. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/paper1.yaml +0 -0
  411. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/paper2.yaml +0 -0
  412. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/paper3.yaml +0 -0
  413. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/paper4.yaml +0 -0
  414. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/phase0.yaml +0 -0
  415. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_a.yaml +0 -0
  416. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_acq.yaml +0 -0
  417. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_aldesign.yaml +0 -0
  418. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_alvalidate.yaml +0 -0
  419. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_atlas.yaml +0 -0
  420. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_b.yaml +0 -0
  421. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_ba.yaml +0 -0
  422. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_ba_v33.yaml +0 -0
  423. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_ba_v45.yaml +0 -0
  424. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_bench.yaml +0 -0
  425. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_c.yaml +0 -0
  426. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_cal.yaml +0 -0
  427. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_calib.yaml +0 -0
  428. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_challenge.yaml +0 -0
  429. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_chat.yaml +0 -0
  430. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_cite.yaml +0 -0
  431. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_continual.yaml +0 -0
  432. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_cosci2.yaml +0 -0
  433. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_crit.yaml +0 -0
  434. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_ct.yaml +0 -0
  435. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_d.yaml +0 -0
  436. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_drift.yaml +0 -0
  437. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_e.yaml +0 -0
  438. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_env.yaml +0 -0
  439. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_ep.yaml +0 -0
  440. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_epitope.yaml +0 -0
  441. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_expr2.yaml +0 -0
  442. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_f.yaml +0 -0
  443. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_frontend.yaml +0 -0
  444. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_g.yaml +0 -0
  445. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_gen.yaml +0 -0
  446. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_genotox.yaml +0 -0
  447. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_graph.yaml +0 -0
  448. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_h.yaml +0 -0
  449. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_hybrid.yaml +0 -0
  450. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_immune.yaml +0 -0
  451. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_immune2.yaml +0 -0
  452. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_ingest.yaml +0 -0
  453. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_innate.yaml +0 -0
  454. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_loop.yaml +0 -0
  455. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_manifest.yaml +0 -0
  456. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_mc.yaml +0 -0
  457. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_mcp.yaml +0 -0
  458. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_mech.yaml +0 -0
  459. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_mon.yaml +0 -0
  460. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_o.yaml +0 -0
  461. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_offtarget.yaml +0 -0
  462. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_openapi.yaml +0 -0
  463. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_orch.yaml +0 -0
  464. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_outcome.yaml +0 -0
  465. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_pareto.yaml +0 -0
  466. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_peg.yaml +0 -0
  467. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_plan.yaml +0 -0
  468. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_policy.yaml +0 -0
  469. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_profile.yaml +0 -0
  470. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_proto.yaml +0 -0
  471. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_r.yaml +0 -0
  472. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_redteam.yaml +0 -0
  473. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_route.yaml +0 -0
  474. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_screen.yaml +0 -0
  475. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_seroprev.yaml +0 -0
  476. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_simlab.yaml +0 -0
  477. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_twincal.yaml +0 -0
  478. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_uq.yaml +0 -0
  479. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_v.yaml +0 -0
  480. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_vcell.yaml +0 -0
  481. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_writer.yaml +0 -0
  482. {pen_stack-6.10.3 → pen_stack-6.10.4}/prereg/ws_wv.yaml +0 -0
  483. {pen_stack-6.10.3 → pen_stack-6.10.4}/scripts/calibrate_immune_axes.py +0 -0
  484. {pen_stack-6.10.3 → pen_stack-6.10.4}/scripts/fetch_licensed_sources.py +0 -0
  485. {pen_stack-6.10.3 → pen_stack-6.10.4}/scripts/offtarget_chromatin_matched.py +0 -0
  486. {pen_stack-6.10.3 → pen_stack-6.10.4}/scripts/offtarget_chromatin_validation.py +0 -0
  487. {pen_stack-6.10.3 → pen_stack-6.10.4}/scripts/p1_build_atlas.py +0 -0
  488. {pen_stack-6.10.3 → pen_stack-6.10.4}/scripts/p1_build_durability.py +0 -0
  489. {pen_stack-6.10.3 → pen_stack-6.10.4}/scripts/p1_build_position_effect.py +0 -0
  490. {pen_stack-6.10.3 → pen_stack-6.10.4}/scripts/p1_build_writer_eff.py +0 -0
  491. {pen_stack-6.10.3 → pen_stack-6.10.4}/scripts/p1_export_tracks.py +0 -0
  492. {pen_stack-6.10.3 → pen_stack-6.10.4}/scripts/p1_safety_concordance.py +0 -0
  493. {pen_stack-6.10.3 → pen_stack-6.10.4}/scripts/p1_train_safety.py +0 -0
  494. {pen_stack-6.10.3 → pen_stack-6.10.4}/scripts/p1_validation_report.py +0 -0
  495. {pen_stack-6.10.3 → pen_stack-6.10.4}/scripts/p2_build_atlas.py +0 -0
  496. {pen_stack-6.10.3 → pen_stack-6.10.4}/scripts/p3_benchmark_report.py +0 -0
  497. {pen_stack-6.10.3 → pen_stack-6.10.4}/scripts/p4_genome_scan.py +0 -0
  498. {pen_stack-6.10.3 → pen_stack-6.10.4}/scripts/p52_build_genotox_oracle.py +0 -0
  499. {pen_stack-6.10.3 → pen_stack-6.10.4}/scripts/p53_build_epitope_oracle.py +0 -0
  500. {pen_stack-6.10.3 → pen_stack-6.10.4}/scripts/ws_b_report.py +0 -0
  501. {pen_stack-6.10.3 → pen_stack-6.10.4}/scripts/ws_c_report.py +0 -0
  502. {pen_stack-6.10.3 → pen_stack-6.10.4}/setup.cfg +0 -0
@@ -3,6 +3,30 @@
3
3
  All notable changes to PEN-STACK are documented here. This file follows
4
4
  [Keep a Changelog](https://keepachangelog.com/) and the program's phase structure.
5
5
 
6
+ ## [6.10.4] - 2026-06-20 - Chromatin incremental-value test (annotation, not a re-ranker) — chromatin work complete
7
+
8
+ **PATCH — the final chromatin question, answered.** v6.10.3 validated accessibility as a moderate standalone
9
+ predictor; v6.10.4 tests whether it adds **incremental** value *on top of* the CRISOT sequence score — i.e. whether
10
+ it should re-rank.
11
+
12
+ ### Added
13
+ - **Incremental-value analysis** (`scripts/offtarget_chromatin_incremental.py`; result in
14
+ `benchmarks/offtarget/chromatin_incremental.json`). On GUIDE-seq (HEK293T-matched), per off-target CRISOT +
15
+ accessibility: (A) a conditional logistic regression `active ~ z(CRISOT) + z(accessibility)` and (B) a
16
+ leave-one-guide-out held-out AUPRC of CRISOT-only vs a CRISOT+accessibility combiner — tested at two candidate
17
+ imbalances (1:16 and a realistic 1:123). **Result:** accessibility carries a **small, real conditional signal**
18
+ (coef ≈ 0.35, bootstrap CI excludes 0 at both imbalances) but adds **NO held-out ranking improvement** over CRISOT
19
+ (AUPRC gap CI includes 0 at both: −0.0025 [−0.011, +0.005] and +0.0027 [−0.014, +0.021]).
20
+
21
+ ### Decision
22
+ - **Chromatin is a validated ANNOTATION, NOT a re-ranker.** The CRISOT sequence score already captures the
23
+ practically-relevant nomination ranking; a CRISOT+accessibility combiner does not improve held-out AUPRC, so it is
24
+ **not** wired into the numeric risk score (`CHROMATIN_VALIDATION.changes_numeric_risk_score = False`). The fitted
25
+ combiner coefficients are recorded for transparency but intentionally not applied. Ledger + docs updated.
26
+ - **This completes the chromatin context work** (v6.10.1 wired → v6.10.2 cross-cell weak → v6.10.3 cell-type-matched
27
+ VALIDATED moderate → v6.10.4 incremental tested, annotation-only). Nothing about chromatin is now open or
28
+ undisclosed.
29
+
6
30
  ## [6.10.3] - 2026-06-20 - Chromatin context: cell-type-matched validation (VALIDATED, moderate)
7
31
 
8
32
  **PATCH — the definitive chromatin test.** v6.10.2's controlled experiment was ambiguous (GUIDE-seq positive, TTISS
@@ -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.10.3
4
+ version: 6.10.4
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.10.3
3
+ Version: 6.10.4
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
@@ -90,7 +90,7 @@ every design against rule-grounded mechanism, reports calibrated confidence, cit
90
90
  [![codecov](https://codecov.io/gh/ahmedanees-m/pen-stack/branch/main/graph/badge.svg)](https://codecov.io/gh/ahmedanees-m/pen-stack)
91
91
  [![License: MIT](https://img.shields.io/badge/License-MIT-informational.svg)](LICENSE)
92
92
  [![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue.svg)](https://www.python.org/)
93
- [![Version](https://img.shields.io/badge/version-6.10.3-blue.svg)](CHANGELOG.md)
93
+ [![Version](https://img.shields.io/badge/version-6.10.4-blue.svg)](CHANGELOG.md)
94
94
  [![Status](https://img.shields.io/badge/status-1.0%20First%20Stable-success.svg)](docs/STABILITY.md)
95
95
  [![Tests](https://img.shields.io/badge/tests-378%20passing-success.svg)](tests/)
96
96
  [![Lint: ruff](https://img.shields.io/badge/lint-ruff-purple.svg)](https://github.com/astral-sh/ruff)
@@ -15,7 +15,7 @@ every design against rule-grounded mechanism, reports calibrated confidence, cit
15
15
  [![codecov](https://codecov.io/gh/ahmedanees-m/pen-stack/branch/main/graph/badge.svg)](https://codecov.io/gh/ahmedanees-m/pen-stack)
16
16
  [![License: MIT](https://img.shields.io/badge/License-MIT-informational.svg)](LICENSE)
17
17
  [![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue.svg)](https://www.python.org/)
18
- [![Version](https://img.shields.io/badge/version-6.10.3-blue.svg)](CHANGELOG.md)
18
+ [![Version](https://img.shields.io/badge/version-6.10.4-blue.svg)](CHANGELOG.md)
19
19
  [![Status](https://img.shields.io/badge/status-1.0%20First%20Stable-success.svg)](docs/STABILITY.md)
20
20
  [![Tests](https://img.shields.io/badge/tests-378%20passing-success.svg)](tests/)
21
21
  [![Lint: ruff](https://img.shields.io/badge/lint-ruff-purple.svg)](https://github.com/astral-sh/ruff)
@@ -16,7 +16,7 @@ applicable (e.g. single contributor).
16
16
  |---|---|---|
17
17
  | Nuclease predictor named in plan (CCLMoff / CRISMER) vs shipped (CRISOT) | **DISCLOSED** | We use **CRISOT-Score** (Chen 2023, CC-BY-NC, CPU), not the plan's CCLMoff/CRISMER. Justified: **CRISMER ships no license** (cannot be redistributed/wrapped); **CCLMoff** is a GPU RNA-language-model stack AND was trained on these very assays (evaluating it on them would be **leakage**), whereas **CRISOT-Score is MD-physics, assay-agnostic → a leakage-clean held-out evaluation**. CRISOT is the more rigorous and license-appropriate choice. A genuine substitution, disclosed. |
18
18
  | Assay coverage (plan listed GUIDE/CIRCLE/CHANGE/SITE/SURRO/TTISS/Digenome-seq) | **FIXED (v6.10.1)** | v6.10.0 used GUIDE-seq + CIRCLE-seq only. v6.10.1 adds **CHANGE-seq + SITE-seq** (independent broad guide panels) — CRISOT beats homology on **all four** (per-guide bootstrap CI excludes 0). SURRO-seq is targeted/biased (kept as an orthogonal reference, not genome-wide truth); TTISS/Digenome-seq remain **DISCLOSED** as not-yet-folded-in. |
19
- | "Chromatin-aware via the Stage B feature store" | **VALIDATED (moderate, cell-type-matched; v6.10.3)** | v6.10.0 overclaimed "chromatin-aware" with only a caller hook → v6.10.1 added a real `locus_accessibility()` (verified on the VM) → v6.10.2 ran a controlled test with the cross-cell K562 proxy and got a *weak/inconsistent* result (GUIDE-seq 0.58, TTISS 0.346, in-vitro null) → **v6.10.3 settled it with a CELL-TYPE-MATCHED track** (ENCODE HEK293T DNase, ENCFF529BOG; matches GUIDE-seq/TTISS). **Cell-type matching lifts the canonical WT-Cas9 cell-based assay GUIDE-seq from AUROC 0.58 → 0.671 (CI [0.642, 0.701])**, the in-vitro control stays null (0.494). **VERDICT: VALIDATED (moderate, cell-type-matched) for WT-Cas9 cell-based off-target activity** — the cross-cell K562 proxy was dampening a real effect. Honest caveats: the effect is **moderate** (the sequence/CRISOT score still dominates); it does **not** transfer to TTISS (0.383, an expected outlier — a Cas9-*variant* specificity assay); and chromatin is surfaced as a validated **annotation** that does **not yet change the numeric risk score** (a calibrated CRISOT+accessibility combination is the remaining refinement, deferred). Full result: `benchmarks/offtarget/chromatin_validation.json`; reproducible scripts `scripts/offtarget_chromatin_{validation,matched}.py`. |
19
+ | "Chromatin-aware via the Stage B feature store" | **VALIDATED (moderate, cell-type-matched; v6.10.3)** | v6.10.0 overclaimed "chromatin-aware" with only a caller hook → v6.10.1 added a real `locus_accessibility()` (verified on the VM) → v6.10.2 ran a controlled test with the cross-cell K562 proxy and got a *weak/inconsistent* result (GUIDE-seq 0.58, TTISS 0.346, in-vitro null) → **v6.10.3 settled it with a CELL-TYPE-MATCHED track** (ENCODE HEK293T DNase, ENCFF529BOG; matches GUIDE-seq/TTISS). **Cell-type matching lifts the canonical WT-Cas9 cell-based assay GUIDE-seq from AUROC 0.58 → 0.671 (CI [0.642, 0.701])**, the in-vitro control stays null (0.494). **VERDICT: VALIDATED (moderate, cell-type-matched) for WT-Cas9 cell-based off-target activity** — the cross-cell K562 proxy was dampening a real effect. Honest caveats: the effect is **moderate** (the sequence/CRISOT score dominates); it does **not** transfer to TTISS (0.383, an expected outlier — a Cas9-*variant* specificity assay). **v6.10.4 closed the last piece** — does accessibility add *incremental* value over CRISOT? On GUIDE-seq (HEK293T-matched), accessibility carries a **small real conditional signal** (logreg coef ~0.35, CI excludes 0 at two imbalances) but adds **NO held-out ranking improvement** over CRISOT (AUPRC gap CI includes 0 at both). **Decision: chromatin is a validated ANNOTATION, NOT a re-ranker** — it does **not** change the numeric risk score (CRISOT captures the ranking); the fitted combiner is recorded but intentionally not applied. Full results: `benchmarks/offtarget/chromatin_{validation,incremental}.json`; reproducible scripts `scripts/offtarget_chromatin_{validation,matched,incremental}.py`. **This is the final, complete state — nothing about chromatin is now open or undisclosed.** |
20
20
  | Held-out **guide** AND **locus** splits | **DISCLOSED** | Held-out-**guide** is implemented; a genomic-coordinate **locus** split is **not possible** — the harmonized assay data ships sequences, not coordinates. Instead we add **cross-assay generalization** (the assay-agnostic CRISOT-Score evaluated on GUIDE/CIRCLE canonical guides + CHANGE/SITE independent panels). This is the leakage-clean substitute and is stated in `benchmarks/offtarget/split.json`. |
21
21
  | Learned **integrase** off-target scorer (plan: "learned on HIDE/Cryptic-seq") | **DISCLOSED** | Shipped as a documented **pseudo-attB cryptic scan** on the real Bxb1 attB core, not a learned model — Cryptic-seq/HIDE-seq are recent preprints and IntQuery has **no public weights**, so a real learned integrase predictor is not groundable. Flagged extrapolative; IntQuery cited as paper-only. |
22
22
  | Bench "joins the Challenge" | **FIXED (v6.10.1)** | An `offtarget` nomination task is added to the Genome-Writing Challenge (`benchmarks/genome_writing_challenge/harness.py`) — non-circular (label = wet-lab Active call), data-gated on the fixture. |
@@ -61,10 +61,16 @@ AUROC of accessibility for active-vs-inactive off-targets per assay, with in-vit
61
61
  DNase track (`ENCFF529BOG`, matching GUIDE-seq's HEK293 and TTISS's HEK293T): **cell-type matching lifts the
62
62
  canonical WT-Cas9 cell-based assay from 0.58 → 0.671** (the cross-cell proxy was dampening a real effect), with the
63
63
  in-vitro control still null. **Verdict: VALIDATED (moderate, cell-type-matched)** for WT-Cas9 cell-based off-target
64
- activity. Honest caveats: the effect is **moderate** (the sequence/CRISOT score still dominates nomination); it does
65
- **not** transfer to TTISS (a Cas9-variant specificity assay, the expected outlier); and chromatin is surfaced as a
66
- validated **annotation** that does **not yet change the numeric risk score** (a calibrated CRISOT+accessibility
67
- combination is the remaining refinement). Reproducible: `scripts/offtarget_chromatin_{validation,matched}.py`.
64
+ activity. Honest caveats: the effect is **moderate** (the sequence/CRISOT score dominates nomination); it does
65
+ **not** transfer to TTISS (a Cas9-variant specificity assay, the expected outlier).
66
+
67
+ **Incremental value over CRISOT (v6.10.4, `chromatin_incremental.json`):** on GUIDE-seq (HEK293T-matched),
68
+ accessibility carries a **small real conditional signal** (logistic-regression coefficient ~0.35, bootstrap CI
69
+ excludes 0 at both 1:16 and 1:123 candidate imbalance) but adds **NO held-out ranking improvement** over CRISOT
70
+ (leave-one-guide-out AUPRC gap CI includes 0 at both). **Decision: chromatin is a validated ANNOTATION, NOT a
71
+ re-ranker** — it does **not** change the numeric risk score (CRISOT already captures the practically-relevant ranking
72
+ signal); the fitted CRISOT+accessibility combiner is recorded but intentionally not applied. Reproducible:
73
+ `scripts/offtarget_chromatin_{validation,matched,incremental}.py`.
68
74
 
69
75
  ## Risk calibration (grounded)
70
76
  The nomination risk band IS the empirical fraction of candidates at *k* mismatches that were validated-active
@@ -1,2 +1,2 @@
1
1
  """PEN-STACK v3.0 - open infrastructure for genome writing."""
2
- __version__ = "6.10.3"
2
+ __version__ = "6.10.4"
@@ -75,12 +75,24 @@ CHROMATIN_VALIDATION = {
75
75
  "siteseq": {"modality": "in_vitro_control", "auroc": 0.494, "k562_cross_cell": 0.469, "ci95": [0.475, 0.514]},
76
76
  },
77
77
  "matched_track": "ENCODE HEK293T DNase-seq (ENCFF529BOG, GRCh38)",
78
+ # v6.10.4 — does accessibility add INCREMENTAL value over the CRISOT sequence score? Tested at two imbalances:
79
+ # a small REAL conditional signal (logreg acc coef ~0.35, CI excludes 0) but NO held-out ranking improvement
80
+ # (CRISOT+acc AUPRC gap CI includes 0). DECISION: annotation, NOT a re-ranker. Full result:
81
+ # benchmarks/offtarget/chromatin_incremental.json.
82
+ "incremental_over_crisot": {
83
+ "conditional_acc_coef": 0.351, "conditional_acc_coef_ci95": [0.2385, 0.5584], "adds_conditional_signal": True,
84
+ "heldout_auprc_gap": 0.0027, "heldout_auprc_gap_ci95": [-0.014, 0.0214], "improves_ranking": False,
85
+ "decision": "annotation only — accessibility carries a small real conditional signal but does NOT improve "
86
+ "held-out nomination ranking over the CRISOT sequence score (at realistic imbalance); a "
87
+ "re-ranking combiner is NOT wired in (no demonstrated benefit).",
88
+ },
89
+ "changes_numeric_risk_score": False,
78
90
  "note": "cell-type-matched accessibility predicts WT-Cas9 cell-based off-target activity (GUIDE-seq AUROC "
79
91
  "0.58 cross-cell -> 0.671 matched; in-vitro control null -> method sound). MODERATE effect (the "
80
92
  "sequence/CRISOT score dominates nomination) and CELL-TYPE-SPECIFIC. Does NOT transfer to the "
81
- "Cas9-VARIANT assay TTISS (0.383, the expected outlier). Surfaced as a validated qualitative annotation; "
82
- "it does NOT yet change the numeric risk score (a calibrated CRISOT+accessibility combination is the "
83
- "remaining refinement).",
93
+ "Cas9-VARIANT assay TTISS (0.383, the expected outlier). v6.10.4 tested the incremental value over "
94
+ "CRISOT: a small real conditional signal but NO held-out ranking improvement -> chromatin is surfaced "
95
+ "as a VALIDATED ANNOTATION and does NOT change the numeric risk score (CRISOT captures the ranking).",
84
96
  }
85
97
 
86
98
  # ---- Off-Target-Bench headline (REAL full-data result; per-guide AUPRC, held-out-guide bootstrap CI) -----
@@ -103,10 +103,11 @@ def _chromatin_modifier(accessibility: float | None = None, locus_acc: dict | No
103
103
  Stage B accessibility (`locus_acc`) when available, else a caller-supplied 0..1 scalar; abstains (None) when
104
104
  neither is given. It is QUALITATIVE and does NOT change the numeric risk score — a controlled test on our data
105
105
  found the signal weak/inconsistent (see `offtarget_data.CHROMATIN_VALIDATION`)."""
106
- val = {"validated": True, "effect_size": "moderate",
107
- "validation": "validated (moderate, cell-type-matched): GUIDE-seq off-target AUROC 0.58 cross-cell -> "
108
- "0.671 with matched HEK293T DNase (CI [0.642,0.701]); in-vitro control null. Annotation only does not "
109
- "yet change the numeric risk score (sequence/CRISOT dominates).",
106
+ val = {"validated": True, "effect_size": "moderate", "changes_risk_score": False,
107
+ "validation": "validated standalone (moderate, cell-type-matched: GUIDE-seq off-target AUROC 0.58 "
108
+ "cross-cell -> 0.671 matched HEK293T DNase). ANNOTATION ONLY v6.10.4 tested the incremental value over "
109
+ "CRISOT: small real conditional signal but NO held-out ranking improvement, so it does NOT change the "
110
+ "numeric risk score (CRISOT sequence score captures the ranking).",
110
111
  "doi": "10.1038/s41587-020-0555-7"}
111
112
  if locus_acc is not None:
112
113
  raises = bool(locus_acc.get("accessible"))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pen-stack
3
- Version: 6.10.3
3
+ Version: 6.10.4
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
@@ -90,7 +90,7 @@ every design against rule-grounded mechanism, reports calibrated confidence, cit
90
90
  [![codecov](https://codecov.io/gh/ahmedanees-m/pen-stack/branch/main/graph/badge.svg)](https://codecov.io/gh/ahmedanees-m/pen-stack)
91
91
  [![License: MIT](https://img.shields.io/badge/License-MIT-informational.svg)](LICENSE)
92
92
  [![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue.svg)](https://www.python.org/)
93
- [![Version](https://img.shields.io/badge/version-6.10.3-blue.svg)](CHANGELOG.md)
93
+ [![Version](https://img.shields.io/badge/version-6.10.4-blue.svg)](CHANGELOG.md)
94
94
  [![Status](https://img.shields.io/badge/status-1.0%20First%20Stable-success.svg)](docs/STABILITY.md)
95
95
  [![Tests](https://img.shields.io/badge/tests-378%20passing-success.svg)](tests/)
96
96
  [![Lint: ruff](https://img.shields.io/badge/lint-ruff-purple.svg)](https://github.com/astral-sh/ruff)
@@ -480,6 +480,7 @@ prereg/ws_writer.yaml
480
480
  prereg/ws_wv.yaml
481
481
  scripts/calibrate_immune_axes.py
482
482
  scripts/fetch_licensed_sources.py
483
+ scripts/offtarget_chromatin_incremental.py
483
484
  scripts/offtarget_chromatin_matched.py
484
485
  scripts/offtarget_chromatin_validation.py
485
486
  scripts/p1_build_atlas.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pen-stack"
7
- version = "6.10.3"
7
+ version = "6.10.4"
8
8
  description = "Open infrastructure for genome writing: the Writable Genome atlas, the Writer Atlas, and the Write Planner."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -0,0 +1,148 @@
1
+ """Reproducible analysis (v6.10.4): does chromatin accessibility add INCREMENTAL value over the CRISOT sequence
2
+ score for nominating off-targets? On GUIDE-seq (cell-based) with cell-type-matched HEK293T DNase accessibility:
3
+
4
+ (A) conditional logistic regression active ~ z(CRISOT) + z(accessibility) -> bootstrap-over-guides 95% CI on
5
+ the accessibility coefficient (does accessibility carry signal CONDITIONAL on CRISOT?).
6
+ (B) leave-one-guide-out held-out AUPRC of CRISOT-only vs a CRISOT+accessibility logistic combiner, bootstrap
7
+ 95% CI on the per-guide gap (does the combiner IMPROVE held-out nomination ranking?).
8
+
9
+ RESULT (committed in benchmarks/offtarget/chromatin_incremental.json): accessibility carries a SMALL, REAL
10
+ conditional signal (coef ~0.35, CI excludes 0 at both 1:16 and 1:123 imbalance) but adds NO held-out ranking
11
+ improvement over CRISOT (AUPRC gap CI includes 0 at both). DECISION: chromatin is a validated ANNOTATION, NOT a
12
+ re-ranker — the CRISOT sequence score already captures the practically-relevant ranking signal.
13
+
14
+ Needs: the CRISOT repo (CRISOT-Score), hg38 GRCh38.fa, the HEK293T DNase bigWig, the GUIDE-seq CSV, plus
15
+ xgboost / pyBigWig / scikit-learn. Run on the VM. (Inactive cap controls the candidate imbalance.)
16
+ """
17
+ from __future__ import annotations
18
+
19
+ import json
20
+ import os
21
+ import subprocess
22
+ import sys
23
+
24
+ import numpy as np
25
+ import pandas as pd
26
+ import pyBigWig
27
+ from sklearn.linear_model import LogisticRegression
28
+ from sklearn.metrics import average_precision_score
29
+
30
+ sys.path.insert(0, os.environ.get("CRISOT", "/crisot"))
31
+ from crisot_modules import CRISOT # noqa: E402
32
+ from utils import load_pkl # noqa: E402
33
+
34
+ FA = os.environ.get("FA", "/ref/GRCh38.fa")
35
+ BW = os.environ.get("BW", "/ref/hek293t_dnase.bigWig")
36
+ DS = os.environ.get("DS", "/d")
37
+ INACT_CAP = int(os.environ.get("INACT_CAP", "4000")) # 4000/guide ~ realistic imbalance
38
+ COMP = str.maketrans("ACGT", "TGCA")
39
+ VALID = {f"chr{i}" for i in list(range(1, 23)) + ["X", "Y"]}
40
+
41
+
42
+ def rc(s: str) -> str:
43
+ return s.translate(COMP)[::-1]
44
+
45
+
46
+ def main() -> dict:
47
+ rng = np.random.RandomState(7)
48
+ pr, _ab, _bins, _w = load_pkl(os.environ.get("CRISOT", "/crisot") + "/models/crisot_score_param.pkl")
49
+ model = CRISOT(param=pr, ref_genome=os.environ.get("CRISOT", "/crisot") + "/script/hg38.na")
50
+ df = pd.read_csv(f"{DS}/guideseq.csv")
51
+ df["On20"] = df["On"].str[:20]
52
+ g = df.groupby("On20")["Active"].sum()
53
+ df = df[df["On20"].isin(list(g[g >= 5].index))].copy()
54
+ parts = []
55
+ for _gd, sub in df.groupby("On20"):
56
+ inact = sub[sub.Active == 0]
57
+ parts.append(pd.concat([sub[sub.Active == 1], inact.sample(n=min(INACT_CAP, len(inact)), random_state=rng)]))
58
+ d = pd.concat(parts).reset_index(drop=True)
59
+ d["crisot"] = model.score(data_df=d, On="On", Off="Off")
60
+ d["off23"] = d["Off"].str[:23]
61
+ pat = {}
62
+ for off in d["off23"].unique():
63
+ if len(off) == 23 and set(off) <= set("ACGT"):
64
+ pat[off] = off
65
+ pat[rc(off)] = off
66
+ open("/tmp/pats.txt", "w").write("\n".join(pat) + "\n")
67
+ hits: dict = {}
68
+ cur, buf = None, []
69
+
70
+ def flush(chrom, seq):
71
+ c = chrom if chrom and chrom.startswith("chr") else f"chr{chrom}"
72
+ if not seq or c not in VALID:
73
+ return
74
+ open("/tmp/chr.txt", "w").write(seq)
75
+ p = subprocess.run(["grep", "-boFf", "/tmp/pats.txt", "/tmp/chr.txt"], capture_output=True, text=True)
76
+ for ln in p.stdout.splitlines():
77
+ ob, _, m = ln.partition(":")
78
+ if pat.get(m):
79
+ hits.setdefault(pat[m], []).append((c, int(ob)))
80
+ with open(FA) as fh:
81
+ for line in fh:
82
+ if line.startswith(">"):
83
+ if cur:
84
+ flush(cur, "".join(buf))
85
+ cur, buf = line[1:].split()[0], []
86
+ else:
87
+ buf.append(line.strip().upper())
88
+ if cur:
89
+ flush(cur, "".join(buf))
90
+ bw = pyBigWig.open(BW)
91
+ bwc = set(bw.chroms().keys())
92
+ cache: dict = {}
93
+
94
+ def acc(off):
95
+ vals = []
96
+ for c, p in hits.get(off, []):
97
+ bc = c if c in bwc else (c[3:] if c[3:] in bwc else None)
98
+ if bc is None:
99
+ continue
100
+ b0 = (p // 1000) * 1000
101
+ if (bc, b0) not in cache:
102
+ try:
103
+ v = bw.stats(bc, b0, min(b0 + 1000, bw.chroms(bc)), type="mean")[0]
104
+ cache[(bc, b0)] = float(v) if v is not None else None
105
+ except Exception: # noqa: BLE001
106
+ cache[(bc, b0)] = None
107
+ if cache[(bc, b0)] is not None:
108
+ vals.append(cache[(bc, b0)])
109
+ return max(vals) if vals else None
110
+ d["acc"] = d["off23"].map(acc)
111
+ d = d.dropna(subset=["acc"]).reset_index(drop=True)
112
+ d["zc"] = (d.crisot - d.crisot.mean()) / d.crisot.std()
113
+ d["za"] = (d.acc - d.acc.mean()) / d.acc.std()
114
+ guides = sorted(d.On20.unique())
115
+
116
+ def fit(dd):
117
+ lr = LogisticRegression(max_iter=2000, class_weight="balanced").fit(dd[["zc", "za"]], dd.Active)
118
+ return lr.coef_[0], lr.intercept_[0]
119
+ (cc, ca), _b = fit(d)
120
+ accb = []
121
+ for _ in range(1000):
122
+ gs = rng.choice(guides, len(guides), replace=True)
123
+ try:
124
+ accb.append(fit(pd.concat([d[d.On20 == x] for x in gs]))[0][1])
125
+ except Exception: # noqa: BLE001
126
+ pass
127
+ acc_ci = [round(float(np.percentile(accb, 2.5)), 4), round(float(np.percentile(accb, 97.5)), 4)]
128
+ cris_ap, comb_ap = [], []
129
+ for held in guides:
130
+ tr, te = d[d.On20 != held], d[d.On20 == held]
131
+ if te.Active.sum() == 0 or len(te) < 5:
132
+ continue
133
+ lr = LogisticRegression(max_iter=2000, class_weight="balanced").fit(tr[["zc", "za"]], tr.Active)
134
+ comb_ap.append(average_precision_score(te.Active, lr.predict_proba(te[["zc", "za"]])[:, 1]))
135
+ cris_ap.append(average_precision_score(te.Active, te.zc.values))
136
+ gap = np.array(comb_ap) - np.array(cris_ap)
137
+ gb = [float(np.mean(gap[rng.randint(0, len(gap), len(gap))])) for _ in range(1000)]
138
+ out = {"n_offtargets": int(len(d)), "n_actives": int(d.Active.sum()), "n_guides": len(guides),
139
+ "conditional_acc_coef": round(float(ca), 4), "acc_coef_ci95": acc_ci,
140
+ "mean_crisot_only_auprc": round(float(np.mean(cris_ap)), 4),
141
+ "mean_crisot_plus_acc_auprc": round(float(np.mean(comb_ap)), 4),
142
+ "auprc_gap_ci95": [round(float(np.percentile(gb, 2.5)), 4), round(float(np.percentile(gb, 97.5)), 4)]}
143
+ print(json.dumps(out, indent=2))
144
+ return out
145
+
146
+
147
+ if __name__ == "__main__":
148
+ main()
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes