pen-stack 7.1.4__tar.gz → 7.1.6__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 (567) hide show
  1. {pen_stack-7.1.4 → pen_stack-7.1.6}/CHANGELOG.md +59 -0
  2. {pen_stack-7.1.4 → pen_stack-7.1.6}/CITATION.cff +2 -2
  3. {pen_stack-7.1.4 → pen_stack-7.1.6}/PKG-INFO +1 -1
  4. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/__init__.py +1 -1
  5. pen_stack-7.1.6/pen_stack/planner/chromosome.py +106 -0
  6. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/planner/immune_profile.py +33 -1
  7. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/server/api.py +17 -0
  8. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/verify/service.py +12 -0
  9. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack.egg-info/PKG-INFO +1 -1
  10. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack.egg-info/SOURCES.txt +1 -0
  11. {pen_stack-7.1.4 → pen_stack-7.1.6}/pyproject.toml +1 -1
  12. {pen_stack-7.1.4 → pen_stack-7.1.6}/LICENSE +0 -0
  13. {pen_stack-7.1.4 → pen_stack-7.1.6}/MANIFEST.in +0 -0
  14. {pen_stack-7.1.4 → pen_stack-7.1.6}/README.md +0 -0
  15. {pen_stack-7.1.4 → pen_stack-7.1.6}/bench/run.py +0 -0
  16. {pen_stack-7.1.4 → pen_stack-7.1.6}/benchmarks/chat_grounding/README.md +0 -0
  17. {pen_stack-7.1.4 → pen_stack-7.1.6}/benchmarks/chat_grounding/SHA256SUMS +0 -0
  18. {pen_stack-7.1.4 → pen_stack-7.1.6}/benchmarks/chat_headtohead/README.md +0 -0
  19. {pen_stack-7.1.4 → pen_stack-7.1.6}/benchmarks/chat_routing/README.md +0 -0
  20. {pen_stack-7.1.4 → pen_stack-7.1.6}/benchmarks/chat_routing/SHA256SUMS +0 -0
  21. {pen_stack-7.1.4 → pen_stack-7.1.6}/benchmarks/chat_safety/README.md +0 -0
  22. {pen_stack-7.1.4 → pen_stack-7.1.6}/benchmarks/chat_safety/SHA256SUMS +0 -0
  23. {pen_stack-7.1.4 → pen_stack-7.1.6}/benchmarks/delivery/SHA256SUMS +0 -0
  24. {pen_stack-7.1.4 → pen_stack-7.1.6}/benchmarks/genome_writing_bench/LEADERBOARD.md +0 -0
  25. {pen_stack-7.1.4 → pen_stack-7.1.6}/benchmarks/genome_writing_bench/README.md +0 -0
  26. {pen_stack-7.1.4 → pen_stack-7.1.6}/benchmarks/genome_writing_bench/SHA256SUMS +0 -0
  27. {pen_stack-7.1.4 → pen_stack-7.1.6}/benchmarks/genome_writing_bench/SUBMISSIONS.md +0 -0
  28. {pen_stack-7.1.4 → pen_stack-7.1.6}/benchmarks/genome_writing_bench/tasks.yaml +0 -0
  29. {pen_stack-7.1.4 → pen_stack-7.1.6}/benchmarks/genome_writing_challenge/README.md +0 -0
  30. {pen_stack-7.1.4 → pen_stack-7.1.6}/benchmarks/genome_writing_challenge/SUBMISSIONS.md +0 -0
  31. {pen_stack-7.1.4 → pen_stack-7.1.6}/benchmarks/loop/SHA256SUMS +0 -0
  32. {pen_stack-7.1.4 → pen_stack-7.1.6}/benchmarks/offtarget/SHA256SUMS +0 -0
  33. {pen_stack-7.1.4 → pen_stack-7.1.6}/benchmarks/oracle/SHA256SUMS +0 -0
  34. {pen_stack-7.1.4 → pen_stack-7.1.6}/benchmarks/position_effect/README.md +0 -0
  35. {pen_stack-7.1.4 → pen_stack-7.1.6}/benchmarks/position_effect/SHA256SUMS +0 -0
  36. {pen_stack-7.1.4 → pen_stack-7.1.6}/benchmarks/verify/SHA256SUMS +0 -0
  37. {pen_stack-7.1.4 → pen_stack-7.1.6}/benchmarks/writer_efficiency/README.md +0 -0
  38. {pen_stack-7.1.4 → pen_stack-7.1.6}/benchmarks/writer_efficiency/SHA256SUMS +0 -0
  39. {pen_stack-7.1.4 → pen_stack-7.1.6}/benchmarks/writespec/SHA256SUMS +0 -0
  40. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/aav_serotype_tropism.yaml +0 -0
  41. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/antipeg.yaml +0 -0
  42. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/atlas_families.yaml +0 -0
  43. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/bridge_offtarget_profile.yaml +0 -0
  44. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/calibration/preexisting_nab_independent.yaml +0 -0
  45. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/capsid_epitope_oracle.yaml +0 -0
  46. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/capsid_sequences.fasta +0 -0
  47. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/cargo_polish.yaml +0 -0
  48. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/cell_types.yaml +0 -0
  49. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/datasets.yaml +0 -0
  50. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/delivery_constraints.yaml +0 -0
  51. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/delivery_rules.yaml +0 -0
  52. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/delivery_vehicles.yaml +0 -0
  53. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/expression/modifiers.yaml +0 -0
  54. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/expression/promoters.yaml +0 -0
  55. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/gates_v3.yaml +0 -0
  56. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/genotoxicity_oracle.yaml +0 -0
  57. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/gsh_validated_heldout.yaml +0 -0
  58. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/intent_weights.yaml +0 -0
  59. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/known_unknowns.yaml +0 -0
  60. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/llm.yaml +0 -0
  61. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/metric_guide.yaml +0 -0
  62. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/mhc_epitope_oracle.yaml +0 -0
  63. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/monitor_queries.yaml +0 -0
  64. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/oracles/execution.yaml +0 -0
  65. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/oracles/reliability.yaml +0 -0
  66. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/oracles/scope_cards.yaml +0 -0
  67. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/rules/compliance.yaml +0 -0
  68. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/rules/delivery.yaml +0 -0
  69. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/rules/fold.yaml +0 -0
  70. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/rules/multiplex.yaml +0 -0
  71. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/rules/payload.yaml +0 -0
  72. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/rules/reachability.yaml +0 -0
  73. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/safety/hazard_registry.yaml +0 -0
  74. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/safety/policy.yaml +0 -0
  75. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/safety/probes.yaml +0 -0
  76. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/score_axes.yaml +0 -0
  77. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/seroprevalence.yaml +0 -0
  78. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/target_sites.yaml +0 -0
  79. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/universe_crosswalk.yaml +0 -0
  80. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/write_types.yaml +0 -0
  81. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/writer_sequences.fasta +0 -0
  82. {pen_stack-7.1.4 → pen_stack-7.1.6}/configs/wtkb_curated.yaml +0 -0
  83. {pen_stack-7.1.4 → pen_stack-7.1.6}/data/curated/bridge_offtarget_energetics.json +0 -0
  84. {pen_stack-7.1.4 → pen_stack-7.1.6}/data/curated/bridge_offtarget_profile_measured.parquet +0 -0
  85. {pen_stack-7.1.4 → pen_stack-7.1.6}/data/curated/gene_coords.parquet +0 -0
  86. {pen_stack-7.1.4 → pen_stack-7.1.6}/data/curated/unified_editor_universe.parquet +0 -0
  87. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/BACKLOG.md +0 -0
  88. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/DEPLOY.md +0 -0
  89. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/INFRA.md +0 -0
  90. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/MCP.md +0 -0
  91. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/RELEASING.md +0 -0
  92. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/REPRO.md +0 -0
  93. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/STABILITY.md +0 -0
  94. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/agent.md +0 -0
  95. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/alphagenome_feasibility.md +0 -0
  96. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/autonomy.md +0 -0
  97. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/benchmark_circularity.md +0 -0
  98. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/biosecurity.md +0 -0
  99. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/build_interface.md +0 -0
  100. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/cards/atlas.md +0 -0
  101. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/cards/durability.md +0 -0
  102. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/cards/offtarget_data.md +0 -0
  103. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/cards/position_effect_data.md +0 -0
  104. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/cards/safety.md +0 -0
  105. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/cards/writer_efficiency_data.md +0 -0
  106. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/challenge.md +0 -0
  107. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/closed_loop.md +0 -0
  108. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/co_scientist.md +0 -0
  109. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/co_scientist_loop.md +0 -0
  110. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/delivery.md +0 -0
  111. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/delivery_immunology.md +0 -0
  112. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/delivery_recommender.md +0 -0
  113. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/digital_twin.md +0 -0
  114. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/dissemination.md +0 -0
  115. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/environment.md +0 -0
  116. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/experiment_design.md +0 -0
  117. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/generative_design.md +0 -0
  118. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/immune_profiler.md +0 -0
  119. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/index.md +0 -0
  120. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/integrations.md +0 -0
  121. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/live_oracles.md +0 -0
  122. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/mechanistic_constraints.md +0 -0
  123. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/offtarget.md +0 -0
  124. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/oracle_mesh.md +0 -0
  125. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/oracles.md +0 -0
  126. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/position_effect.md +0 -0
  127. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/positioning.md +0 -0
  128. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/private_data_formats.md +0 -0
  129. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/quickstart.md +0 -0
  130. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/responsible_use.md +0 -0
  131. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/rule_spec.md +0 -0
  132. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/rules.md +0 -0
  133. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/scope.md +0 -0
  134. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/scorecard.md +0 -0
  135. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/tpe_bench.md +0 -0
  136. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/tutorials/compare-families.md +0 -0
  137. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/tutorials/score-deliverability.md +0 -0
  138. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/tutorials/where-can-i-write.md +0 -0
  139. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/tutorials/which-writer-reaches-locus.md +0 -0
  140. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/uncertainty.md +0 -0
  141. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/verify.md +0 -0
  142. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/verify_service.md +0 -0
  143. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/world_model.md +0 -0
  144. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/writer_efficiency.md +0 -0
  145. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/writer_verification.md +0 -0
  146. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/writespec_bench.md +0 -0
  147. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/writespec_profile.md +0 -0
  148. {pen_stack-7.1.4 → pen_stack-7.1.6}/docs/wtkb.md +0 -0
  149. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/_resources.py +0 -0
  150. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/active/__init__.py +0 -0
  151. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/active/acquire.py +0 -0
  152. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/active/brains.py +0 -0
  153. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/active/campaign.py +0 -0
  154. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/active/design.py +0 -0
  155. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/active/validate.py +0 -0
  156. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/adapt/__init__.py +0 -0
  157. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/adapt/finetune.py +0 -0
  158. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/adapt/ingest.py +0 -0
  159. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/adapt/pipeline.py +0 -0
  160. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/adapt/recalibrate.py +0 -0
  161. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/adapt/report.py +0 -0
  162. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/agent/__init__.py +0 -0
  163. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/agent/cite.py +0 -0
  164. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/agent/co_scientist.py +0 -0
  165. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/agent/epistemic.py +0 -0
  166. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/agent/guardrails.py +0 -0
  167. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/agent/mcp_server.py +0 -0
  168. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/agent/orchestrator.py +0 -0
  169. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/agent/orchestrator_live.py +0 -0
  170. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/agent/pen_agent.py +0 -0
  171. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/agent/scope.py +0 -0
  172. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/agent/tools.py +0 -0
  173. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/api/__init__.py +0 -0
  174. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/api/manifest.py +0 -0
  175. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/atlas/__init__.py +0 -0
  176. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/atlas/build_wtkb.py +0 -0
  177. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/atlas/crosslink.py +0 -0
  178. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/atlas/expand.py +0 -0
  179. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/atlas/guide_design.py +0 -0
  180. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/atlas/schema.py +0 -0
  181. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/atlas/scorecard.py +0 -0
  182. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/atlas/universe.py +0 -0
  183. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/atlas/variant_propose.py +0 -0
  184. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/atlas/writer_efficiency.py +0 -0
  185. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/atlas/writer_predict.py +0 -0
  186. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/atlas/writer_recommend.py +0 -0
  187. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/atlas/writer_verify.py +0 -0
  188. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/bridge/__init__.py +0 -0
  189. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/bridge/activity.py +0 -0
  190. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/bridge/cli.py +0 -0
  191. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/bridge/fold_qc.py +0 -0
  192. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/bridge/guide_qc.py +0 -0
  193. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/bridge/ingest.py +0 -0
  194. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/bridge/offtarget.py +0 -0
  195. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/bridge/offtarget_energetics.py +0 -0
  196. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/bridge/ortholog_screen.py +0 -0
  197. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/bridge/pipeline.py +0 -0
  198. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/build/__init__.py +0 -0
  199. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/build/cloudlab.py +0 -0
  200. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/build/ingest.py +0 -0
  201. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/build/protocol.py +0 -0
  202. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/build/simlab.py +0 -0
  203. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/cli.py +0 -0
  204. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/data/__init__.py +0 -0
  205. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/data/encode.py +0 -0
  206. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/data/genome.py +0 -0
  207. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/data/ingest_chromatin.py +0 -0
  208. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/data/ingest_integration.py +0 -0
  209. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/data/ingest_safety_annot.py +0 -0
  210. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/data/ingest_trip.py +0 -0
  211. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/design/__init__.py +0 -0
  212. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/design/capsid_generate.py +0 -0
  213. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/design/generate.py +0 -0
  214. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/design/pareto.py +0 -0
  215. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/design/space.py +0 -0
  216. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/design/writer_variants.py +0 -0
  217. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/env/__init__.py +0 -0
  218. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/env/genome_writing_env.py +0 -0
  219. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/env/policies.py +0 -0
  220. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/graph/__init__.py +0 -0
  221. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/graph/build.py +0 -0
  222. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/graph/cell_types.py +0 -0
  223. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/graph/ingest.py +0 -0
  224. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/graph/query.py +0 -0
  225. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/graph/schema.py +0 -0
  226. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/loop/__init__.py +0 -0
  227. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/loop/continual.py +0 -0
  228. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/loop/cycle.py +0 -0
  229. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/loop/drift.py +0 -0
  230. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/mech/__init__.py +0 -0
  231. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/mech/classify_atlas.py +0 -0
  232. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/mech/whitelist.py +0 -0
  233. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/monitor/__init__.py +0 -0
  234. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/monitor/europepmc.py +0 -0
  235. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/monitor/run.py +0 -0
  236. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/monitor/triage.py +0 -0
  237. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/oracles/__init__.py +0 -0
  238. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/oracles/affinity.py +0 -0
  239. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/oracles/cache.py +0 -0
  240. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/oracles/energetics.py +0 -0
  241. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/oracles/genome.py +0 -0
  242. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/oracles/protein_design.py +0 -0
  243. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/oracles/reliability.py +0 -0
  244. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/oracles/rna.py +0 -0
  245. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/oracles/schema.py +0 -0
  246. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/oracles/status.py +0 -0
  247. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/oracles/structure.py +0 -0
  248. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/oracles/structure_run.py +0 -0
  249. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/oracles/vcell.py +0 -0
  250. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/planner/__init__.py +0 -0
  251. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/planner/ada_risk.py +0 -0
  252. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/planner/antipeg_oracle.py +0 -0
  253. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/planner/capsid_epitope_oracle.py +0 -0
  254. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/planner/cargo.py +0 -0
  255. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/planner/cargo_polish.py +0 -0
  256. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/planner/delivery.py +0 -0
  257. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/planner/delivery_constraints.py +0 -0
  258. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/planner/delivery_immune.py +0 -0
  259. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/planner/delivery_immunology.py +0 -0
  260. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/planner/delivery_predict.py +0 -0
  261. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/planner/delivery_vehicles.py +0 -0
  262. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/planner/genotoxicity_oracle.py +0 -0
  263. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/planner/immune_mhc2.py +0 -0
  264. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/planner/innate_sensing.py +0 -0
  265. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/planner/multiplex.py +0 -0
  266. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/planner/optimize.py +0 -0
  267. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/planner/pipeline.py +0 -0
  268. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/planner/report.py +0 -0
  269. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/planner/router.py +0 -0
  270. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/planner/seroprevalence_oracle.py +0 -0
  271. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/planner/target_site.py +0 -0
  272. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/rag/__init__.py +0 -0
  273. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/rag/corpus.py +0 -0
  274. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/rag/embed.py +0 -0
  275. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/rag/ground.py +0 -0
  276. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/rag/index.py +0 -0
  277. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/rag/llm.py +0 -0
  278. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/rag/qa.py +0 -0
  279. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/rag/retrieve.py +0 -0
  280. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/rules/__init__.py +0 -0
  281. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/rules/evaluators.py +0 -0
  282. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/rules/loader.py +0 -0
  283. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/rules/schema.py +0 -0
  284. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/rules/solver.py +0 -0
  285. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/rules/spec.py +0 -0
  286. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/safety/__init__.py +0 -0
  287. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/safety/audit.py +0 -0
  288. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/safety/gate.py +0 -0
  289. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/safety/policy.py +0 -0
  290. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/safety/redteam.py +0 -0
  291. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/safety/registry.py +0 -0
  292. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/safety/screen.py +0 -0
  293. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/safety/standards.py +0 -0
  294. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/score/__init__.py +0 -0
  295. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/score/recalibrate.py +0 -0
  296. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/score/therapeutic.py +0 -0
  297. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/server/__init__.py +0 -0
  298. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/spec/__init__.py +0 -0
  299. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/spec/clarify.py +0 -0
  300. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/spec/extract.py +0 -0
  301. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/spec/resolvers/__init__.py +0 -0
  302. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/spec/resolvers/cell.py +0 -0
  303. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/spec/resolvers/chem.py +0 -0
  304. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/spec/resolvers/feature.py +0 -0
  305. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/spec/resolvers/gene.py +0 -0
  306. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/spec/resolvers/locus.py +0 -0
  307. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/spec/resolvers/phenotype.py +0 -0
  308. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/spec/satisfy.py +0 -0
  309. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/spec/service.py +0 -0
  310. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/spec/writespec.py +0 -0
  311. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/twin/__init__.py +0 -0
  312. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/twin/calibrate.py +0 -0
  313. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/twin/data/__init__.py +0 -0
  314. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/twin/data/position_effect.py +0 -0
  315. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/twin/mechanistic.py +0 -0
  316. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/twin/outcome.py +0 -0
  317. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/twin/position_effect.py +0 -0
  318. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/ui/__init__.py +0 -0
  319. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/ui/app.py +0 -0
  320. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/__init__.py +0 -0
  321. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/adapt_demo.py +0 -0
  322. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/agent_eval.py +0 -0
  323. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/bench_adversarial_tasks.py +0 -0
  324. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/bench_coscientist_tasks.py +0 -0
  325. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/bench_graph_tasks.py +0 -0
  326. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/bench_rule_tasks.py +0 -0
  327. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/bench_trust_tasks.py +0 -0
  328. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/bench_writetype_tasks.py +0 -0
  329. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/blind_gsh_discovery.py +0 -0
  330. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/cargo_directionality.py +0 -0
  331. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/closed_loop.py +0 -0
  332. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/durability_baselines.py +0 -0
  333. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/experiment_design.py +0 -0
  334. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/expr_controls.py +0 -0
  335. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/forward_hypotheses.py +0 -0
  336. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/generative_design.py +0 -0
  337. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/guide_qc_demo.py +0 -0
  338. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/heldout_celltype_expr.py +0 -0
  339. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/immune_calibration.py +0 -0
  340. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/intent_specification.py +0 -0
  341. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/known_biology_expr.py +0 -0
  342. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/offtarget_energetics_eval.py +0 -0
  343. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/out_of_scope_refusal.py +0 -0
  344. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/outcome_calibration.py +0 -0
  345. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/outcome_prediction.py +0 -0
  346. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/paper3_benchmark.py +0 -0
  347. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/paper4_real_validation.py +0 -0
  348. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/paper4_validation.py +0 -0
  349. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/protocol_safety.py +0 -0
  350. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/safety_screening.py +0 -0
  351. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/selective_prediction.py +0 -0
  352. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/seq_vs_measured.py +0 -0
  353. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/target_site_controls.py +0 -0
  354. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/uncertainty_eval.py +0 -0
  355. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/ungrounded_baseline.py +0 -0
  356. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/within_locus_ranking.py +0 -0
  357. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/validate/writer_recovery.py +0 -0
  358. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/verify/__init__.py +0 -0
  359. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/verify/proof.py +0 -0
  360. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/verify/schema.py +0 -0
  361. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/web/__init__.py +0 -0
  362. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/web/guide.py +0 -0
  363. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/web/llm.py +0 -0
  364. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/web/llm_provider.py +0 -0
  365. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/web/router.py +0 -0
  366. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/web/server.py +0 -0
  367. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/web/tools.py +0 -0
  368. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/wgenome/__init__.py +0 -0
  369. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/wgenome/chromatin_seq.py +0 -0
  370. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/wgenome/durability.py +0 -0
  371. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/wgenome/export_tracks.py +0 -0
  372. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/wgenome/features.py +0 -0
  373. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/wgenome/gsh_baseline.py +0 -0
  374. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/wgenome/mesh_features.py +0 -0
  375. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/wgenome/offtarget_assay.py +0 -0
  376. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/wgenome/offtarget_data.py +0 -0
  377. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/wgenome/offtarget_predict.py +0 -0
  378. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/wgenome/ood.py +0 -0
  379. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/wgenome/providers.py +0 -0
  380. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/wgenome/safety.py +0 -0
  381. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/wgenome/structure3d.py +0 -0
  382. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/wgenome/uncertainty.py +0 -0
  383. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack/wgenome/writability.py +0 -0
  384. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack.egg-info/dependency_links.txt +0 -0
  385. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack.egg-info/entry_points.txt +0 -0
  386. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack.egg-info/requires.txt +0 -0
  387. {pen_stack-7.1.4 → pen_stack-7.1.6}/pen_stack.egg-info/top_level.txt +0 -0
  388. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_phase0.json +0 -0
  389. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_phase1_5.json +0 -0
  390. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_phase2.json +0 -0
  391. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_phase3.json +0 -0
  392. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_a.json +0 -0
  393. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_acq.json +0 -0
  394. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_aldesign.json +0 -0
  395. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_alvalidate.json +0 -0
  396. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_atlas.json +0 -0
  397. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_b.json +0 -0
  398. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_ba.json +0 -0
  399. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_ba_v33.json +0 -0
  400. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_ba_v45.json +0 -0
  401. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_bench.json +0 -0
  402. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_c.json +0 -0
  403. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_cal.json +0 -0
  404. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_calib.json +0 -0
  405. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_challenge.json +0 -0
  406. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_chat.json +0 -0
  407. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_cite.json +0 -0
  408. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_closedloop.json +0 -0
  409. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_continual.json +0 -0
  410. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_cosci2.json +0 -0
  411. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_crit.json +0 -0
  412. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_ct.json +0 -0
  413. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_d.json +0 -0
  414. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_delivery.json +0 -0
  415. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_drift.json +0 -0
  416. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_e.json +0 -0
  417. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_env.json +0 -0
  418. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_ep.json +0 -0
  419. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_epitope.json +0 -0
  420. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_expr2.json +0 -0
  421. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_f.json +0 -0
  422. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_frontend.json +0 -0
  423. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_g.json +0 -0
  424. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_gen.json +0 -0
  425. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_genotox.json +0 -0
  426. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_graph.json +0 -0
  427. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_h.json +0 -0
  428. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_hybrid.json +0 -0
  429. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_immune.json +0 -0
  430. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_immune2.json +0 -0
  431. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_ingest.json +0 -0
  432. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_innate.json +0 -0
  433. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_loop.json +0 -0
  434. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_manifest.json +0 -0
  435. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_mc.json +0 -0
  436. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_mcp.json +0 -0
  437. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_mech.json +0 -0
  438. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_mon.json +0 -0
  439. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_o.json +0 -0
  440. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_offtarget.json +0 -0
  441. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_openapi.json +0 -0
  442. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_oracle.json +0 -0
  443. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_orch.json +0 -0
  444. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_outcome.json +0 -0
  445. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_pareto.json +0 -0
  446. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_peg.json +0 -0
  447. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_penchat.json +0 -0
  448. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_plan.json +0 -0
  449. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_policy.json +0 -0
  450. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_profile.json +0 -0
  451. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_proto.json +0 -0
  452. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_r.json +0 -0
  453. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_redteam.json +0 -0
  454. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_route.json +0 -0
  455. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_screen.json +0 -0
  456. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_seroprev.json +0 -0
  457. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_simlab.json +0 -0
  458. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_twincal.json +0 -0
  459. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_uq.json +0 -0
  460. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_v.json +0 -0
  461. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_vcell.json +0 -0
  462. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_verify.json +0 -0
  463. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_writer.json +0 -0
  464. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_writespec.json +0 -0
  465. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/SHA256_LOCK_ws_wv.json +0 -0
  466. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/paper1.yaml +0 -0
  467. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/paper2.yaml +0 -0
  468. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/paper3.yaml +0 -0
  469. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/paper4.yaml +0 -0
  470. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/phase0.yaml +0 -0
  471. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_a.yaml +0 -0
  472. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_acq.yaml +0 -0
  473. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_aldesign.yaml +0 -0
  474. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_alvalidate.yaml +0 -0
  475. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_atlas.yaml +0 -0
  476. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_b.yaml +0 -0
  477. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_ba.yaml +0 -0
  478. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_ba_v33.yaml +0 -0
  479. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_ba_v45.yaml +0 -0
  480. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_bench.yaml +0 -0
  481. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_c.yaml +0 -0
  482. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_cal.yaml +0 -0
  483. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_calib.yaml +0 -0
  484. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_challenge.yaml +0 -0
  485. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_chat.yaml +0 -0
  486. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_cite.yaml +0 -0
  487. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_closedloop.yaml +0 -0
  488. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_continual.yaml +0 -0
  489. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_cosci2.yaml +0 -0
  490. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_crit.yaml +0 -0
  491. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_ct.yaml +0 -0
  492. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_d.yaml +0 -0
  493. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_delivery.yaml +0 -0
  494. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_drift.yaml +0 -0
  495. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_e.yaml +0 -0
  496. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_env.yaml +0 -0
  497. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_ep.yaml +0 -0
  498. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_epitope.yaml +0 -0
  499. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_expr2.yaml +0 -0
  500. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_f.yaml +0 -0
  501. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_frontend.yaml +0 -0
  502. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_g.yaml +0 -0
  503. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_gen.yaml +0 -0
  504. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_genotox.yaml +0 -0
  505. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_graph.yaml +0 -0
  506. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_h.yaml +0 -0
  507. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_hybrid.yaml +0 -0
  508. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_immune.yaml +0 -0
  509. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_immune2.yaml +0 -0
  510. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_ingest.yaml +0 -0
  511. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_innate.yaml +0 -0
  512. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_loop.yaml +0 -0
  513. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_manifest.yaml +0 -0
  514. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_mc.yaml +0 -0
  515. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_mcp.yaml +0 -0
  516. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_mech.yaml +0 -0
  517. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_mon.yaml +0 -0
  518. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_o.yaml +0 -0
  519. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_offtarget.yaml +0 -0
  520. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_openapi.yaml +0 -0
  521. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_oracle.yaml +0 -0
  522. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_orch.yaml +0 -0
  523. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_outcome.yaml +0 -0
  524. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_pareto.yaml +0 -0
  525. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_peg.yaml +0 -0
  526. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_penchat.yaml +0 -0
  527. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_plan.yaml +0 -0
  528. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_policy.yaml +0 -0
  529. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_profile.yaml +0 -0
  530. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_proto.yaml +0 -0
  531. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_r.yaml +0 -0
  532. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_redteam.yaml +0 -0
  533. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_route.yaml +0 -0
  534. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_screen.yaml +0 -0
  535. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_seroprev.yaml +0 -0
  536. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_simlab.yaml +0 -0
  537. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_twincal.yaml +0 -0
  538. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_uq.yaml +0 -0
  539. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_v.yaml +0 -0
  540. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_vcell.yaml +0 -0
  541. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_verify.yaml +0 -0
  542. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_writer.yaml +0 -0
  543. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_writespec.yaml +0 -0
  544. {pen_stack-7.1.4 → pen_stack-7.1.6}/prereg/ws_wv.yaml +0 -0
  545. {pen_stack-7.1.4 → pen_stack-7.1.6}/scripts/build_capsid_fitness.py +0 -0
  546. {pen_stack-7.1.4 → pen_stack-7.1.6}/scripts/build_rag_corpus.py +0 -0
  547. {pen_stack-7.1.4 → pen_stack-7.1.6}/scripts/calibrate_immune_axes.py +0 -0
  548. {pen_stack-7.1.4 → pen_stack-7.1.6}/scripts/fetch_licensed_sources.py +0 -0
  549. {pen_stack-7.1.4 → pen_stack-7.1.6}/scripts/offtarget_chromatin_incremental.py +0 -0
  550. {pen_stack-7.1.4 → pen_stack-7.1.6}/scripts/offtarget_chromatin_matched.py +0 -0
  551. {pen_stack-7.1.4 → pen_stack-7.1.6}/scripts/offtarget_chromatin_validation.py +0 -0
  552. {pen_stack-7.1.4 → pen_stack-7.1.6}/scripts/p1_build_atlas.py +0 -0
  553. {pen_stack-7.1.4 → pen_stack-7.1.6}/scripts/p1_build_durability.py +0 -0
  554. {pen_stack-7.1.4 → pen_stack-7.1.6}/scripts/p1_build_position_effect.py +0 -0
  555. {pen_stack-7.1.4 → pen_stack-7.1.6}/scripts/p1_build_writer_eff.py +0 -0
  556. {pen_stack-7.1.4 → pen_stack-7.1.6}/scripts/p1_export_tracks.py +0 -0
  557. {pen_stack-7.1.4 → pen_stack-7.1.6}/scripts/p1_safety_concordance.py +0 -0
  558. {pen_stack-7.1.4 → pen_stack-7.1.6}/scripts/p1_train_safety.py +0 -0
  559. {pen_stack-7.1.4 → pen_stack-7.1.6}/scripts/p1_validation_report.py +0 -0
  560. {pen_stack-7.1.4 → pen_stack-7.1.6}/scripts/p2_build_atlas.py +0 -0
  561. {pen_stack-7.1.4 → pen_stack-7.1.6}/scripts/p3_benchmark_report.py +0 -0
  562. {pen_stack-7.1.4 → pen_stack-7.1.6}/scripts/p4_genome_scan.py +0 -0
  563. {pen_stack-7.1.4 → pen_stack-7.1.6}/scripts/p52_build_genotox_oracle.py +0 -0
  564. {pen_stack-7.1.4 → pen_stack-7.1.6}/scripts/p53_build_epitope_oracle.py +0 -0
  565. {pen_stack-7.1.4 → pen_stack-7.1.6}/scripts/ws_b_report.py +0 -0
  566. {pen_stack-7.1.4 → pen_stack-7.1.6}/scripts/ws_c_report.py +0 -0
  567. {pen_stack-7.1.4 → pen_stack-7.1.6}/setup.cfg +0 -0
@@ -3,6 +3,65 @@
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
+ ## [7.1.6] - 2026-06-30 - Immune axes wired end-to-end + Delivery folded into Design Studio
7
+
8
+ ### Fixed
9
+ - **Four immune-risk axes were unreachable from the web UI and showed as out-of-scope** — innate sensing, anti-PEG,
10
+ and the writer-as-antigen MHC-II + ADA axes abstained on every web design because the design form never collected
11
+ their inputs (the engine computed them correctly when called directly; this was a wiring gap, not a model gap):
12
+ - **`innate`** needs a cargo sequence. The design form now has an optional **Cargo sequence** field; the cargo
13
+ nucleic-acid form (DNA -> CpG/TLR9, mRNA -> U-content + dsRNA, RNP -> transient) is derived from the vehicle's
14
+ defining cargo class (`immune_profile._vehicle_cargo_form`) so the axis computes for any caller (chat / MCP /
15
+ REST) once a sequence is supplied. Empty sequence still abstains; an explicit `cargo_form` still wins. No
16
+ fabrication: an unknown vehicle returns no form and the axis abstains.
17
+ - **`mhc2_writer` / `ada_writer`** need a writer protein. The design form now has a **Writer enzyme** selector
18
+ (the three grounded families with a bundled UniProt sequence + committed NetMHCIIpan-4.0 cache: serine integrase
19
+ Bxb1, bridge recombinase ISCro4, Cas9 SpCas9); `DEFAULT_DESIGN` ships a serine integrase so the two axes populate
20
+ out of the box. No writer selected -> the two axes abstain (never fabricated).
21
+ - **`anti_peg`** applies only to PEGylated vehicles; selecting `lnp_mrna` now surfaces it (with an inline hint),
22
+ and it correctly abstains for non-PEG vehicles.
23
+ - `ImmuneProfileCard` now shows the **writer-as-antigen** summary (representative writer, foreign/self, dominant
24
+ antigen) so the writer axes are self-explanatory.
25
+
26
+ ### Changed
27
+ - **Delivery & Immunity folded into Design Studio.** The standalone Delivery page duplicated the same design form and
28
+ immune profile, so it is merged into Design Studio as a third action - **Profile immune & delivery** - with the
29
+ per-axis immune ScoreGuide, the vehicle quick-switch, the `ImmuneProfileCard` and the scope ledger. Design Studio is
30
+ now one design surface with three actions (Verify / Generate / Profile immune & delivery). `/delivery` redirects to
31
+ `/design`; the nav drops the separate item; old links keep working.
32
+
33
+ ### Added
34
+ - `test_ws_profile.py`: tests for the vehicle-derived cargo form (innate computes for a DNA vehicle with a cargo
35
+ sequence; abstains without one; explicit form overrides) and for the writer axes computing when a grounded writer
36
+ is supplied (and abstaining otherwise).
37
+
38
+ ## [7.1.5] - 2026-06-29 - Chromosome field: validation, gene concordance, context
39
+
40
+ ### Added
41
+ - The `chrom` design field was a free-text pass-through with no validation and no downstream effect. It is now
42
+ meaningful (`pen_stack/planner/chromosome.py`):
43
+ - **Validation** — the web form's Chromosome input is a controlled dropdown (chr1–chr22, chrX, chrY, chrM), so
44
+ an impossible value like `chrZZZ` can no longer be entered; `canonical_chromosome()` normalises/validates on
45
+ the backend (`chrX`/`X`/`x`, `chr1`/`1`, `chrM`/`chrMT`/`MT`, `23`→X, `24`→Y; rejects the rest).
46
+ - **Gene/chromosome concordance** — `verify()` now flags `chromosome_mismatch` when the entered chromosome does
47
+ not match the named gene's canonical location (e.g. *BRCA1 is on chr17, not chr1*), `chromosome_invalid` for a
48
+ non-standard value, and `chromosome_unverifiable` for an unknown gene. The web form shows the warning inline
49
+ with a one-click fix, driven by the new `GET /api/gene/location` endpoint. This closes the silent-mismatch gap.
50
+ - **Chromosome context** — `chromosome_context()` adds grounded, chromosome-driven advisories surfaced as scope
51
+ flags: **chrM** is not addressable by nuclear genome-writing tools (mtDNA needs DdCBE/TALED — out of scope),
52
+ **chrY** is male-specific with ampliconic repeats, **chrX** is hemizygous in 46,XY vs X-inactivated in 46,XX.
53
+ - The Design Studio **cell-type dropdown now shows writability-atlas coverage** (from `/api/celltypes`): K562 /
54
+ HepG2 / HSPC are labelled measured (full / full / partial), while h1_hesc / iPSC / CD8 T / PBMC are labelled
55
+ "no atlas" — so a data-gated cell type is no longer silently indistinguishable from a measured one (the same
56
+ honest-field principle as the chromosome field). The 7 cell types are unchanged and already matched the backend.
57
+
58
+ ### Note (honest scoping)
59
+ - The free-text chromosome does **not** move the scored locus: per-locus safety / durability / accessibility /
60
+ off-target are indexed by the gene's *resolved genomic coordinates* via the writability atlas, so a bare
61
+ chromosome string with no position cannot refine them. Rather than fabricate a per-chromosome score delta, the
62
+ field's grounded effect is validation + gene concordance (ensuring the score is read for the right locus, and
63
+ flagging when the entered chromosome disagrees with the gene) + the chromosome-context advisories above.
64
+
6
65
  ## [7.1.4] - 2026-06-29 - Germline-prohibition legality rule
7
66
 
8
67
  ### Added
@@ -1,8 +1,8 @@
1
1
  cff-version: 1.2.0
2
2
  message: "If you use PEN-STACK, please cite it as below."
3
3
  title: "PEN-STACK: open infrastructure for genome writing"
4
- version: 7.1.4
5
- date-released: 2026-06-29
4
+ version: 7.1.6
5
+ date-released: 2026-06-30
6
6
  authors:
7
7
  - family-names: "Mahaboob Ali"
8
8
  given-names: "Anees Ahmed"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pen-stack
3
- Version: 7.1.4
3
+ Version: 7.1.6
4
4
  Summary: Open infrastructure for genome writing: the Writable Genome atlas, the Writer Atlas, and the Write Planner.
5
5
  Author-email: Anees Ahmed Mahaboob Ali <ahmedaneesm@gmail.com>
6
6
  License: MIT
@@ -1,2 +1,2 @@
1
1
  """PEN-STACK v3.0 - open infrastructure for genome writing."""
2
- __version__ = "7.1.4"
2
+ __version__ = "7.1.6"
@@ -0,0 +1,106 @@
1
+ """Chromosome validation, gene/chromosome concordance, and chromosome-context advisories (v7.1.5).
2
+
3
+ The `chrom` field on a design was previously a free-text pass-through with no validation and no downstream
4
+ effect. This module makes it meaningful WITHOUT fabricating a score: the engine's per-locus safety / durability /
5
+ accessibility / off-target numbers are indexed by the GENE's resolved genomic coordinates via the writability
6
+ atlas (`planner.optimize.gene_region`), not by a free-text chromosome string - a bare "chrX" with no position
7
+ cannot index a specific locus value. So the honest, grounded use of the field is:
8
+
9
+ * `canonical_chromosome` - validate / normalise to a standard human chromosome (chr1-chr22, chrX, chrY, chrM);
10
+ * `gene_chromosome` - the gene's canonical chromosome from the gene-coordinate table;
11
+ * `chromosome_concordance` - flag when the entered chromosome does not match the named gene's real location
12
+ (the "BRCA1 is on chr17, not chr1" case), making explicit that scoring uses the gene's canonical locus;
13
+ * `chromosome_context` - chromosome-driven advisories that ARE grounded in biology: chrM is not addressable by
14
+ nuclear genome-writing tools (mtDNA needs DdCBE/TALED - out of scope), chrY is male-specific with ampliconic
15
+ repeats, chrX is hemizygous in 46,XY vs X-inactivated in 46,XX.
16
+ """
17
+ from __future__ import annotations
18
+
19
+ import re
20
+
21
+ STANDARD_CHROMOSOMES = [f"chr{i}" for i in range(1, 23)] + ["chrX", "chrY", "chrM"]
22
+
23
+
24
+ def canonical_chromosome(chrom: str | None) -> str | None:
25
+ """Normalise a chromosome string to canonical UCSC form (chr1..chr22, chrX, chrY, chrM), or None if it is not
26
+ a standard human chromosome. Accepts 'chrX'/'X'/'x', 'chr1'/'1', 'chrM'/'chrMT'/'MT', '23'->X, '24'->Y."""
27
+ if chrom is None:
28
+ return None
29
+ c = re.sub(r"\s+", "", str(chrom)).lower()
30
+ if not c:
31
+ return None
32
+ if c.startswith("chr"):
33
+ c = c[3:]
34
+ c = {"mt": "m", "23": "x", "24": "y", "25": "m"}.get(c, c)
35
+ if c in {"x", "y", "m"}:
36
+ return "chr" + c.upper()
37
+ if c.isdigit() and 1 <= int(c) <= 22:
38
+ return "chr" + c
39
+ return None
40
+
41
+
42
+ def gene_chromosome(gene: str | None) -> str | None:
43
+ """The canonical chromosome of a gene (or safe-harbour locus nickname), from the gene-coordinate table; None
44
+ if the gene is unknown."""
45
+ if not gene:
46
+ return None
47
+ try:
48
+ from pen_stack.planner.optimize import gene_region
49
+ reg = gene_region(gene)
50
+ except Exception: # noqa: BLE001 - coords table absent (bare checkout) -> cannot resolve, do not fabricate
51
+ return None
52
+ return canonical_chromosome(reg[0]) if reg else None
53
+
54
+
55
+ def chromosome_concordance(gene: str | None, chrom: str | None) -> dict:
56
+ """Validate the entered chromosome and check it against the named gene's canonical location.
57
+
58
+ status is one of:
59
+ * 'invalid' - the entered string is not a standard human chromosome;
60
+ * 'mismatch' - valid, but does not match the gene's canonical chromosome (the silent-mismatch case);
61
+ * 'match' - matches the gene's canonical chromosome;
62
+ * 'unverifiable' - valid chromosome but the gene's location is unknown (cannot confirm);
63
+ * 'none' - no chromosome supplied.
64
+ """
65
+ entered = canonical_chromosome(chrom)
66
+ gchrom = gene_chromosome(gene)
67
+ out = {"entered_raw": chrom, "entered": entered, "valid": entered is not None,
68
+ "gene": gene, "gene_chrom": gchrom}
69
+ if chrom in (None, "") or str(chrom).strip() == "":
70
+ out["status"] = "none"
71
+ out["message"] = None
72
+ elif entered is None:
73
+ out["status"] = "invalid"
74
+ out["message"] = (f"'{chrom}' is not a standard human chromosome. Use chr1-chr22, chrX, chrY, or chrM.")
75
+ elif gchrom and entered != gchrom:
76
+ out["status"] = "mismatch"
77
+ out["message"] = (f"{gene} is on {gchrom}, not {entered}. Locus scoring uses {gene}'s canonical location "
78
+ f"({gchrom}); the entered chromosome does not move the locus.")
79
+ elif gchrom and entered == gchrom:
80
+ out["status"] = "match"
81
+ out["message"] = f"{entered} matches the canonical location of {gene}."
82
+ else:
83
+ out["status"] = "unverifiable"
84
+ out["message"] = (f"{entered} is a valid chromosome, but {gene or 'the gene'} is not in the coordinate "
85
+ "table, so the gene/chromosome match cannot be confirmed.")
86
+ return out
87
+
88
+
89
+ def chromosome_context(chrom: str | None) -> dict | None:
90
+ """A grounded, chromosome-driven advisory (or None for an autosome). These are real biological constraints
91
+ the chromosome identity alone implies; magnitudes remain locus/subject-dependent (not predicted here)."""
92
+ c = canonical_chromosome(chrom)
93
+ if c == "chrM":
94
+ return {"chrom": "chrM", "severity": "high",
95
+ "note": ("the mitochondrial genome is NOT addressable by nuclear genome-writing tools "
96
+ "(integrases / recombinases / nuclear-targeted Cas9); mtDNA editing requires "
97
+ "mitochondrially-targeted base editors (DdCBE / TALED) - out of scope for this tool.")}
98
+ if c == "chrY":
99
+ return {"chrom": "chrY", "severity": "medium",
100
+ "note": ("the Y chromosome is male-specific (absent in 46,XX) and rich in ampliconic / palindromic "
101
+ "repeats, so confirm the target is single-copy before trusting a unique-site assumption.")}
102
+ if c == "chrX":
103
+ return {"chrom": "chrX", "severity": "low",
104
+ "note": ("the X chromosome is hemizygous in 46,XY (one copy) but subject to X-inactivation in "
105
+ "46,XX (mosaic expression); dosage and durability are sex- and locus-dependent.")}
106
+ return None
@@ -53,6 +53,34 @@ _SCORE_KEY = {"genotoxicity": "genotox_score", "cd8_epitope": "capsid_immune_sco
53
53
  "innate": "innate_score", "preexisting_nab": "preexisting_score",
54
54
  "anti_peg": "preexisting_antipeg_score"}
55
55
 
56
+ # Canonical cargo nucleic-acid FORM per delivery vehicle, used to drive the innate-sensing pathway (DNA -> TLR9
57
+ # CpG; mRNA -> TLR7/8 + RIG-I/MDA5; RNP -> transient) when a design does not state ``cargo_form`` explicitly.
58
+ # This is the vehicle's defining cargo class, NOT a fabricated quantity: an LNP-mRNA vehicle delivers mRNA, a
59
+ # DNA-virus / electroporated-plasmid vehicle delivers DNA, an (e)VLP delivers a transient ribonucleoprotein. A
60
+ # lentivirus is packaged as RNA but the persistent, innate-relevant cassette is the integrated proviral DNA.
61
+ # An unknown vehicle returns None so the innate axis ABSTAINS rather than guesses a form.
62
+ _VEHICLE_CARGO_FORM = {
63
+ "lnp_mrna": "mRNA",
64
+ "aav_single": "DNA", "aav_dual": "DNA", "lentivirus": "DNA",
65
+ "helper_dependent_adenovirus": "DNA", "hsv_amplicon": "DNA", "electroporation": "DNA",
66
+ "evlp": "RNP", "vlp": "RNP",
67
+ }
68
+
69
+
70
+ def _vehicle_cargo_form(vehicle: str | None) -> str | None:
71
+ """Derive the cargo nucleic-acid form (DNA / mRNA / RNP) from the delivery vehicle, or None when unknown.
72
+ Used only when the design does not supply ``cargo_form`` / ``writer_output_form`` explicitly."""
73
+ if not vehicle:
74
+ return None
75
+ v = str(vehicle).strip().lower()
76
+ if v in _VEHICLE_CARGO_FORM:
77
+ return _VEHICLE_CARGO_FORM[v]
78
+ if "mrna" in v or "lnp" in v:
79
+ return "mRNA"
80
+ if "vlp" in v:
81
+ return "RNP"
82
+ return None
83
+
56
84
 
57
85
  def _axis(result, axis: str) -> dict:
58
86
  """One axis record: value (headline score or None when abstaining) + native uncertainty + scope + the
@@ -108,7 +136,11 @@ def immune_profile(design: dict) -> dict:
108
136
  veh = design.get("delivery_vehicle") or design.get("vehicle")
109
137
  sero = design.get("serotype")
110
138
  cargo_seq = design.get("cargo_seq") or ""
111
- form = design.get("writer_output_form") or design.get("cargo_form") or ""
139
+ # cargo form: honour an explicit design field, else derive it from the vehicle's defining cargo class so the
140
+ # innate axis computes for any caller (chat / MCP / REST) once a cargo sequence is supplied. Still abstains
141
+ # with no sequence and for an unknown vehicle (form None) - never fabricates.
142
+ form = (design.get("writer_output_form") or design.get("cargo_form")
143
+ or _vehicle_cargo_form(veh) or "")
112
144
  peg = design.get("pegylated")
113
145
 
114
146
  capsid_cd8 = capsid_epitope_oracle(veh)
@@ -119,6 +119,23 @@ def crosslink_loci(request: Request, family: str, ct: str = "k562", cell_type: s
119
119
  return {"family": family, "ct": ct, "loci": _records(loci), "disclaimer": _DISCLAIMER}
120
120
 
121
121
 
122
+ @app.get("/gene/location")
123
+ def gene_location(gene: str):
124
+ """v7.1.5: the canonical chromosome of a gene (or safe-harbour locus nickname), for the UI's gene/chromosome
125
+ concordance check. found=False when the gene is not in the coordinate table (no fabrication)."""
126
+ from pen_stack.planner.chromosome import canonical_chromosome
127
+ from pen_stack.planner.optimize import gene_region, resolve_gene
128
+ try:
129
+ reg = gene_region(gene)
130
+ except Exception: # noqa: BLE001 - coords table absent -> cannot resolve
131
+ reg = None
132
+ resolved = resolve_gene(gene)
133
+ if reg is None:
134
+ return {"gene": gene, "resolved": resolved, "found": False, "chrom": None}
135
+ return {"gene": gene, "resolved": resolved, "found": True, "chrom": canonical_chromosome(reg[0]),
136
+ "start": int(reg[1]), "end": int(reg[2])}
137
+
138
+
122
139
  @app.get("/writable")
123
140
  def writable(request: Request, gene: str, ct: str = "k562", cell_type: str | None = None,
124
141
  top: int = Query(20, le=200)):
@@ -98,6 +98,18 @@ def verify(design: Design | dict, question: str | None = None, *, actor: str = "
98
98
  for r in results if r["kind"] == "scope_flag" and r["status"] == "scope"]
99
99
  scope_flags += rule_scope
100
100
 
101
+ # v7.1.5: chromosome validation + gene/chromosome concordance + chromosome-context advisory. The free-text
102
+ # chrom field does not move the scored locus (scoring is indexed by the gene's resolved coordinates), so a
103
+ # mismatch / invalid value / chromosome-context note is surfaced as a scope flag, never silently ignored.
104
+ from pen_stack.planner.chromosome import chromosome_concordance, chromosome_context
105
+ conc = chromosome_concordance(design.gene, getattr(design, "chrom", None))
106
+ if conc["status"] in ("invalid", "mismatch", "unverifiable"):
107
+ scope_flags.append({"kind": f"chromosome_{conc['status']}", "reason": conc["message"],
108
+ "entered": conc["entered"], "gene_chrom": conc["gene_chrom"]})
109
+ ctx = chromosome_context(getattr(design, "chrom", None))
110
+ if ctx:
111
+ scope_flags.append({"kind": "chromosome_context", "chrom": ctx["chrom"], "reason": ctx["note"]})
112
+
101
113
  pc = _plan_confidence(design)
102
114
  verdict = classify(grounded=True, confidence=pc["confidence"], out_of_scope=oos_hit)
103
115
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pen-stack
3
- Version: 7.1.4
3
+ Version: 7.1.6
4
4
  Summary: Open infrastructure for genome writing: the Writable Genome atlas, the Writer Atlas, and the Write Planner.
5
5
  Author-email: Anees Ahmed Mahaboob Ali <ahmedaneesm@gmail.com>
6
6
  License: MIT
@@ -252,6 +252,7 @@ pen_stack/planner/antipeg_oracle.py
252
252
  pen_stack/planner/capsid_epitope_oracle.py
253
253
  pen_stack/planner/cargo.py
254
254
  pen_stack/planner/cargo_polish.py
255
+ pen_stack/planner/chromosome.py
255
256
  pen_stack/planner/delivery.py
256
257
  pen_stack/planner/delivery_constraints.py
257
258
  pen_stack/planner/delivery_immune.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pen-stack"
7
- version = "7.1.4"
7
+ version = "7.1.6"
8
8
  description = "Open infrastructure for genome writing: the Writable Genome atlas, the Writer Atlas, and the Write Planner."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes