pen-stack 7.2.3__tar.gz → 8.0.1__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 (606) hide show
  1. {pen_stack-7.2.3 → pen_stack-8.0.1}/CHANGELOG.md +481 -34
  2. {pen_stack-7.2.3 → pen_stack-8.0.1}/CITATION.cff +7 -2
  3. {pen_stack-7.2.3 → pen_stack-8.0.1}/PKG-INFO +130 -58
  4. pen_stack-8.0.1/README.md +295 -0
  5. {pen_stack-7.2.3 → pen_stack-8.0.1}/bench/run.py +14 -5
  6. pen_stack-8.0.1/benchmarks/agentic_baseline/README.md +47 -0
  7. pen_stack-8.0.1/benchmarks/genome_writing_bench/SHA256SUMS +7 -0
  8. pen_stack-8.0.1/benchmarks/genotox_panel/README.md +107 -0
  9. pen_stack-8.0.1/benchmarks/grounding_llm_on/README.md +58 -0
  10. {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/offtarget/integrase/README.md +6 -6
  11. pen_stack-8.0.1/benchmarks/offtarget/integrase_chalberg/README.md +61 -0
  12. {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/position_effect/README.md +11 -3
  13. pen_stack-8.0.1/benchmarks/position_effect_human/README.md +119 -0
  14. pen_stack-8.0.1/benchmarks/position_effect_human/SHA256SUMS +3 -0
  15. pen_stack-8.0.1/benchmarks/priorart/epridict/README.md +62 -0
  16. pen_stack-8.0.1/benchmarks/priorart/epridict/SHA256SUMS +5 -0
  17. pen_stack-8.0.1/benchmarks/priorart/gsh_recovery/README.md +66 -0
  18. pen_stack-8.0.1/benchmarks/priorart/gsh_recovery/SHA256SUMS +4 -0
  19. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/intent_weights.yaml +16 -1
  20. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/llm.yaml +13 -0
  21. {pen_stack-7.2.3 → pen_stack-8.0.1}/data/curated/cast_systems.yaml +6 -6
  22. {pen_stack-7.2.3 → pen_stack-8.0.1}/data/curated/integrase_att.yaml +7 -7
  23. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/INFRA.md +1 -1
  24. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/biosecurity.md +41 -3
  25. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/cards/offtarget_data.md +4 -4
  26. pen_stack-8.0.1/docs/cards/priorart.md +66 -0
  27. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/responsible_use.md +14 -2
  28. pen_stack-8.0.1/pen_stack/__init__.py +2 -0
  29. pen_stack-8.0.1/pen_stack/active/acquire.py +165 -0
  30. pen_stack-8.0.1/pen_stack/active/design.py +66 -0
  31. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/agent/epistemic.py +6 -4
  32. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/agent/orchestrator.py +7 -1
  33. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/api/manifest.py +2 -1
  34. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/atlas/crosslink.py +34 -0
  35. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/atlas/guide_design.py +5 -1
  36. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/atlas/writer_recommend.py +65 -3
  37. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/design/generate.py +12 -1
  38. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/design/space.py +1 -0
  39. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/design/writer_variants.py +4 -3
  40. pen_stack-8.0.1/pen_stack/graph/query.py +148 -0
  41. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/oracles/schema.py +16 -2
  42. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/oracles/structure.py +1 -2
  43. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/delivery_immune.py +2 -1
  44. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/delivery_predict.py +73 -13
  45. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/immune_profile.py +24 -3
  46. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/optimize.py +31 -4
  47. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/pipeline.py +1 -0
  48. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/rag/llm.py +37 -0
  49. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/rules/evaluators.py +21 -3
  50. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/rules/schema.py +20 -3
  51. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/safety/gate.py +21 -0
  52. pen_stack-8.0.1/pen_stack/safety/pfam_scan.py +157 -0
  53. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/safety/policy.py +5 -1
  54. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/safety/registry.py +17 -0
  55. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/safety/screen.py +10 -3
  56. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/server/api.py +106 -25
  57. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/spec/extract.py +26 -4
  58. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/twin/data/position_effect.py +29 -2
  59. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/twin/mechanistic.py +17 -0
  60. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/twin/outcome.py +31 -1
  61. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/twin/position_effect.py +81 -7
  62. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/paper3_benchmark.py +2 -2
  63. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/verify/proof.py +31 -1
  64. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/verify/schema.py +6 -1
  65. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/verify/service.py +4 -1
  66. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/offtarget_assay.py +3 -1
  67. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/offtarget_bridge.py +2 -2
  68. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/offtarget_cast.py +5 -5
  69. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/offtarget_enumerate.py +6 -6
  70. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/offtarget_integrase.py +34 -8
  71. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/offtarget_nuclease.py +35 -3
  72. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/offtarget_paste.py +3 -3
  73. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/offtarget_predict.py +6 -3
  74. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack.egg-info/PKG-INFO +130 -58
  75. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack.egg-info/SOURCES.txt +19 -0
  76. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack.egg-info/requires.txt +9 -0
  77. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_offtarget2.json +1 -1
  78. pen_stack-8.0.1/prereg/SHA256_LOCK_ws_priorart.json +10 -0
  79. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_offtarget2.yaml +3 -3
  80. pen_stack-8.0.1/prereg/ws_priorart.yaml +169 -0
  81. {pen_stack-7.2.3 → pen_stack-8.0.1}/pyproject.toml +9 -3
  82. {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/build_capsid_fitness.py +5 -0
  83. pen_stack-8.0.1/scripts/fetch_artifacts.sh +215 -0
  84. pen_stack-8.0.1/scripts/p2_build_human_head.py +79 -0
  85. pen_stack-8.0.1/scripts/pa_epridict_distinctness.py +66 -0
  86. pen_stack-8.0.1/scripts/reproduce.py +115 -0
  87. pen_stack-8.0.1/scripts/validate_components.py +158 -0
  88. pen_stack-7.2.3/README.md +0 -232
  89. pen_stack-7.2.3/benchmarks/genome_writing_bench/SHA256SUMS +0 -7
  90. pen_stack-7.2.3/pen_stack/__init__.py +0 -2
  91. pen_stack-7.2.3/pen_stack/active/acquire.py +0 -73
  92. pen_stack-7.2.3/pen_stack/active/design.py +0 -51
  93. pen_stack-7.2.3/pen_stack/graph/query.py +0 -79
  94. {pen_stack-7.2.3 → pen_stack-8.0.1}/LICENSE +0 -0
  95. {pen_stack-7.2.3 → pen_stack-8.0.1}/MANIFEST.in +0 -0
  96. {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/chat_grounding/README.md +0 -0
  97. {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/chat_grounding/SHA256SUMS +0 -0
  98. {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/chat_headtohead/README.md +0 -0
  99. {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/chat_routing/README.md +0 -0
  100. {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/chat_routing/SHA256SUMS +0 -0
  101. {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/chat_safety/README.md +0 -0
  102. {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/chat_safety/SHA256SUMS +0 -0
  103. {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/delivery/SHA256SUMS +0 -0
  104. {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/genome_writing_bench/LEADERBOARD.md +0 -0
  105. {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/genome_writing_bench/README.md +0 -0
  106. {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/genome_writing_bench/SUBMISSIONS.md +0 -0
  107. {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/genome_writing_bench/tasks.yaml +0 -0
  108. {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/genome_writing_challenge/README.md +0 -0
  109. {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/genome_writing_challenge/SUBMISSIONS.md +0 -0
  110. {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/loop/SHA256SUMS +0 -0
  111. {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/offtarget/SHA256SUMS +0 -0
  112. {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/offtarget/integrase/SHA256SUMS +0 -0
  113. {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/oracle/SHA256SUMS +0 -0
  114. {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/position_effect/SHA256SUMS +0 -0
  115. {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/verify/SHA256SUMS +0 -0
  116. {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/writer_efficiency/README.md +0 -0
  117. {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/writer_efficiency/SHA256SUMS +0 -0
  118. {pen_stack-7.2.3 → pen_stack-8.0.1}/benchmarks/writespec/SHA256SUMS +0 -0
  119. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/aav_serotype_tropism.yaml +0 -0
  120. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/antipeg.yaml +0 -0
  121. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/atlas_families.yaml +0 -0
  122. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/bridge_offtarget_profile.yaml +0 -0
  123. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/calibration/preexisting_nab_independent.yaml +0 -0
  124. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/capsid_epitope_oracle.yaml +0 -0
  125. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/capsid_sequences.fasta +0 -0
  126. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/cargo_polish.yaml +0 -0
  127. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/cell_types.yaml +0 -0
  128. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/datasets.yaml +0 -0
  129. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/delivery_constraints.yaml +0 -0
  130. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/delivery_rules.yaml +0 -0
  131. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/delivery_vehicles.yaml +0 -0
  132. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/expression/modifiers.yaml +0 -0
  133. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/expression/promoters.yaml +0 -0
  134. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/gates_v3.yaml +0 -0
  135. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/genotoxicity_oracle.yaml +0 -0
  136. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/gsh_validated_heldout.yaml +0 -0
  137. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/known_unknowns.yaml +0 -0
  138. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/metric_guide.yaml +0 -0
  139. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/mhc_epitope_oracle.yaml +0 -0
  140. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/monitor_queries.yaml +0 -0
  141. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/oracles/execution.yaml +0 -0
  142. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/oracles/reliability.yaml +0 -0
  143. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/oracles/scope_cards.yaml +0 -0
  144. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/rules/compliance.yaml +0 -0
  145. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/rules/delivery.yaml +0 -0
  146. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/rules/fold.yaml +0 -0
  147. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/rules/multiplex.yaml +0 -0
  148. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/rules/payload.yaml +0 -0
  149. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/rules/reachability.yaml +0 -0
  150. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/safety/hazard_registry.yaml +0 -0
  151. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/safety/policy.yaml +0 -0
  152. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/safety/probes.yaml +0 -0
  153. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/score_axes.yaml +0 -0
  154. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/seroprevalence.yaml +0 -0
  155. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/target_sites.yaml +0 -0
  156. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/universe_crosswalk.yaml +0 -0
  157. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/write_types.yaml +0 -0
  158. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/writer_sequences.fasta +0 -0
  159. {pen_stack-7.2.3 → pen_stack-8.0.1}/configs/wtkb_curated.yaml +0 -0
  160. {pen_stack-7.2.3 → pen_stack-8.0.1}/data/curated/bridge_offtarget_energetics.json +0 -0
  161. {pen_stack-7.2.3 → pen_stack-8.0.1}/data/curated/bridge_offtarget_profile_measured.parquet +0 -0
  162. {pen_stack-7.2.3 → pen_stack-8.0.1}/data/curated/gene_coords.parquet +0 -0
  163. {pen_stack-7.2.3 → pen_stack-8.0.1}/data/curated/unified_editor_universe.parquet +0 -0
  164. {pen_stack-7.2.3 → pen_stack-8.0.1}/data/offtarget/enumerated_cache.parquet +0 -0
  165. {pen_stack-7.2.3 → pen_stack-8.0.1}/data/offtarget/motif_cache.parquet +0 -0
  166. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/BACKLOG.md +0 -0
  167. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/DEPLOY.md +0 -0
  168. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/MCP.md +0 -0
  169. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/RELEASING.md +0 -0
  170. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/REPRO.md +0 -0
  171. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/STABILITY.md +0 -0
  172. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/agent.md +0 -0
  173. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/alphagenome_feasibility.md +0 -0
  174. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/autonomy.md +0 -0
  175. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/benchmark_circularity.md +0 -0
  176. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/build_interface.md +0 -0
  177. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/cards/atlas.md +0 -0
  178. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/cards/durability.md +0 -0
  179. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/cards/position_effect_data.md +0 -0
  180. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/cards/safety.md +0 -0
  181. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/cards/writer_efficiency_data.md +0 -0
  182. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/challenge.md +0 -0
  183. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/closed_loop.md +0 -0
  184. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/co_scientist.md +0 -0
  185. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/co_scientist_loop.md +0 -0
  186. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/delivery.md +0 -0
  187. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/delivery_immunology.md +0 -0
  188. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/delivery_recommender.md +0 -0
  189. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/digital_twin.md +0 -0
  190. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/dissemination.md +0 -0
  191. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/environment.md +0 -0
  192. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/experiment_design.md +0 -0
  193. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/generative_design.md +0 -0
  194. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/immune_profiler.md +0 -0
  195. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/index.md +0 -0
  196. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/integrations.md +0 -0
  197. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/live_oracles.md +0 -0
  198. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/mechanistic_constraints.md +0 -0
  199. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/offtarget.md +0 -0
  200. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/oracle_mesh.md +0 -0
  201. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/oracles.md +0 -0
  202. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/position_effect.md +0 -0
  203. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/positioning.md +0 -0
  204. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/private_data_formats.md +0 -0
  205. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/quickstart.md +0 -0
  206. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/rule_spec.md +0 -0
  207. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/rules.md +0 -0
  208. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/scope.md +0 -0
  209. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/scorecard.md +0 -0
  210. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/tpe_bench.md +0 -0
  211. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/tutorials/compare-families.md +0 -0
  212. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/tutorials/score-deliverability.md +0 -0
  213. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/tutorials/where-can-i-write.md +0 -0
  214. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/tutorials/which-writer-reaches-locus.md +0 -0
  215. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/uncertainty.md +0 -0
  216. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/verify.md +0 -0
  217. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/verify_service.md +0 -0
  218. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/world_model.md +0 -0
  219. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/writer_efficiency.md +0 -0
  220. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/writer_verification.md +0 -0
  221. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/writespec_bench.md +0 -0
  222. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/writespec_profile.md +0 -0
  223. {pen_stack-7.2.3 → pen_stack-8.0.1}/docs/wtkb.md +0 -0
  224. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/_resources.py +0 -0
  225. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/active/__init__.py +0 -0
  226. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/active/brains.py +0 -0
  227. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/active/campaign.py +0 -0
  228. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/active/validate.py +0 -0
  229. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/adapt/__init__.py +0 -0
  230. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/adapt/finetune.py +0 -0
  231. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/adapt/ingest.py +0 -0
  232. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/adapt/pipeline.py +0 -0
  233. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/adapt/recalibrate.py +0 -0
  234. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/adapt/report.py +0 -0
  235. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/agent/__init__.py +0 -0
  236. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/agent/cite.py +0 -0
  237. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/agent/co_scientist.py +0 -0
  238. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/agent/guardrails.py +0 -0
  239. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/agent/mcp_server.py +0 -0
  240. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/agent/orchestrator_live.py +0 -0
  241. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/agent/pen_agent.py +0 -0
  242. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/agent/scope.py +0 -0
  243. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/agent/tools.py +0 -0
  244. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/api/__init__.py +0 -0
  245. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/atlas/__init__.py +0 -0
  246. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/atlas/build_wtkb.py +0 -0
  247. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/atlas/expand.py +0 -0
  248. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/atlas/schema.py +0 -0
  249. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/atlas/scorecard.py +0 -0
  250. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/atlas/universe.py +0 -0
  251. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/atlas/variant_propose.py +0 -0
  252. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/atlas/writer_efficiency.py +0 -0
  253. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/atlas/writer_predict.py +0 -0
  254. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/atlas/writer_verify.py +0 -0
  255. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/bridge/__init__.py +0 -0
  256. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/bridge/activity.py +0 -0
  257. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/bridge/cli.py +0 -0
  258. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/bridge/fold_qc.py +0 -0
  259. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/bridge/guide_qc.py +0 -0
  260. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/bridge/ingest.py +0 -0
  261. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/bridge/offtarget.py +0 -0
  262. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/bridge/offtarget_energetics.py +0 -0
  263. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/bridge/ortholog_screen.py +0 -0
  264. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/bridge/pipeline.py +0 -0
  265. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/build/__init__.py +0 -0
  266. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/build/cloudlab.py +0 -0
  267. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/build/ingest.py +0 -0
  268. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/build/protocol.py +0 -0
  269. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/build/simlab.py +0 -0
  270. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/cli.py +0 -0
  271. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/data/__init__.py +0 -0
  272. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/data/encode.py +0 -0
  273. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/data/genome.py +0 -0
  274. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/data/ingest_chromatin.py +0 -0
  275. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/data/ingest_integration.py +0 -0
  276. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/data/ingest_safety_annot.py +0 -0
  277. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/data/ingest_trip.py +0 -0
  278. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/design/__init__.py +0 -0
  279. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/design/capsid_generate.py +0 -0
  280. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/design/pareto.py +0 -0
  281. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/env/__init__.py +0 -0
  282. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/env/genome_writing_env.py +0 -0
  283. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/env/policies.py +0 -0
  284. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/graph/__init__.py +0 -0
  285. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/graph/build.py +0 -0
  286. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/graph/cell_types.py +0 -0
  287. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/graph/ingest.py +0 -0
  288. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/graph/schema.py +0 -0
  289. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/loop/__init__.py +0 -0
  290. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/loop/continual.py +0 -0
  291. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/loop/cycle.py +0 -0
  292. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/loop/drift.py +0 -0
  293. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/mech/__init__.py +0 -0
  294. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/mech/classify_atlas.py +0 -0
  295. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/mech/whitelist.py +0 -0
  296. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/monitor/__init__.py +0 -0
  297. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/monitor/europepmc.py +0 -0
  298. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/monitor/run.py +0 -0
  299. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/monitor/triage.py +0 -0
  300. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/oracles/__init__.py +0 -0
  301. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/oracles/affinity.py +0 -0
  302. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/oracles/cache.py +0 -0
  303. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/oracles/energetics.py +0 -0
  304. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/oracles/genome.py +0 -0
  305. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/oracles/protein_design.py +0 -0
  306. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/oracles/reliability.py +0 -0
  307. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/oracles/rna.py +0 -0
  308. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/oracles/status.py +0 -0
  309. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/oracles/structure_run.py +0 -0
  310. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/oracles/vcell.py +0 -0
  311. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/__init__.py +0 -0
  312. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/ada_risk.py +0 -0
  313. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/antipeg_oracle.py +0 -0
  314. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/capsid_epitope_oracle.py +0 -0
  315. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/cargo.py +0 -0
  316. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/cargo_polish.py +0 -0
  317. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/chromosome.py +0 -0
  318. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/delivery.py +0 -0
  319. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/delivery_constraints.py +0 -0
  320. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/delivery_immunology.py +0 -0
  321. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/delivery_vehicles.py +0 -0
  322. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/genotoxicity_oracle.py +0 -0
  323. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/immune_mhc2.py +0 -0
  324. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/innate_sensing.py +0 -0
  325. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/multiplex.py +0 -0
  326. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/report.py +0 -0
  327. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/router.py +0 -0
  328. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/seroprevalence_oracle.py +0 -0
  329. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/planner/target_site.py +0 -0
  330. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/rag/__init__.py +0 -0
  331. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/rag/corpus.py +0 -0
  332. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/rag/embed.py +0 -0
  333. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/rag/ground.py +0 -0
  334. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/rag/index.py +0 -0
  335. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/rag/qa.py +0 -0
  336. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/rag/retrieve.py +0 -0
  337. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/rules/__init__.py +0 -0
  338. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/rules/loader.py +0 -0
  339. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/rules/solver.py +0 -0
  340. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/rules/spec.py +0 -0
  341. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/safety/__init__.py +0 -0
  342. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/safety/audit.py +0 -0
  343. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/safety/redteam.py +0 -0
  344. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/safety/standards.py +0 -0
  345. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/score/__init__.py +0 -0
  346. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/score/recalibrate.py +0 -0
  347. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/score/therapeutic.py +0 -0
  348. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/server/__init__.py +0 -0
  349. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/spec/__init__.py +0 -0
  350. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/spec/clarify.py +0 -0
  351. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/spec/resolvers/__init__.py +0 -0
  352. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/spec/resolvers/cell.py +0 -0
  353. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/spec/resolvers/chem.py +0 -0
  354. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/spec/resolvers/feature.py +0 -0
  355. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/spec/resolvers/gene.py +0 -0
  356. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/spec/resolvers/locus.py +0 -0
  357. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/spec/resolvers/phenotype.py +0 -0
  358. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/spec/satisfy.py +0 -0
  359. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/spec/service.py +0 -0
  360. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/spec/writespec.py +0 -0
  361. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/twin/__init__.py +0 -0
  362. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/twin/calibrate.py +0 -0
  363. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/twin/data/__init__.py +0 -0
  364. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/ui/__init__.py +0 -0
  365. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/ui/app.py +0 -0
  366. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/__init__.py +0 -0
  367. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/adapt_demo.py +0 -0
  368. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/agent_eval.py +0 -0
  369. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/bench_adversarial_tasks.py +0 -0
  370. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/bench_coscientist_tasks.py +0 -0
  371. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/bench_graph_tasks.py +0 -0
  372. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/bench_rule_tasks.py +0 -0
  373. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/bench_trust_tasks.py +0 -0
  374. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/bench_writetype_tasks.py +0 -0
  375. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/blind_gsh_discovery.py +0 -0
  376. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/cargo_directionality.py +0 -0
  377. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/closed_loop.py +0 -0
  378. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/durability_baselines.py +0 -0
  379. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/experiment_design.py +0 -0
  380. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/expr_controls.py +0 -0
  381. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/forward_hypotheses.py +0 -0
  382. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/generative_design.py +0 -0
  383. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/guide_qc_demo.py +0 -0
  384. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/heldout_celltype_expr.py +0 -0
  385. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/immune_calibration.py +0 -0
  386. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/intent_specification.py +0 -0
  387. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/known_biology_expr.py +0 -0
  388. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/offtarget_energetics_eval.py +0 -0
  389. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/out_of_scope_refusal.py +0 -0
  390. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/outcome_calibration.py +0 -0
  391. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/outcome_prediction.py +0 -0
  392. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/paper4_real_validation.py +0 -0
  393. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/paper4_validation.py +0 -0
  394. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/protocol_safety.py +0 -0
  395. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/safety_screening.py +0 -0
  396. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/selective_prediction.py +0 -0
  397. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/seq_vs_measured.py +0 -0
  398. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/target_site_controls.py +0 -0
  399. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/uncertainty_eval.py +0 -0
  400. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/ungrounded_baseline.py +0 -0
  401. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/within_locus_ranking.py +0 -0
  402. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/validate/writer_recovery.py +0 -0
  403. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/verify/__init__.py +0 -0
  404. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/web/__init__.py +0 -0
  405. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/web/guide.py +0 -0
  406. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/web/llm.py +0 -0
  407. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/web/llm_provider.py +0 -0
  408. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/web/router.py +0 -0
  409. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/web/server.py +0 -0
  410. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/web/tools.py +0 -0
  411. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/__init__.py +0 -0
  412. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/chromatin_seq.py +0 -0
  413. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/durability.py +0 -0
  414. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/export_tracks.py +0 -0
  415. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/features.py +0 -0
  416. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/gsh_baseline.py +0 -0
  417. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/mesh_features.py +0 -0
  418. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/offtarget_data.py +0 -0
  419. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/ood.py +0 -0
  420. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/providers.py +0 -0
  421. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/safety.py +0 -0
  422. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/structure3d.py +0 -0
  423. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/uncertainty.py +0 -0
  424. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack/wgenome/writability.py +0 -0
  425. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack.egg-info/dependency_links.txt +0 -0
  426. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack.egg-info/entry_points.txt +0 -0
  427. {pen_stack-7.2.3 → pen_stack-8.0.1}/pen_stack.egg-info/top_level.txt +0 -0
  428. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_phase0.json +0 -0
  429. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_phase1_5.json +0 -0
  430. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_phase2.json +0 -0
  431. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_phase3.json +0 -0
  432. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_a.json +0 -0
  433. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_acq.json +0 -0
  434. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_aldesign.json +0 -0
  435. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_alvalidate.json +0 -0
  436. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_atlas.json +0 -0
  437. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_b.json +0 -0
  438. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_ba.json +0 -0
  439. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_ba_v33.json +0 -0
  440. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_ba_v45.json +0 -0
  441. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_bench.json +0 -0
  442. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_c.json +0 -0
  443. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_cal.json +0 -0
  444. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_calib.json +0 -0
  445. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_challenge.json +0 -0
  446. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_chat.json +0 -0
  447. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_cite.json +0 -0
  448. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_closedloop.json +0 -0
  449. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_continual.json +0 -0
  450. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_cosci2.json +0 -0
  451. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_crit.json +0 -0
  452. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_ct.json +0 -0
  453. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_d.json +0 -0
  454. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_delivery.json +0 -0
  455. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_drift.json +0 -0
  456. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_e.json +0 -0
  457. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_env.json +0 -0
  458. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_ep.json +0 -0
  459. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_epitope.json +0 -0
  460. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_expr2.json +0 -0
  461. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_f.json +0 -0
  462. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_frontend.json +0 -0
  463. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_g.json +0 -0
  464. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_gen.json +0 -0
  465. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_genotox.json +0 -0
  466. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_graph.json +0 -0
  467. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_h.json +0 -0
  468. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_hybrid.json +0 -0
  469. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_immune.json +0 -0
  470. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_immune2.json +0 -0
  471. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_ingest.json +0 -0
  472. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_innate.json +0 -0
  473. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_loop.json +0 -0
  474. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_manifest.json +0 -0
  475. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_mc.json +0 -0
  476. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_mcp.json +0 -0
  477. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_mech.json +0 -0
  478. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_mon.json +0 -0
  479. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_o.json +0 -0
  480. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_offtarget.json +0 -0
  481. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_openapi.json +0 -0
  482. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_oracle.json +0 -0
  483. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_orch.json +0 -0
  484. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_outcome.json +0 -0
  485. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_pareto.json +0 -0
  486. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_peg.json +0 -0
  487. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_penchat.json +0 -0
  488. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_plan.json +0 -0
  489. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_policy.json +0 -0
  490. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_profile.json +0 -0
  491. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_proto.json +0 -0
  492. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_r.json +0 -0
  493. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_redteam.json +0 -0
  494. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_route.json +0 -0
  495. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_screen.json +0 -0
  496. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_seroprev.json +0 -0
  497. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_simlab.json +0 -0
  498. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_twincal.json +0 -0
  499. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_uq.json +0 -0
  500. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_v.json +0 -0
  501. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_vcell.json +0 -0
  502. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_verify.json +0 -0
  503. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_writer.json +0 -0
  504. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_writespec.json +0 -0
  505. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/SHA256_LOCK_ws_wv.json +0 -0
  506. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/paper1.yaml +0 -0
  507. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/paper2.yaml +0 -0
  508. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/paper3.yaml +0 -0
  509. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/paper4.yaml +0 -0
  510. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/phase0.yaml +0 -0
  511. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_a.yaml +0 -0
  512. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_acq.yaml +0 -0
  513. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_aldesign.yaml +0 -0
  514. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_alvalidate.yaml +0 -0
  515. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_atlas.yaml +0 -0
  516. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_b.yaml +0 -0
  517. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_ba.yaml +0 -0
  518. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_ba_v33.yaml +0 -0
  519. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_ba_v45.yaml +0 -0
  520. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_bench.yaml +0 -0
  521. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_c.yaml +0 -0
  522. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_cal.yaml +0 -0
  523. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_calib.yaml +0 -0
  524. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_challenge.yaml +0 -0
  525. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_chat.yaml +0 -0
  526. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_cite.yaml +0 -0
  527. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_closedloop.yaml +0 -0
  528. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_continual.yaml +0 -0
  529. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_cosci2.yaml +0 -0
  530. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_crit.yaml +0 -0
  531. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_ct.yaml +0 -0
  532. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_d.yaml +0 -0
  533. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_delivery.yaml +0 -0
  534. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_drift.yaml +0 -0
  535. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_e.yaml +0 -0
  536. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_env.yaml +0 -0
  537. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_ep.yaml +0 -0
  538. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_epitope.yaml +0 -0
  539. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_expr2.yaml +0 -0
  540. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_f.yaml +0 -0
  541. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_frontend.yaml +0 -0
  542. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_g.yaml +0 -0
  543. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_gen.yaml +0 -0
  544. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_genotox.yaml +0 -0
  545. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_graph.yaml +0 -0
  546. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_h.yaml +0 -0
  547. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_hybrid.yaml +0 -0
  548. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_immune.yaml +0 -0
  549. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_immune2.yaml +0 -0
  550. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_ingest.yaml +0 -0
  551. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_innate.yaml +0 -0
  552. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_loop.yaml +0 -0
  553. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_manifest.yaml +0 -0
  554. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_mc.yaml +0 -0
  555. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_mcp.yaml +0 -0
  556. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_mech.yaml +0 -0
  557. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_mon.yaml +0 -0
  558. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_o.yaml +0 -0
  559. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_offtarget.yaml +0 -0
  560. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_openapi.yaml +0 -0
  561. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_oracle.yaml +0 -0
  562. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_orch.yaml +0 -0
  563. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_outcome.yaml +0 -0
  564. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_pareto.yaml +0 -0
  565. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_peg.yaml +0 -0
  566. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_penchat.yaml +0 -0
  567. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_plan.yaml +0 -0
  568. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_policy.yaml +0 -0
  569. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_profile.yaml +0 -0
  570. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_proto.yaml +0 -0
  571. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_r.yaml +0 -0
  572. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_redteam.yaml +0 -0
  573. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_route.yaml +0 -0
  574. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_screen.yaml +0 -0
  575. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_seroprev.yaml +0 -0
  576. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_simlab.yaml +0 -0
  577. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_twincal.yaml +0 -0
  578. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_uq.yaml +0 -0
  579. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_v.yaml +0 -0
  580. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_vcell.yaml +0 -0
  581. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_verify.yaml +0 -0
  582. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_writer.yaml +0 -0
  583. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_writespec.yaml +0 -0
  584. {pen_stack-7.2.3 → pen_stack-8.0.1}/prereg/ws_wv.yaml +0 -0
  585. {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/build_rag_corpus.py +0 -0
  586. {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/calibrate_immune_axes.py +0 -0
  587. {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/fetch_licensed_sources.py +0 -0
  588. {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/offtarget_chromatin_incremental.py +0 -0
  589. {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/offtarget_chromatin_matched.py +0 -0
  590. {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/offtarget_chromatin_validation.py +0 -0
  591. {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/p1_build_atlas.py +0 -0
  592. {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/p1_build_durability.py +0 -0
  593. {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/p1_build_position_effect.py +0 -0
  594. {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/p1_build_writer_eff.py +0 -0
  595. {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/p1_export_tracks.py +0 -0
  596. {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/p1_safety_concordance.py +0 -0
  597. {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/p1_train_safety.py +0 -0
  598. {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/p1_validation_report.py +0 -0
  599. {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/p2_build_atlas.py +0 -0
  600. {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/p3_benchmark_report.py +0 -0
  601. {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/p4_genome_scan.py +0 -0
  602. {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/p52_build_genotox_oracle.py +0 -0
  603. {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/p53_build_epitope_oracle.py +0 -0
  604. {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/ws_b_report.py +0 -0
  605. {pen_stack-7.2.3 → pen_stack-8.0.1}/scripts/ws_c_report.py +0 -0
  606. {pen_stack-7.2.3 → pen_stack-8.0.1}/setup.cfg +0 -0
@@ -3,13 +3,460 @@
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
+ ## [8.0.1] - 2026-07-13
7
+
8
+ A reproducibility and API-hardening patch. No scientific result and no public function signature changes.
9
+
10
+ ### Changed
11
+ - **Result, verdict, and safety types are now immutable (frozen).** `OracleResult` and its nested
12
+ `Provenance`, `Verdict`, `SafetyVerdict`, `ScreenHit`, `Rule`, and `RuleResult` can no longer be mutated
13
+ after construction, so a result's provenance and scope, a verdict's legality, or a screen hit's severity
14
+ cannot be edited downstream. Build a changed copy with `model_copy(update=...)`.
15
+ - **The REST, MCP, and Gymnasium-environment tests and the SBOL3/GenBank round-trip run by default.**
16
+ `fastapi`, `uvicorn`, `httpx`, `fastmcp`, `gymnasium`, `sbol3`, and `biopython` are in the `[dev]` extra, so
17
+ the full suite exercises these features rather than skipping them. Heavy compiled extras stay opt-in.
18
+ - **The one-command reproduction recomputes a second headline from committed source.**
19
+ `scripts/pa_epridict_distinctness.py` (wired into `make repro`) re-derives the durability-vs-ePRIDICT
20
+ distinctness result, and `scripts/reproduce.py` now distinguishes recomputed headlines from echoed sealed
21
+ metrics.
22
+
23
+ ### Fixed
24
+ - **An abstention is no longer reported as high confidence.** A design verified with no calibrated confidence
25
+ is now `not-computable`, not `grounded-confident`.
26
+ - **The frozen-input integrity check works on a fresh checkout.** `python bench/run.py --verify` parses the
27
+ standard `sha256sum` manifest format (two-space, CRLF-tolerant); the manifest re-seals only on explicit
28
+ `--seal`; a `.gitattributes` pins the hashed inputs to LF for cross-platform stability.
29
+ - **The reproduction harness can fail.** `scripts/reproduce.py` exits non-zero if any block fails instead of
30
+ always reporting success.
31
+ - Corrected the ePRIDICT variance figure in the README (R-squared 0.041, matching the committed metrics).
32
+
33
+ ## [8.0.0] - 2026-07-13 - Stable release of record
34
+
35
+ The first stable, citable release. The major version marks a committed public API surface (the SDK
36
+ functions, the REST endpoints, and the twenty MCP tools) governed by a one-minor-version deprecation policy.
37
+ It consolidates the gated 7.x development trail rather than replacing it: the pre-registrations, SHA-locked
38
+ benchmarks, and disclosed negatives that trail documents remain intact and referenced. Stable surfaces
39
+ carry calibrated uncertainty and validation status; the mechanism-based paths (serine-integrase, bridge, and
40
+ CAST off-target) are marked experimental and may change.
41
+
42
+ ### Added
43
+ - **A one-chromosome demo atlas** (`data/demo/atlas_k562.parquet`, chr19). A fresh clone can run the
44
+ safe-harbour quickstart without first fetching the full release: `PEN_ATLAS_DIR=data/demo pen-stack
45
+ writable --gene AAVS1 --ct k562` returns the ranked writable bins of the AAVS1 (PPP1R12C) locus. Opt-in via
46
+ `PEN_ATLAS_DIR`, so the atlas-gated test suite is unchanged. Full genome-wide atlases come from Zenodo via
47
+ `scripts/fetch_artifacts.sh`.
48
+ - **An Anthropic (Claude) provider in the LLM layer.** `pen_stack/rag/llm.py` now supports three provider
49
+ styles (OpenAI-compatible, Ollama, Anthropic Messages), including multi-turn tool calling, so the
50
+ conversational agent and the evaluations run provider-agnostically across hosted-frontier and local models.
51
+ Keys are read from an env var or a gitignored file and are never committed.
52
+ - **A measured, LLM-on grounding evaluation** (`benchmarks/grounding_llm_on/`). The ungrounded-baseline
53
+ contrast ships a committed metrics file and an adversarial probe set, run with the model live across three
54
+ model families: with no tools an ungrounded model emits concrete tool-only quantities (fabrication), while
55
+ the grounded agent, which routes every quantity through a validated tool, emits none. Transcripts are cached
56
+ and replay offline in CI.
57
+ - **An agentic baseline** (`benchmarks/agentic_baseline/`). A real external LLM agent drives the validated
58
+ tools and every number in its trace is audited to a direct tool call. Verified across three models spanning
59
+ a small local model to hosted-frontier models; the no-fabrication audit passes for all.
60
+ - **A one-command reproduction path.** `make repro` reproduces every result that runs on the committed data
61
+ and the demo atlas on a fresh clone, with no download and no API key (`scripts/reproduce.py`); `make fetch`
62
+ then `make repro-full` add the genome-wide atlas benchmarks from the Zenodo release. Verified end to end in
63
+ a clean `python:3.12-slim` container.
64
+ - **Committed metrics for the three headline analyses** (`benchmarks/position_effect_human/`,
65
+ `offtarget/integrase_chalberg/`, `genotox_panel/`), so the paper's central numbers reproduce directly from
66
+ the repository.
67
+
68
+ ### Changed
69
+ - Benchmark provenance references relative paths only. The license (MIT), MCP tool count (twenty), and
70
+ Verify-Bench rule count (eleven) are reconciled across the package metadata, the repository, and the
71
+ manuscript. The repository was confirmed free of hardcoded credentials, addresses, and absolute local paths.
72
+
73
+ ## [7.3.21] - 2026-07-11 - World-model graph: resolve any locus (not just exact GSH names)
74
+
75
+ ### Fixed
76
+ - **The world-model graph query resolved only the exact curated safe-harbour node names.** The graph materialises
77
+ a `locus:` node for each curated GSH locus and matched the query string exactly, so `PPP1R12C` (AAVS1's anchor
78
+ gene), `ROSA26` (whose node is `hRosa26`), and real genes such as TRAC, HBB, and LMO2 all returned nothing. The
79
+ query now resolves in three tiers:
80
+ - A curated node is matched by **GSH name, anchor gene, or alias, case-insensitively** (AAVS1 ≡ aavs1 ≡
81
+ PPP1R12C; ROSA26 ≡ hRosa26; HIPP11 ≡ H11), returning the same DOI-provenanced answer.
82
+ - A query that is not a curated safe harbour but resolves to a **real gene** returns the **tier-1 reprogrammable
83
+ writers**, which engage any locus at the locus level (the documented crosslink property), flagged as a
84
+ candidate rather than a curated safe harbour (per-site reachability and safety remain the Planner's and
85
+ Guardian's responsibility).
86
+ - Anything else returns an explained empty result rather than an error.
87
+ The response carries `resolved_locus` and `is_curated_safe_harbour`, and the Closed Loop page shows the resolved
88
+ locus and a curated-vs-candidate badge.
89
+
90
+ ## [7.3.20] - 2026-07-11 - Stage J closed loop: a UI surface + /cloudlab 500-on-bad-provider fix
91
+
92
+ ### Fixed
93
+ - **`POST /api/cloudlab` returned an unhandled 500 for any `provider` other than "mock".** `submit()` raises
94
+ `CloudLabError` for a provider outside the wired set, but `submit_gated()` caught only the safety refusal
95
+ (`ProtocolExportError`), so it propagated. The endpoint now returns a **422** with the valid-provider list for an
96
+ unknown provider, and a null/empty/missing provider falls back to the wired `mock` dry-run path.
97
+
98
+ ### Added
99
+ - **A "Closed Loop" page (Stage J).** Three closed-loop capabilities previously reachable only via the API are now
100
+ surfaced (the fourth, the validation campaign, is already on Experiments):
101
+ - **Build & submit (cloud-lab)**: a design form plus provider select drives the verify-first flow: a cleared
102
+ design returns a DRAFT protocol preview and a mock/dry-run job receipt (Level 3, human-in-control); a hazardous
103
+ cargo (e.g. ricin) is refused with no protocol emitted.
104
+ - **SDL-brain benchmark**: the EIG/VOI designer versus random/greedy (curve-area gap with CI), BayBE/Atlas
105
+ cited, with a "BayBE not installed in this deployment" note when the optional dependency is absent.
106
+ - **World-model graph**: a locus/cargo-form query returns the provenanced writer→locus→vehicle paths.
107
+ Wired into the left-rail nav (Build & learn) and the router at `/closed-loop`.
108
+
109
+ ## [7.3.19] - 2026-07-11 - Experiment designer: expected information gain varies with cell-type coverage
110
+
111
+ ### Changed
112
+ - **`expected_info_gain` now varies across candidates** instead of reducing to the twin's fixed ±0.20 uncertainty
113
+ band (which read a near-constant ~0.0202 for every candidate). EIG folds in the design-varying uncertainty the
114
+ fixed band understates: an unmeasured cell type (no atlas data, so more reducible uncertainty) and an
115
+ out-of-distribution design widen the effective standard deviation. EIG is ~0.02 in a fully-measured cell
116
+ (K562/HepG2), ~0.43 partially-measured (HSPC), ~0.71 unmeasured (iPSC/PBMC/…), and ~1.5 out-of-distribution; it
117
+ is constant across gene/vehicle/cargo within one cell type, since the mechanistic twin carries no per-gene
118
+ uncertainty. Coverage and OOD are folded into EIG rather than double-counted as separate acquisition terms.
119
+
120
+ ## [7.3.18] - 2026-07-11 - Experiment designer: acquisition rebuilt on design-varying signals
121
+
122
+ ### Changed
123
+ - **The experiment-suggestion acquisition is rebuilt on design-varying signals.** Expected information gain derives
124
+ entirely from the twin's fixed ±0.20 uncertainty band, so the suggested batch scored a near-constant ~0.02 for
125
+ almost every candidate, and the pool varied only vehicle × cargo at one cell type, where relative expression is
126
+ per-copy (cargo-independent). The acquisition now combines:
127
+ - **Coverage novelty**: an experiment in an unmeasured cell type reduces more uncertainty; the measured-atlas
128
+ roster (K562/HepG2 full, HSPC partial, others none) drives it.
129
+ - **Feasibility gate**: an experiment that cannot be built as specified (cargo overflowing the vehicle) is
130
+ down-weighted.
131
+ - **Immune value-of-information**, counting only **in-scope** proxy axes, so it varies by vehicle (a PEGylated
132
+ LNP puts the anti-PEG axis in scope; AAV does not).
133
+ - **Marginal gain**: the submodular greedy objective (informativeness minus overlap with the picks already
134
+ scheduled), distinct per experiment and decreasing down the batch.
135
+ The candidate pool spans all cell types × 4 vehicles so the coverage/feasibility/immune signals differ across it;
136
+ the batch is scored per candidate cell, and each experiment is returned with its full breakdown. The Experiments
137
+ page shows the marginal-gain ranking with a "why" line (coverage, immune-VOI, buildability) and states that the
138
+ mechanistic twin cannot finely rank two experiments in the same regime, the ranking is coverage + buildability +
139
+ immune-VOI + diversity. `select_batch` scores each candidate once.
140
+ - The "Load expression-validation campaign" plan is a fixed pre-registered 48-row campaign, independent of the
141
+ candidate-pool form; the scores panel notes this.
142
+
143
+ ## [7.3.17] - 2026-07-10 - App-wide input-validation sweep (out-of-domain values are flagged everywhere)
144
+
145
+ ### Added
146
+ - **A consistent input-validation pass across every page.** Shared helpers in `lib/format.js`
147
+ (`invalidNucleotides`, `clampInt`) and a reusable `SeqWarning` component in `ui.jsx`:
148
+ - **Nucleotide sequence fields** warn on characters outside A/C/G/T/U/N (kept, not silently accepted):
149
+ Design Studio / Twin / Guardian cargo sequence, Off-Target guide / crRNA spacer / bridge target-core, Writer
150
+ Atlas guide-design target and donor.
151
+ - **Writer Atlas "Cargo bp"** now shows the same "clamped to X (allowed 1–300,000)" note Site Finder uses,
152
+ instead of clamping silently.
153
+ - **Design Studio multiplex edits**: the free-text chromosome flags an invalid value (chr1–chr22, chrX/Y/M)
154
+ and the genomic position clamps to a non-negative coordinate (was `parseInt || 0`, accepting negatives).
155
+ - Twin chromatin marks (0–1) and cargo-size vehicle cap + non-positive (from 7.3.16) complete the set.
156
+
157
+ ### Fixed
158
+ - **Twin chromatin-mark fields no longer mangle a typed negative** (`"-5"` had become `"05"`). The value was
159
+ coerced with `parseFloat || 0` on every keystroke, collapsing a lone leading `-` to `0`. The fields now hold
160
+ the raw string while editing (coerced to a number only at predict time) and drop the native `min`/`max`, so an
161
+ out-of-range value, including a negative, can be entered and is flagged rather than silently blocked.
162
+ Free-text NL fields (co-scientist chat, WriteSpec brief), amino-acid / SMILES fields (capsid, oracles), and the
163
+ free-form model-feature fields are intentionally left unconstrained, since client-side validation would false-warn.
164
+
165
+ ## [7.3.16] - 2026-07-10 - Stage-H: vehicle-aware cargo hint, OOD-widen scope, input range warnings
166
+
167
+ ### Fixed
168
+ - **The "Cargo size (bp)" hint reflects the selected delivery vehicle.** It was hardcoded to "AAV single-vector
169
+ payload caps near ~4.7 kb" for every vehicle; it now reflects the selected vehicle's real capacity (AAV dual
170
+ ~9 kb, lentivirus ~8 kb, LNP ~15 kb, HDAd ~35 kb, HSV ~100 kb, electroporation = no packaging limit), sourced
171
+ from a `VEHICLE_CAP_BP` map mirroring `configs/delivery_vehicles.yaml`, with an inline over-capacity warning when
172
+ the entered cargo exceeds the cap.
173
+ - **The Stage-H "OOD widen" factor and its presentation.** The factor reads near its ×3 ceiling for most realistic
174
+ chromatin input. It is genuinely computed (near-zero input ≈ ×1, mid-range ≈ ×2.4–×2.8, cap ×3), but the
175
+ position-effect head was trained on normalized exact-site features, so typical 0–1 histone values at the app's
176
+ coarse 1 kb resolution sit outside that distribution and the widen flags them as out-of-distribution (near the
177
+ cap). The stat caption, the not-outcome-validated banner, and the scores panel now explain that a high widen at
178
+ this resolution is the signal working, the same cause as `outcome_validated: false`, rather than a fixed value.
179
+
180
+ ### Added
181
+ - **Range warnings on out-of-domain inputs.** The five chromatin marks are documented normalized signal in [0,1];
182
+ the fields previously accepted e.g. -5 and fed it to the model unflagged. They are now bordered and warned when
183
+ outside 0–1 (value kept, not clamped, so the OOD signal still reflects it). A non-positive cargo size is flagged
184
+ (`feasibility.buildable=False` + `cargo_size_nonpositive` scope flag) instead of reading as buildable.
185
+ - **A promoter/cell-type note.** Selecting a tissue-specific promoter (e.g. TBG = liver) surfaces that the
186
+ mechanistic estimate is cell-type-agnostic and applies the same strength regardless of tissue match, so a
187
+ maximally-optimistic score for a biologically inappropriate promoter/cell-type pairing is not misread.
188
+
189
+ ## [7.3.15] - 2026-07-09 - Health check surfaces writability-atlas presence (deploy-mount visibility)
190
+
191
+ ### Fixed
192
+ - **`/api/health` reports whether the per-cell-type writability atlases are present,** not just the bundled
193
+ writer atlas. A deploy that drops the runtime `-v ~/data/out:/work/data/out` mount leaves the container with no
194
+ per-cell-type atlas parquets, so Site Finder returns `atlas_<ct>.parquet not found` and the cell-type dropdown
195
+ shows "no atlas" for every cell type (including the measured K562/HepG2/HSPC), yet `/api/health` stayed green
196
+ because `atlas_present` checks only the bundled writer atlas. Health now includes `writability_atlas:
197
+ {measured_count, measured, ok}`; `measured_count == 0` makes a dropped-mount deploy immediately visible.
198
+
199
+ ## [7.3.14] - 2026-07-09 - Digital Twin: surface the Stage-H model's OWN OOD signal + disambiguate the two OOD checks
200
+
201
+ ### Fixed
202
+ - **The Twin page's top-level "OOD" flag is disambiguated from the Stage-H model's own OOD signal.** The
203
+ top-level flag is bound to the **virtual-cell response oracle's** scope card (its list of in-distribution cell
204
+ types and perturbation kinds), and every cell type the dropdown offers is on that list, so it reads "no" through
205
+ this UI by construction, not a broken gate. The Stage-H **position-effect** model has its own separate
206
+ out-of-distribution signal (`ood_widen`, a Mahalanobis distance over the 5 supplied chromatin marks) that the
207
+ API returned but the UI never surfaced (×2.09 at typical marks, saturating at ×3.0 for marks pushed to 10–100).
208
+ Changes:
209
+ - The Stage-H card shows an **"OOD widen (this head)"** stat (×1 typical → ×3 cap), colour-graded, so the
210
+ position-effect model's own OOD signal is visible and moves with the chromatin context.
211
+ - The top-level stat is relabelled **"OOD (response model)"** with an inline note that it is the response
212
+ oracle's scope-card check (expected to read "no" for any dropdown cell type), a different signal from the
213
+ Stage-H widen factor.
214
+ - The "How to read these scores" panel documents both OOD checks separately.
215
+ - A regression test locks in that `position_effect.ood_widen` widens for out-of-range chromatin marks.
216
+
217
+ ## [7.3.13] - 2026-07-09 - Guardian: FASTA-header robustness fix + Design Studio Proof detail parity
218
+
219
+ ### Fixed
220
+ - **A sequence pasted straight from a database (a `>accession description` FASTA header plus wrapped sequence
221
+ lines) is now screened correctly.** `_looks_like_nucleotide()` ran on the raw pasted text, header included; the
222
+ header's non-nucleotide characters diluted the nucleotide fraction below the classification threshold, so the
223
+ header+sequence blob was misclassified as protein and scanned as one string, with no 6-frame translation. The
224
+ screen now strips FASTA/GenBank header lines (`>`, `;`) and whitespace before the nucleotide-vs-protein decision
225
+ (`_strip_headers_and_whitespace`) and cleans stray non-amino-acid characters in the protein branch. A
226
+ FASTA-formatted toxin sequence that previously returned zero hits now refuses.
227
+ - **Design Studio's Proof object (`/api/verify/proof`) carries the full hazard detail.** A hazard hit was reduced
228
+ to a bare `{signature, kind, severity}` with no reason, citation, or (for a sequence-domain hit) the Pfam
229
+ accession/bit score that Guardian's `/api/safety` view already showed. `_biosecurity_axis()` now carries `reason`
230
+ (the matched signature name), `citation` (the control-list reference), and `pfam_accession`/`bit_score` when the
231
+ hit came from the sequence screen; the Proof panel renders them as Guardian's hit list does.
232
+
233
+ ## [7.3.12] - 2026-07-09 - Guardian: local Pfam/HMMER sequence-domain screen (the Cargo sequence box is now screened)
234
+
235
+ ### Added
236
+ - **A raw Cargo sequence (DNA/RNA/protein) is screened for the curated toxin families, not only a declared
237
+ Cargo function.** `sequence_homology()` was previously a no-op in this deployment (its `external_hook` was an
238
+ unwired extension point). `HazardRegistry` now has a `.default()` registry that wires
239
+ `pen_stack/safety/pfam_scan.py` as that hook: a cargo sequence is 6-frame-translated (DNA/RNA) or scanned
240
+ directly (protein) against bundled public Pfam profile HMMs for the same 17 accessions already in
241
+ `configs/safety/hazard_registry.yaml` (ricin/RIP, botulinum, diphtheria, anthrax, cholera, staph/strep
242
+ enterotoxin, conotoxin), using each profile's Pfam gathering (GA) cutoff, the threshold Pfam's own annotation
243
+ pipeline uses to call a family match. No hazard sequences are bundled: profile HMMs are public statistical
244
+ models built from many aligned sequences, not any one organism's sequence, consistent with the registry's
245
+ existing no-hazard-sequences policy. The screen reaches every entry point unchanged (`/api/safety`,
246
+ `/api/verify`, `/api/generate`, the Co-Scientist chat's design lane), since all funnel through `screen_design()`
247
+ → the default registry: a sequence for a curated family refuses with no cargo_function declared, while benign
248
+ cargo (a GFP CDS fragment, a Factor IX fragment) stays clear. Scope: this covers the curated family list only
249
+ and is not a substitute for a full external homology screener (IBBIS Common Mechanism / SecureDNA) over a larger
250
+ reference set; an integrator can override via `HazardRegistry.load(external_hook=...)`.
251
+ - `provenance.declared_signal` (v7.3.11) now counts a submitted `cargo_seq`/`cargo_sequence` as signal, since it
252
+ is genuinely screened.
253
+
254
+ ## [7.3.11] - 2026-07-09 - Guardian: distinguish an empty submission from a screened-clear result + Cargo function autofill fix
255
+
256
+ ### Fixed
257
+ - **An empty Guardian submission is distinguished from a screened benign design.** With no cargo function, domain
258
+ tag, or taxon declared, `safety_gate` has no signal and correctly decides `clear`, but the badge and reason
259
+ ("no hazard signal") were indistinguishable from a benign design ("human factor IX") that was actually checked.
260
+ `SafetyVerdict.provenance` now carries `declared_signal` (whether anything screenable was submitted); the reason
261
+ text reads "nothing was screened" when it is `False`, and the Guardian page renders a caveat: *"Nothing was
262
+ screened. 'Clear' here means there was no input to check, not a verified-safe result."*
263
+ - **Cargo function field text duplication.** The field had no `autoComplete` attribute, leaving it open to the
264
+ browser's autofill/suggestion heuristics interfering with a controlled input. `autoComplete="off"` is set on the
265
+ Cargo function and Gene/target inputs and the Cargo sequence textarea (the app's React state is the single source
266
+ of truth for these fields).
267
+
268
+ ## [7.3.10] - 2026-07-08 - Stage H: promoter selector + cargo-capacity feasibility + mechanistic/learned transparency; multiplex verify fix
269
+
270
+ ### Fixed
271
+ - **The multiplex plan (v7.3.9) now triggers its rule.** A multi-edit plan was sent with the original
272
+ `write_type` (e.g. `insertion`), whose rule categories exclude `multiplex`, so `multiplex.translocation_risk`
273
+ never ran (empty `soft_flags`). The plan now routes as `write_type="multiplex"`, so the translocation screen
274
+ fires (two DSB nucleases on different chromosomes → risk 0.64 flag; a DSB-free plan → ~zero).
275
+ - **The Digital Twin's top-level "Relative expression" reflects promoter and vehicle changes; its
276
+ cell-type-agnostic, per-copy basis is now explicit.** The mechanistic estimate is
277
+ `promoter × copy-number × accessibility × pre-existing-NAb`, with accessibility neutral (no cell-type chromatin
278
+ track mounted), **cell-type-agnostic** (the cell-type position effect is the learned Stage-H head) and
279
+ **per-copy** (independent of cargo size), so it did not move with cell type or cargo size. The page now (a)
280
+ exposes the **31-promoter palette** as a selector, a live lever the estimate reacts to (`GET /twin/promoters`,
281
+ `design.promoter`); (b) surfaces the **learned head's cell-type-aware relative expression** next to the
282
+ mechanistic headline, so a cell-type change is visible; (c) flags **cargo-over-capacity** as not-buildable
283
+ (`feasibility` in `/predict`); (d) states the mechanistic basis inline.
284
+
285
+ ## [7.3.9] - 2026-07-08 - Design Studio: multiplex-plan UI + advisory (soft-penalty) flags surfaced
286
+
287
+ ### Added
288
+ - **A "Plan multiple simultaneous edits" section on Design Studio** builds a 2–5-edit plan (chromosome / position /
289
+ writer-family rows) and sends it as `design.edits`, making the `multiplex.translocation_risk` legality rule
290
+ (implemented and rule-spec-published since v3.1, but with no UI path to `design.edits`) reachable. The default
291
+ two-row example matches the rule's own test fixture (two DSB nucleases on different chromosomes) and reproduces a
292
+ "flag" on first Verify.
293
+ - **Advisory (soft-penalty) flags are rendered on the Verify result.** `Verdict.soft_flags` was always computed
294
+ (multiplex translocation risk, AAV packaging margin, delivery sequence constraints, fold cross-loop
295
+ complementarity) but never rendered, since soft penalties do not fail legality and the Proof object's legality
296
+ axis never carried them. A new "Advisory flags" panel shows the rule id, reason, and value for any soft-penalty
297
+ rule that fires, labelled non-blocking.
298
+
299
+ ## [7.3.8] - 2026-07-08 - Stage F: not_evaluated state under biosecurity refuse + standards concordance surfaced
300
+
301
+ ### Fixed
302
+ - **The legality and confidence proof axes no longer report a verdict when biosecurity refuses a design.**
303
+ `verify.service.verify()` short-circuits on a biosecurity refuse and returns *before* the rules engine or
304
+ confidence calibration run (`legal=None`, `violations=[]`), a security-first fail-fast posture. `verify_proof()`'s
305
+ legality axis previously read that state as `status="fail"` with an empty violated list and no repair hint, and
306
+ the confidence axis read it as `status="abstain"` with a repair hint suggesting "supply the soft per-axis scores
307
+ to calibrate", which would not help. Both axes now report **`status="not_evaluated"`**, `ok=True` (an
308
+ unevaluated axis does not itself block; biosecurity already blocks `passable`), with an explanatory,
309
+ non-actionable repair hint. A genuine legality failure with no biosecurity hazard is unaffected (regression-tested).
310
+
311
+ ### Added
312
+ - **Standards concordance (v6.12) is reachable via REST and rendered on the Guardian page.**
313
+ `concordance_report()` and `align_to_common_mechanism()` were implemented and unit-tested since v6.12 but had no
314
+ API endpoint or UI surface. `GET /safety/concordance` serves the labelled-probe-set report (8/8 concordant);
315
+ `POST /safety` additively carries a per-decision `standards` field (Common Mechanism ScreenStatus + SecureDNA
316
+ outcome), leaving the underlying decision unchanged. Guardian.jsx renders the per-screen standards alignment and
317
+ a concordance-benchmark card.
318
+
319
+ ## [7.3.7] - 2026-07-08 - Writer immunogenicity: surface the human self control so the ADA foreignness term is visible
320
+
321
+ ### Added
322
+ - **The Writer Atlas immunogenicity table surfaces the human self control (albumin) as a labelled reference
323
+ row.** Every genome writer is foreign (foreignness = 1), so the shipped rows could not show that
324
+ `ada_risk = MHC-II density × foreignness(origin)` is multiplicative, the numbers were indistinguishable from
325
+ `ada_risk = MHC-II load`. The self control (origin = self → foreignness 0) has a non-zero MHC-II density (0.32)
326
+ yet ADA-risk 0, so ADA decouples from the load: the row demonstrates that the foreignness term does real work
327
+ (central tolerance). `writer_immunogenicity_table()` appends it with `is_control: True`; the UI highlights it and
328
+ explains the decoupling; a test asserts control ada_risk 0 versus foreign writers ada_risk > 0.
329
+
330
+ ## [7.3.6] - 2026-07-08 - Design Studio: immune-risk profile no longer shows stale numbers when the main vehicle changes
331
+
332
+ ### Fixed
333
+ - **The Immune-risk profile card no longer desyncs from the main form's Delivery vehicle.** Changing the main-form
334
+ vehicle dropdown moved the profile card's highlighted vehicle chip (it tracked `design.delivery_vehicle`) while
335
+ the axis numbers stayed on the previously-profiled vehicle, so AAV numbers could be read as if they were LNP's.
336
+ The chip highlight now tracks the vehicle the profile was actually **computed for** (`immVehicle`), so chip and
337
+ numbers agree, and a banner appears when the main-form vehicle diverges ("These axes are for X … click its chip
338
+ or press Profile again to recompute for Y").
339
+
340
+ ## [7.3.5] - 2026-07-08 - Off-Target auto-scroll hotfix (instant, not smooth)
341
+
342
+ ### Fixed
343
+ - **The v7.3.4 auto-scroll-to-result now moves the viewport.** `scrollIntoView({behavior:"smooth"})` no-ops on
344
+ this app's scroll container; dropping `behavior:"smooth"` makes the Off-Target result reliably scroll into view
345
+ on the first click.
346
+
347
+ ## [7.3.4] - 2026-07-08 - Off-Target page: scroll the result into view + guard rapid writer-class switches
348
+
349
+ ### Fixed
350
+ - **The Off-Target finder result scrolls into view when it renders.** The page was the only finder missing the
351
+ shared auto-scroll-to-result pattern, so a result rendered below the tall explainer cards read as "no visible
352
+ output" on the first click. Adds a `resultsRef` and a `scrollIntoView` effect on busy/result/error, matching
353
+ Site Finder / Write Spec / Writer Atlas.
354
+ - **A slow previous-writer-class response can no longer clobber the current one.** `run()` tags each request and
355
+ only the latest may write `res`/`error`/`busy` (a request-id guard), so switching writer class and clicking in
356
+ quick succession renders the current selection's result.
357
+
358
+ ## [7.3.3] - 2026-07-07 - Off-Target page copy: reflect SITE-seq, the chromatin annotation, and Cas12a in the on-page description and score guide
359
+
360
+ ### Changed
361
+ - **Off-Target page `WhatYouGet` / `ScoreGuide` copy now documents the v7.3.1 capabilities** that were shipped in
362
+ the mechanics but not the descriptions: SITE-seq is named as the fourth grounding/confirming assay; the chromatin
363
+ accessibility annotation is described (validated, HEK293T DNase GUIDE-seq AUROC 0.671, annotation-only, not a
364
+ re-ranker); and Cas12a is noted as enumeration-supported but SpCas9-scorer-scoped (the finder abstains rather than
365
+ mis-scoring). No behavior change, copy only.
366
+
367
+ ## [7.3.2] - 2026-07-07 - Digital Twin: surface the learned Stage-H position-effect head (served model + resolution-aware validation state)
368
+
369
+ ### Added
370
+ - **Stage-H position-effect head surfaced on the Digital Twin page (`Twin.jsx`).** When a chromatin context is
371
+ supplied, the page shows which learned head served (human K562, Leemans 2019 / mESC TRIP), the served feature
372
+ resolution, and the `outcome_validated` flag, plus the learned log2-expression, its conformal interval and
373
+ p(silenced). An optional chromatin-context input (the head's five histone marks) enables the learned head from the
374
+ page. The human K562 head's validated regime (ρ≈0.57 at exact-site per-locus features) is distinguished from the
375
+ app's coarse 1 kb serving resolution, at which the head serves with `outcome_validated: false`.
376
+ - The `stage_h_mode` (learned vs heuristic) is shown as a pill on the predicted-outcome card.
377
+ - The human K562 position-effect head (`models/position_effect_human_k562.pkl`, Leemans 2019) and the mESC head
378
+ (`models/position_effect.pkl`) are staged into the served image so the v7.3.0 head loads at serve time (it was
379
+ wired in v7.3.0 but its artifact was not mounted); the artifacts are re-serialized in the serving image
380
+ (scikit-learn 1.9.0).
381
+
382
+ ### Changed
383
+ - The Digital Twin `WhatYouGet` / `ScoreGuide` copy documents the learned Stage-H head and the exact-site vs coarse
384
+ 1 kb resolution distinction.
385
+
386
+ ## [7.3.1] - 2026-07-07 - Off-Target finder: SITE-seq in the assay recommender, chromatin-annotation surfacing, and Cas12a scoping
387
+
388
+ ### Added
389
+ - **SITE-seq in the nuclease validation-assay recommender.** `offtarget_assay.recommend_assay` now lists SITE-seq
390
+ (Cameron et al., Nat Methods 2017; DOI 10.1038/nmeth.4284) alongside GUIDE-/CHANGE-/CIRCLE-seq, completing the
391
+ four unbiased assays the mismatch-calibrated risk band is grounded on.
392
+ - **Cas12a in the Off-Target finder writer-class selector (AsCas12a).** Genome-wide enumeration supports the Cas12a
393
+ TTTV 5' PAM, but the validated CRISOT-Score and the mismatch-calibrated risk band are SpCas9-specific; the finder
394
+ therefore reports that a validated Cas12a off-target scorer is not available rather than scoring Cas12a sites with
395
+ the SpCas9 model.
396
+ - **Chromatin-accessibility annotation surfaced on the nuclease finder result**: its standalone validation
397
+ (cell-type-matched HEK293T DNase; GUIDE-seq AUROC 0.671) plus a per-site accessibility column when the Stage B
398
+ accessibility track is mounted.
399
+
400
+ ### Changed
401
+ - **The nuclease off-target `method` string and the `nominate_offtargets` capability manifest now describe the
402
+ chromatin layer precisely**, a validated annotation surfaced when the Stage B track is mounted (annotation-only,
403
+ not a re-ranker), instead of describing it unconditionally.
404
+
405
+ ### Fixed
406
+ - **The nuclease finder no longer returns a chromatin field with no context when the Stage B accessibility track is
407
+ absent.** The result now carries `chromatin_available` and a note stating the annotation is track-gated and the
408
+ CRISOT-driven ranking is unaffected, in place of a silent null.
409
+
410
+ ## [7.3.0] - 2026-07-04 - PEN-EXPRESS-HUMAN: a cell-type-matched Stage-H position-effect head for human K562 (Leemans 2019), replacing the non-transferring cross-species axis; served claim is resolution-aware
411
+
412
+ ### Added
413
+ - **Human K562 position-effect head behind Stage H.** `twin.data.position_effect` now wires the **Leemans 2019**
414
+ human K562 dataset (Cell; PMID 30982597; DOI 10.1016/j.cell.2019.03.009) with a real loader (`_load_leemans`),
415
+ per-barcode coordinates fetched from the Cell supplement Dataset S2 joined to the van Steensel feature set.
416
+ `twin.position_effect.load_human_k562_model` + cell-type routing in `predict_stage_h` serve a `PositionEffectModel`
417
+ trained on human K562 for human K562 designs, falling back to the mESC model otherwise.
418
+ - Held-out validation (chromosome-blocked 5-fold OOF; n=9,298; 5 shared histone marks): expression Spearman
419
+ **ρ ≈ 0.59**, split-conformal held-out coverage **0.90** (nominal 0.90, within tolerance). This beats the mESC
420
+ model applied cross-species, which is an honest null on human K562 (held-out ρ ≈ 0.13, does not beat the
421
+ lamina/heterochromatin baseline ρ ≈ 0.39), and the trivial "avoid heterochromatin" baseline.
422
+
423
+ ### Changed
424
+ - **The v6.7 cross-cell-type transfer axis is no longer data-gated.** With a human cell type now fetched, a human
425
+ K562 design's Stage-H provenance/scope reflect **human K562 supervision** instead of "single_context_supervision
426
+ (mESC), cross-cell-type transfer data-gated". `predict_stage_h` gains a `cell_type` argument (default `None`;
427
+ backward compatible; `twin.outcome` passes the cell state through).
428
+
429
+ ### Serve-time honesty, resolution-aware `outcome_validated` scope
430
+ - The head's held-out validation (ρ ≈ 0.57 / +0.065 over a learned-heterochromatin baseline, CI [0.026, 0.103])
431
+ holds at **exact-site per-integration** chromatin-feature resolution. On coarse 1 kb-binned features even a
432
+ human-trained model realizes only **ρ ≈ 0.16** (P2_MATCHED_TRANSFER). `predict_stage_h` therefore stamps the
433
+ `human_K562_outcome_validated` scope **only when the caller declares exact-site features** (`feature_resolution`
434
+ / `chromatin_features_resolution`, or `chromatin_ctx.resolution` ∈ exact-site set). Otherwise, including
435
+ undeclared resolution (conservative default), it returns `outcome_validated: False` and a downgraded flag
436
+ (`human_K562_head_served_UNVALIDATED_RESOLUTION …`) naming both numbers and the requirement. The prediction is
437
+ still served; only the validation claim is withheld until the served resolution matches the validated regime.
438
+ The output gains `served_feature_resolution` and `outcome_validated` fields.
439
+ - **Deferred to v7.4:** exact-site chromatin-feature extraction *at serve time* (point-query ChIP for an arbitrary
440
+ locus), so the served path realizes the validated ρ ≈ 0.57 directly and auto-earns the `outcome_validated` scope.
441
+
442
+ ### Notes (honest scope)
443
+ - The cassette factorization (`f_cassette + g_context`) adds no value on Leemans' 6 similar promoters (factored
444
+ ρ 0.588 vs context-only ρ 0.592); additive suffices, reported not hidden. The served silenced (escaper/repressed)
445
+ call is promoter-driven, not a position signal. The head's validated output is steady-state **position-effect
446
+ expression in K562**, not temporal durability or other cell types.
447
+ - **Cross-species transfer is poor** (matched-source mouse↔human ρ ~0.08–0.20; P2_MATCHED_TRANSFER). The axis is
448
+ cell-type-specific; train a head per target cell type. An earlier draft over-read a feature-source-confounded
449
+ ρ 0.505 as transfer; corrected.
450
+ - The model artifact + Leemans parquet are deployment data (git-ignored under `data/`/`models/`, per the data
451
+ policy), not shipped in the wheel. Absent them, the human loader returns `None` and Stage H is unchanged.
452
+
6
453
  ## [7.2.3] - 2026-07-02 - Off-Target: professional wording (self-contained, no external-tool comparisons) + a plain-language explainer
7
454
 
8
455
  ### Changed
9
456
  - **Removed all external-tool comparisons** ("like CRISPOR / CHOPCHOP", "CRISPOR-class", "CRISPOR-comparable") from
10
- every off-target surface the Off-Target page, nav, code docstrings, REST docstring, the data card, `positioning.md`,
457
+ every off-target surface, the Off-Target page, nav, code docstrings, REST docstring, the data card, `positioning.md`,
11
458
  the prereg (re-SHA-locked), paper-4 prereg, and the v7.2.0 CHANGELOG entry. The capability is now described on its
12
- own terms: a genome-wide off-target *finder* given a guide/target it enumerates and ranks the off-target sites
459
+ own terms: a genome-wide off-target *finder*. Given a guide/target, it enumerates and ranks the off-target sites
13
460
  itself. No functional change.
14
461
  - **Off-Target page now explains off-target effects in plain language**: a new top card covers *what an off-target
15
462
  effect is*, *what you enter* (per writer class), and *what you get back* (ranked genome-wide sites with
@@ -19,25 +466,25 @@ All notable changes to PEN-STACK are documented here. This file follows
19
466
 
20
467
  ## [7.2.2] - 2026-07-02 - Integrase: precise capability framing (the negative is about a method, not the biology)
21
468
 
22
- A framing/presentation refinement of the v7.2.1 sealed-negative result no science changes, the number is
469
+ A framing/presentation refinement of the v7.2.1 sealed-negative result: no science changes; the number is
23
470
  unchanged and the negative stands.
24
471
 
25
472
  ### Changed
26
473
  - **Precise claim, everywhere:** what the sealed PhiC31 benchmark showed is that a specific *method* (attP
27
- sequence-similarity scanning) is insufficient **NOT** that pseudosites are unpredictable. The signal is real
474
+ sequence-similarity scanning) is insufficient, **NOT** that pseudosites are unpredictable. The signal is real
28
475
  (Chalberg's palindromic consensus; IntQuery's success on 410,776 cryptic attB), just not capturable by simple
29
476
  identity. So the honest, narrow claim is "sequence similarity is insufficient," and this negative is the
30
477
  empirical justification for a learned/DMS model (the indicated next step). Sharpened in `offtarget_integrase.py`,
31
478
  `phic31_recall_metrics.json`, and the data card so nothing reads as "unpredictable."
32
479
  - **App presentation:** `nominate_integrase` now returns a `capability` disclosure (badge + plain microcopy). The
33
480
  Off-Target page shows a badge reading **"mechanism-based · not predictive by sequence alone"** (not a bare red
34
- flag) plus one line *"φC31 pseudosite activity is sequence-guided but not predictable from similarity alone
35
- (sealed benchmark, negative); confirm empirically"* separating the grounded facts (verified att + documented
481
+ flag) plus one line, *"φC31 pseudosite activity is sequence-guided but not predictable from similarity alone
482
+ (sealed benchmark, negative); confirm empirically"*, separating the grounded facts (verified att + documented
36
483
  pseudo-attP with GenBank accessions) from the honest capability limit. A trust-building disclosure, not an alarm.
37
484
 
38
485
  ## [7.2.1] - 2026-07-02 - PhiC31 integrase: close the O-WS3/O-G2 data gap with verified data + a sealed recall benchmark (honest NEGATIVE)
39
486
 
40
- Closes the one genuine open item from v7.2.0 the PhiC31 integrase data gap with independently-verified,
487
+ Closes the one genuine open item from v7.2.0, the PhiC31 integrase data gap, with independently-verified,
41
488
  open, citable sequences (no fabrication) and a **sealed recall benchmark whose result is reported verbatim**.
42
489
 
43
490
  ### Added
@@ -49,16 +496,16 @@ open, citable sequences (no fabrication) and a **sealed recall benchmark whose r
49
496
  DOI `10.1128/MCB.21.12.3926-3934.2001`; chr8/16/15). Corrected DOIs: Groth 2000 `10.1073/pnas.090527097`,
50
497
  Chalberg 2006 `10.1016/j.jmb.2005.11.098` (was `...11.108`).
51
498
  - **Sealed PhiC31 pseudo-attP recall benchmark** (`benchmarks/offtarget/integrase/`, O-G2): does attP-sequence-
52
- similarity recover the documented pseudo-attP above length-matched GRCh38 background? **Result NEGATIVE,
499
+ similarity recover the documented pseudo-attP above length-matched GRCh38 background? **Result: NEGATIVE,
53
500
  reported verbatim:** all three sites score 14 mm / 30 bp (53.3% identity), exactly the background **median**
54
501
  (60.6% / 77.0% / 82.4% of random windows are as-or-more attP-similar). Sequence identity to attP is **not** a
55
- validated PhiC31 pseudo-attP predictor φC31 recognition depends on palindromic architecture (Chalberg 2006) /
502
+ validated PhiC31 pseudo-attP predictor; φC31 recognition depends on palindromic architecture (Chalberg 2006) /
56
503
  a learned model (IntQuery), not raw identity.
57
504
 
58
505
  ### Changed
59
506
  - **Integrase status corrected: `semi_validated` → `mechanism_based_unvalidated` (with a sealed-NEGATIVE benchmark).**
60
507
  The v7.2.0 "semi-validated (documented pseudosites as partial ground truth)" implied the sites validated the
61
- method; the sealed benchmark shows they do not. This is a *stronger, more honest* outcome a tested negative
508
+ method; the sealed benchmark shows they do not. This is a *stronger, more honest* outcome, a tested negative
62
509
  rather than an untested claim. The verified att + documented pseudosites remain grounded facts and are surfaced
63
510
  as verified known off-target loci. `nominate_integrase` PhiC31 returns the documented pseudo-attP + the sealed
64
511
  benchmark; Bxb1 returns genome-wide similarity candidates carrying the same `similarity_ranking_validated: false`
@@ -67,33 +514,33 @@ open, citable sequences (no fabrication) and a **sealed recall benchmark whose r
67
514
 
68
515
  ## [7.2.0] - 2026-07-01 - PEN-OFFTGT v2: Stage E becomes a genome-wide, per-mechanism off-target FINDER (all 5 writer classes)
69
516
 
70
- Stage E was a candidate *scorer* it ranked off-target sites you supplied. An off-target *finder* instead takes
517
+ Stage E was a candidate *scorer*; it ranked off-target sites you supplied. An off-target *finder* instead takes
71
518
  a guide/target and enumerates the genome-wide off-target sites itself. PEN-OFFTGT v2 closes that enumeration gap
72
519
  AND applies the **correct off-target mechanism for each writer class**, each carrying a truthful per-mechanism
73
520
  validation status (O-WS0–O-WS9 of the plan).
74
521
 
75
522
  ### Per-mechanism paths (O-WS3–O-WS6)
76
- - **Serine integrase** (`offtarget_integrase.py`, O-WS3): a genome-wide **pseudo-attP** scan a fixed-sequence
523
+ - **Serine integrase** (`offtarget_integrase.py`, O-WS3): a genome-wide **pseudo-attP** scan, a fixed-sequence
77
524
  Cas-OFFinder scan of the attP core window over GRCh38, scored by att-arm similarity. **Bxb1** is fully encoded
78
525
  (FlyBase FBto0000359 / Ghosh 2003) and is highly specific. Status **semi-validated**. **PhiC31 is a disclosed
79
- data gap** (its documented human pseudo-attP set Chalberg 2006 could not be verified from an open source in
526
+ data gap** (its documented human pseudo-attP set, Chalberg 2006, could not be verified from an open source in
80
527
  this build, so it abstains rather than fabricate). `data/curated/integrase_att.yaml`.
81
528
  - **Bridge** (`offtarget_bridge.py`, O-WS4): wraps the existing DMS-scored genome scan (measured Perry-2025
82
- specificity, held-out ranking AUROC 0.88). Status **hard-locked mechanism-based-unvalidated** the ranker is
529
+ specificity, held-out ranking AUROC 0.88). Status **hard-locked mechanism-based-unvalidated**; the ranker is
83
530
  DMS-validated but **no genome-wide cellular off-target assay exists** for bridge recombinases, so genomic
84
531
  recovery is unvalidated (stated in a no-ground-truth disclosure).
85
- - **CAST** (`offtarget_cast.py` + `data/curated/cast_systems.yaml`, O-WS5) NEW: guide-directed spacer scan +
532
+ - **CAST** (`offtarget_cast.py` + `data/curated/cast_systems.yaml`, O-WS5), NEW: guide-directed spacer scan +
86
533
  the distinctive **guide-independent untargeted-transposition** background per system (ShCAST/Type V-K high +
87
534
  AT-biased; VchCAST/Type I-F >95–99% on-target), all DOI-tagged. Status **mechanism-based-unvalidated**.
88
- - **PASTE / (ee)PASSIGE** (`offtarget_paste.py`, O-WS6) NEW: composes the validated nuclease finder (Cas9
535
+ - **PASTE / (ee)PASSIGE** (`offtarget_paste.py`, O-WS6), NEW: composes the validated nuclease finder (Cas9
89
536
  nickase, pegRNA) with the semi-validated integrase pseudo-attP scan (installed att); returns both component sets
90
537
  and recommends BOTH a nuclease assay and an integrase assay. Status **composite**.
91
538
 
92
539
  ### Status labels + assay recommender (O-WS7) + disclosures (O-WS8 / gate O-G3)
93
540
  - Every nomination carries a per-mechanism status label + the mechanism-appropriate confirm assay; `recommend_assay`
94
541
  now covers CAST (transposon insertion-site seq) and PASTE (dual). `docs/cards/offtarget_data.md` documents the
95
- per-mechanism ground-truth status **O-G3: every mechanism has either a sealed benchmark (nuclease) or an
96
- explicit no-ground-truth / data-gap disclosure (integrase-PhiC31, bridge, CAST) never a fabricated metric.**
542
+ per-mechanism ground-truth status, **O-G3: every mechanism has either a sealed benchmark (nuclease) or an
543
+ explicit no-ground-truth / data-gap disclosure (integrase-PhiC31, bridge, CAST), never a fabricated metric.**
97
544
  - Disclosed deviations from the plan (no silent substitution): `att_pwm.json` → an att-similarity model in
98
545
  `integrase_att.yaml` (a per-position PWM needs aligned pseudosites that do not exist at genome scale);
99
546
  `bridge_dms_specificity.parquet` → the existing measured `bridge_offtarget_profile_measured.parquet` is reused;
@@ -108,11 +555,11 @@ validation status (O-WS0–O-WS9 of the plan).
108
555
  mismatch count. Supports SpCas9 (NGG), SaCas9 (NNGRRT), and Cas12a (TTTV, 5' PAM). A full scan is heavy, so it
109
556
  runs **only on the VM** (`casoffinder:tools` Docker image, `docker/casoffinder.Dockerfile`); the live app
110
557
  **replays a committed coordinate cache** for the canonical guides or **abstains honestly** for a novel one
111
- (never fabricates sites) the same replay-or-abstain pattern as the heavy structure oracles. The enumerated
558
+ (never fabricates sites), the same replay-or-abstain pattern as the heavy structure oracles. The enumerated
112
559
  coordinates are facts from the public GRCh38 assembly (no license restriction), so the cache is committed
113
560
  (`data/offtarget/enumerated_cache.parquet`, 8 canonical guides, 40,268 sites).
114
561
  - **Nuclease off-target FINDER** (`pen_stack/wgenome/offtarget_nuclease.py`, O-WS2): chains enumeration into the
115
- existing, validated scorer real CRISOT-Score → mismatch-calibrated risk band → chromatin annotation so a
562
+ existing, validated scorer, real CRISOT-Score → mismatch-calibrated risk band → chromatin annotation, so a
116
563
  guide returns the genome-wide ranked off-target set *with coordinates*. Scoring is unchanged from v6.10 (still
117
564
  validated: CRISOT beats homology on four unbiased assays); v2 adds the enumeration front end.
118
565
  - **O-G1 gate PASSED**: enumeration recovers **100%** of EMX1's documented GUIDE-seq off-targets within the ≤5-mm
@@ -141,14 +588,14 @@ validation status (O-WS0–O-WS9 of the plan).
141
588
  immune & delivery" action correctly scopes to the **delivery/vehicle** axes (genotoxicity, CD8 capsid, innate,
142
589
  pre-existing NAb, anti-PEG). `ImmuneProfileCard` hides the writer axes by default (`hideWriterAxes`).
143
590
  - A new **Writer immunogenicity** card on the **Writer Atlas** surfaces each genome writer's MHC-II/CD4 epitope
144
- load + ADA risk + human self-match, read from the **committed NetMHCIIpan-4.0 cache not recomputed**
591
+ load + ADA risk + human self-match, read from the **committed NetMHCIIpan-4.0 cache, not recomputed**
145
592
  (`GET /api/writer/immune`, `immune_profile.writer_immunogenicity_table()`).
146
593
  - **SpCas9 is removed** from the writer set: it is a nuclease/editor, not a large-cargo genome writer. The Writer
147
- Atlas immunogenicity covers the actual writers **Bxb1** (serine integrase) and **ISCro4** (bridge recombinase);
594
+ Atlas immunogenicity covers the actual writers, **Bxb1** (serine integrase) and **ISCro4** (bridge recombinase);
148
595
  the Cas9 nuclease and the human self control are excluded. (The engine retains SpCas9 in its cache for other
149
596
  uses; only the user-facing writer list drops it.)
150
597
  - The engine still returns the `mhc2_writer` / `ada_writer` axes from `immune_profile()` for API/MCP callers that
151
- pass a `writer_family` only the web UI moved the writer profiling to the Writer Atlas. No data was recomputed.
598
+ pass a `writer_family`; only the web UI moved the writer profiling to the Writer Atlas. No data was recomputed.
152
599
 
153
600
  ### Added
154
601
  - `test_ws_profile.py`: `test_writer_immunogenicity_table_for_the_writer_atlas` (covers Bxb1 + ISCro4 from the
@@ -163,11 +610,11 @@ validation status (O-WS0–O-WS9 of the plan).
163
610
  grounded administration modifier (`immune_profile._administration_modifier` / `_apply_administration`):
164
611
  - **Pre-existing NAb is muted to "no barrier" (1.0) ex vivo.** Ex-vivo delivery (cells transduced in a dish and
165
612
  washed before transplant) never exposes the vector to the patient's circulating antibodies, so pre-existing
166
- anti-vector NAb does not gate eligibility the eligibility fraction is 1.0 regardless of titer. The original
613
+ anti-vector NAb does not gate eligibility; the eligibility fraction is 1.0 regardless of titer. The original
167
614
  seroprevalence value is preserved (`pre_admin_value`) and the muting is explained in the axis note. This is the
168
615
  same in-vivo/ex-vivo distinction the v5.1 `delivery_immunology` profile already encodes (`computed_ex_vivo_muted`).
169
616
  - **CD8 capsid is flagged muted ex vivo** (systemic anti-capsid response minimal), but its intrinsic presentability
170
- value is kept transduced cells can still present capsid epitopes, a real residual concern, so no number is
617
+ value is kept; transduced cells can still present capsid epitopes, a real residual concern, so no number is
171
618
  fabricated.
172
619
  - **Genotoxicity, innate, anti-PEG and the writer axes are unchanged** by administration context (insertional risk
173
620
  and cargo/writer immunogenicity are intrinsic, not a function of circulating-antibody exposure).
@@ -182,7 +629,7 @@ validation status (O-WS0–O-WS9 of the plan).
182
629
  ## [7.1.6] - 2026-06-30 - Immune axes wired end-to-end + Delivery folded into Design Studio
183
630
 
184
631
  ### Fixed
185
- - **Four immune-risk axes were unreachable from the web UI and showed as out-of-scope** innate sensing, anti-PEG,
632
+ - **Four immune-risk axes were unreachable from the web UI and showed as out-of-scope**: innate sensing, anti-PEG,
186
633
  and the writer-as-antigen MHC-II + ADA axes abstained on every web design because the design form never collected
187
634
  their inputs (the engine computed them correctly when called directly; this was a wiring gap, not a model gap):
188
635
  - **`innate`** needs a cargo sequence. The design form now has an optional **Cargo sequence** field; the cargo
@@ -216,19 +663,19 @@ validation status (O-WS0–O-WS9 of the plan).
216
663
  ### Added
217
664
  - The `chrom` design field was a free-text pass-through with no validation and no downstream effect. It is now
218
665
  meaningful (`pen_stack/planner/chromosome.py`):
219
- - **Validation** the web form's Chromosome input is a controlled dropdown (chr1–chr22, chrX, chrY, chrM), so
666
+ - **Validation**: the web form's Chromosome input is a controlled dropdown (chr1–chr22, chrX, chrY, chrM), so
220
667
  an impossible value like `chrZZZ` can no longer be entered; `canonical_chromosome()` normalises/validates on
221
668
  the backend (`chrX`/`X`/`x`, `chr1`/`1`, `chrM`/`chrMT`/`MT`, `23`→X, `24`→Y; rejects the rest).
222
- - **Gene/chromosome concordance** `verify()` now flags `chromosome_mismatch` when the entered chromosome does
669
+ - **Gene/chromosome concordance**: `verify()` now flags `chromosome_mismatch` when the entered chromosome does
223
670
  not match the named gene's canonical location (e.g. *BRCA1 is on chr17, not chr1*), `chromosome_invalid` for a
224
671
  non-standard value, and `chromosome_unverifiable` for an unknown gene. The web form shows the warning inline
225
672
  with a one-click fix, driven by the new `GET /api/gene/location` endpoint. This closes the silent-mismatch gap.
226
- - **Chromosome context** `chromosome_context()` adds grounded, chromosome-driven advisories surfaced as scope
227
- flags: **chrM** is not addressable by nuclear genome-writing tools (mtDNA needs DdCBE/TALED out of scope),
673
+ - **Chromosome context**: `chromosome_context()` adds grounded, chromosome-driven advisories surfaced as scope
674
+ flags: **chrM** is not addressable by nuclear genome-writing tools (mtDNA needs DdCBE/TALED, out of scope),
228
675
  **chrY** is male-specific with ampliconic repeats, **chrX** is hemizygous in 46,XY vs X-inactivated in 46,XX.
229
676
  - The Design Studio **cell-type dropdown now shows writability-atlas coverage** (from `/api/celltypes`): K562 /
230
677
  HepG2 / HSPC are labelled measured (full / full / partial), while h1_hesc / iPSC / CD8 T / PBMC are labelled
231
- "no atlas" so a data-gated cell type is no longer silently indistinguishable from a measured one (the same
678
+ "no atlas", so a data-gated cell type is no longer silently indistinguishable from a measured one (the same
232
679
  honest-field principle as the chromosome field). The 7 cell types are unchanged and already matched the backend.
233
680
 
234
681
  ### Note (honest scoping)
@@ -274,12 +721,12 @@ validation status (O-WS0–O-WS9 of the plan).
274
721
  receptor-binding / tropism, high severity) and `FUNC-ONCOGENIC-SUPPRESSOR` (dominant-negative TP53 / RB / PTEN,
275
722
  apoptosis-checkpoint ablation, high severity), both DURC / HHS-P3CO categories.
276
723
  - **Oncogenic-manipulation PATTERN screen** (`oncogenic_manipulation` in the registry +
277
- `HazardRegistry.oncogenic_flags`): a flat keyword list is brittle to paraphrase a red-team pass found the
724
+ `HazardRegistry.oncogenic_flags`): a flat keyword list is brittle to paraphrase; a red-team pass found the
278
725
  Guardian caught only **1/8** mechanism/synonym phrasings ("R175H p53 abolishing transactivation", "PTEN
279
726
  knockout", "RAS G12D constitutive activation", "hTERT immortalization", "APC frameshift", "EGFR
280
727
  ligand-independent activation", "NF1+BAX/BAK knockout"). The pattern screen flags the *combination*
281
728
  `(tumor-suppressor + disruptive verb)` OR `(oncogene + activating signature)` OR `immortalization`, which
282
- catches **8/8** while the deliberate asymmetry spares therapy with **no allow-list** restoring a suppressor or
729
+ catches **8/8** while the deliberate asymmetry spares therapy with **no allow-list**: restoring a suppressor or
283
730
  silencing an oncogene matches neither, so "p53 correction to restore apoptosis", "TRAC/CCR5 knockout",
284
731
  "knock-down of mutant KRAS" stay clear (**11/11** benign). Disposition is escalate (dual-use → human review).
285
732
  - **Keyword matcher hardened** (`_kw_match`): a plain substring test made the ricin abbreviation `"rip"` fire
@@ -301,7 +748,7 @@ validation status (O-WS0–O-WS9 of the plan).
301
748
  pbmc / h1_hesc / ipsc) returned an empty table, because the planner-backed `candidate_space` needs `plan_write`.
302
749
  `generate_designs` now falls back to `space.vehicle_sweep(goal)`: it sweeps the capacity-compatible vehicles,
303
750
  carries `cargo_function` (the Guardian still screens), runs full legality + biosecurity discrimination, and
304
- ABSTAINS on the calibrated confidence (no fabricated band) surfaced as "abstained, no measured atlas for this
751
+ ABSTAINS on the calibrated confidence (no fabricated band), surfaced as "abstained, no measured atlas for this
305
752
  cell type". `candidate_space` still returns `[]` without the atlas; `generate_designs(candidates=[])` still
306
753
  returns `[]`.
307
754
  - **Designer (administration context):** the vehicle sweep now filters by the goal's `in_vivo` flag using the