pen-stack 6.11.0__tar.gz → 6.13.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (835) hide show
  1. pen_stack-6.13.0/CHANGELOG.md +1617 -0
  2. pen_stack-6.13.0/CITATION.cff +19 -0
  3. pen_stack-6.13.0/PKG-INFO +304 -0
  4. pen_stack-6.13.0/README.md +229 -0
  5. pen_stack-6.13.0/bench/run.py +164 -0
  6. pen_stack-6.13.0/benchmarks/genome_writing_bench/LEADERBOARD.md +67 -0
  7. pen_stack-6.13.0/benchmarks/genome_writing_bench/README.md +87 -0
  8. pen_stack-6.13.0/benchmarks/genome_writing_bench/tasks.yaml +335 -0
  9. pen_stack-6.13.0/benchmarks/genome_writing_challenge/README.md +49 -0
  10. pen_stack-6.13.0/benchmarks/genome_writing_challenge/SUBMISSIONS.md +16 -0
  11. pen_stack-6.13.0/benchmarks/oracle/SHA256SUMS +5 -0
  12. pen_stack-6.13.0/benchmarks/position_effect/README.md +60 -0
  13. pen_stack-6.13.0/benchmarks/verify/SHA256SUMS +2 -0
  14. pen_stack-6.13.0/benchmarks/writer_efficiency/README.md +54 -0
  15. pen_stack-6.13.0/configs/aav_serotype_tropism.yaml +81 -0
  16. pen_stack-6.13.0/configs/antipeg.yaml +28 -0
  17. pen_stack-6.13.0/configs/atlas_families.yaml +81 -0
  18. pen_stack-6.13.0/configs/bridge_offtarget_profile.yaml +51 -0
  19. pen_stack-6.13.0/configs/calibration/preexisting_nab_independent.yaml +25 -0
  20. pen_stack-6.13.0/configs/cargo_polish.yaml +45 -0
  21. pen_stack-6.13.0/configs/cell_types.yaml +56 -0
  22. pen_stack-6.13.0/configs/datasets.yaml +99 -0
  23. pen_stack-6.13.0/configs/delivery_constraints.yaml +50 -0
  24. pen_stack-6.13.0/configs/delivery_rules.yaml +15 -0
  25. pen_stack-6.13.0/configs/delivery_vehicles.yaml +185 -0
  26. pen_stack-6.13.0/configs/expression/modifiers.yaml +59 -0
  27. pen_stack-6.13.0/configs/expression/promoters.yaml +52 -0
  28. pen_stack-6.13.0/configs/gates_v3.yaml +208 -0
  29. pen_stack-6.13.0/configs/gsh_validated_heldout.yaml +87 -0
  30. pen_stack-6.13.0/configs/intent_weights.yaml +42 -0
  31. pen_stack-6.13.0/configs/known_unknowns.yaml +110 -0
  32. pen_stack-6.13.0/configs/llm.yaml +59 -0
  33. pen_stack-6.13.0/configs/metric_guide.yaml +109 -0
  34. pen_stack-6.13.0/configs/oracles/execution.yaml +95 -0
  35. pen_stack-6.13.0/configs/oracles/reliability.yaml +92 -0
  36. pen_stack-6.13.0/configs/oracles/scope_cards.yaml +250 -0
  37. pen_stack-6.13.0/configs/rules/fold.yaml +15 -0
  38. pen_stack-6.13.0/configs/rules/reachability.yaml +16 -0
  39. pen_stack-6.13.0/configs/safety/hazard_registry.yaml +147 -0
  40. pen_stack-6.13.0/configs/safety/policy.yaml +23 -0
  41. pen_stack-6.13.0/configs/safety/probes.yaml +74 -0
  42. pen_stack-6.13.0/configs/score_axes.yaml +68 -0
  43. pen_stack-6.13.0/configs/seroprevalence.yaml +64 -0
  44. pen_stack-6.13.0/configs/target_sites.yaml +66 -0
  45. pen_stack-6.13.0/configs/universe_crosswalk.yaml +36 -0
  46. pen_stack-6.13.0/configs/write_types.yaml +57 -0
  47. pen_stack-6.13.0/configs/wtkb_curated.yaml +165 -0
  48. pen_stack-6.13.0/docs/BACKLOG.md +20 -0
  49. pen_stack-6.13.0/docs/STABILITY.md +51 -0
  50. pen_stack-6.13.0/docs/agent.md +78 -0
  51. pen_stack-6.13.0/docs/alphagenome_feasibility.md +49 -0
  52. pen_stack-6.13.0/docs/autonomy.md +36 -0
  53. pen_stack-6.13.0/docs/benchmark_circularity.md +64 -0
  54. pen_stack-6.13.0/docs/biosecurity.md +64 -0
  55. pen_stack-6.13.0/docs/build_interface.md +50 -0
  56. pen_stack-6.13.0/docs/cards/durability.md +43 -0
  57. pen_stack-6.13.0/docs/cards/offtarget_data.md +92 -0
  58. pen_stack-6.13.0/docs/cards/position_effect_data.md +36 -0
  59. pen_stack-6.13.0/docs/cards/writer_efficiency_data.md +48 -0
  60. pen_stack-6.13.0/docs/challenge.md +33 -0
  61. pen_stack-6.13.0/docs/closed_loop.md +54 -0
  62. pen_stack-6.13.0/docs/co_scientist.md +31 -0
  63. pen_stack-6.13.0/docs/co_scientist_loop.md +31 -0
  64. pen_stack-6.13.0/docs/delivery.md +22 -0
  65. pen_stack-6.13.0/docs/delivery_immunology.md +150 -0
  66. pen_stack-6.13.0/docs/delivery_recommender.md +54 -0
  67. pen_stack-6.13.0/docs/digital_twin.md +55 -0
  68. pen_stack-6.13.0/docs/dissemination.md +34 -0
  69. pen_stack-6.13.0/docs/environment.md +59 -0
  70. pen_stack-6.13.0/docs/experiment_design.md +44 -0
  71. pen_stack-6.13.0/docs/generative_design.md +63 -0
  72. pen_stack-6.13.0/docs/immune_profiler.md +70 -0
  73. pen_stack-6.13.0/docs/index.md +48 -0
  74. pen_stack-6.13.0/docs/integrations.md +87 -0
  75. pen_stack-6.13.0/docs/live_oracles.md +56 -0
  76. pen_stack-6.13.0/docs/mechanistic_constraints.md +59 -0
  77. pen_stack-6.13.0/docs/offtarget.md +57 -0
  78. pen_stack-6.13.0/docs/oracle_mesh.md +64 -0
  79. pen_stack-6.13.0/docs/oracles.md +51 -0
  80. pen_stack-6.13.0/docs/position_effect.md +57 -0
  81. pen_stack-6.13.0/docs/positioning.md +55 -0
  82. pen_stack-6.13.0/docs/private_data_formats.md +61 -0
  83. pen_stack-6.13.0/docs/responsible_use.md +84 -0
  84. pen_stack-6.13.0/docs/rule_spec.md +18 -0
  85. pen_stack-6.13.0/docs/rules.md +19 -0
  86. pen_stack-6.13.0/docs/scope.md +50 -0
  87. pen_stack-6.13.0/docs/tpe_bench.md +48 -0
  88. pen_stack-6.13.0/docs/tutorials/which-writer-reaches-locus.md +41 -0
  89. pen_stack-6.13.0/docs/uncertainty.md +84 -0
  90. pen_stack-6.13.0/docs/verify.md +60 -0
  91. pen_stack-6.13.0/docs/verify_service.md +52 -0
  92. pen_stack-6.13.0/docs/world_model.md +49 -0
  93. pen_stack-6.13.0/docs/writer_efficiency.md +59 -0
  94. pen_stack-6.13.0/docs/writer_verification.md +46 -0
  95. pen_stack-6.13.0/pen_stack/__init__.py +2 -0
  96. pen_stack-6.13.0/pen_stack/_resources.py +34 -0
  97. pen_stack-6.13.0/pen_stack/active/__init__.py +20 -0
  98. pen_stack-6.13.0/pen_stack/active/acquire.py +73 -0
  99. pen_stack-6.13.0/pen_stack/active/design.py +51 -0
  100. pen_stack-6.13.0/pen_stack/active/validate.py +104 -0
  101. pen_stack-6.13.0/pen_stack/adapt/ingest.py +86 -0
  102. pen_stack-6.13.0/pen_stack/adapt/pipeline.py +101 -0
  103. pen_stack-6.13.0/pen_stack/adapt/recalibrate.py +58 -0
  104. pen_stack-6.13.0/pen_stack/adapt/report.py +130 -0
  105. pen_stack-6.13.0/pen_stack/agent/cite.py +175 -0
  106. pen_stack-6.13.0/pen_stack/agent/co_scientist.py +268 -0
  107. pen_stack-6.13.0/pen_stack/agent/epistemic.py +100 -0
  108. pen_stack-6.13.0/pen_stack/agent/guardrails.py +67 -0
  109. pen_stack-6.13.0/pen_stack/agent/mcp_server.py +180 -0
  110. pen_stack-6.13.0/pen_stack/agent/orchestrator.py +106 -0
  111. pen_stack-6.13.0/pen_stack/agent/orchestrator_live.py +56 -0
  112. pen_stack-6.13.0/pen_stack/agent/pen_agent.py +242 -0
  113. pen_stack-6.13.0/pen_stack/agent/scope.py +60 -0
  114. pen_stack-6.13.0/pen_stack/api/__init__.py +12 -0
  115. pen_stack-6.13.0/pen_stack/api/manifest.py +132 -0
  116. pen_stack-6.13.0/pen_stack/atlas/build_wtkb.py +80 -0
  117. pen_stack-6.13.0/pen_stack/atlas/crosslink.py +141 -0
  118. pen_stack-6.13.0/pen_stack/atlas/expand.py +190 -0
  119. pen_stack-6.13.0/pen_stack/atlas/guide_design.py +174 -0
  120. pen_stack-6.13.0/pen_stack/atlas/schema.py +59 -0
  121. pen_stack-6.13.0/pen_stack/atlas/scorecard.py +134 -0
  122. pen_stack-6.13.0/pen_stack/atlas/variant_propose.py +155 -0
  123. pen_stack-6.13.0/pen_stack/atlas/writer_efficiency.py +184 -0
  124. pen_stack-6.13.0/pen_stack/atlas/writer_predict.py +225 -0
  125. pen_stack-6.13.0/pen_stack/atlas/writer_recommend.py +103 -0
  126. pen_stack-6.13.0/pen_stack/atlas/writer_verify.py +167 -0
  127. pen_stack-6.13.0/pen_stack/bridge/cli.py +65 -0
  128. pen_stack-6.13.0/pen_stack/bridge/fold_qc.py +53 -0
  129. pen_stack-6.13.0/pen_stack/bridge/guide_qc.py +87 -0
  130. pen_stack-6.13.0/pen_stack/bridge/ingest.py +139 -0
  131. pen_stack-6.13.0/pen_stack/bridge/offtarget.py +191 -0
  132. pen_stack-6.13.0/pen_stack/bridge/offtarget_energetics.py +105 -0
  133. pen_stack-6.13.0/pen_stack/bridge/ortholog_screen.py +73 -0
  134. pen_stack-6.13.0/pen_stack/bridge/pipeline.py +83 -0
  135. pen_stack-6.13.0/pen_stack/build/__init__.py +16 -0
  136. pen_stack-6.13.0/pen_stack/build/ingest.py +47 -0
  137. pen_stack-6.13.0/pen_stack/build/protocol.py +82 -0
  138. pen_stack-6.13.0/pen_stack/build/simlab.py +30 -0
  139. pen_stack-6.13.0/pen_stack/cli.py +126 -0
  140. pen_stack-6.13.0/pen_stack/data/encode.py +84 -0
  141. pen_stack-6.13.0/pen_stack/data/genome.py +71 -0
  142. pen_stack-6.13.0/pen_stack/data/ingest_chromatin.py +119 -0
  143. pen_stack-6.13.0/pen_stack/data/ingest_integration.py +112 -0
  144. pen_stack-6.13.0/pen_stack/data/ingest_safety_annot.py +201 -0
  145. pen_stack-6.13.0/pen_stack/data/ingest_trip.py +76 -0
  146. pen_stack-6.13.0/pen_stack/design/__init__.py +14 -0
  147. pen_stack-6.13.0/pen_stack/design/capsid_generate.py +62 -0
  148. pen_stack-6.13.0/pen_stack/design/generate.py +48 -0
  149. pen_stack-6.13.0/pen_stack/design/pareto.py +70 -0
  150. pen_stack-6.13.0/pen_stack/design/space.py +85 -0
  151. pen_stack-6.13.0/pen_stack/design/writer_variants.py +121 -0
  152. pen_stack-6.13.0/pen_stack/env/genome_writing_env.py +248 -0
  153. pen_stack-6.13.0/pen_stack/env/policies.py +94 -0
  154. pen_stack-6.13.0/pen_stack/graph/build.py +133 -0
  155. pen_stack-6.13.0/pen_stack/graph/cell_types.py +58 -0
  156. pen_stack-6.13.0/pen_stack/graph/ingest.py +132 -0
  157. pen_stack-6.13.0/pen_stack/graph/query.py +79 -0
  158. pen_stack-6.13.0/pen_stack/graph/schema.py +100 -0
  159. pen_stack-6.13.0/pen_stack/loop/__init__.py +15 -0
  160. pen_stack-6.13.0/pen_stack/loop/continual.py +61 -0
  161. pen_stack-6.13.0/pen_stack/loop/cycle.py +84 -0
  162. pen_stack-6.13.0/pen_stack/loop/drift.py +41 -0
  163. pen_stack-6.13.0/pen_stack/mech/classify_atlas.py +71 -0
  164. pen_stack-6.13.0/pen_stack/mech/whitelist.py +66 -0
  165. pen_stack-6.13.0/pen_stack/monitor/europepmc.py +32 -0
  166. pen_stack-6.13.0/pen_stack/monitor/run.py +57 -0
  167. pen_stack-6.13.0/pen_stack/monitor/triage.py +63 -0
  168. pen_stack-6.13.0/pen_stack/oracles/__init__.py +65 -0
  169. pen_stack-6.13.0/pen_stack/oracles/affinity.py +116 -0
  170. pen_stack-6.13.0/pen_stack/oracles/cache.py +53 -0
  171. pen_stack-6.13.0/pen_stack/oracles/energetics.py +33 -0
  172. pen_stack-6.13.0/pen_stack/oracles/genome.py +167 -0
  173. pen_stack-6.13.0/pen_stack/oracles/protein_design.py +136 -0
  174. pen_stack-6.13.0/pen_stack/oracles/reliability.py +64 -0
  175. pen_stack-6.13.0/pen_stack/oracles/rna.py +28 -0
  176. pen_stack-6.13.0/pen_stack/oracles/schema.py +63 -0
  177. pen_stack-6.13.0/pen_stack/oracles/status.py +123 -0
  178. pen_stack-6.13.0/pen_stack/oracles/structure.py +43 -0
  179. pen_stack-6.13.0/pen_stack/oracles/structure_run.py +76 -0
  180. pen_stack-6.13.0/pen_stack/oracles/vcell.py +74 -0
  181. pen_stack-6.13.0/pen_stack/planner/ada_risk.py +64 -0
  182. pen_stack-6.13.0/pen_stack/planner/antipeg_oracle.py +75 -0
  183. pen_stack-6.13.0/pen_stack/planner/capsid_epitope_oracle.py +136 -0
  184. pen_stack-6.13.0/pen_stack/planner/cargo.py +56 -0
  185. pen_stack-6.13.0/pen_stack/planner/cargo_polish.py +146 -0
  186. pen_stack-6.13.0/pen_stack/planner/delivery.py +55 -0
  187. pen_stack-6.13.0/pen_stack/planner/delivery_constraints.py +110 -0
  188. pen_stack-6.13.0/pen_stack/planner/delivery_immune.py +60 -0
  189. pen_stack-6.13.0/pen_stack/planner/delivery_immunology.py +208 -0
  190. pen_stack-6.13.0/pen_stack/planner/delivery_predict.py +136 -0
  191. pen_stack-6.13.0/pen_stack/planner/genotoxicity_oracle.py +112 -0
  192. pen_stack-6.13.0/pen_stack/planner/immune_mhc2.py +154 -0
  193. pen_stack-6.13.0/pen_stack/planner/immune_profile.py +156 -0
  194. pen_stack-6.13.0/pen_stack/planner/innate_sensing.py +135 -0
  195. pen_stack-6.13.0/pen_stack/planner/multiplex.py +110 -0
  196. pen_stack-6.13.0/pen_stack/planner/optimize.py +251 -0
  197. pen_stack-6.13.0/pen_stack/planner/pipeline.py +86 -0
  198. pen_stack-6.13.0/pen_stack/planner/report.py +26 -0
  199. pen_stack-6.13.0/pen_stack/planner/router.py +57 -0
  200. pen_stack-6.13.0/pen_stack/planner/seroprevalence_oracle.py +92 -0
  201. pen_stack-6.13.0/pen_stack/planner/target_site.py +118 -0
  202. pen_stack-6.13.0/pen_stack/rag/llm.py +178 -0
  203. pen_stack-6.13.0/pen_stack/rag/qa.py +105 -0
  204. pen_stack-6.13.0/pen_stack/rules/__init__.py +9 -0
  205. pen_stack-6.13.0/pen_stack/rules/evaluators.py +222 -0
  206. pen_stack-6.13.0/pen_stack/rules/schema.py +82 -0
  207. pen_stack-6.13.0/pen_stack/rules/solver.py +43 -0
  208. pen_stack-6.13.0/pen_stack/rules/spec.py +78 -0
  209. pen_stack-6.13.0/pen_stack/safety/__init__.py +21 -0
  210. pen_stack-6.13.0/pen_stack/safety/audit.py +90 -0
  211. pen_stack-6.13.0/pen_stack/safety/gate.py +37 -0
  212. pen_stack-6.13.0/pen_stack/safety/policy.py +65 -0
  213. pen_stack-6.13.0/pen_stack/safety/redteam.py +71 -0
  214. pen_stack-6.13.0/pen_stack/safety/registry.py +173 -0
  215. pen_stack-6.13.0/pen_stack/safety/screen.py +51 -0
  216. pen_stack-6.13.0/pen_stack/safety/standards.py +141 -0
  217. pen_stack-6.13.0/pen_stack/score/therapeutic.py +85 -0
  218. pen_stack-6.13.0/pen_stack/server/api.py +335 -0
  219. pen_stack-6.13.0/pen_stack/twin/__init__.py +14 -0
  220. pen_stack-6.13.0/pen_stack/twin/calibrate.py +61 -0
  221. pen_stack-6.13.0/pen_stack/twin/data/__init__.py +12 -0
  222. pen_stack-6.13.0/pen_stack/twin/data/position_effect.py +224 -0
  223. pen_stack-6.13.0/pen_stack/twin/mechanistic.py +119 -0
  224. pen_stack-6.13.0/pen_stack/twin/outcome.py +102 -0
  225. pen_stack-6.13.0/pen_stack/twin/position_effect.py +369 -0
  226. pen_stack-6.13.0/pen_stack/ui/app.py +713 -0
  227. pen_stack-6.13.0/pen_stack/validate/adapt_demo.py +69 -0
  228. pen_stack-6.13.0/pen_stack/validate/agent_eval.py +117 -0
  229. pen_stack-6.13.0/pen_stack/validate/bench_adversarial_tasks.py +118 -0
  230. pen_stack-6.13.0/pen_stack/validate/bench_coscientist_tasks.py +60 -0
  231. pen_stack-6.13.0/pen_stack/validate/bench_graph_tasks.py +64 -0
  232. pen_stack-6.13.0/pen_stack/validate/bench_rule_tasks.py +84 -0
  233. pen_stack-6.13.0/pen_stack/validate/bench_trust_tasks.py +92 -0
  234. pen_stack-6.13.0/pen_stack/validate/bench_writetype_tasks.py +101 -0
  235. pen_stack-6.13.0/pen_stack/validate/blind_gsh_discovery.py +261 -0
  236. pen_stack-6.13.0/pen_stack/validate/cargo_directionality.py +57 -0
  237. pen_stack-6.13.0/pen_stack/validate/closed_loop.py +63 -0
  238. pen_stack-6.13.0/pen_stack/validate/durability_baselines.py +185 -0
  239. pen_stack-6.13.0/pen_stack/validate/experiment_design.py +65 -0
  240. pen_stack-6.13.0/pen_stack/validate/expr_controls.py +39 -0
  241. pen_stack-6.13.0/pen_stack/validate/forward_hypotheses.py +104 -0
  242. pen_stack-6.13.0/pen_stack/validate/generative_design.py +62 -0
  243. pen_stack-6.13.0/pen_stack/validate/guide_qc_demo.py +69 -0
  244. pen_stack-6.13.0/pen_stack/validate/heldout_celltype_expr.py +32 -0
  245. pen_stack-6.13.0/pen_stack/validate/immune_calibration.py +133 -0
  246. pen_stack-6.13.0/pen_stack/validate/intent_specification.py +82 -0
  247. pen_stack-6.13.0/pen_stack/validate/offtarget_energetics_eval.py +144 -0
  248. pen_stack-6.13.0/pen_stack/validate/out_of_scope_refusal.py +82 -0
  249. pen_stack-6.13.0/pen_stack/validate/outcome_calibration.py +194 -0
  250. pen_stack-6.13.0/pen_stack/validate/outcome_prediction.py +76 -0
  251. pen_stack-6.13.0/pen_stack/validate/paper3_benchmark.py +165 -0
  252. pen_stack-6.13.0/pen_stack/validate/paper4_real_validation.py +144 -0
  253. pen_stack-6.13.0/pen_stack/validate/paper4_validation.py +82 -0
  254. pen_stack-6.13.0/pen_stack/validate/protocol_safety.py +62 -0
  255. pen_stack-6.13.0/pen_stack/validate/safety_screening.py +72 -0
  256. pen_stack-6.13.0/pen_stack/validate/selective_prediction.py +104 -0
  257. pen_stack-6.13.0/pen_stack/validate/seq_vs_measured.py +134 -0
  258. pen_stack-6.13.0/pen_stack/validate/target_site_controls.py +65 -0
  259. pen_stack-6.13.0/pen_stack/validate/uncertainty_eval.py +244 -0
  260. pen_stack-6.13.0/pen_stack/validate/ungrounded_baseline.py +234 -0
  261. pen_stack-6.13.0/pen_stack/validate/within_locus_ranking.py +84 -0
  262. pen_stack-6.13.0/pen_stack/validate/writer_recovery.py +91 -0
  263. pen_stack-6.13.0/pen_stack/verify/proof.py +169 -0
  264. pen_stack-6.13.0/pen_stack/verify/schema.py +48 -0
  265. pen_stack-6.13.0/pen_stack/verify/service.py +176 -0
  266. pen_stack-6.13.0/pen_stack/web/__init__.py +18 -0
  267. pen_stack-6.13.0/pen_stack/web/guide.py +110 -0
  268. pen_stack-6.13.0/pen_stack/web/llm.py +413 -0
  269. pen_stack-6.13.0/pen_stack/web/router.py +96 -0
  270. pen_stack-6.13.0/pen_stack/web/server.py +95 -0
  271. pen_stack-6.13.0/pen_stack/web/tools.py +197 -0
  272. pen_stack-6.13.0/pen_stack/wgenome/chromatin_seq.py +83 -0
  273. pen_stack-6.13.0/pen_stack/wgenome/durability.py +108 -0
  274. pen_stack-6.13.0/pen_stack/wgenome/features.py +82 -0
  275. pen_stack-6.13.0/pen_stack/wgenome/gsh_baseline.py +154 -0
  276. pen_stack-6.13.0/pen_stack/wgenome/mesh_features.py +61 -0
  277. pen_stack-6.13.0/pen_stack/wgenome/offtarget_assay.py +55 -0
  278. pen_stack-6.13.0/pen_stack/wgenome/offtarget_data.py +148 -0
  279. pen_stack-6.13.0/pen_stack/wgenome/offtarget_predict.py +238 -0
  280. pen_stack-6.13.0/pen_stack/wgenome/ood.py +135 -0
  281. pen_stack-6.13.0/pen_stack/wgenome/providers.py +278 -0
  282. pen_stack-6.13.0/pen_stack/wgenome/safety.py +69 -0
  283. pen_stack-6.13.0/pen_stack/wgenome/structure3d.py +212 -0
  284. pen_stack-6.13.0/pen_stack/wgenome/uncertainty.py +260 -0
  285. pen_stack-6.13.0/pen_stack/wgenome/writability.py +72 -0
  286. pen_stack-6.13.0/pen_stack.egg-info/PKG-INFO +304 -0
  287. pen_stack-6.13.0/pen_stack.egg-info/SOURCES.txt +524 -0
  288. pen_stack-6.13.0/prereg/SHA256_LOCK_ws_delivery.json +8 -0
  289. pen_stack-6.13.0/prereg/SHA256_LOCK_ws_hybrid.json +8 -0
  290. pen_stack-6.13.0/prereg/SHA256_LOCK_ws_immune2.json +8 -0
  291. pen_stack-6.13.0/prereg/SHA256_LOCK_ws_offtarget.json +8 -0
  292. pen_stack-6.13.0/prereg/SHA256_LOCK_ws_oracle.json +8 -0
  293. pen_stack-6.13.0/prereg/SHA256_LOCK_ws_r.json +14 -0
  294. pen_stack-6.13.0/prereg/SHA256_LOCK_ws_verify.json +8 -0
  295. pen_stack-6.13.0/prereg/SHA256_LOCK_ws_writer.json +8 -0
  296. pen_stack-6.13.0/prereg/ws_delivery.yaml +39 -0
  297. pen_stack-6.13.0/prereg/ws_hybrid.yaml +30 -0
  298. pen_stack-6.13.0/prereg/ws_immune2.yaml +36 -0
  299. pen_stack-6.13.0/prereg/ws_offtarget.yaml +42 -0
  300. pen_stack-6.13.0/prereg/ws_oracle.yaml +45 -0
  301. pen_stack-6.13.0/prereg/ws_r.yaml +51 -0
  302. pen_stack-6.13.0/prereg/ws_verify.yaml +45 -0
  303. pen_stack-6.13.0/prereg/ws_writer.yaml +43 -0
  304. pen_stack-6.13.0/pyproject.toml +111 -0
  305. pen_stack-6.13.0/scripts/build_capsid_fitness.py +93 -0
  306. pen_stack-6.13.0/scripts/calibrate_immune_axes.py +116 -0
  307. pen_stack-6.13.0/scripts/fetch_licensed_sources.py +57 -0
  308. pen_stack-6.13.0/scripts/offtarget_chromatin_incremental.py +148 -0
  309. pen_stack-6.13.0/scripts/offtarget_chromatin_matched.py +135 -0
  310. pen_stack-6.13.0/scripts/offtarget_chromatin_validation.py +115 -0
  311. pen_stack-6.13.0/scripts/p1_build_atlas.py +87 -0
  312. pen_stack-6.13.0/scripts/p1_build_durability.py +61 -0
  313. pen_stack-6.13.0/scripts/p1_build_position_effect.py +103 -0
  314. pen_stack-6.13.0/scripts/p1_build_writer_eff.py +66 -0
  315. pen_stack-6.13.0/scripts/p1_export_tracks.py +22 -0
  316. pen_stack-6.13.0/scripts/p1_safety_concordance.py +82 -0
  317. pen_stack-6.13.0/scripts/p1_train_safety.py +48 -0
  318. pen_stack-6.13.0/scripts/p1_validation_report.py +80 -0
  319. pen_stack-6.13.0/scripts/p2_build_atlas.py +36 -0
  320. pen_stack-6.13.0/scripts/p3_benchmark_report.py +82 -0
  321. pen_stack-6.13.0/scripts/p4_genome_scan.py +43 -0
  322. pen_stack-6.13.0/scripts/p52_build_genotox_oracle.py +115 -0
  323. pen_stack-6.13.0/scripts/p53_build_epitope_oracle.py +120 -0
  324. pen_stack-6.13.0/scripts/ws_b_report.py +104 -0
  325. pen_stack-6.11.0/CHANGELOG.md +0 -1565
  326. pen_stack-6.11.0/CITATION.cff +0 -19
  327. pen_stack-6.11.0/PKG-INFO +0 -1132
  328. pen_stack-6.11.0/README.md +0 -1057
  329. pen_stack-6.11.0/bench/run.py +0 -164
  330. pen_stack-6.11.0/benchmarks/genome_writing_bench/LEADERBOARD.md +0 -67
  331. pen_stack-6.11.0/benchmarks/genome_writing_bench/README.md +0 -87
  332. pen_stack-6.11.0/benchmarks/genome_writing_bench/tasks.yaml +0 -335
  333. pen_stack-6.11.0/benchmarks/genome_writing_challenge/README.md +0 -49
  334. pen_stack-6.11.0/benchmarks/genome_writing_challenge/SUBMISSIONS.md +0 -16
  335. pen_stack-6.11.0/benchmarks/position_effect/README.md +0 -60
  336. pen_stack-6.11.0/benchmarks/writer_efficiency/README.md +0 -54
  337. pen_stack-6.11.0/configs/aav_serotype_tropism.yaml +0 -81
  338. pen_stack-6.11.0/configs/antipeg.yaml +0 -28
  339. pen_stack-6.11.0/configs/atlas_families.yaml +0 -81
  340. pen_stack-6.11.0/configs/bridge_offtarget_profile.yaml +0 -51
  341. pen_stack-6.11.0/configs/calibration/preexisting_nab_independent.yaml +0 -25
  342. pen_stack-6.11.0/configs/cargo_polish.yaml +0 -45
  343. pen_stack-6.11.0/configs/cell_types.yaml +0 -56
  344. pen_stack-6.11.0/configs/datasets.yaml +0 -99
  345. pen_stack-6.11.0/configs/delivery_constraints.yaml +0 -50
  346. pen_stack-6.11.0/configs/delivery_rules.yaml +0 -15
  347. pen_stack-6.11.0/configs/delivery_vehicles.yaml +0 -185
  348. pen_stack-6.11.0/configs/expression/modifiers.yaml +0 -59
  349. pen_stack-6.11.0/configs/expression/promoters.yaml +0 -52
  350. pen_stack-6.11.0/configs/gates_v3.yaml +0 -208
  351. pen_stack-6.11.0/configs/gsh_validated_heldout.yaml +0 -87
  352. pen_stack-6.11.0/configs/intent_weights.yaml +0 -42
  353. pen_stack-6.11.0/configs/known_unknowns.yaml +0 -110
  354. pen_stack-6.11.0/configs/llm.yaml +0 -59
  355. pen_stack-6.11.0/configs/metric_guide.yaml +0 -109
  356. pen_stack-6.11.0/configs/oracles/execution.yaml +0 -87
  357. pen_stack-6.11.0/configs/oracles/scope_cards.yaml +0 -237
  358. pen_stack-6.11.0/configs/rules/fold.yaml +0 -15
  359. pen_stack-6.11.0/configs/rules/reachability.yaml +0 -16
  360. pen_stack-6.11.0/configs/safety/hazard_registry.yaml +0 -147
  361. pen_stack-6.11.0/configs/safety/policy.yaml +0 -23
  362. pen_stack-6.11.0/configs/safety/probes.yaml +0 -74
  363. pen_stack-6.11.0/configs/score_axes.yaml +0 -68
  364. pen_stack-6.11.0/configs/seroprevalence.yaml +0 -64
  365. pen_stack-6.11.0/configs/target_sites.yaml +0 -66
  366. pen_stack-6.11.0/configs/universe_crosswalk.yaml +0 -36
  367. pen_stack-6.11.0/configs/write_types.yaml +0 -57
  368. pen_stack-6.11.0/configs/wtkb_curated.yaml +0 -165
  369. pen_stack-6.11.0/docs/BACKLOG.md +0 -20
  370. pen_stack-6.11.0/docs/DEVIATIONS_AND_DISCLOSURES.md +0 -68
  371. pen_stack-6.11.0/docs/STABILITY.md +0 -51
  372. pen_stack-6.11.0/docs/agent.md +0 -78
  373. pen_stack-6.11.0/docs/alphagenome_feasibility.md +0 -49
  374. pen_stack-6.11.0/docs/autonomy.md +0 -36
  375. pen_stack-6.11.0/docs/benchmark_circularity.md +0 -64
  376. pen_stack-6.11.0/docs/biosecurity.md +0 -64
  377. pen_stack-6.11.0/docs/build_interface.md +0 -50
  378. pen_stack-6.11.0/docs/cards/durability.md +0 -43
  379. pen_stack-6.11.0/docs/cards/offtarget_data.md +0 -92
  380. pen_stack-6.11.0/docs/cards/position_effect_data.md +0 -36
  381. pen_stack-6.11.0/docs/cards/writer_efficiency_data.md +0 -48
  382. pen_stack-6.11.0/docs/challenge.md +0 -33
  383. pen_stack-6.11.0/docs/closed_loop.md +0 -54
  384. pen_stack-6.11.0/docs/co_scientist.md +0 -31
  385. pen_stack-6.11.0/docs/co_scientist_loop.md +0 -31
  386. pen_stack-6.11.0/docs/delivery.md +0 -22
  387. pen_stack-6.11.0/docs/delivery_immunology.md +0 -150
  388. pen_stack-6.11.0/docs/delivery_recommender.md +0 -54
  389. pen_stack-6.11.0/docs/digital_twin.md +0 -55
  390. pen_stack-6.11.0/docs/dissemination.md +0 -34
  391. pen_stack-6.11.0/docs/environment.md +0 -59
  392. pen_stack-6.11.0/docs/experiment_design.md +0 -44
  393. pen_stack-6.11.0/docs/generative_design.md +0 -63
  394. pen_stack-6.11.0/docs/immune_profiler.md +0 -70
  395. pen_stack-6.11.0/docs/index.md +0 -48
  396. pen_stack-6.11.0/docs/integrations.md +0 -87
  397. pen_stack-6.11.0/docs/live_oracles.md +0 -56
  398. pen_stack-6.11.0/docs/mechanistic_constraints.md +0 -59
  399. pen_stack-6.11.0/docs/offtarget.md +0 -58
  400. pen_stack-6.11.0/docs/oracles.md +0 -51
  401. pen_stack-6.11.0/docs/position_effect.md +0 -57
  402. pen_stack-6.11.0/docs/positioning.md +0 -55
  403. pen_stack-6.11.0/docs/private_data_formats.md +0 -61
  404. pen_stack-6.11.0/docs/responsible_use.md +0 -84
  405. pen_stack-6.11.0/docs/rules.md +0 -19
  406. pen_stack-6.11.0/docs/scope.md +0 -50
  407. pen_stack-6.11.0/docs/tpe_bench.md +0 -48
  408. pen_stack-6.11.0/docs/tutorials/which-writer-reaches-locus.md +0 -41
  409. pen_stack-6.11.0/docs/uncertainty.md +0 -84
  410. pen_stack-6.11.0/docs/verify.md +0 -60
  411. pen_stack-6.11.0/docs/world_model.md +0 -49
  412. pen_stack-6.11.0/docs/writer_efficiency.md +0 -59
  413. pen_stack-6.11.0/docs/writer_verification.md +0 -46
  414. pen_stack-6.11.0/pen_stack/__init__.py +0 -2
  415. pen_stack-6.11.0/pen_stack/_resources.py +0 -34
  416. pen_stack-6.11.0/pen_stack/active/__init__.py +0 -20
  417. pen_stack-6.11.0/pen_stack/active/acquire.py +0 -73
  418. pen_stack-6.11.0/pen_stack/active/design.py +0 -51
  419. pen_stack-6.11.0/pen_stack/active/validate.py +0 -104
  420. pen_stack-6.11.0/pen_stack/adapt/ingest.py +0 -86
  421. pen_stack-6.11.0/pen_stack/adapt/pipeline.py +0 -101
  422. pen_stack-6.11.0/pen_stack/adapt/recalibrate.py +0 -58
  423. pen_stack-6.11.0/pen_stack/adapt/report.py +0 -130
  424. pen_stack-6.11.0/pen_stack/agent/cite.py +0 -168
  425. pen_stack-6.11.0/pen_stack/agent/co_scientist.py +0 -268
  426. pen_stack-6.11.0/pen_stack/agent/epistemic.py +0 -100
  427. pen_stack-6.11.0/pen_stack/agent/guardrails.py +0 -67
  428. pen_stack-6.11.0/pen_stack/agent/mcp_server.py +0 -149
  429. pen_stack-6.11.0/pen_stack/agent/orchestrator.py +0 -106
  430. pen_stack-6.11.0/pen_stack/agent/orchestrator_live.py +0 -56
  431. pen_stack-6.11.0/pen_stack/agent/pen_agent.py +0 -242
  432. pen_stack-6.11.0/pen_stack/agent/scope.py +0 -60
  433. pen_stack-6.11.0/pen_stack/api/__init__.py +0 -12
  434. pen_stack-6.11.0/pen_stack/api/manifest.py +0 -121
  435. pen_stack-6.11.0/pen_stack/atlas/build_wtkb.py +0 -80
  436. pen_stack-6.11.0/pen_stack/atlas/crosslink.py +0 -141
  437. pen_stack-6.11.0/pen_stack/atlas/expand.py +0 -190
  438. pen_stack-6.11.0/pen_stack/atlas/guide_design.py +0 -174
  439. pen_stack-6.11.0/pen_stack/atlas/schema.py +0 -59
  440. pen_stack-6.11.0/pen_stack/atlas/scorecard.py +0 -134
  441. pen_stack-6.11.0/pen_stack/atlas/variant_propose.py +0 -155
  442. pen_stack-6.11.0/pen_stack/atlas/writer_efficiency.py +0 -184
  443. pen_stack-6.11.0/pen_stack/atlas/writer_predict.py +0 -225
  444. pen_stack-6.11.0/pen_stack/atlas/writer_recommend.py +0 -103
  445. pen_stack-6.11.0/pen_stack/atlas/writer_verify.py +0 -167
  446. pen_stack-6.11.0/pen_stack/bridge/cli.py +0 -65
  447. pen_stack-6.11.0/pen_stack/bridge/fold_qc.py +0 -53
  448. pen_stack-6.11.0/pen_stack/bridge/guide_qc.py +0 -87
  449. pen_stack-6.11.0/pen_stack/bridge/ingest.py +0 -139
  450. pen_stack-6.11.0/pen_stack/bridge/offtarget.py +0 -191
  451. pen_stack-6.11.0/pen_stack/bridge/offtarget_energetics.py +0 -105
  452. pen_stack-6.11.0/pen_stack/bridge/ortholog_screen.py +0 -73
  453. pen_stack-6.11.0/pen_stack/bridge/pipeline.py +0 -83
  454. pen_stack-6.11.0/pen_stack/build/__init__.py +0 -16
  455. pen_stack-6.11.0/pen_stack/build/ingest.py +0 -47
  456. pen_stack-6.11.0/pen_stack/build/protocol.py +0 -82
  457. pen_stack-6.11.0/pen_stack/build/simlab.py +0 -30
  458. pen_stack-6.11.0/pen_stack/cli.py +0 -126
  459. pen_stack-6.11.0/pen_stack/data/encode.py +0 -84
  460. pen_stack-6.11.0/pen_stack/data/genome.py +0 -71
  461. pen_stack-6.11.0/pen_stack/data/ingest_chromatin.py +0 -119
  462. pen_stack-6.11.0/pen_stack/data/ingest_integration.py +0 -112
  463. pen_stack-6.11.0/pen_stack/data/ingest_safety_annot.py +0 -201
  464. pen_stack-6.11.0/pen_stack/data/ingest_trip.py +0 -76
  465. pen_stack-6.11.0/pen_stack/design/__init__.py +0 -14
  466. pen_stack-6.11.0/pen_stack/design/capsid_generate.py +0 -62
  467. pen_stack-6.11.0/pen_stack/design/generate.py +0 -48
  468. pen_stack-6.11.0/pen_stack/design/pareto.py +0 -70
  469. pen_stack-6.11.0/pen_stack/design/space.py +0 -85
  470. pen_stack-6.11.0/pen_stack/design/writer_variants.py +0 -121
  471. pen_stack-6.11.0/pen_stack/env/genome_writing_env.py +0 -248
  472. pen_stack-6.11.0/pen_stack/env/policies.py +0 -94
  473. pen_stack-6.11.0/pen_stack/graph/build.py +0 -133
  474. pen_stack-6.11.0/pen_stack/graph/cell_types.py +0 -58
  475. pen_stack-6.11.0/pen_stack/graph/ingest.py +0 -132
  476. pen_stack-6.11.0/pen_stack/graph/query.py +0 -79
  477. pen_stack-6.11.0/pen_stack/graph/schema.py +0 -100
  478. pen_stack-6.11.0/pen_stack/loop/__init__.py +0 -15
  479. pen_stack-6.11.0/pen_stack/loop/continual.py +0 -61
  480. pen_stack-6.11.0/pen_stack/loop/cycle.py +0 -84
  481. pen_stack-6.11.0/pen_stack/loop/drift.py +0 -41
  482. pen_stack-6.11.0/pen_stack/mech/classify_atlas.py +0 -71
  483. pen_stack-6.11.0/pen_stack/mech/whitelist.py +0 -66
  484. pen_stack-6.11.0/pen_stack/monitor/europepmc.py +0 -32
  485. pen_stack-6.11.0/pen_stack/monitor/run.py +0 -57
  486. pen_stack-6.11.0/pen_stack/monitor/triage.py +0 -63
  487. pen_stack-6.11.0/pen_stack/oracles/__init__.py +0 -65
  488. pen_stack-6.11.0/pen_stack/oracles/cache.py +0 -53
  489. pen_stack-6.11.0/pen_stack/oracles/energetics.py +0 -33
  490. pen_stack-6.11.0/pen_stack/oracles/genome.py +0 -167
  491. pen_stack-6.11.0/pen_stack/oracles/protein_design.py +0 -136
  492. pen_stack-6.11.0/pen_stack/oracles/rna.py +0 -28
  493. pen_stack-6.11.0/pen_stack/oracles/schema.py +0 -63
  494. pen_stack-6.11.0/pen_stack/oracles/status.py +0 -110
  495. pen_stack-6.11.0/pen_stack/oracles/structure.py +0 -43
  496. pen_stack-6.11.0/pen_stack/oracles/vcell.py +0 -74
  497. pen_stack-6.11.0/pen_stack/planner/ada_risk.py +0 -64
  498. pen_stack-6.11.0/pen_stack/planner/antipeg_oracle.py +0 -75
  499. pen_stack-6.11.0/pen_stack/planner/capsid_epitope_oracle.py +0 -136
  500. pen_stack-6.11.0/pen_stack/planner/cargo.py +0 -56
  501. pen_stack-6.11.0/pen_stack/planner/cargo_polish.py +0 -146
  502. pen_stack-6.11.0/pen_stack/planner/delivery.py +0 -55
  503. pen_stack-6.11.0/pen_stack/planner/delivery_constraints.py +0 -110
  504. pen_stack-6.11.0/pen_stack/planner/delivery_immune.py +0 -60
  505. pen_stack-6.11.0/pen_stack/planner/delivery_immunology.py +0 -208
  506. pen_stack-6.11.0/pen_stack/planner/delivery_predict.py +0 -136
  507. pen_stack-6.11.0/pen_stack/planner/genotoxicity_oracle.py +0 -112
  508. pen_stack-6.11.0/pen_stack/planner/immune_mhc2.py +0 -154
  509. pen_stack-6.11.0/pen_stack/planner/immune_profile.py +0 -156
  510. pen_stack-6.11.0/pen_stack/planner/innate_sensing.py +0 -135
  511. pen_stack-6.11.0/pen_stack/planner/multiplex.py +0 -110
  512. pen_stack-6.11.0/pen_stack/planner/optimize.py +0 -251
  513. pen_stack-6.11.0/pen_stack/planner/pipeline.py +0 -86
  514. pen_stack-6.11.0/pen_stack/planner/report.py +0 -26
  515. pen_stack-6.11.0/pen_stack/planner/router.py +0 -57
  516. pen_stack-6.11.0/pen_stack/planner/seroprevalence_oracle.py +0 -92
  517. pen_stack-6.11.0/pen_stack/planner/target_site.py +0 -118
  518. pen_stack-6.11.0/pen_stack/rag/llm.py +0 -178
  519. pen_stack-6.11.0/pen_stack/rag/qa.py +0 -105
  520. pen_stack-6.11.0/pen_stack/rules/__init__.py +0 -9
  521. pen_stack-6.11.0/pen_stack/rules/evaluators.py +0 -217
  522. pen_stack-6.11.0/pen_stack/rules/schema.py +0 -82
  523. pen_stack-6.11.0/pen_stack/rules/solver.py +0 -43
  524. pen_stack-6.11.0/pen_stack/safety/__init__.py +0 -21
  525. pen_stack-6.11.0/pen_stack/safety/audit.py +0 -90
  526. pen_stack-6.11.0/pen_stack/safety/gate.py +0 -37
  527. pen_stack-6.11.0/pen_stack/safety/policy.py +0 -65
  528. pen_stack-6.11.0/pen_stack/safety/redteam.py +0 -71
  529. pen_stack-6.11.0/pen_stack/safety/registry.py +0 -173
  530. pen_stack-6.11.0/pen_stack/safety/screen.py +0 -51
  531. pen_stack-6.11.0/pen_stack/score/therapeutic.py +0 -85
  532. pen_stack-6.11.0/pen_stack/server/api.py +0 -313
  533. pen_stack-6.11.0/pen_stack/twin/__init__.py +0 -14
  534. pen_stack-6.11.0/pen_stack/twin/calibrate.py +0 -61
  535. pen_stack-6.11.0/pen_stack/twin/data/__init__.py +0 -12
  536. pen_stack-6.11.0/pen_stack/twin/data/position_effect.py +0 -224
  537. pen_stack-6.11.0/pen_stack/twin/mechanistic.py +0 -119
  538. pen_stack-6.11.0/pen_stack/twin/outcome.py +0 -102
  539. pen_stack-6.11.0/pen_stack/twin/position_effect.py +0 -369
  540. pen_stack-6.11.0/pen_stack/ui/app.py +0 -713
  541. pen_stack-6.11.0/pen_stack/validate/adapt_demo.py +0 -69
  542. pen_stack-6.11.0/pen_stack/validate/agent_eval.py +0 -117
  543. pen_stack-6.11.0/pen_stack/validate/bench_adversarial_tasks.py +0 -118
  544. pen_stack-6.11.0/pen_stack/validate/bench_coscientist_tasks.py +0 -60
  545. pen_stack-6.11.0/pen_stack/validate/bench_graph_tasks.py +0 -64
  546. pen_stack-6.11.0/pen_stack/validate/bench_rule_tasks.py +0 -84
  547. pen_stack-6.11.0/pen_stack/validate/bench_trust_tasks.py +0 -92
  548. pen_stack-6.11.0/pen_stack/validate/bench_writetype_tasks.py +0 -101
  549. pen_stack-6.11.0/pen_stack/validate/blind_gsh_discovery.py +0 -261
  550. pen_stack-6.11.0/pen_stack/validate/cargo_directionality.py +0 -57
  551. pen_stack-6.11.0/pen_stack/validate/closed_loop.py +0 -63
  552. pen_stack-6.11.0/pen_stack/validate/durability_baselines.py +0 -185
  553. pen_stack-6.11.0/pen_stack/validate/experiment_design.py +0 -65
  554. pen_stack-6.11.0/pen_stack/validate/expr_controls.py +0 -39
  555. pen_stack-6.11.0/pen_stack/validate/forward_hypotheses.py +0 -104
  556. pen_stack-6.11.0/pen_stack/validate/generative_design.py +0 -62
  557. pen_stack-6.11.0/pen_stack/validate/guide_qc_demo.py +0 -69
  558. pen_stack-6.11.0/pen_stack/validate/heldout_celltype_expr.py +0 -32
  559. pen_stack-6.11.0/pen_stack/validate/immune_calibration.py +0 -133
  560. pen_stack-6.11.0/pen_stack/validate/intent_specification.py +0 -82
  561. pen_stack-6.11.0/pen_stack/validate/offtarget_energetics_eval.py +0 -144
  562. pen_stack-6.11.0/pen_stack/validate/out_of_scope_refusal.py +0 -82
  563. pen_stack-6.11.0/pen_stack/validate/outcome_calibration.py +0 -194
  564. pen_stack-6.11.0/pen_stack/validate/outcome_prediction.py +0 -76
  565. pen_stack-6.11.0/pen_stack/validate/paper3_benchmark.py +0 -165
  566. pen_stack-6.11.0/pen_stack/validate/paper4_real_validation.py +0 -144
  567. pen_stack-6.11.0/pen_stack/validate/paper4_validation.py +0 -82
  568. pen_stack-6.11.0/pen_stack/validate/protocol_safety.py +0 -62
  569. pen_stack-6.11.0/pen_stack/validate/safety_screening.py +0 -72
  570. pen_stack-6.11.0/pen_stack/validate/selective_prediction.py +0 -104
  571. pen_stack-6.11.0/pen_stack/validate/seq_vs_measured.py +0 -134
  572. pen_stack-6.11.0/pen_stack/validate/target_site_controls.py +0 -65
  573. pen_stack-6.11.0/pen_stack/validate/uncertainty_eval.py +0 -244
  574. pen_stack-6.11.0/pen_stack/validate/ungrounded_baseline.py +0 -234
  575. pen_stack-6.11.0/pen_stack/validate/within_locus_ranking.py +0 -84
  576. pen_stack-6.11.0/pen_stack/validate/writer_recovery.py +0 -91
  577. pen_stack-6.11.0/pen_stack/verify/schema.py +0 -48
  578. pen_stack-6.11.0/pen_stack/verify/service.py +0 -176
  579. pen_stack-6.11.0/pen_stack/web/__init__.py +0 -18
  580. pen_stack-6.11.0/pen_stack/web/guide.py +0 -110
  581. pen_stack-6.11.0/pen_stack/web/llm.py +0 -413
  582. pen_stack-6.11.0/pen_stack/web/router.py +0 -96
  583. pen_stack-6.11.0/pen_stack/web/server.py +0 -95
  584. pen_stack-6.11.0/pen_stack/web/tools.py +0 -197
  585. pen_stack-6.11.0/pen_stack/wgenome/chromatin_seq.py +0 -83
  586. pen_stack-6.11.0/pen_stack/wgenome/durability.py +0 -108
  587. pen_stack-6.11.0/pen_stack/wgenome/features.py +0 -82
  588. pen_stack-6.11.0/pen_stack/wgenome/gsh_baseline.py +0 -154
  589. pen_stack-6.11.0/pen_stack/wgenome/mesh_features.py +0 -61
  590. pen_stack-6.11.0/pen_stack/wgenome/offtarget_assay.py +0 -55
  591. pen_stack-6.11.0/pen_stack/wgenome/offtarget_data.py +0 -148
  592. pen_stack-6.11.0/pen_stack/wgenome/offtarget_predict.py +0 -238
  593. pen_stack-6.11.0/pen_stack/wgenome/ood.py +0 -135
  594. pen_stack-6.11.0/pen_stack/wgenome/providers.py +0 -278
  595. pen_stack-6.11.0/pen_stack/wgenome/safety.py +0 -69
  596. pen_stack-6.11.0/pen_stack/wgenome/structure3d.py +0 -212
  597. pen_stack-6.11.0/pen_stack/wgenome/uncertainty.py +0 -260
  598. pen_stack-6.11.0/pen_stack/wgenome/writability.py +0 -72
  599. pen_stack-6.11.0/pen_stack.egg-info/PKG-INFO +0 -1132
  600. pen_stack-6.11.0/pen_stack.egg-info/SOURCES.txt +0 -509
  601. pen_stack-6.11.0/prereg/SHA256_LOCK_ws_delivery.json +0 -8
  602. pen_stack-6.11.0/prereg/SHA256_LOCK_ws_hybrid.json +0 -8
  603. pen_stack-6.11.0/prereg/SHA256_LOCK_ws_immune2.json +0 -8
  604. pen_stack-6.11.0/prereg/SHA256_LOCK_ws_offtarget.json +0 -8
  605. pen_stack-6.11.0/prereg/SHA256_LOCK_ws_r.json +0 -14
  606. pen_stack-6.11.0/prereg/SHA256_LOCK_ws_writer.json +0 -8
  607. pen_stack-6.11.0/prereg/ws_delivery.yaml +0 -39
  608. pen_stack-6.11.0/prereg/ws_hybrid.yaml +0 -30
  609. pen_stack-6.11.0/prereg/ws_immune2.yaml +0 -36
  610. pen_stack-6.11.0/prereg/ws_offtarget.yaml +0 -42
  611. pen_stack-6.11.0/prereg/ws_r.yaml +0 -51
  612. pen_stack-6.11.0/prereg/ws_writer.yaml +0 -43
  613. pen_stack-6.11.0/pyproject.toml +0 -111
  614. pen_stack-6.11.0/scripts/build_capsid_fitness.py +0 -93
  615. pen_stack-6.11.0/scripts/calibrate_immune_axes.py +0 -116
  616. pen_stack-6.11.0/scripts/fetch_licensed_sources.py +0 -57
  617. pen_stack-6.11.0/scripts/offtarget_chromatin_incremental.py +0 -148
  618. pen_stack-6.11.0/scripts/offtarget_chromatin_matched.py +0 -135
  619. pen_stack-6.11.0/scripts/offtarget_chromatin_validation.py +0 -115
  620. pen_stack-6.11.0/scripts/p1_build_atlas.py +0 -87
  621. pen_stack-6.11.0/scripts/p1_build_durability.py +0 -61
  622. pen_stack-6.11.0/scripts/p1_build_position_effect.py +0 -103
  623. pen_stack-6.11.0/scripts/p1_build_writer_eff.py +0 -66
  624. pen_stack-6.11.0/scripts/p1_export_tracks.py +0 -22
  625. pen_stack-6.11.0/scripts/p1_safety_concordance.py +0 -82
  626. pen_stack-6.11.0/scripts/p1_train_safety.py +0 -48
  627. pen_stack-6.11.0/scripts/p1_validation_report.py +0 -80
  628. pen_stack-6.11.0/scripts/p2_build_atlas.py +0 -36
  629. pen_stack-6.11.0/scripts/p3_benchmark_report.py +0 -82
  630. pen_stack-6.11.0/scripts/p4_genome_scan.py +0 -43
  631. pen_stack-6.11.0/scripts/p52_build_genotox_oracle.py +0 -115
  632. pen_stack-6.11.0/scripts/p53_build_epitope_oracle.py +0 -120
  633. pen_stack-6.11.0/scripts/ws_b_report.py +0 -104
  634. {pen_stack-6.11.0 → pen_stack-6.13.0}/LICENSE +0 -0
  635. {pen_stack-6.11.0 → pen_stack-6.13.0}/MANIFEST.in +0 -0
  636. {pen_stack-6.11.0 → pen_stack-6.13.0}/benchmarks/delivery/SHA256SUMS +0 -0
  637. {pen_stack-6.11.0 → pen_stack-6.13.0}/benchmarks/genome_writing_bench/SHA256SUMS +0 -0
  638. {pen_stack-6.11.0 → pen_stack-6.13.0}/benchmarks/genome_writing_bench/SUBMISSIONS.md +0 -0
  639. {pen_stack-6.11.0 → pen_stack-6.13.0}/benchmarks/offtarget/SHA256SUMS +0 -0
  640. {pen_stack-6.11.0 → pen_stack-6.13.0}/benchmarks/position_effect/SHA256SUMS +0 -0
  641. {pen_stack-6.11.0 → pen_stack-6.13.0}/benchmarks/writer_efficiency/SHA256SUMS +0 -0
  642. {pen_stack-6.11.0 → pen_stack-6.13.0}/configs/capsid_epitope_oracle.yaml +0 -0
  643. {pen_stack-6.11.0 → pen_stack-6.13.0}/configs/capsid_sequences.fasta +0 -0
  644. {pen_stack-6.11.0 → pen_stack-6.13.0}/configs/genotoxicity_oracle.yaml +0 -0
  645. {pen_stack-6.11.0 → pen_stack-6.13.0}/configs/mhc_epitope_oracle.yaml +0 -0
  646. {pen_stack-6.11.0 → pen_stack-6.13.0}/configs/monitor_queries.yaml +0 -0
  647. {pen_stack-6.11.0 → pen_stack-6.13.0}/configs/rules/delivery.yaml +0 -0
  648. {pen_stack-6.11.0 → pen_stack-6.13.0}/configs/rules/multiplex.yaml +0 -0
  649. {pen_stack-6.11.0 → pen_stack-6.13.0}/configs/rules/payload.yaml +0 -0
  650. {pen_stack-6.11.0 → pen_stack-6.13.0}/configs/writer_sequences.fasta +0 -0
  651. {pen_stack-6.11.0 → pen_stack-6.13.0}/data/curated/bridge_offtarget_energetics.json +0 -0
  652. {pen_stack-6.11.0 → pen_stack-6.13.0}/data/curated/bridge_offtarget_profile_measured.parquet +0 -0
  653. {pen_stack-6.11.0 → pen_stack-6.13.0}/data/curated/gene_coords.parquet +0 -0
  654. {pen_stack-6.11.0 → pen_stack-6.13.0}/data/curated/unified_editor_universe.parquet +0 -0
  655. {pen_stack-6.11.0 → pen_stack-6.13.0}/docs/DEPLOY.md +0 -0
  656. {pen_stack-6.11.0 → pen_stack-6.13.0}/docs/INFRA.md +0 -0
  657. {pen_stack-6.11.0 → pen_stack-6.13.0}/docs/MCP.md +0 -0
  658. {pen_stack-6.11.0 → pen_stack-6.13.0}/docs/RELEASING.md +0 -0
  659. {pen_stack-6.11.0 → pen_stack-6.13.0}/docs/REPRO.md +0 -0
  660. {pen_stack-6.11.0 → pen_stack-6.13.0}/docs/cards/atlas.md +0 -0
  661. {pen_stack-6.11.0 → pen_stack-6.13.0}/docs/cards/safety.md +0 -0
  662. {pen_stack-6.11.0 → pen_stack-6.13.0}/docs/quickstart.md +0 -0
  663. {pen_stack-6.11.0 → pen_stack-6.13.0}/docs/scorecard.md +0 -0
  664. {pen_stack-6.11.0 → pen_stack-6.13.0}/docs/tutorials/compare-families.md +0 -0
  665. {pen_stack-6.11.0 → pen_stack-6.13.0}/docs/tutorials/score-deliverability.md +0 -0
  666. {pen_stack-6.11.0 → pen_stack-6.13.0}/docs/tutorials/where-can-i-write.md +0 -0
  667. {pen_stack-6.11.0 → pen_stack-6.13.0}/docs/wtkb.md +0 -0
  668. {pen_stack-6.11.0 → pen_stack-6.13.0}/pen_stack/adapt/__init__.py +0 -0
  669. {pen_stack-6.11.0 → pen_stack-6.13.0}/pen_stack/adapt/finetune.py +0 -0
  670. {pen_stack-6.11.0 → pen_stack-6.13.0}/pen_stack/agent/__init__.py +0 -0
  671. {pen_stack-6.11.0 → pen_stack-6.13.0}/pen_stack/agent/tools.py +0 -0
  672. {pen_stack-6.11.0 → pen_stack-6.13.0}/pen_stack/atlas/__init__.py +0 -0
  673. {pen_stack-6.11.0 → pen_stack-6.13.0}/pen_stack/atlas/universe.py +0 -0
  674. {pen_stack-6.11.0 → pen_stack-6.13.0}/pen_stack/bridge/__init__.py +0 -0
  675. {pen_stack-6.11.0 → pen_stack-6.13.0}/pen_stack/bridge/activity.py +0 -0
  676. {pen_stack-6.11.0 → pen_stack-6.13.0}/pen_stack/data/__init__.py +0 -0
  677. {pen_stack-6.11.0 → pen_stack-6.13.0}/pen_stack/env/__init__.py +0 -0
  678. {pen_stack-6.11.0 → pen_stack-6.13.0}/pen_stack/graph/__init__.py +0 -0
  679. {pen_stack-6.11.0 → pen_stack-6.13.0}/pen_stack/mech/__init__.py +0 -0
  680. {pen_stack-6.11.0 → pen_stack-6.13.0}/pen_stack/monitor/__init__.py +0 -0
  681. {pen_stack-6.11.0 → pen_stack-6.13.0}/pen_stack/planner/__init__.py +0 -0
  682. {pen_stack-6.11.0 → pen_stack-6.13.0}/pen_stack/planner/delivery_vehicles.py +0 -0
  683. {pen_stack-6.11.0 → pen_stack-6.13.0}/pen_stack/rag/__init__.py +0 -0
  684. {pen_stack-6.11.0 → pen_stack-6.13.0}/pen_stack/rag/index.py +0 -0
  685. {pen_stack-6.11.0 → pen_stack-6.13.0}/pen_stack/rules/loader.py +0 -0
  686. {pen_stack-6.11.0 → pen_stack-6.13.0}/pen_stack/score/__init__.py +0 -0
  687. {pen_stack-6.11.0 → pen_stack-6.13.0}/pen_stack/score/recalibrate.py +0 -0
  688. {pen_stack-6.11.0 → pen_stack-6.13.0}/pen_stack/server/__init__.py +0 -0
  689. {pen_stack-6.11.0 → pen_stack-6.13.0}/pen_stack/ui/__init__.py +0 -0
  690. {pen_stack-6.11.0 → pen_stack-6.13.0}/pen_stack/validate/__init__.py +0 -0
  691. {pen_stack-6.11.0 → pen_stack-6.13.0}/pen_stack/validate/known_biology_expr.py +0 -0
  692. {pen_stack-6.11.0 → pen_stack-6.13.0}/pen_stack/verify/__init__.py +0 -0
  693. {pen_stack-6.11.0 → pen_stack-6.13.0}/pen_stack/wgenome/__init__.py +0 -0
  694. {pen_stack-6.11.0 → pen_stack-6.13.0}/pen_stack/wgenome/export_tracks.py +0 -0
  695. {pen_stack-6.11.0 → pen_stack-6.13.0}/pen_stack.egg-info/dependency_links.txt +0 -0
  696. {pen_stack-6.11.0 → pen_stack-6.13.0}/pen_stack.egg-info/entry_points.txt +0 -0
  697. {pen_stack-6.11.0 → pen_stack-6.13.0}/pen_stack.egg-info/requires.txt +0 -0
  698. {pen_stack-6.11.0 → pen_stack-6.13.0}/pen_stack.egg-info/top_level.txt +0 -0
  699. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_phase0.json +0 -0
  700. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_phase1_5.json +0 -0
  701. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_phase2.json +0 -0
  702. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_phase3.json +0 -0
  703. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_a.json +0 -0
  704. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_acq.json +0 -0
  705. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_aldesign.json +0 -0
  706. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_alvalidate.json +0 -0
  707. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_atlas.json +0 -0
  708. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_b.json +0 -0
  709. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_ba.json +0 -0
  710. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_ba_v33.json +0 -0
  711. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_ba_v45.json +0 -0
  712. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_bench.json +0 -0
  713. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_c.json +0 -0
  714. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_cal.json +0 -0
  715. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_calib.json +0 -0
  716. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_challenge.json +0 -0
  717. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_chat.json +0 -0
  718. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_cite.json +0 -0
  719. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_continual.json +0 -0
  720. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_cosci2.json +0 -0
  721. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_crit.json +0 -0
  722. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_ct.json +0 -0
  723. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_d.json +0 -0
  724. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_drift.json +0 -0
  725. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_e.json +0 -0
  726. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_env.json +0 -0
  727. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_ep.json +0 -0
  728. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_epitope.json +0 -0
  729. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_expr2.json +0 -0
  730. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_f.json +0 -0
  731. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_frontend.json +0 -0
  732. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_g.json +0 -0
  733. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_gen.json +0 -0
  734. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_genotox.json +0 -0
  735. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_graph.json +0 -0
  736. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_h.json +0 -0
  737. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_immune.json +0 -0
  738. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_ingest.json +0 -0
  739. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_innate.json +0 -0
  740. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_loop.json +0 -0
  741. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_manifest.json +0 -0
  742. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_mc.json +0 -0
  743. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_mcp.json +0 -0
  744. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_mech.json +0 -0
  745. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_mon.json +0 -0
  746. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_o.json +0 -0
  747. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_openapi.json +0 -0
  748. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_orch.json +0 -0
  749. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_outcome.json +0 -0
  750. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_pareto.json +0 -0
  751. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_peg.json +0 -0
  752. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_plan.json +0 -0
  753. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_policy.json +0 -0
  754. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_profile.json +0 -0
  755. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_proto.json +0 -0
  756. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_redteam.json +0 -0
  757. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_route.json +0 -0
  758. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_screen.json +0 -0
  759. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_seroprev.json +0 -0
  760. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_simlab.json +0 -0
  761. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_twincal.json +0 -0
  762. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_uq.json +0 -0
  763. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_v.json +0 -0
  764. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_vcell.json +0 -0
  765. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/SHA256_LOCK_ws_wv.json +0 -0
  766. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/paper1.yaml +0 -0
  767. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/paper2.yaml +0 -0
  768. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/paper3.yaml +0 -0
  769. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/paper4.yaml +0 -0
  770. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/phase0.yaml +0 -0
  771. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_a.yaml +0 -0
  772. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_acq.yaml +0 -0
  773. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_aldesign.yaml +0 -0
  774. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_alvalidate.yaml +0 -0
  775. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_atlas.yaml +0 -0
  776. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_b.yaml +0 -0
  777. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_ba.yaml +0 -0
  778. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_ba_v33.yaml +0 -0
  779. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_ba_v45.yaml +0 -0
  780. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_bench.yaml +0 -0
  781. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_c.yaml +0 -0
  782. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_cal.yaml +0 -0
  783. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_calib.yaml +0 -0
  784. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_challenge.yaml +0 -0
  785. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_chat.yaml +0 -0
  786. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_cite.yaml +0 -0
  787. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_continual.yaml +0 -0
  788. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_cosci2.yaml +0 -0
  789. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_crit.yaml +0 -0
  790. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_ct.yaml +0 -0
  791. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_d.yaml +0 -0
  792. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_drift.yaml +0 -0
  793. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_e.yaml +0 -0
  794. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_env.yaml +0 -0
  795. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_ep.yaml +0 -0
  796. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_epitope.yaml +0 -0
  797. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_expr2.yaml +0 -0
  798. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_f.yaml +0 -0
  799. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_frontend.yaml +0 -0
  800. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_g.yaml +0 -0
  801. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_gen.yaml +0 -0
  802. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_genotox.yaml +0 -0
  803. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_graph.yaml +0 -0
  804. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_h.yaml +0 -0
  805. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_immune.yaml +0 -0
  806. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_ingest.yaml +0 -0
  807. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_innate.yaml +0 -0
  808. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_loop.yaml +0 -0
  809. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_manifest.yaml +0 -0
  810. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_mc.yaml +0 -0
  811. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_mcp.yaml +0 -0
  812. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_mech.yaml +0 -0
  813. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_mon.yaml +0 -0
  814. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_o.yaml +0 -0
  815. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_openapi.yaml +0 -0
  816. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_orch.yaml +0 -0
  817. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_outcome.yaml +0 -0
  818. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_pareto.yaml +0 -0
  819. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_peg.yaml +0 -0
  820. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_plan.yaml +0 -0
  821. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_policy.yaml +0 -0
  822. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_profile.yaml +0 -0
  823. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_proto.yaml +0 -0
  824. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_redteam.yaml +0 -0
  825. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_route.yaml +0 -0
  826. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_screen.yaml +0 -0
  827. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_seroprev.yaml +0 -0
  828. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_simlab.yaml +0 -0
  829. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_twincal.yaml +0 -0
  830. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_uq.yaml +0 -0
  831. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_v.yaml +0 -0
  832. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_vcell.yaml +0 -0
  833. {pen_stack-6.11.0 → pen_stack-6.13.0}/prereg/ws_wv.yaml +0 -0
  834. {pen_stack-6.11.0 → pen_stack-6.13.0}/scripts/ws_c_report.py +0 -0
  835. {pen_stack-6.11.0 → pen_stack-6.13.0}/setup.cfg +0 -0
@@ -0,0 +1,1617 @@
1
+ # Changelog
2
+
3
+ All notable changes to PEN-STACK are documented here. This file follows
4
+ [Keep a Changelog](https://keepachangelog.com/).
5
+
6
+ ## [6.13.0] - 2026-06-22 - Oracle mesh: binding-affinity dimension, per-oracle reliability, disagreement-to-uncertainty
7
+
8
+ Hardens the foundation-model oracle mesh under one result contract. Adds a binding-affinity dimension
9
+ (Boltz-2), surfaces each oracle's published reliability reported verbatim from public benchmarks, and makes
10
+ cross-oracle disagreement widen the reported interval. Every oracle output stays a candidate, never ground
11
+ truth.
12
+
13
+ ### Added
14
+ - **Binding-affinity oracle** (`pen_stack/oracles/affinity.py`). Wraps the Boltz-2 protein-ligand affinity head
15
+ (MIT, `10.1101/2025.06.14.659707`): a binder probability and a predicted affinity value with native
16
+ uncertainty taken from the model's own outputs. The head is protein-small-molecule only, so protein-protein
17
+ and protein-DNA pairs are returned as out-of-scope (extrapolating). The backend runs off the request path and
18
+ is cached; an uncached request defers (cache-or-abstain) rather than blocking or fabricating. A grounded,
19
+ in-domain example is committed: 4-hydroxytamoxifen binding the ERT2 ligand-binding domain (the inducible-writer
20
+ switch), predicted as a high-confidence binder (binder probability 0.99, complex pLDDT 0.94).
21
+ - **Per-oracle reliability registry** (`pen_stack/oracles/reliability.py`, `configs/oracles/reliability.yaml`).
22
+ Each oracle's published benchmark accuracy, reported verbatim with citation: the Boltz-2 affinity head's
23
+ FEP+ Pearson r of about 0.62 (paper-reported) is the verified anchor. These are the wrapped models' published
24
+ numbers, not a claim about this stack's accuracy and not re-computed; where a verbatim score was not verified
25
+ the value is left null with the cited benchmark as the pointer.
26
+ - **Disagreement to uncertainty.** Cross-oracle disagreement widens the reported interval (native uncertainty
27
+ plus half the cross-oracle spread); a check confirms the widening is monotonic in the spread.
28
+ - **Held-oracle runner** (`pen_stack/oracles/structure_run.py`) for the structure oracles over writer-substrate
29
+ and att-site complexes: off the request path, cache-or-abstain.
30
+ - **Oracle-Bench** (`benchmarks/oracle/`) reporting the three gates, and surfaces: `GET /api/oracles` extended
31
+ with reliability and the disagreement check, `POST /api/oracle/affinity`, MCP `oracle_query`, the manifest
32
+ `oracle_query` tool, the web Oracle Mesh page, and `docs/oracle_mesh.md`.
33
+
34
+ ### Notes
35
+ - Affinity predictions are candidates with native uncertainty, not measured binding constants; reliability is
36
+ surfaced so a confident-looking value is not over-trusted.
37
+ - The structure oracles over full complexes (AlphaFold3 / Boltz-2 / Chai-1 / Protenix) remain held: run
38
+ separately on GPU or cloud and cached, never inline on the request path.
39
+
40
+ ## [6.12.0] - 2026-06-21 - Verification service: published rule spec, proof object, standards-aligned biosecurity
41
+
42
+ Hardens `verify(design)` into a formal verification service. The rule base becomes a published, citable spec;
43
+ `verify_proof()` returns a repair-oriented proof object an agent can fix a failed design from; and the
44
+ biosecurity gate is mapped to the community synthesis-screening standards.
45
+
46
+ ### Added
47
+ - **Published rule spec** (`pen_stack/rules/spec.py`, `benchmarks/verify/rule_spec.json`, `docs/rule_spec.md`).
48
+ The rule base exports as a machine-readable, citable document. A parity check confirms the exported spec
49
+ round-trips to the exact ruleset the solver loads (0 mismatches), every rule names a registered evaluator,
50
+ and every rule carries a DOI or a note.
51
+ - **Repair-oriented proof object** (`pen_stack/verify/proof.py`). `verify_proof(design)` returns three axes,
52
+ legality, confidence and biosecurity, reported separately, each with a status, the rule or signature that
53
+ fired, evidence, and a repair hint; the collapsed verdict is `None`. `repair_from_proof` fixes a
54
+ failed-on-legality design using only the proof object and re-verifies it. Biosecurity hazards are
55
+ acknowledged and routed to human review, never auto-repaired.
56
+ - **Biosecurity standards alignment** (`pen_stack/safety/standards.py`). Maps the Guardian screen kinds and
57
+ decisions onto the IBBIS Common Mechanism categories and `ScreenStatus` (Pass / Warning / Flag) and onto
58
+ SecureDNA's pass/deny outcome, with a concordance report (8/8 concordant on the labelled probe set).
59
+ References: Common Mechanism (Wheeler et al. 2024, `10.1089/apb.2023.0034`); SecureDNA (`arXiv:2403.14023`).
60
+ - **Verify-Bench** (`benchmarks/verify/`) reporting the three gates, and surfaces: REST `POST /api/verify/proof`,
61
+ MCP `verify_proof`, manifest tool `verify_proof`, the web Verify page (per-axis green/amber/red with the
62
+ violated rule, its citation, and the suggested fix), and `docs/verify_service.md`.
63
+
64
+ ### Notes
65
+ - The verdict covers legality, feasibility and biosecurity, not efficacy (efficacy stays a downstream
66
+ prediction with its own uncertainty). The biosecurity hook is the in-design gate; the full sequence-screening
67
+ pipeline is BioFirewall, and the standard alignment is a concordance, not a certification.
68
+ - The plan paired this with a Stage A WriteSpec / SAT repair loop. Stage A is not yet built, so the proof-object
69
+ repair loop here is self-contained; the WriteSpec coupling is a documented future integration.
70
+
71
+ ## [6.11.0] - 2026-06-20 - Cross-modality deliverability and a learned capsid-fitness model
72
+
73
+ Delivery moves from an 8-vehicle rule palette to a cross-modality recommender. It adds a learned,
74
+ benchmarked AAV capsid-fitness model, a serotype-to-tissue tropism prior grounded in approved therapies, and an
75
+ immune-coupled dose tradeoff, without fabricating tropism. All datasets were independently verified.
76
+
77
+ ### Added
78
+ - **Learned AAV capsid-fitness on FLIP-AAV** (`pen_stack/planner/delivery_predict.py`, `scripts/build_capsid_fitness.py`,
79
+ `benchmarks/delivery/`). Trained on the FLIP-AAV benchmark (Dallago 2021; Bryant 2021 packaging fitness,
80
+ `10.1038/s41587-020-00793-4`; Ogden 2019 `10.1126/science.aaw2900`). It beats a mutation-burden baseline on
81
+ both held-out splits: `sampled` Spearman 0.920 vs 0.522 (CI [0.387, 0.411]); `mut_des`
82
+ (mutant to designed) 0.814 vs 0.752 (CI [0.061, 0.064]). The 217 MB/split FLIP data stays on the VM; the derived
83
+ metrics and the reproducible build script are committed. The ~3 MB model itself is gitignored, regenerated via
84
+ `scripts/build_capsid_fitness.py` and mounted into the deployed app (like `position_effect.pkl`); the axis abstains
85
+ gracefully when absent. Predicted fitness is a candidate for the measured packaging axis, not in-vivo tropism.
86
+ - **Serotype-to-tissue tropism priors** (`configs/aav_serotype_tropism.yaml`) from approved AAV therapies (AAV9 to CNS,
87
+ AAVrh74 to skeletal muscle vs AAVRh74var to liver: different capsids, kept separate; AAV5 to liver; AAV2 to retina/
88
+ putamen via local injection). This is a grounded prior for an approved serotype and a known-unknown (abstain) for a novel
89
+ capsid. Casgevy/Lyfgenia carry no serotype prior (not-AAV controls).
90
+ - **Immune-coupled dose tradeoff** (`pen_stack/planner/delivery_immune.py`) fuses deliverability with the Stage G
91
+ immune profile and surfaces dose vs immunogenicity per vehicle as a vector (`collapsed_score=None`, never fused).
92
+ - **Verify-gated generative capsids** (`pen_stack/design/capsid_generate.py`): fitness-filtered VP1 variants,
93
+ candidates only; abstains without the model.
94
+ - **Surfaces:** REST `POST /delivery`, `POST /capsid_fitness`, and `GET /delivery/tropism`; MCP `delivery_recommend`;
95
+ manifest `recommend_delivery` and `capsid_fitness`; a `capsid_fitness` scope card; a `delivery` Challenge task
96
+ (serotype to tissue); preregistration `ws_delivery.yaml`.
97
+
98
+ ### Limitations
99
+ - The capsid-fitness model is a one-hot gradient-boosting model, not a protein-LM (it passes the gate; a protein-LM is
100
+ the upgrade path). Capsid-fitness covers AAV only (VLP/LNP data is thinner). In-vivo human tropism is
101
+ a known-unknown except for the approved-therapy priors; novel capsids abstain on tropism. alpha-retro-VLP is exploratory.
102
+
103
+ ## [6.10.4] - 2026-06-20 - Chromatin incremental-value test (annotation, not a re-ranker)
104
+
105
+ This patch closes out the chromatin work. v6.10.3 validated accessibility as a moderate standalone
106
+ predictor; v6.10.4 tests whether it adds incremental value on top of the CRISOT sequence score, i.e. whether
107
+ it should re-rank.
108
+
109
+ ### Added
110
+ - **Incremental-value analysis** (`scripts/offtarget_chromatin_incremental.py`; result in
111
+ `benchmarks/offtarget/chromatin_incremental.json`). On GUIDE-seq (HEK293T-matched), per off-target CRISOT plus
112
+ accessibility: (A) a conditional logistic regression `active ~ z(CRISOT) + z(accessibility)` and (B) a
113
+ leave-one-guide-out held-out AUPRC of CRISOT-only vs a CRISOT+accessibility combiner, tested at two candidate
114
+ imbalances (1:16 and a realistic 1:123). Result: accessibility carries a small, real conditional signal
115
+ (coef ~0.35, bootstrap CI excludes 0 at both imbalances) but adds no held-out ranking improvement over CRISOT
116
+ (AUPRC gap CI includes 0 at both: -0.0025 [-0.011, +0.005] and +0.0027 [-0.014, +0.021]).
117
+
118
+ ### Decision
119
+ - Chromatin is a validated annotation, not a re-ranker. The CRISOT sequence score already captures the
120
+ practically-relevant nomination ranking; a CRISOT+accessibility combiner does not improve held-out AUPRC, so it is
121
+ not wired into the numeric risk score (`CHROMATIN_VALIDATION.changes_numeric_risk_score = False`). The fitted
122
+ combiner coefficients are recorded but intentionally not applied. Ledger and docs updated.
123
+ - This completes the chromatin context work (v6.10.1 wired it, v6.10.2 cross-cell weak, v6.10.3 cell-type-matched
124
+ validated moderate, v6.10.4 incremental tested, annotation-only). Nothing about chromatin remains open or
125
+ undisclosed.
126
+
127
+ ## [6.10.3] - 2026-06-20 - Chromatin context: cell-type-matched validation (validated, moderate)
128
+
129
+ This patch settles the chromatin test. v6.10.2's controlled experiment was ambiguous (GUIDE-seq positive, TTISS
130
+ reversed) on a cross-cell-type K562 proxy; v6.10.3 re-runs it with a cell-type-matched track.
131
+
132
+ ### Added / changed
133
+ - **Cell-type-matched validation** (`scripts/offtarget_chromatin_matched.py`; result in
134
+ `benchmarks/offtarget/chromatin_validation.json` phase2). Downloaded the matched ENCODE HEK293T DNase-seq track
135
+ (`ENCFF529BOG`; HEK293T matches GUIDE-seq's HEK293 and TTISS's HEK293T), queried it at each off-target's 1 kb bin
136
+ (pyBigWig), and recomputed the AUROC. Cell-type matching lifts the canonical WT-Cas9 cell-based assay GUIDE-seq
137
+ from AUROC 0.58 (cross-cell K562) to 0.671 (matched, CI [0.642, 0.701]); the in-vitro negative control stays null
138
+ (0.494). The cross-cell proxy was dampening a real effect.
139
+ - Verdict: chromatin is validated (moderate, cell-type-matched) for WT-Cas9 cell-based off-target activity
140
+ (`offtarget_data.CHROMATIN_VALIDATION` now `validated=True`, `effect="moderate"`). The caveats, all in-code and
141
+ in the docs: the effect is moderate (the sequence/CRISOT score still dominates nomination); it does not
142
+ transfer to TTISS (0.383, the expected outlier, a Cas9-variant specificity assay driven by variant fidelity, not
143
+ WT chromatin); and chromatin is still surfaced as a validated annotation that does not yet change the numeric
144
+ risk score (a calibrated CRISOT+accessibility combination is the remaining, deferred refinement).
145
+ - Reclassified the chromatin axis from "weak/inconsistent" to "validated (moderate, cell-type-matched)" with the
146
+ matched evidence and the caveats.
147
+
148
+ ## [6.10.2] - 2026-06-20 - Chromatin context: controlled validation (weak/inconsistent result)
149
+
150
+ This patch validates the chromatin axis, then scopes it to what the data supports. v6.10.1 wired a real
151
+ Stage B accessibility read but had not demonstrated it carries signal. v6.10.2 runs a controlled experiment and
152
+ reports the result: it is not a clean win.
153
+
154
+ ### Added
155
+ - **A controlled chromatin validation** (`benchmarks/offtarget/chromatin_validation.json`,
156
+ `scripts/offtarget_chromatin_validation.py`). Off-target protospacers mapped to hg38 (GRCh38.fa, exact match both
157
+ strands, 98.5% mapped); AUROC of the Stage B K562 ATAC/DNase accessibility for active-vs-inactive off-targets per
158
+ assay, with in-vitro assays as a negative control (cell-free, so no chromatin). Result: the in-vitro controls hug
159
+ 0.5 (method sound, no spurious signal); the canonical cell-based assay GUIDE-seq is a textbook modest positive
160
+ (AUROC 0.58, CI [0.550, 0.613]) even with a cross-cell-type K562 proxy; but the second cell-based assay TTISS
161
+ reverses (0.346). Verdict: weak and inconsistent, chromatin is not a validated quantitative axis on this data
162
+ (the cross-cell-type proxy is the likely cause; a cell-type-matched accessibility track would settle it, deferred).
163
+
164
+ ### Changed
165
+ - The chromatin-accessibility modifier is now an explicit annotation only, labelled `validated=false`: it reads
166
+ the real Stage B track (or a caller-supplied scalar) and notes the qualitative Lazzarotto-2020 direction, but it
167
+ does not change the numeric off-target risk score. `offtarget_data.CHROMATIN_VALIDATION` carries the result.
168
+ - Corrected the v6.10.1 entry that had marked chromatin "FIXED"; that was too strong. It is now recorded as
169
+ tested, weak/inconsistent, documented annotation, not a validated axis.
170
+
171
+ This is a negative result reported in full.
172
+
173
+ ## [6.10.1] - 2026-06-20 - Off-target rigor pass and retroactive audit (v6.7-v6.9)
174
+
175
+ This patch completes the Stage E plan and documents every remaining deviation. It closes the v6.10.0 gaps and
176
+ re-audits v6.7/v6.8/v6.9 (plan vs shipped vs code) and corrects the findings. No item is reported complete if it
177
+ is a silent substitution, partial, or deferral.
178
+
179
+ ### Added / changed (Stage E completion)
180
+ - **Off-Target-Bench expanded to four unbiased assays.** Added CHANGE-seq (Lazzarotto 2020, `10.1038/s41587-020-0555-7`)
181
+ and SITE-seq (Cameron 2017, `10.1038/nmeth.4284`) on independent broad guide panels (20 and 11 guides). The real
182
+ CRISOT-Score (MD-physics, assay-agnostic so leakage-clean) beats the homology baseline on all four:
183
+ AUPRC 0.646/0.520/0.541/0.521 vs 0.467/0.266/0.249/0.233; per-guide bootstrap CI excludes 0 on each.
184
+ - **Chromatin wired to the real Stage B track and relabelled.** `locus_accessibility(chrom, bin, ct)` reads
185
+ `phase_1/features/chromatin_{ct}.parquet` (ATAC/DNase) when present and abstains otherwise; the docs now say
186
+ "chromatin-accessibility modifier" (not "chromatin-aware engine"), since the bare wheel and the deployed atlas do not ship the
187
+ raw track, so the modifier is inactive there.
188
+ - **Off-target task added to the Genome-Writing Challenge** (`benchmarks/genome_writing_challenge/harness.py`):
189
+ non-circular (label = wet-lab Active call), data-gated on the fixture; the reference solver nominates correctly.
190
+ - **Substitutions:** CRISOT is used instead of the plan-named CCLMoff/CRISMER (CRISMER ships no license;
191
+ CCLMoff is GPU and trained on these assays, so it leaks; CRISOT is the leakage-clean, license-clean, CPU choice). A
192
+ genomic-coordinate locus split is not possible (harmonized data is coordinate-free), so held-out-guide and cross-assay are used.
193
+
194
+ ### Fixed (retroactive audit)
195
+ - **v6.9:** dropped the inaccurate "OOD-gated" claim in the MHC-II axis status (it is coverage-gated, abstains
196
+ when uncached, with no distributional OOD gate); corrected the stale `AXIS_STATUS["mhc2_writer"].reason` and the
197
+ `immune_mhc2.py` module docstring (they still described the dropped v6.9.0 P1-anchor proxy as "the method"; the
198
+ production axis is the real NetMHCIIpan-4.0). The plan-named MHC-II tool ensemble and the IEDB/ImmunoSeq/FVIII
199
+ ADA datasets were not used (single-tool NetMHCIIpan-4.0; the recovery bench is a 4-protein sanity check, not an
200
+ IEDB held-out leaderboard); the 6.9.1 to 6.9.2 MHC-II metric changed from peptide-fraction to residue-coverage.
201
+ - **v6.8:** v6.8.0's attB was a poly-G/C schematic (replaced with the real Bxb1 attB in v6.9.2);
202
+ inter-curator agreement is N/A (single contributor); "at least 1 external submission" is unmet (forward-looking).
203
+ - **v6.7:** corrected the "chromosome-Mondrian" served-interval wording (per-chromosome Mondrian qhats are computed,
204
+ but the global qhat is served, which is correct since a query has no chromosome at serve time); recorded the prereg
205
+ consolidation and the deferred HEK293T-OOD demo / scope-manifest entry.
206
+
207
+ ## [6.10.0] - 2026-06-20 - Cross-writer-family off-target nomination
208
+
209
+ Off-target moves from a single-family bridge pseudosite scan to a cross-writer-family,
210
+ chromatin-aware nomination engine grounded in unbiased genome-wide assays, completing the safety triad
211
+ (site B, writer C, off-target E). Nomination is framed as not a clearance: every candidate
212
+ ships with the empirical assay that would confirm it.
213
+
214
+ ### Added
215
+ - **Off-Target-Bench** (`benchmarks/offtarget/`): a real, leakage-controlled nomination benchmark over canonical
216
+ Cas9 guides (EMX1/VEGFA1-3/FANCF/HEK293) with experimentally validated off-targets from GUIDE-seq
217
+ (Tsai 2015, `10.1038/nbt.3117`) and CIRCLE-seq (Tsai 2017, `10.1038/nmeth.4278`). Held-out-guide split, per-assay
218
+ provenance, SHA256SUMS. On real data with a real tool, the licensed CRISOT-Score predictor
219
+ (Chen et al., Nat Commun 2023, `10.1038/s41467-023-42695-4`; XGBoost RNA-DNA fingerprint) beats the sequence-
220
+ homology baseline: GUIDE-seq AUPRC 0.646 vs 0.467 (gap +0.179, CI [0.015, 0.340]); CIRCLE-seq 0.520 vs
221
+ 0.266 (gap +0.253, CI [0.140, 0.361]); per-guide bootstrap CI excludes 0 on both assays.
222
+ - `pen_stack/wgenome/offtarget_data.py`: validated assay/predictor provenance, a grounded mismatch-to-active-fraction
223
+ risk calibration (real-data: GUIDE-seq 0-1mm to 100% active, 2mm to 76%, 3mm to 23%, 4mm to 3.3%), the bench fixture loader.
224
+ - `pen_stack/wgenome/offtarget_predict.py`: `nominate_offtargets(writer_family, ...)`. Nuclease (mismatch-
225
+ calibrated risk band plus the real cached CRISOT score plus a documented chromatin modifier, Lazzarotto 2020);
226
+ serine integrase (cryptic pseudo-attB scan on the real documented Bxb1 attB core GCGGTCTC/GT);
227
+ bridge (delegates to the existing Perry-DMS pseudosite engine). Abstains without inputs; never fabricates sites.
228
+ - `pen_stack/wgenome/offtarget_assay.py`: validation-assay recommender (GUIDE/CHANGE/CIRCLE-seq for nucleases;
229
+ Cryptic-seq/HIDE-seq for integrases; a documented gap for bridge recombinases, since no published genome-wide
230
+ unbiased off-target assay or predictor exists, verified).
231
+ - **Surfaces:** REST `POST /offtarget` and `GET /offtarget/assay`; MCP `offtarget_scan`; manifest `nominate_offtargets`
232
+ (fabricates=False); an `offtarget_nomination` scope card; and a web Off-Target page.
233
+
234
+ ### Limitations
235
+ - Nomination is not a clearance; genome-wide candidate enumeration needs the on-VM Cas-OFFinder/genome scan (this
236
+ engine scores, ranks, and risk-bands supplied candidates). The CRISOT predictor is CC-BY-NC: it runs only on the
237
+ VM and its weights are never redistributed; only derived scores are cached (CI-safe). Bridge/integrase off-target
238
+ is data-thin and unmodeled and is flagged extrapolative; IntQuery (Tome Biosciences) is a paper-only reference.
239
+
240
+ ## [6.9.2] - 2026-06-19 - Real-tool rigor pass across the immune and writer axes (no proxies, no heuristics)
241
+
242
+ A top-to-bottom audit replaces every remaining proxy/heuristic in the immune and writer-design stack with
243
+ the real on-VM tool (gold-standard, licensed) or an abstention. No silent fallbacks. All licensed binaries stay on
244
+ the VM; only derived numbers are cached.
245
+
246
+ ### Changed
247
+ - **MHC-I capsid axis re-grounded on NetMHCpan-4.1** (`pen_stack/planner/capsid_epitope_oracle.py`). The primary
248
+ capsid CD8 predictor is now the gold-standard licensed NetMHCpan-4.1 (%Rank_EL<=0.5, residue coverage, 12-allele
249
+ panel; `configs/mhc_epitope_oracle.yaml` `mhc1`); the v5.3 MHCflurry value is kept as an explicit, reported
250
+ cross-check (never silently substituted). Both agree AAV is the least CD8-immunogenic capsid
251
+ (AAV `capsid_immune_score` 0.4585 NetMHCpan / 0.2803 MHCflurry; the predictor disagreement is surfaced, not hidden).
252
+ - **ADA-risk re-grounded** (`pen_stack/planner/ada_risk.py`). `ada_risk = real NetMHCIIpan-4.0 density x foreignness`,
253
+ where foreignness is the protein origin (the authoritative central-tolerance signal). Unknown origin or uncached
254
+ density now abstains (no k-mer guess, no heuristic), replacing the v6.9.0 albumin-only self-tolerance
255
+ heuristic. The real human-proteome 9-mer self-match (computed on the VM over the full UniProt reference
256
+ proteome, 20,431 proteins / 10.4 M 9-mers) is reported as a cross-check: human albumin 1.0 (self), the
257
+ foreign writers (SpCas9/ISCro4/Bxb1) and capsids 0.0 (non-self), a clean self/non-self separation.
258
+ - **MHC-II axis no longer falls back to a production proxy** (`pen_stack/planner/immune_mhc2.py`). `mhc2_epitope_load`
259
+ uses the real NetMHCIIpan-4.0 cache by antigen name and otherwise abstains; the documented promiscuous-binder
260
+ estimate is retained as `mhc2_proxy_estimate` for offline triage only (explicitly labelled, not the production axis).
261
+ - **Real Bxb1 attB written** (`pen_stack/atlas/guide_design.py`). The PASTE/PASSIGE pegRNA 3' extension now writes the
262
+ real documented Bxb1 minimal attB verbatim (FlyBase FBto0000359; Ghosh, Kim & Hatfull, Mol Cell 2003;
263
+ 8-bp common core GCGGTCTC around the central GT crossover) instead of the schematic poly-G/poly-C arms. Integrases
264
+ without a bundled documented site expose only the central core (never a fabricated full sequence).
265
+ - `pen_stack/planner/immune_profile.py`: the writer-as-antigen card surfaces `foreignness`, the real
266
+ `self_match_human_proteome` cross-check, and the MHC-II/ADA backends (this replaces the removed `self_tolerance` field).
267
+
268
+ ### Deviations from the v6.9 pre-registration (`prereg/ws_immune2.yaml`)
269
+ - The pre-registered "1 - self_match_fraction from a human-proteome k-mer filter" foreignness fallback is
270
+ dropped: foreignness is the authoritative origin, and an unknown origin abstains rather than imputing from a
271
+ k-mer match (the real self-match is reported only as a cross-check). This is a stricter rule.
272
+
273
+ ### Data / tests
274
+ - `configs/mhc_epitope_oracle.yaml`: corrected `self_match` (the v6.9.x cache had a FASTA-keying bug that collapsed
275
+ the 20,431-protein proteome to 1 protein, zeroing every self-match including albumin); recomputed correctly on the VM.
276
+ - `tests/unit/{test_ws_immune2,test_ws_epitope,test_ws_writer,test_ws_rel}.py` updated for the abstain semantics,
277
+ the NetMHCpan-4.1 primary capsid value plus MHCflurry cross-check, the real attB, and the 6.9.2 version pins.
278
+
279
+ ## [6.9.1] - 2026-06-20 - Real NetMHCIIpan-4.0 / NetMHCpan-4.1 MHC epitope load (replaces the v6.9.0 proxy)
280
+
281
+ This patch is a rigour upgrade. v6.9.0's MHC-II axis was a documented heuristic proxy (P1-anchor density). The
282
+ gold-standard licensed predictors were already on the VM, so v6.9.1 computes the MHC-II epitope load with real
283
+ NetMHCIIpan-4.0 (and MHC-I with NetMHCpan-4.1) over a frequent HLA panel, and re-grounds the axis on the real
284
+ values. The licensed binaries are never committed or distributed; only the derived fractions are
285
+ cached (`configs/mhc_epitope_oracle.yaml`), exactly like the v5.3 MHCflurry cache.
286
+
287
+ ### Changed
288
+ - `pen_stack/planner/immune_mhc2.py`: `mhc2_epitope_load(seq, name)` now uses the real NetMHCIIpan-4.0 EL
289
+ %Rank<=2 cache (over 7 frequent HLA-II alleles) when the antigen is cached; the documented promiscuous-binder
290
+ proxy remains only as the offline/CI fallback for uncached sequences. `real_mhc2_load(name)` exposes the cache.
291
+ - `ada_risk`, `immune_profile` (writer-as-antigen), and `benchmarks/immuno` thread the antigen name to real values.
292
+ - `configs/mhc_epitope_oracle.yaml` (committed): derived epitope fractions for the writer and capsid antigens.
293
+
294
+ ### Result (the real tool is more discriminating than the proxy)
295
+ - Real NetMHCIIpan-4.0 strong-binder fraction: SpCas9 0.153, Bxb1 0.152, ISCro4 0.112, AAV2 0.114 vs
296
+ human albumin (self) 0.066, the lowest. The gold-standard tool shows the self protein has a genuinely lower
297
+ MHC-II load and the foreign writers higher, a signal the heuristic proxy flattened (~0.08-0.10 for all). The
298
+ immunogenic-vs-tolerated recovery is unchanged (foreign well above self) but now on real predictions.
299
+
300
+ ### How it ran (no host install; per the VM Docker rule)
301
+ - `penmhc:tools` (debian + tcsh + gawk + perl) with `~/netmhc` (the licensed tools) mounted, NMHOME fixed at
302
+ runtime; `scratch/v691_mhc_compute.py` runs both predictors and writes the derived cache. The axis stays a
303
+ population-level proxy (frequent-HLA panel, not a patient-HLA magnitude, a known-unknown).
304
+
305
+ ## [6.9.0] - 2026-06-20 - Immune profile: MHC-II/CD4, ADA, and writer-as-antigen
306
+
307
+ This minor feature release extends the immune profile from CD8/MHC-I-only to a full T-cell profile: MHC-I plus
308
+ MHC-II/CD4 plus ADA risk with self-tolerance filtering, scored over the writer enzyme as a distinct antigen,
309
+ still population-level, OOD-gated, and never collapsed. It wraps the v5.6 unified profile. No fabrication: real
310
+ UniProt sequences, a grounded documented method, proxy-labelled axes.
311
+
312
+ ### Added: the MHC-II and ADA axes
313
+ - `pen_stack/planner/immune_mhc2.py`: a grounded, dependency-free promiscuous MHC-II binder density (documented
314
+ P1 hydrophobic anchor, Stern & Wiley 1994; secondary pockets, Southwood 1998) over capsid and writer sequences plus
315
+ the bundled real writer/control FASTA. `configs/writer_sequences.fasta`: real UniProt for SpCas9 (Q99ZW2), ISCro4
316
+ bridge recombinase (D2TGM5), Bxb1 integrase (Q9B086), human albumin self control (P02768).
317
+ - `pen_stack/planner/ada_risk.py`: ADA-risk = MHC-II epitope density x foreignness with a JanusMatrix-style
318
+ self-tolerance filter (origin authoritative; human-proteome k-mer filter otherwise). It recovers
319
+ immunogenic-vs-tolerated: foreign writers score above the human self control (clean separation).
320
+
321
+ ### Changed: the unified profile
322
+ - `pen_stack/planner/immune_profile.py`: adds `mhc2_writer` and `ada_writer` axes and a `writer_as_antigen` card
323
+ with `dominant_antigen` and `writer_dominant_risk` (which fires for a foreign writer, especially non-viral delivery
324
+ where there is no capsid antigen). `collapsed_score` stays `None` (asserted). `immune_calibration.AXIS_STATUS`
325
+ registers the two new axes as mechanistic/population proxies.
326
+
327
+ ### Added: Immuno-Bench and calibration
328
+ - `benchmarks/immuno/harness.py`: the immunogenic-vs-tolerated recovery track (non-circular: label = protein
329
+ origin) plus a `calibrate_axis` ADA pass that remains a proxy at public-data power (no manufactured validation).
330
+ - `tests/unit/test_ws_immune2.py` (CI-safe; pure-Python method plus committed sequences). `prereg/ws_immune2.yaml`.
331
+
332
+ ### Limitations
333
+ - Every axis is a population-level proxy, never a patient-specific ADA titer or realized CD4 magnitude (known-
334
+ unknowns). The MHC-II method is sequence-intrinsic presentation potential, not a trained allele-specific predictor.
335
+ The self-tolerance k-mer filter is seeded by the bundled human reference (the full human proteome is substitutable on the
336
+ VM); the authoritative foreignness signal is the protein origin. Axes are a vector, never fused.
337
+
338
+ ## [6.8.0] - 2026-06-20 - Cross-family writer-efficiency engine and Writer-Efficiency Bench
339
+
340
+ This minor feature release upgrades Stage C (pick the writer) from a curated-KB ranking to a prediction plus
341
+ design layer: the first curated writer-efficiency benchmark, a learned cross-family efficiency predictor,
342
+ integrated guide/att design, and serine-integrase variant critique. It wraps the Writer Atlas and v4.0 writer-verification.
343
+ No fabrication: every efficiency is a real published number with a DOI and a verbatim quote.
344
+
345
+ ### Added: the curated dataset and benchmark
346
+ - `pen_stack/atlas/writer_efficiency.py` plus `data/writer_efficiency.parquet` (SHA-locked): ~45 records / 9 DOIs /
347
+ 4 families, each row with a DOI, a verbatim quote, and a source-access grade (39 pmc_verbatim, 1 abstract, 5 secondary).
348
+ Sources: PASTE (Yarnall *Nat Biotechnol* 2023), (ee)PASSIGE (Pandey/Liu *Nat Biomed Eng* 2025), hyperactive
349
+ integrases (Hew *Nucleic Acids Res* 2024 e64), evoCAST (*Science* 2025), ShCAST (*Science* 2019), enIS621
350
+ (*Nat Commun* 2026), ISCro4 (*Science*).
351
+ - `benchmarks/writer_efficiency/`: the Writer-Efficiency Bench, a sealed, SHA-locked held-out-family plus
352
+ held-out-locus track set plus a baseline leaderboard plus a submission harness. `docs/cards/writer_efficiency_data.md`.
353
+
354
+ ### Added: the learned predictor and the gate
355
+ - `pen_stack/atlas/writer_predict.py`: interpretable-feature HistGradientBoosting plus a family-blocked split-conformal
356
+ interval, candidate-flagged. The pre-registered gate: it beats the KB family-mean baseline on held-out
357
+ locus (MAE 11.7 vs 15.2, paired-bootstrap CI excludes 0; rho +0.38 vs -0.26) and ranks families better on
358
+ held-out family (rho +0.52 vs -0.20), but the held-out-family MAE gain is not significant at N=42/4-families, so
359
+ the KB ranking is retained as primary, the predictor ships candidate-flagged, and the dataset plus bench are the
360
+ contribution. The negative is reported.
361
+
362
+ ### Added: guide design and variant critique
363
+ - `pen_stack/atlas/guide_design.py`: bridge-RNA TBL/DBL loops (Durrant 2024), pegRNA+attB (Yarnall 2023; Bxb1
364
+ core GT), orthogonal att-pair selection (Roelle 2023 GA/GT), with round-trip and invariant recovery tests.
365
+ - `pen_stack/design/writer_variants.py`: extends v4.0 writer-verification to serine-integrase hyperactive mutants
366
+ (Hew 2024 / Keravala 2009); recovers Bxb1 `c22` and PhiC31 P2/P3 retrospectively; defers the
367
+ LM-vs-conservation blind claim (LM naturalness is not engineered hyperactivity).
368
+
369
+ ### Added: the recommender surface
370
+ - `pen_stack/atlas/writer_recommend.py` plus manifest tool `recommend_writers`: ranks families (KB-grounded primary)
371
+ plus candidate predicted efficiency with a conformal interval plus an auto-designed guide. Efficiency is never extrapolated
372
+ to a family absent from the dataset (KB-only there).
373
+
374
+ ### Limitations
375
+ - Predicted efficiencies are candidates with intervals, never asserted activity. 4 families is the binding
376
+ statistical limit, reported. Range efficiencies stored as midpoints (raw string retained);
377
+ secondary-source rows flagged and droppable (strict subset).
378
+
379
+ ## [6.7.0] - 2026-06-19 - Learned, trained-conformal Stage H and TPE-Bench
380
+
381
+ This minor feature release upgrades the digital twin's Stage H expression/outcome layer from a validation-failing
382
+ closed-form heuristic to a learned, trained-conformal, decomposable position-effect model, and ships the
383
+ held-out benchmark the expression capability never had. Wrap, don't rebuild: it extends `twin`, `wgenome.uncertainty`,
384
+ `wgenome.ood`, and `benchmarks`. No fabrication: every metric is from a real CV run on real TRIP supervision, and
385
+ the cross-cell-type transfer claim is data-gated, never faked.
386
+
387
+ ### Added: the learned model and trained conformal
388
+ - `pen_stack/twin/data/position_effect.py`: a unified position-effect schema plus a dataset registry with verified
389
+ accessions/DOIs (TRIP live; PatchMPRA/MPIRE/lentiMPRA/Leemans registered and recorded `available=False` until
390
+ fetched), z-normalization within (dataset x cassette), domain-blocked plus held-out-cell-type splits, a leakage check.
391
+ - `pen_stack/twin/position_effect.py`: `PositionEffectModel` (factored `f_cassette` plus `g_context`, LightGBM),
392
+ `evaluate()` (chromosome-blocked CV vs the v3.x durability head plus cassette-only, paired-bootstrap CIs,
393
+ separability), split-conformal calibration (`ConformalRegressor`, chromosome-Mondrian, OOD-widened),
394
+ `predict_stage_h()` serving seam. Result (real TRIP): expression rho 0.428 to 0.469 (CI excludes 0);
395
+ held-out conformal coverage 0.885 vs 0.90 nominal.
396
+ - `configs/twin/position_effect_conformal.json`: the shipped calibration (qhat plus N plus held-out coverage).
397
+ - `scripts/p1_build_position_effect.py`: regenerates the model plus conformal artifacts (real CV report).
398
+
399
+ ### Changed: Stage H integration
400
+ - `pen_stack/twin/outcome.py`: when a chromatin context is supplied and the artifact is present, `predict_outcome`
401
+ serves the learned trained-conformal interval plus `p_silenced` plus an OOD tier (`position_effect` block,
402
+ `stage_h_mode`); with no context/artifact it falls back to the heuristic band, backward compatible (the
403
+ v5.9 relative-scale contract is intact).
404
+
405
+ ### Added: TPE-Bench and controls
406
+ - `benchmarks/position_effect/`: TPE-Bench, a sealed, SHA-locked held-out-chromosome track plus a baseline
407
+ leaderboard (cassette-only / durability head / factored). The leave-one-cell-type-out
408
+ transfer track is scaffolded and data-gated (no fabricated transfer number).
409
+ - `pen_stack/validate/{expr_controls,known_biology_expr,heldout_celltype_expr}.py`: a label-shuffle-to-chance control,
410
+ an H3K9me3-heterochromatin-to-silencing recovery, and the data-gated transfer harness.
411
+ - `tests/unit/test_ws_pe.py`: CI-safe (synthetic planted signal); the real-TRIP claim runs on a checkout, skips in CI.
412
+
413
+ ### Limitations
414
+ - Public data cannot flip expression to outcome-validated (the v6.5 wall); v6.7 ships the learned and calibrated
415
+ upgrade plus the benchmark plus the data-gating, not a manufactured result. Cross-cell-type transfer needs the additional
416
+ human datasets (a data-acquisition step), reported as such. Wet-lab validation omitted by scope.
417
+
418
+ ## [6.6.0] - 2026-06-16 - License-clean provenance (COSMIC to CancerMine)
419
+
420
+ This minor release is a provenance refactor: no new science, no capability lost. The shipped artifact now sources the
421
+ oncogene/TSG/driver list from CancerMine (CC0) instead of COSMIC Cancer Gene Census (free for academia but
422
+ no-redistribution). Copyright protects the compiled database, not the fact that a gene is an oncogene, so
423
+ sourcing the list from a CC0 compilation removes all licensing doubt while keeping the same capability. This is prep for
424
+ the BioFirewall release, whose open repo vendors PEN-STACK's hazard data.
425
+
426
+ ### Changed
427
+ - `pen_stack/data/ingest_safety_annot.py`: `load_cancermine()` (CC0) is the default oncogene/TSG source
428
+ (HUGO to coords via GENCODE, `--min-citations` precision knob); `load_cosmic()` stays available but off by
429
+ default (bring-your-own-license, local enrichment only).
430
+ - `configs/genotoxicity_oracle.yaml`: regenerated from CancerMine; provenance and DOIs updated (CancerMine
431
+ 10.1038/s41592-019-0422-y). `safety_{ct}.pkl` plus the Writable-Genome atlas regenerated on CancerMine features
432
+ (re-deposited on Zenodo, superseding the COSMIC-derived deposit).
433
+
434
+ ### Added
435
+ - **`DATA_LICENSES.md`**: every source by license by redistribution-status by where-used.
436
+ - `tests/unit/test_data_licenses.py`: a CI license gate that fails if a restricted source (COSMIC/OncoKB) is the
437
+ shipped derived-data source or a raw restricted gene-list is committed; CancerMine is the default.
438
+ - `scripts/fetch_licensed_sources.py`: a bring-your-own-license fetcher for COSMIC/OncoKB (local-only, validation).
439
+
440
+ ### Notes
441
+ - Metrics may shift (CancerMine has broader coverage than CGC), reported. The genotoxicity axis is a
442
+ mechanism-grounded proxy (not outcome-validated) before and after; the swap changes only the source.
443
+
444
+ ## [6.5.0] - 2026-06-15 - Comprehensive expression model and proxy-validation pass
445
+
446
+ This minor feature release has two threads, one principle (no fabrication):
447
+
448
+ ### Added: a comprehensive, literature-cited expression model
449
+ - `configs/expression/promoters.yaml`: the twin's promoter palette expands from 5 to 31 promoters (constitutive plus
450
+ tissue-specific: liver TBG/LP1/hAAT, neuron hSyn/CaMKIIa, muscle MHCK7/MCK/CK8, astrocyte GfaABC1D, SFFV/MND/
451
+ MSCV/RSV, and more). Each entry carries `strength` plus context plus assay plus citation plus confidence, because promoter
452
+ strength has no universal scalar (it depends on cell type by vector by readout), so a single number is encoded
453
+ with its context, never as a universal truth.
454
+ - `configs/expression/modifiers.yaml`: a modifier layer (WPRE, intron, polyA, Kozak, codon-optimization/CAI,
455
+ CpG-silencing) as literature priors/ranges, applied as a bounded uplift range (never a point multiplier, since
456
+ the chimeric intron is ~20x for one transgene, ~3x for another). `twin/mechanistic.py` consumes both.
457
+
458
+ ### Added: a proxy-to-outcome validation harness
459
+ - `scripts/calibrate_immune_axes.py` plus `configs/calibration/preexisting_nab_independent.yaml`: runs the existing
460
+ `calibrate_axis` gate (N>=6 AND bootstrap Spearman CI excludes 0) against independent measured data.
461
+
462
+ ### Result (the deliverable)
463
+ - No immune or expression axis flips to outcome-validated. Pre-existing NAb tested vs an independent cohort
464
+ (Navarro-Oliveros 2024, Basque): rho=0.12, CI includes 0, geography-dependent. Relative-expression tested vs an
465
+ independent promoter study (Damdindorj 2014): rho=0.12, CI includes 0, promoter strength is context-dependent
466
+ (Damdindorj found CMV strongest; Qin found the opposite). Genotoxicity (3 vectors), CD8 (5 capsids), anti-PEG
467
+ (1), and innate (0 fixed) are structurally below the N>=6 gate. The labels stay proxy with empirical backing;
468
+ flipping them would require measured-outcome data at a statistical power the public literature does not provide.
469
+
470
+ ### Tests
471
+ - `tests/unit/test_ws_express.py`: the palette is comprehensive and cited; context is encoded; the modifier profile is a
472
+ bounded range; the proxy does not falsely claim cross-study validation (the no-fabrication gate holds).
473
+
474
+ ## [6.4.3] - 2026-06-12 - Chat vehicle-parse fix (AAVS1 no longer hijacks the vehicle)
475
+
476
+ This patch fixes a parsing bug. `web/tools.py::parse_goal` matched the delivery vehicle by substring, so the safe-harbour nickname
477
+ AAVS1 (which contains "aav") wrongly selected the AAV vehicle even when the user said lentivirus or
478
+ LNP, producing the wrong immune profile (e.g. genotoxicity 1.0 instead of lentivirus's 0.481). Fix: strip the
479
+ safe-harbour nicknames (AAVS1/H11/HIPP11/ROSA26) from the vehicle-search text before matching, so the user's
480
+ stated vehicle wins. Explicit "AAV" still selects AAV. A new test locks all three cases.
481
+
482
+ ## [6.4.2] - 2026-06-12 - Co-Scientist chat: real writer recommendations and self-explanatory values
483
+
484
+ This patch fixes a stale/confusing chat experience reported from the live app. Three problems, three fixes:
485
+
486
+ 1. **The chat dossier was generic and barely changed per query.** `web/tools.py::parse_goal` hardcoded
487
+ `chrom="chr19"` (so a goal about ITGB2, chr21, was mis-located) and `run_tools` never called the planner,
488
+ so a "which writer can integrate N kb in GENE" question got a vehicle-keyed immune profile but no named
489
+ writer. Fix: `parse_goal` now resolves the gene's real chromosome (`planner.gene_region`, atlas-gated,
490
+ falls back offline), and `run_tools` runs the planner and attaches a `plan` block: the recommended writer
491
+ family, top site, safety/durability/score, cargo-capacity fit, and delivery, all engine-computed. It says so
492
+ when the gene isn't in the atlas ("not found, check the HGNC symbol"); never fabricated.
493
+ 2. **The LLM narration produced `[unverified]` spam.** With no writer in the tool results, the model invented
494
+ one (`AAV9-CRISPR` plus made-up numbers) and the grounding guard struck them all. Fix: the system prompt now
495
+ forbids inventing a writer/vehicle/table/number, and if the guard still strikes 2 or more numbers the reply falls
496
+ back to the fully-grounded deterministic narration, so the spam never reaches the user.
497
+ 3. **Values and the "extrapolating" badge weren't self-explanatory.** Each immune axis now carries a
498
+ plain-language `meaning` ("0.55 on a 0-1 scale, moderate; higher = fewer patients excluded; this is a
499
+ proxy, not validated against a measured outcome"), the deterministic narration uses it, and
500
+ `ImmuneProfileCard` renders it plus a one-line legend explaining that "extrapolating" means a proxy estimate.
501
+
502
+ ### Added
503
+ - `tests/unit/test_ws_chat.py`: chrom resolution, axis-meaning, real writer plan, and the no-`[unverified]`-spam
504
+ fallback are locked by new tests.
505
+
506
+ ## [6.4.1] - 2026-06-12 - Defence-in-depth: pre-route safety screen
507
+
508
+ This patch closes a screening gap. The grounded co-scientist chat ran the Guardian (biosecurity gate) only in the design lane (via
509
+ `run_tools`); a hazardous request with no design signal (no vehicle/locus) routed to `general`/`explain`/`meta`
510
+ and was never screened. Fix: `pen_stack/web/llm.py::_pre_route_safety` runs the Guardian, framing-stripped, the
511
+ authority on the decision, at the top of `grounded_reply()`, before lane routing. A `refuse`/`escalate`
512
+ verdict short-circuits to a clear decline (`mode="safety"`, with the decision in `tool_results`). Benign
513
+ hazard-adjacent biology (vaccines, generic pathogen questions) is not blocked: the Guardian clears it and
514
+ routing continues. A broad regex only decides whether to invoke the Guardian; a false trigger is harmless.
515
+
516
+ ### Added
517
+ - `tests/unit/test_ws_chat.py`: `test_pre_route_safety_screens_a_hazardous_general_query` and
518
+ `test_pre_route_safety_does_not_over_refuse_benign_questions` lock both sides of the screen.
519
+
520
+ ## [6.4.0] - 2026-06-12 - Live Oracles (the foundation models actually execute)
521
+
522
+ The oracle mesh goes live. The foundation-model adapters that were deferred contracts now run real backends,
523
+ without touching the no-fabrication invariant (generated outputs stay candidates, OOD inputs are flagged, a down
524
+ backend defers). Live execution is opt-in via `PEN_STACK_ORACLE_NET=1`; with the flag unset (CI/offline) every
525
+ oracle behaves exactly as before. This is a minor feature release on the stable 6.x API.
526
+
527
+ ### Added: live oracles
528
+ - **Evo2-40B (hosted):** `oracles/genome.py::generate_dna` calls NVIDIA's hosted Evo2-40B (real generated DNA plus
529
+ per-token probability). ~1-3 s.
530
+ - **AlphaGenome (hosted):** `oracles/genome.py::variant_effect` connected to the existing v3.1
531
+ `wgenome.AlphaGenomeProvider` (added `score_variant`; no duplicate client), a real regulatory variant-effect
532
+ magnitude. ~2-10 s. (AlphaGenome already ran live in v3.1 for expression/tracks/contact, 416 cached predictions.)
533
+ - **ProteinMPNN / ESM3-open / RFdiffusion (local GPU):** `model_servers/{proteinmpnn,esm3,rfdiffusion}` small
534
+ FastAPI servers on the VM GPU (reuse `penstack:phase1.5` / `rfdiffusion:base`); `oracles/protein_design.py`
535
+ HTTP-calls them. ProteinMPNN ~1-9 s, ESM3 ~1-2 s warm, RFdiffusion ~1-2 min. `docker-compose.models.yml` starts
536
+ them on demand.
537
+ - **Execution and latency surface:** `configs/oracles/execution.yaml` plus `oracles/status.py` (`oracle_status`,
538
+ `summary`) plus `GET /oracles` plus the chat meta facts: per-oracle execution, latency class
539
+ (instant/seconds/slow/long_job), and live status, so the assistant states the cost before running anything.
540
+
541
+ ### Held / deferred
542
+ - **AlphaFold3, Boltz-2, Chai-1, Protenix:** held, they need a rented A100/H100 (24-80 GB; AF3 also ~1 TB
543
+ databases). They run separately on cloud, never on the 16 GB VM and never in the request path.
544
+ - **Arc STATE / scGPT:** the package is verified installable (`pip install arc-state`; SE-600M embeds cells), but a
545
+ trustworthy perturbation outcome needs the State-Transition model plus a reference scRNA pipeline, and even
546
+ SOTA doesn't beat naive baselines (Arc VCC), so the magnitude stays a known-unknown, deferred
547
+ (a uniform gated hook is added via `PEN_STACK_VCELL_URL` for when an ST server is stood up).
548
+
549
+ ### Verified on the VM (RTX A4000)
550
+ Evo2-40B generation ~1.2 s; AlphaGenome variant score `chr22:36201698 A>C` max|effect| 3.15 over 14,652 tracks
551
+ in 3.6 s; ProteinMPNN designed real ubiquitin-fold sequences (global_score ~0.80) in ~9 s; ESM3-open completed the
552
+ ubiquitin sequence from a partial prompt in 1.4 s warm; RFdiffusion diffused a real 60-residue backbone in ~105 s.
553
+ All generated outputs remain candidates (`as_claim()` raises).
554
+
555
+ ## [6.3.1] - 2026-06-12 - Router fix: general "how does it work" no longer misrouted to the meta lane
556
+
557
+ This patch corrects routing. It was found by a full-stack test pass (every oracle plus every endpoint plus the 4
558
+ chat lanes plus general/biological-intelligence questions).
559
+
560
+ ### Fixed
561
+ - **Router meta-lane over-capture.** A general-biology question phrased "and how does it work / cut DNA?"
562
+ (e.g. *"what is CRISPR-Cas9 and how does it cut DNA?"*) matched the meta pattern `how (do|does) (you|it|this|pen)`
563
+ and was answered from PEN-STACK capability facts instead of general knowledge. Narrowed the bare-pronoun meta
564
+ trigger to `how (do|does) (you|pen)` so a general "how does it ..." routes to the general lane (labelled,
565
+ with an engine pointer); a pen-stack-scoped "how do you compute X" stays meta (the verb-qualified pattern is
566
+ unchanged). Regression cases added to `tests/unit/test_ws_chat.py::test_router_classifies_the_four_lanes`.
567
+
568
+ ### Verified (v6.3 test pass)
569
+ - **Oracle mesh (42/42, engine-direct):** ViennaRNA computes a real MFE fold (-38.3 kcal/mol); AlphaGenome,
570
+ Evo2, vcell (Arc-STATE), AF3/Boltz/Chai/Protenix, and RFdiffusion/ProteinMPNN/ESM3 either compute or defer
571
+ with the OOD gate plus provenance intact, never fabricate; the generative-candidate `as_claim()` guard
572
+ raises. Computed immune layers reproduce orderings from data: genotoxicity LV 0.481 < gammaretro 0.177
573
+ (LMO2/SCID-X1), capsid AAV 0.28 > Ad 0.18, CpG O/E rich > poor, seroprevalence AAV 0.55 / Ad5 0.35, anti-PEG
574
+ 0.515; full `verify()` clears a clean design, rejects a 7 kb single-AAV (alt lentivirus legal), refuses ricin,
575
+ rejects an RNP-over-AAV, and flags multiplex translocation risk 0.95.
576
+ - **App surface (live, LLM on):** every endpoint 200 plus a grounded shape; the 4 chat lanes route correctly with the
577
+ grounding guard clean on the grounded lanes (0 ungrounded numbers, Nemotron backend).
578
+
579
+ ## [6.3.0] - 2026-06-12 - The Hybrid Co-Scientist (grounded engine plus general intelligence)
580
+
581
+ The chat gains general and biological intelligence without loosening the no-fabrication core. A 4-lane router
582
+ keeps grounded engine output and general trained-knowledge in separate, explicitly-labelled lanes, so a
583
+ general-knowledge fact can never be mistaken for a PEN-STACK result. Numbers now come with their meaning,
584
+ reference range, and how they were computed; the conversation has memory. This is a minor feature release on the stable
585
+ 6.x API, SHA-locked.
586
+
587
+ ### Added
588
+ - A deterministic 4-lane chat surface: `pen_stack/web/router.py` (classifier: `design` / `explain` / `meta` /
589
+ `general`, biased to the engine whenever a design signal is present) plus `pen_stack/web/guide.py`
590
+ (`metric_guide()` interpretation cards plus `pen_stack_facts()` assembled from live engine data) plus a rewritten
591
+ `pen_stack/web/llm.py::grounded_reply` that dispatches per lane and returns `{mode, provenance, grounded, ...}`.
592
+ - **`configs/metric_guide.yaml`:** grounded interpretation for every engine number (genotoxicity, CD8 epitope,
593
+ innate, pre-existing NAb, anti-PEG, confidence, relative expression, and the safety decisions): what it means, the
594
+ scale plus direction, reference bands, how it is computed, and its validation status. The chat now explains a value
595
+ (scale / what's good-or-bad / reference range / method), not just prints it.
596
+ - **Lanes and provenance:** `design`/`explain`/`meta` are engine-grounded (the grounding guard runs over the tool
597
+ results, the metric guide, or the live facts); `general` answers from the LLM's trained knowledge, is labelled
598
+ "General knowledge, not PEN-STACK-verified", attributes no number to PEN-STACK, and points to the engine
599
+ wherever PEN-STACK could compute a concrete answer (`pen_stack_angles`).
600
+ - **Conversation memory:** the last turns are passed to every lane so follow-ups ("what does that 0.55 mean?")
601
+ resolve against the prior dossier; the frontend keeps history in-session until refresh and renders a per-message
602
+ provenance badge (grounded vs general) plus the "PEN-STACK can compute this" pointers.
603
+ - Tests: `tests/unit/test_ws_chat.py` covers the 4-lane router, the general lane labelled/unattributed/pointered, the
604
+ meta lane grounded in live facts, the explain lane interpreting prior values without a fresh design, the metric
605
+ guide complete. Preregistration `ws_hybrid` plus SHA lock; deposit `phase_6.3/`.
606
+
607
+ ### Notes
608
+ - The core is untouched. The guard still runs on every PEN-STACK-attributed number; we added a general lane,
609
+ we did not loosen the grounded lane. The cost is that general-lane answers carry the LLM's fallibility,
610
+ made safe by the explicit label and by redirecting to the engine for anything computable.
611
+
612
+ ## [6.2.4] - 2026-06-12 - Faster grounded narration (LLM backends) (patch)
613
+
614
+ Performance plus a real fix, from benchmarking the narration backends on the deployment GPU (RTX A4000). The
615
+ LLM only narrates over engine tool results (the grounding guard runs regardless), so latency is the thing to
616
+ tune. Measured (real grounded prompt): Ollama qwen2.5:7b = ~50s warm / 120s cold (3.4 tok/s, a workstation
617
+ GPU is slow for an LLM); qwen2.5:3b = ~27s; llama3.2:3b = ~17s; hosted Nemotron-49B = ~5s. All keep the
618
+ grounding guard clean (0 ungrounded). The old Nemotron fallback model (`llama-3.1-nemotron-70b-instruct`) now
619
+ 404s, i.e. the fallback was silently broken.
620
+
621
+ ### Fixed / changed (`pen_stack/web/llm.py`)
622
+ - **Nemotron model corrected** to `nvidia/llama-3.3-nemotron-super-49b-v1` (the 70B name was retired, so the
623
+ fallback 404'd). Restores a working, ~5s hosted backend.
624
+ - **Default local model qwen2.5:7b to qwen2.5:3b-instruct** (~2x faster narration, grounding unchanged).
625
+ - **`keep_alive` (default 30m)** so the model stays resident on the GPU and idle calls don't pay the cold start.
626
+ - **Configurable backend order** `PEN_STACK_LLM_ORDER` (default `ollama,nemotron` = local/private-first;
627
+ `nemotron,ollama` = speed-first ~5s). `web/.env.example` documents all knobs.
628
+
629
+ ## [6.2.3] - 2026-06-12 - Scope matcher covers functional titer and durability (patch)
630
+
631
+ A coverage fix (from the 20-query acceptance suite, `phase_6.2/PEN-STACK_ACCEPTANCE_TESTS.md`). The
632
+ known-unknowns matcher (`configs/known_unknowns.yaml`) had no entry for functional titer / absolute in-vivo
633
+ expression magnitude and its durability terms were too narrow ("how long will it last in a patient"), so
634
+ common measured-endpoint questions ("what functional titer (% of normal)?", "how long will episomal AAV
635
+ expression last?") were not explicitly deferred. The no-fabrication spine already held (no titer/half-life was
636
+ ever emitted, and the immune profile lists `patient_specific_titer`), but the matcher should flag these
637
+ proactively.
638
+
639
+ ### Added / Fixed
640
+ - `configs/known_unknowns.yaml`: a new known-unknown `in_vivo_expression_magnitude` (functional titer / % of normal
641
+ / absolute expression, a measured clinical endpoint, never predicted; PEN-STACK gives the relative mechanistic
642
+ proxy plus immune context); broadened `long_term_clinical_durability` match-terms/patterns to catch "how long will
643
+ ... last/persist", "durability", "half-life". Regression test
644
+ `tests/unit/test_ws_api.py::test_scope_defers_titer_and_durability_questions`.
645
+
646
+ ### Acceptance suite result
647
+ - 20/20 behave as specified at the engine level: grounded where earned, refusing where unsafe (ricin/botulinum),
648
+ abstaining/deferring where appropriate (titer, durability, phenotype), no fabricated number. T10 (RNP/AAV) and T12
649
+ (multiplex translocation) are enforced via `delivery.cargo_form_compatible` and `multiplex.translocation_risk`
650
+ on the structured design fields (`writer_output_form`, `edits`).
651
+
652
+ ## [6.2.2] - 2026-06-12 - Safe-harbour locus-nickname resolution (patch)
653
+
654
+ A usability fix. Site Finder / `/plan` / `/writable` returned 0 plans for `AAVS1` because it is a genomic
655
+ safe-harbour locus nickname, not an HGNC gene symbol, so the gene-to-coordinate lookup (`gene_coords`, 60,888
656
+ symbols) could not resolve it: an empty result, but unhelpful for the most-typed safe harbour. (The cell-type
657
+ atlases are complete; real symbols like `PCSK9`/`HBB`/`CCR5`/`CLYBL` resolved fine.)
658
+
659
+ ### Fixed
660
+ - `pen_stack/planner/optimize.py`: `resolve_gene()` maps well-documented safe-harbour nicknames to their host
661
+ gene (`AAVS1` to `PPP1R12C` 19q13.42; `H11`/`Hipp11` to `EIF4ENIF1` 22q12) at every gene-to-coordinate lookup
662
+ (`gene_region`, `plan`, `crosslink.loci_for_gene`); real symbols pass through unchanged. Regression test
663
+ `tests/unit/test_ws_api.py::test_safe_harbour_nickname_resolves_to_host_gene`.
664
+
665
+ ## [6.2.1] - 2026-06-12 - JSON-safe atlas/crosslink endpoints (patch)
666
+
667
+ A bug fix. The `/atlas`, `/writable`, and `/crosslink/loci` endpoints returned raw DataFrame records, which
668
+ leak non-finite floats (`NaN`/`inf`) present in `atlas.parquet`; the JSON encoder rejects these
669
+ (`ValueError: Out of range float values are not JSON compliant`, so HTTP 500). Surfaced on the v6.2 Web Platform's
670
+ Writer Atlas and Site Finder pages.
671
+
672
+ ### Fixed
673
+ - `pen_stack/server/api.py`: a `_records()` helper serializes DataFrame rows JSON-safely (via pandas `to_json`,
674
+ so `NaN`/`inf` become `null` and numpy scalars become native), applied to `/atlas`, `/writable`, `/crosslink/loci`.
675
+ Regression test `tests/unit/test_ws_api.py::test_records_helper_is_json_safe_with_non_finite_floats`.
676
+
677
+ ## [6.2.0] - 2026-06-11 - The Web Platform (the human surface)
678
+
679
+ A post-1.0 adoption surface for bench scientists. A complete, friendly web application: a grounded co-scientist
680
+ chat plus structured feature pages, over the same typed v6.1 API the AI surface uses. The LLM narrates and
681
+ routes but never sources a number; every quantitative answer renders with its confidence band, provenance, and
682
+ an explicit ledger of what PEN-STACK can't tell you. This is a minor release on the stable 6.0 API, SHA-locked.
683
+
684
+ ### Added
685
+ - **Backend:** `pen_stack/web/server.py`, one FastAPI gateway that mounts the v6.1 engine surface under
686
+ `/api` (so the frontend has one base URL and one OpenAPI) and adds the grounded `/chat` (plus SSE `/chat/stream`),
687
+ CORS, and static serving of the built frontend (`web/dist`). A `/health` for the live grounded indicator.
688
+ - **Chat (the hard gate):** `pen_stack/web/tools.py` (the deterministic engine tool-runner: parse a goal,
689
+ run `verify`/`safety`/`immune_profile`/scope, return a grounded dossier; `extract_grounded_numbers` is the allow-list)
690
+ and `pen_stack/web/llm.py` (the grounded co-scientist: Ollama, then Nemotron, then deterministic narrator, with
691
+ `_enforce_grounding` striking any numeric token the model can't trace to a tool result). A reply's numbers are
692
+ always engine-sourced; `tests/unit/test_ws_chat.py` asserts no number in a reply is absent from the tool
693
+ results, and that the deterministic narrator works with both LLMs offline.
694
+ - **Frontend:** `web/` (React/Vite plus Tailwind): the UX component library (`ConfidenceBand`,
695
+ `ProvenanceChip`, `ScopeLedger`, `SafetyBadge`, `ImmuneProfileCard`), so a number is never shown without its
696
+ uncertainty plus provenance, and the scope ledger appears on every answer.
697
+ - **Pages:** 11 feature pages over the typed API: Co-Scientist, Site Finder, Writer Atlas, Designer,
698
+ Verify, Delivery & Immunity, Digital Twin, Guardian, Experiments, Challenge, Scope & About. Each renders
699
+ through the UX library and degrades gracefully when the LLM is offline.
700
+ - **Deploy:** `docker/web.Dockerfile` (multi-stage: a node:20 stage builds the frontend, a slim Python
701
+ serves UI plus API from one origin) plus a `web` service in `docker-compose.yml`: one-command self-host
702
+ (`docker compose up web ollama`, open `http://localhost:8000`). `web/.env.example`, `web/README.md` quickstart.
703
+ - Read-only Challenge surface for the web page: `GET /api/challenge/{tasks,leaderboard}` (public tasks plus the
704
+ PEN-STACK reference leaderboard; submissions are still scored offline, never accepted over HTTP).
705
+ - Preregistration `ws_{chat,frontend}` plus SHA locks; deposit `phase_6.2/`.
706
+
707
+ ### Notes
708
+ - The LLM never sources a number. It explains, compares, and routes over the engine's tool outputs; the
709
+ grounding guard strips any value it can't trace, and the app runs in a deterministic, no-LLM mode (the science
710
+ lives in the engine, not the model). This cycle improves usability/adoption, not validation; a real-data
711
+ result and a first lab user remain the standing bottleneck. No new science; contracts under the 1.0 commitment.
712
+
713
+ ## [6.1.0] - 2026-06-11 - The AI Integration Surface
714
+
715
+ A post-1.0 adoption surface for AI builders. Not new capability: the introspectable, documented, dependable
716
+ contract that lets an external agent discover what PEN-STACK offers and what it refuses to answer. This is a minor
717
+ release on the stable 6.0 API, SHA-locked.
718
+
719
+ ### Added
720
+ - **Capability and scope manifests (the differentiator):** `pen_stack/api/manifest.py`: `capability_manifest()`
721
+ (machine-readable: the stable tools, inputs/outputs, all `fabricates=False`, guarantees, stability) and `scope_manifest()`
722
+ (machine-readable: the known-unknowns registry plus every oracle scope card, i.e. what PEN-STACK refuses to
723
+ answer). Generated from the live registry/scope cards (never hand-written); internal matcher fields not leaked.
724
+ - **OpenAPI:** `pen_stack/server/api.py`: `GET /capabilities` plus `GET /scope` plus `POST /verify /safety /immune
725
+ /generate /predict /suggest /session`; FastAPI auto-generates the OpenAPI 3.1 spec at `/openapi.json`.
726
+ - **MCP:** `pen_stack/agent/mcp_server.py`: the self-describing resources `pen-stack://capabilities` plus
727
+ `pen-stack://scope`, plus the engine tools (`safety_screen`, `immune_profile`, `generate_designs`,
728
+ `predict_outcome`, `suggest_experiment`, `co_scientist_session`). A hazardous design returns a structured
729
+ refusal an agent branches on.
730
+ - **Examples:** a runnable golden path: `examples/external_agent.py` (REST: discover scope, submit, branch on
731
+ safety/legality), `examples/mcp_client.py` (MCP), `examples/agent_tools.py` (framework-agnostic tool specs built
732
+ from the live manifest plus an in-process dispatcher to the validated engine).
733
+ - Docs: `docs/integrations.md` rewritten as "Integrate PEN-STACK in your AI" (the four guarantees plus the scope
734
+ contract plus REST/MCP/framework quickstarts); preregistration `ws_{manifest,openapi,mcp}` plus SHA locks; deposit `phase_6.1/`.
735
+
736
+ ### Notes
737
+ - Scope is data, not a disclaimer. The scope manifest makes the scope machinery itself an API, the thing
738
+ that makes trustworthy autonomy something another system can build on. This cycle lowers the barrier to
739
+ adoption; it does not, by itself, create it: outreach plus a real result remain the standing bottleneck. No new
740
+ science or validation; contracts versioned plus deprecation-policed under the 1.0 commitment.
741
+
742
+ ## [6.0.0] - 2026-06-11 - 1.0, First Stable (the graduation)
743
+
744
+ The Closed-Loop arc is complete (7/7), and PEN-STACK graduates to "1.0, First Stable." The public API,
745
+ exercised across every surface (verify, safety, generative design, twin, experiment design, build interface,
746
+ closed loop, co-scientist, and the Genome-Writing Challenge), is documented and frozen with a deprecation
747
+ policy. "First Stable" is earned, not declared: it is cut only after the closed loop is demonstrated (v5.12),
748
+ the benchmark is public (v5.13), and the integration surface ships.
749
+
750
+ ### Changed
751
+ - **`Development Status :: 5 - Production/Stable`** (was Beta). Version 6.0.0 (MAJOR).
752
+ - The public API is documented and frozen with a deprecation policy: **`docs/STABILITY.md`** (semver from 6.0.0;
753
+ deprecations warn at least 1 MINOR before removal in a MAJOR; the `OracleResult`/`Verdict`/`SafetyVerdict`/immune-profile
754
+ contracts and invariants, including `collapsed_score is None` and the no-fabrication guard, are stable across 6.x).
755
+ - The Genome-Writing Challenge is public.
756
+
757
+ ### Notes
758
+ - "1.0, First Stable" is a commitment to API stability, not a claim of solving genetic engineering. The
759
+ unknown funnel remains, made legible (scope flags, known-unknowns, baselines, no fabrication), not
760
+ hidden. The high version numbers of the program's fast youth finally meet a real stability commitment.
761
+
762
+ ## [5.13.0] - 2026-06-11 - The Standard (Genome-Writing Challenge plus Co-Scientist II)
763
+
764
+ This cycle aims to make PEN-STACK the field's reference: an open, recurring, held-out benchmark
765
+ others build to, and to give scientists a co-scientist that drives the whole loop with immune-risk first-class.
766
+ SHA-locked. (The v6.0.0 "1.0, First Stable" graduation follows.)
767
+
768
+ ### Added
769
+ - **The Genome-Writing Challenge** (`benchmarks/genome_writing_challenge/`): an open,
770
+ recurring, held-out leaderboard (the CASP / Virtual-Cell-Challenge model). `evaluate(Submission, round_id)`
771
+ scores an external `predict_fn(public_input) -> answer` on a held-out round whose labels it never sees; labels
772
+ are computed by the validated PEN-STACK layers (rules / v5.7 Guardian / v5.6 immune profile) so no task uses a
773
+ circular label; a no-fabrication audit runs on every submission; task families include an immune-risk
774
+ task grounded in the v5.6 oracles. A one-command runner (`run.py`); a reference submission anchors the leaderboard.
775
+ - **The matured co-scientist** (`pen_stack/agent/co_scientist.py::co_scientist_session(goal, cell_state)`)
776
+ drives the whole loop: safe, legal, calibrated designs, then predicted outcomes, then suggested
777
+ experiments, then exportable protocols, returning the Pareto strategies, calibrated `predicted_outcomes`,
778
+ per-axis immune profiles (first-class), `suggested_experiments`, citations (resolve by construction),
779
+ a complete scope ledger, and the per-design safety decision. The scientist/lab decides; the co-scientist
780
+ drives. No number is fabricated; hazardous candidates are discarded.
781
+ - **The integration surface:** MCP server tools, the Challenge submission API, and a worked reference
782
+ example (`docs/integrations.md`). The standing adoption criterion (at least 1 external integration plus at least 1 external
783
+ submission) depends on outreach, the non-code bottleneck flagged since v3.1; the surface is shipped.
784
+ - Docs: `docs/{challenge,co_scientist_loop,integrations}.md`; preregistration `ws_{challenge,cosci2}` plus SHA locks; deposit
785
+ `phase_5.13/`.
786
+
787
+ ### Notes
788
+ - A standard requires a community: PEN-STACK provides the open, reproducible, held-out benchmark and the
789
+ integration surface; adoption depends on outreach. The co-scientist drives and presents (including the
790
+ immune-risk profile with its known-unknowns); the scientist and lab decide.
791
+
792
+ ## [5.12.0] - 2026-06-11 - The Closed Loop (autonomy Level 3)
793
+
794
+ This release integrates everything into one continual design/build/test/learn cycle,
795
+ humans/lab in control, no fabrication, drift-aware. It reaches autonomy Level 3 (the program's ceiling).
796
+ SHA-locked.
797
+
798
+ ### Added
799
+ - **The loop** (`pen_stack/loop/cycle.py`): `run_loop(goal, cell_state, ...)` orchestrates every prior cycle each
800
+ round: generate (v5.8), decide/batch (v5.10), safety-gated export (v5.7 plus v5.11), run (sim-lab v5.11 /
801
+ real lab), ingest (v4.5 gate), drift (v5.12), continual learn (v5.12). Gated: safety, build, and
802
+ belief-admission each await the `approver`. Returns `autonomy_level=3`, `human_in_control=True`,
803
+ `no_fabrication=True`. A hazardous candidate is discarded by the safety-gated pipeline before it is ever run.
804
+ - **Drift** (`pen_stack/loop/drift.py`): `detect_drift(designs, results)` compares the v5.9 twin's predictions
805
+ vs observed readouts; growing miscalibration leads to `severity:"high"` and `inflate_intervals` (widen, don't over-trust).
806
+ - **Continual learning** (`pen_stack/loop/continual.py`): `continual_update(...)` recalibrates trust plus twin plus immune
807
+ proxies on admitted outcomes only; each update is versioned and reversible (`rollback_to`); high drift
808
+ widens intervals; an admitted immune measurement with a CI can graduate a v5.6 proxy to outcome-validated.
809
+ This is recalibration, not foundation-model retraining.
810
+ - **Demo and autonomy criteria:** `loop_converges_faster_than_random` reports the active-vs-random convergence with a
811
+ bootstrap CI (retrospective/simulated, reported either way); `docs/autonomy.md` asserts the Level-3 criteria
812
+ (closed loop, human in control at every gate, anomaly flagging, no fabrication) and that Levels 4/5 are
813
+ not claimed.
814
+ - **Bench v0.3.8:** a new `closed_loop` hard-gate task. The gate is the loop's integrity (gated
815
+ end-to-end run plus no-fabrication plus Level-3 human-in-control plus drift detection plus versioned/reversible continual
816
+ learning); an ungated autopilot fails by construction. Convergence reported informationally.
817
+ - Docs: `docs/{closed_loop,autonomy}.md`; preregistration `ws_{loop,continual,drift}` plus SHA locks; deposit `phase_5.12/`.
818
+
819
+ ### Notes
820
+ - The loop is Level 3: closed, but with humans/lab in control at every gate, not autonomous. It runs in
821
+ silico via the sim-lab (a real lab attaches at the same interface); continual learning recalibrates rather than
822
+ retrains; drift covers calibration/residual shift, not all failures; the convergence demo is retrospective/
823
+ simulated, reported with CIs.
824
+
825
+ ## [5.11.0] - 2026-06-11 - The Build Interface (digital-to-physical bridge)
826
+
827
+ This release makes designs executable and results ingestible: loop-ready, lab-optional,
828
+ safety-gated, with the immune-risk profile attached as protocol metadata. SHA-locked.
829
+
830
+ ### Added
831
+ - **Protocol export** (`pen_stack/build/protocol.py`): `export_protocol(design, experiment, target, actor)` for
832
+ Opentrons / PyLabRobot / cloud-lab. It runs `verify()` first: a safety-`refuse` or illegal design raises
833
+ `ProtocolExportError` (no export path for a flagged design); a cleared design is emitted as a DRAFT
834
+ ("human/lab review required") carrying the v5.6 immune profile plus provenance in its metadata. Never auto-run.
835
+ - **Ingest** (`pen_stack/build/ingest.py`): `ingest_result(result, ...)` validates a result (assay / readout /
836
+ provenance) and turns it into a quarantined measured edge Candidate; the only path into the curated
837
+ world-model is the v4.5 gate (`gate_admit`): automated checks AND explicit human approval. No auto-edit
838
+ (Principle 1). Immune measurements can begin validating the v5.6 proxies on a later pass.
839
+ - **Sim-lab** (`pen_stack/build/simlab.py`): `run_simulated(protocol_ir, design, cell_state)` executes a
840
+ protocol in silico (samples from the v5.9 twin plus measurement noise), labelled `SIMULATED`, so the closed
841
+ loop (v5.12) runs end-to-end (export, sim, ingest) without hardware; it never enters the world-model as
842
+ measured truth.
843
+ - **Bench v0.3.7:** a new `protocol_safety` hard-gate task (`pen_stack/validate/protocol_safety.py`):
844
+ a cleared design exports with immune metadata, a safety-refused/illegal design is blocked, and the simulated
845
+ loop completes with quarantined SIMULATED results; an ungated exporter (which would emit the hazardous protocol)
846
+ fails by construction.
847
+ - Docs: `docs/build_interface.md`; preregistration `ws_{proto,ingest,simlab}` plus SHA locks; deposit `phase_5.11/`.
848
+
849
+ ### Notes
850
+ - PEN-STACK emits protocols and ingests results; it does not run experiments. Protocols are drafts requiring
851
+ human/lab review, results enter only through the gate, and the simulated lab is for development / loop-validation,
852
+ never a substitute for real data. Export is hard-blocked for anything the safety gate flags.
853
+
854
+ ## [5.10.0] - 2026-06-11 - The Experiment Designer (active learning / EIG)
855
+
856
+ The "Learn" brain of a self-driving lab: turn "I'm uncertain" into "run
857
+ this experiment next." It reads the calibrated v5.9 twin's uncertainty plus the v5.6 immune labels, scores each
858
+ candidate experiment by expected information gain, assembles a diverse batch, and proves on held-out data, with
859
+ CIs, that this learns faster than random/greedy (reporting plainly when it does not). SHA-locked.
860
+
861
+ ### Added
862
+ - **Acquisition** (`pen_stack/active/acquire.py`): `expected_information_gain` (reducible uncertainty from the twin's
863
+ predictive distribution; `>= 0`, monotone in uncertainty), `predictive_entropy` (from the twin's interval width),
864
+ and `immune_voi` (value of information for validating an immune proxy axis, v5.6): an experiment that
865
+ would measure a still-proxy axis is high-VOI (it turns proxy to outcome-validated). `acquisition_score` is fully
866
+ traceable to twin quantities plus v5.6 labels; deterministic; no fabricated values.
867
+ - **Batch design** (`pen_stack/active/design.py`): `select_batch` greedily maximises acquisition minus a
868
+ redundancy penalty (shared design facets), giving a diverse batch (not k copies of the most-uncertain point);
869
+ each experiment carries its expected info gain.
870
+ - **Validation** (`pen_stack/active/validate.py`): `retrospective_active_learning` simulates active vs random vs
871
+ greedy campaigns on a held-out split, reports mean±CI learning curves and a bootstrap CI on the curve-area
872
+ gap; `active_beats_random` only when the CI excludes zero, else the not-yet-useful negative is reported.
873
+ - **Bench v0.3.6:** a new `experiment_design` hard-gate task. The gate is the Learn engine's
874
+ properties (twin-sourced EIG monotone in uncertainty plus immune-VOI for proxy validation plus a diverse
875
+ batch plus retrospective active-vs-random with reps and CI); a random selector fails by construction. Active-beats-
876
+ random is reported informationally.
877
+ - Docs: `docs/experiment_design.md`; preregistration `ws_{acq,aldesign,alvalidate}` plus SHA locks; deposit `phase_5.10/`.
878
+
879
+ ### Notes
880
+ - The experiment designer is only as good as the v5.9 twin plus the v5.6 labels it queries; its advantage is validated
881
+ retrospectively with CIs and reported plainly when absent. It chooses informative experiments but does
882
+ not run them; prospective benefit awaits a lab partner (v5.11+). No autonomy claim.
883
+
884
+ ## [5.9.0] - 2026-06-11 - The Digital Twin (calibrated outcome prediction)
885
+
886
+ The missing layer: what does the cell do after the write? Predicted with
887
+ calibrated uncertainty. The twin computes what mechanism allows, adds an in-distribution virtual-cell estimate
888
+ (OOD-gated), screens immune outcome from the v5.6 profile, and is explicit about its boundary at phenotype.
889
+ SHA-locked.
890
+
891
+ ### Added
892
+ - **Virtual cell** (`pen_stack/oracles/vcell.py` plus scope cards `state`/`scgpt`): `predict_response(cell_state,
893
+ perturbation, model)` wraps Arc STATE / scGPT under the v4.0 `OracleResult` contract. A
894
+ perturbation-response prediction is a candidate, OOD-gated (a context outside the documented envelope is marked
895
+ `extrapolating`), cached/deferred (value `None` when absent, never fabricated). It encodes the field's own result
896
+ (Arc Virtual Cell Challenge): perturbation models don't yet consistently beat naive baselines.
897
+ - **Mechanism** (`pen_stack/twin/mechanistic.py`): `cassette_expression` = `promoter_strength x copy_number x
898
+ accessibility` (closed-form steady state); assumptions plus scope flags attached; physics where computable, not
899
+ a phenotype.
900
+ - **Outcome** (`pen_stack/twin/outcome.py`): `predict_outcome(design, cell_state)` fuses mechanism plus an
901
+ in-distribution virtual-cell response plus the v5.6 immune profile into one prediction with an interval that
902
+ widens under OOD, an immune-outcome dimension, and an explicit phenotype / in-vivo-magnitude boundary.
903
+ In-vivo durability may be conditioned on the grounded pre-existing-NAb axis (no invented immune numbers);
904
+ `output_kind="candidate"`.
905
+ - **Calibration** (`pen_stack/twin/calibrate.py`): `calibrate_outcome(...)` reports calibration two-sided: interval
906
+ coverage plus a bootstrap CI on the MAE gap vs a naive mean baseline; the twin "beats" naive only when the CI
907
+ excludes zero, else the negative is reported verbatim; it abstains at `N < 3`.
908
+ - **Bench v0.3.5:** a new `outcome_prediction` hard-gate task (`pen_stack/validate/outcome_prediction.py`):
909
+ the gate is the twin's calibration properties (two-sided calibration plus OOD widening plus immune dimension plus
910
+ phenotype out-of-scope), which an overconfident predictor fails by construction; twin-vs-naive skill is reported
911
+ informationally on a labelled synthetic stream (no public perturbation-outcome calibration set exists).
912
+ - Docs: `docs/digital_twin.md`; preregistration `ws_{vcell,mech,outcome,twincal}` plus SHA locks; deposit `phase_5.9/`.
913
+
914
+ ### Notes
915
+ - The twin is a hypothesis engine, not an oracle of truth: predictions are candidates with intervals;
916
+ phenotype, in-vivo behaviour, immunogenicity magnitude, and durability beyond the computable stay
917
+ scope-flagged. The interval is a heuristic band, not a trained conformal interval (no public outcome
918
+ calibration set). Immune-outcome is sourced from v5.6, never invented.
919
+
920
+ ## [5.8.0] - 2026-06-11 - The Live Agent and Generative Designer
921
+
922
+ PEN-STACK turns from a checker into a grounded designer: it generates
923
+ candidate end-to-end writing systems, keeps only those that pass safety plus legality plus calibration
924
+ (verifier-as-discriminator), and returns the Pareto frontier of real tradeoffs, in which immunogenicity-risk
925
+ is, for the first time, a grounded axis sourced from the v5.6 profile rather than a placeholder. SHA-locked.
926
+
927
+ ### Added
928
+ - **Generation** (`pen_stack/design/{space,generate}.py`): `generate_designs(goal|candidates)` proposes candidates
929
+ (`candidate_space` = the validated Phase-3 planner by the compatible delivery palette) and the v3.3 `verify()`,
930
+ now safety-gated (v5.7) plus legality plus calibration plus immune-profiled, disposes. A candidate survives only
931
+ if legal AND safe (`clear`/`flag`); hazardous (`refuse`/`escalate`) and illegal proposals are discarded,
932
+ never returned (the `as_claim()` guard generalised to whole designs). Survivors carry calibrated confidence,
933
+ the v5.6 immune profile, the safety decision, and `output_kind="candidate"`, never asserted to work.
934
+ - **Pareto** (`pen_stack/design/pareto.py`): `pareto_front(designs)` over `(efficiency, durability, safety,
935
+ deliverability, neg_immune_risk, neg_cost)`. `neg_immune_risk` is grounded by the v5.6 profile: the
936
+ worst-case per-axis in-scope score with the per-axis uncertainty carried as a band; the profile is never
937
+ collapsed into one number and the in-vivo magnitude stays scope-flagged (`in_vivo_magnitude_unknown`).
938
+ - **Orchestration** (`pen_stack/agent/orchestrator_live.py`): `orchestrate(goal)`: plan, generate, call an oracle
939
+ (cache-first/replayable) for a critique signal, dispose via `verify()`, refine. Every number is tool-sourced;
940
+ a seed-locked replay reproduces the trace (replay is the CI default); no fabrication.
941
+ - **Bench v0.3.4:** a new `generative_design` hard-gate task (`pen_stack/validate/generative_design.py`):
942
+ on a frozen mixed pool (benign plus a hazardous ricin payload plus illegal oversize/mRNA-incompatible), the grounded
943
+ designer returns only legal, safe, calibrated, immune-profiled survivors on a grounded-immune-axis Pareto frontier,
944
+ while an ungrounded generator ships hazardous/illegal designs and fails by construction.
945
+ - Docs: `docs/generative_design.md`; preregistration `ws_{gen,pareto,orch}` plus SHA locks; deposit `phase_5.8/`.
946
+
947
+ ### Notes
948
+ - A generated output is a candidate, never a claim; novelty is bounded by the oracles' validity and the
949
+ rules' legality, and never asserted to work. The immune-risk Pareto axis is a worst-case screen; the
950
+ per-axis v5.6 profile (with its validation labels) remains authoritative; in-vivo magnitude is a known-unknown.
951
+
952
+ ## [5.7.0] - 2026-06-11 - The Guardian (biosecurity / dual-use safety gate)
953
+
954
+ This release makes PEN-STACK safe by
955
+ construction before it moves toward "build": every design submitted to `verify()` first passes a biosecurity / dual-use screening gate that
956
+ refuses or escalates select-agent, pandemic-pathogen, and controlled-toxin signatures, with function-based and
957
+ chimera checks that catch AI-designed homologs that homology alone would miss, while legitimate therapeutic designs
958
+ pass untouched. It is orthogonal to (and complementary with) the v5.1-v5.6 immune-risk profile. SHA-locked.
959
+
960
+ ### Added
961
+ - **Screens** (`pen_stack/safety/{registry,screen}.py` plus `configs/safety/hazard_registry.yaml`): a curated,
962
+ version-pinned `HazardRegistry` (`registry_version`) and three or more screens returning typed, provenanced
963
+ `ScreenHit`s: `function_flag` (toxin / pathogen-essential functions, the screen that catches AI-homologs
964
+ at low identity), `taxon_flag` (regulated-pathogen taxa), `chimera_context` (hazardous assembly of benign
965
+ parts plus split-hazard), and `sequence_homology` (delegated to a wrappable external screener: IBBIS Common
966
+ Mechanism / SecureDNA-style; the in-repo baseline is a no-op). Signatures are function/family/taxon-level
967
+ only (public Pfam accessions plus public control-list references: 42 CFR 73 / 7 CFR 331 / 9 CFR 121 / Australia
968
+ Group / HHS P3CO/DURC), no hazard sequences, no synthesis/enhancement detail. All 14+ Pfam accessions were
969
+ independently verified against EBI InterPro before reliance; one error (PF01375, mislabeled anthrax, which is
970
+ heat-labile/cholera enterotoxin) was caught and corrected; anthrax PA was re-sourced from UniProt P13423.
971
+ - **Policy** (`pen_stack/safety/{policy,gate,audit}.py` plus `configs/safety/policy.yaml`): `SafetyVerdict`
972
+ {clear, flag, refuse, escalate}; `safety_gate(design, actor=...)` = strip-framing, screen, decide, audit;
973
+ ambiguous dual-use (gain-of-function) escalates to human review (HHS P3CO/DURC), not auto-refuse; an
974
+ append-only, hash-chained, tamper-evident `audit_log` (plus `verify_chain`) storing a design digest, not the
975
+ design. Re-framing as "defensive research" cannot flip refuse to clear (the artifact decides, not the wording).
976
+ - **Integration:** `Verdict.safety: SafetyVerdict`; `verify(design, actor=...)` runs the gate first and a
977
+ `refuse` short-circuits (the design is returned un-evaluated, not scored/critiqued). No-fabrication holds:
978
+ hits come only from the versioned registry.
979
+ - **Red team** (`pen_stack/safety/redteam.py`): an adversarial harness (AI-homolog, split-hazard, reframing,
980
+ chimera) plus reframing-stability pairs; reports set size plus caught count.
981
+ - **Bench v0.3.3:** a new `safety_screening` hard-gate task (`pen_stack/validate/safety_screening.py`):
982
+ benign therapeutics 0 false refusals, hazards refused/escalated at correct severity, evasions never `clear`;
983
+ beats a no-safety baseline (1.0 vs 0.33) by construction. Frozen probes/registry/policy SHA-locked into the
984
+ bench. The bench is now 17/17 available, planner beats naive on 13/13.
985
+ - Docs: `docs/responsible_use.md` plus `docs/biosecurity.md`; preregistration `ws_{screen,policy,redteam}` plus SHA locks;
986
+ deposit `phase_5.7/` (execution summary plus an independent data/ID verification record).
987
+
988
+ ### Notes
989
+ - The safety gate is a defensive safeguard, not a guarantee, and not a substitute for institutional
990
+ biosafety / IBC review; signatures are versioned and exploit detail is intentionally not published.
991
+ - It is orthogonal to the immune-risk profile: the Guardian asks "is this design hazardous/dual-use?"; the immune
992
+ profile asks "will the patient react?". Both attach to every `Verdict`; neither subsumes the other.
993
+
994
+ ## [5.6.0] - 2026-06-11 - Immunology completion and calibration (anti-PEG, proxy labels, unified profile)
995
+
996
+ This release finishes the delivery-immunology arc (v5.1-v5.5): it adds the missing anti-PEG axis, calibrates the
997
+ proxies, and exposes a unified per-design immune-risk profile that never collapses into one number.
998
+ SHA-locked.
999
+
1000
+ ### Added
1001
+ - **Anti-PEG** (`pen_stack/planner/antipeg_oracle.py` plus `configs/antipeg.yaml`): pre-existing/induced anti-PEG
1002
+ antibodies gate re-dosing of PEGylated LNP. Population prevalence range (25-72%) gives
1003
+ `preexisting_antipeg_score = 1 - midpoint/100`, range surfaced as `native_uncertainty`; abstains for
1004
+ non-PEGylated vehicles. Serosurvey DOIs Crossref-verified (Chen 2016 `10.1021/acs.analchem.6b03109`, Yang &
1005
+ Lai `10.1002/wnan.1339`, Armstrong `10.1002/cncr.22739`, Kozma `10.1016/j.addr.2020.07.024`). Scope card `antipeg`.
1006
+ - **Calibration** (`pen_stack/validate/immune_calibration.py`): `calibrate_axis()` (Spearman rho plus percentile
1007
+ bootstrap CI) labels an axis outcome-validated only when the CI excludes zero, else `weak_proxy`, and
1008
+ `mechanistic_proxy` when N < 6. With no sufficient public paired (proxy, observed) dataset, every axis is
1009
+ labelled a mechanistic/population proxy; the label travels with the profile. (No fabricated
1010
+ outcome data; the machinery is proven on synthetic input.)
1011
+ - **Profile** (`pen_stack/planner/immune_profile.py` plus `Verdict.immune_profile`): a per-design vector
1012
+ of all axes (genotoxicity, CD8 epitope, innate, pre-existing NAb, anti-PEG), each with its own value plus
1013
+ uncertainty plus scope plus validation label. `collapsed_score is None` (never fused, asserted); known-unknowns
1014
+ listed; abstaining axes report `None`.
1015
+ - **Extras:** a documented qualitative route/immune-privilege modifier (eye/CNS lower realized
1016
+ immunogenicity vs systemic; Streilein 2003 `10.1038/nri1224`; no fabricated magnitude); CD4/MHC-II helper
1017
+ epitopes, pre-existing capsid-specific T-cell immunity, and complement/CARPA registered as
1018
+ known-unknowns. `prereg/ws_{peg,calib,profile}.yaml` plus SHA locks.
1019
+
1020
+ ### Changed
1021
+ - Version 5.5.0 to 5.6.0 (minor, additive); `cite.curated_dois()` ingests the anti-PEG plus immune-privilege DOIs.
1022
+
1023
+ ### Scope invariant (unchanged)
1024
+ - Every axis is a relative-risk screen (sequence/mechanistic or population proxy), labelled as such until
1025
+ outcome-validated; the profile is never collapsed into one number; patient-specific titer, post-dose-1
1026
+ induced immunity, and exact in-vivo magnitude stay known-unknowns.
1027
+
1028
+ ## [5.5.0] - 2026-06-10 - Anti-vector seroprevalence oracle (the last immune axis, from data)
1029
+
1030
+ This release completes the computable delivery-immunology axes. Pre-existing humoral immunity (B-cell /
1031
+ neutralizing antibody) to a viral capsid is the one immune axis that cannot be computed from sequence: it is a population
1032
+ prevalence from natural exposure. v5.5 grounds it in published serosurvey data. SHA-locked.
1033
+
1034
+ ### Added
1035
+ - **Seroprevalence table** (`configs/seroprevalence.yaml`): curated population NAb/IgG seroprevalence per serotype
1036
+ as ranges (region/age/assay variation) with DOIs: AAV (Calcedo 2009, Boutin 2010), adenovirus type 5
1037
+ (Mast 2010), HSV-1 (Looker 2015), VSV (negligible).
1038
+ - **Seroprevalence oracle** (`pen_stack/planner/seroprevalence_oracle.py`): `seroprevalence_oracle(vehicle,
1039
+ serotype=None)` returns an `OracleResult`. `preexisting_score = 1 - midpoint(seroprevalence)/100`; the range width is
1040
+ surfaced as `native_uncertainty`. Non-viral becomes 1.0 by mechanism; unknown abstains.
1041
+ - **Wired into the pre-existing axis:** `safety_efficacy_profile()` folds the computed seroprevalence score
1042
+ into the `preexisting_immunity` sub-axis only for in-vivo vehicles (serum NAb neutralises the vector in
1043
+ vivo; ex-vivo transduction in a dish is not reached by host antibody, so it is reported but muted). `seroprevalence_score`
1044
+ surfaces the raw value.
1045
+ - **Result (from data):** adenovirus has the highest pre-existing seroprevalence (40-90%, score 0.35), AAV
1046
+ intermediate (30-60%, 0.55), VSV/lentivirus negligible (0-5%, 0.975), the documented ordering quantified
1047
+ from serosurveys. `prereg/ws_seroprev.yaml`.
1048
+
1049
+ ### Changed
1050
+ - Version 5.4.0 to 5.5.0 (minor, additive data-grounded oracle); `cite.curated_dois()` ingests the
1051
+ seroprevalence DOIs.
1052
+
1053
+ ### Scope invariant (unchanged)
1054
+ - This is a population prevalence (a range; region/age/assay-dependent), not a given patient's NAb titer /
1055
+ sero-status (a clinical test, patient-specific, a known-unknown); the humoral (B-cell) axis only,
1056
+ distinct from the v5.3 T-cell epitope load. No patient-specific magnitude predicted.
1057
+
1058
+ ## [5.4.0] - 2026-06-10 - Computed innate-sensing scorer (completes the computable immune axes)
1059
+
1060
+ The third computed delivery-immunology signal, after v5.2 genotoxicity and v5.3 capsid epitope load. Innate
1061
+ sensing of a delivered nucleic acid is computed directly from the cargo sequence: CpG O/E for DNA (TLR9),
1062
+ U-richness plus dsRNA for mRNA (TLR7/RIG-I), covering every cargo form. SHA-locked.
1063
+
1064
+ ### Added
1065
+ - **Innate scorer** (`pen_stack/planner/innate_sensing.py`): `cpg_observed_expected()` (Gardiner-Garden &
1066
+ Frommer) plus `innate_sensing(seq, cargo_form)` returning an `OracleResult`. DNA gives CpG O/E (vertebrate genome ~0.2
1067
+ tolerated; non-depleted DNA is TLR9-stimulatory), `innate_score = max(0, 1 - CpG_O/E)`. mRNA gives uridine
1068
+ fraction plus ViennaRNA dsRNA pairing (graceful when ViennaRNA absent), flagged partial/`extrapolating`.
1069
+ RNP is minimal/transient. Abstains on empty / unrecognised input (never fabricates). Pure sequence
1070
+ computation, no external data, runs in CI.
1071
+ - **Surfaced in `verify()`:** when a design supplies `cargo_seq`, the computed innate load is attached as a
1072
+ `cargo_innate_sensing` scope flag (cargo form from the writer output form, else the vehicle's first
1073
+ compatible form) and added to `delivery_profile.cargo_innate`. No confidence added; the realized in-vivo
1074
+ innate response stays a known-unknown.
1075
+ - Scope card `innate_sensing`; `prereg/ws_innate.yaml`. `cite.curated_dois()` ingests the innate provenance
1076
+ DOIs (CpG-TLR9 10.1073/pnas.161293498, CpG-depleted AAV 10.1172/JCI68205, RNA modification
1077
+ 10.1016/j.immuni.2005.06.008, plus Krieg 1995 / Hornung 2006).
1078
+
1079
+ ### Changed
1080
+ - Version 5.3.0 to 5.4.0 (minor, additive computed scorer).
1081
+
1082
+ ### Scope invariant (unchanged)
1083
+ - This is a sequence-intrinsic motif-load signal. The realized in-vivo innate response magnitude in a patient is
1084
+ not modelled (known-unknown); the mRNA score is partial because the dominant evasion lever,
1085
+ nucleoside modification (m1-pseudouridine), is a manufacturing choice not derivable from sequence; DNA
1086
+ methylation state is likewise out of scope. No magnitude predicted.
1087
+
1088
+ ## [5.3.0] - 2026-06-10 - Computed capsid epitope-load oracle (covers all vectors)
1089
+
1090
+ v5.2 computed genotoxicity only meaningfully touches integrating vectors. v5.3 brings the NetMHC-style
1091
+ calculation to the adaptive (CD8 T-cell) axis: the fraction of a viral vector's capsid/envelope that is
1092
+ presentable across a frequent HLA-I panel (MHCflurry), so the computed immune signal covers all 8 vehicles
1093
+ (5 viral computed, 3 non-viral by mechanism). SHA-locked.
1094
+
1095
+ ### Added
1096
+ - **Build** (`scripts/p53_build_epitope_oracle.py`, runs in a dedicated `penstack:mhcflurry` image):
1097
+ slides 9-mers across each capsid/envelope antigen and predicts MHCflurry 2.0 affinity %rank per allele across
1098
+ 12 frequent HLA-I alleles; `epitope_fraction_strong` = residues covered by a strong binder (%rank <= 0.5);
1099
+ `capsid_immune_score = 1 - epitope_fraction_strong`. Sequences UniProt-verified and committed
1100
+ (`configs/capsid_sequences.fasta`): AAV2 VP1 P03135, Ad5 hexon P04133, VSV-G P03522, HSV-1 gD P57083 plus gB
1101
+ P06437. Emits the small committed summary `configs/capsid_epitope_oracle.yaml` (MHCflurry plus raw sequences stay
1102
+ on the VM, CI-safe).
1103
+ - **Oracle** (`pen_stack/planner/capsid_epitope_oracle.py`): `capsid_epitope_oracle(vehicle)` returns
1104
+ an `OracleResult` (`output_kind="baseline"`, scope card `capsid_epitope`). Non-viral vehicles become 1.0 by
1105
+ mechanism; unknown / sequence-less abstains.
1106
+ - **Wired into the adaptive axis:** `safety_efficacy_profile()` folds the computed capsid score into the
1107
+ adaptive (CD8) sub-axis only for in-vivo vehicles. The computed score is intrinsic antigen
1108
+ presentability; for ex-vivo lentivirus (whose VSV-G envelope is intrinsically epitope-dense but barely
1109
+ seen by the host ex vivo) it is reported but not folded (`adaptive_source = computed_ex_vivo_muted`), the
1110
+ documented tier kept. `capsid_presentability_score` surfaces the raw computed value.
1111
+ - **Result:** the AAV2 capsid is the least epitope-dense (0.72) and Ad5 hexon among the most (0.82); HDAd's in-vivo
1112
+ immune score drops accordingly, the documented adaptive ordering reproduced from sequence. `prereg/ws_epitope.yaml`.
1113
+
1114
+ ### Changed
1115
+ - Version 5.2.0 to 5.3.0 (minor, additive computed oracle); `cite.curated_dois()` ingests the epitope
1116
+ provenance DOIs (MHCflurry 10.1016/j.cels.2020.06.010, HLA-I supertypes 10.1186/1471-2172-9-1).
1117
+
1118
+ ### Scope invariant (unchanged)
1119
+ - This is a population-level, sequence-intrinsic presentation signal (does the capsid contain HLA binders), not
1120
+ the realized in-vivo / patient-HLA-specific T-cell response (a known-unknown), and CD8/MHC-I only (not
1121
+ antibody / neutralizing-antibody). No magnitude predicted.
1122
+
1123
+ ## [5.2.0] - 2026-06-10 - Computed genotoxicity oracle (data, not a documented tier)
1124
+
1125
+ The v5.1 genotoxicity axis was a documented ordinal tier; for integrating vectors that signal is in fact
1126
+ computable from data the stack already holds. v5.2 adds a computed genotoxicity oracle: the observed
1127
+ enrichment of a vector class's integration sites near COSMIC oncogenes, answering through the v4.0
1128
+ OracleResult contract. SHA-locked.
1129
+
1130
+ ### Added
1131
+ - **Build** (`scripts/p52_build_genotox_oracle.py`, runs on the VM where the data lives): computes,
1132
+ per integrating vector class, `P(integration site within 50 kb of a COSMIC Cancer-Gene-Census oncogene)` and
1133
+ its enrichment over genome background, from VISDB per-virus catalogues by the Phase-1 oncogene annotation
1134
+ (COSMIC CGC v104). Emits the small, auditable, committed summary `configs/genotoxicity_oracle.yaml` (raw
1135
+ catalogues stay on the VM; only the statistics ship, CI-safe).
1136
+ - **Oracle** (`pen_stack/planner/genotoxicity_oracle.py`): `genotoxicity_oracle(vehicle)` returns an
1137
+ `OracleResult` (`output_kind="baseline"`) with `genotox_score = min(1, 1/enrichment)`, native uncertainty
1138
+ (CI on the observed fraction), the `delivery_genotoxicity` scope card, and `extrapolating` for small-n
1139
+ classes. Non-integrating vehicles become 1.0 by mechanism; no computed class abstains (never fabricates).
1140
+ - **Wired into the v5.1 balance:** `safety_efficacy_profile()` now prefers the computed genotox_score for
1141
+ integrating vectors and falls back to the documented tier otherwise (`genotox_source` records which).
1142
+ - **Result (from data):** lentiviral (HIV) integration is 2.08x enriched near oncogenes (n=88,743, robust)
1143
+ vs 5.65x for gammaretroviral (MLV, the LMO2/SCID-X1 comparator, small-n flagged), reproducing the
1144
+ lentivirus-safer-than-gammaretrovirus ordering from VISDB by COSMIC, and the computed lentivirus score
1145
+ (0.48) validates the v5.1 documented "moderate" tier (0.5). `prereg/ws_genotox.yaml`.
1146
+
1147
+ ### Changed
1148
+ - Version 5.1.0 to 5.2.0 (minor, additive computed oracle); `cite.curated_dois()` ingests the genotox
1149
+ provenance DOIs (VISDB 10.1093/nar/gkz867, COSMIC CGC 10.1038/s41568-018-0060-1, HIV/MLV integration biology).
1150
+
1151
+ ### Scope invariant (unchanged)
1152
+ - This is a relative integration-preference signal. The in-vivo clonal-expansion / leukemogenesis outcome
1153
+ in a patient is not modelled and stays a known-unknown (`delivery_genotoxicity` scope card); the immune
1154
+ magnitude likewise stays `in_vivo_immunogenicity`. No magnitude is predicted.
1155
+
1156
+ ## [5.1.0] - 2026-06-10 - Delivery immunology (the safety/efficacy balance)
1157
+
1158
+ The delivery palette gains a documented, cited, qualitative immune plus safety plus efficacy profile per vehicle,
1159
+ so the substrate can make the safety/efficacy tradeoff legible and user-weightable, without ever predicting an
1160
+ immune magnitude (that stays a declared known-unknown). SHA-locked.
1161
+
1162
+ ### Added
1163
+ - **Config** (`configs/delivery_vehicles.yaml` v1.1): an `immune_safety` block on all 8 vehicles
1164
+ (`preexisting_immunity`, `neutralizing_antibody`, `innate_immune`, `adaptive_immune`, `genotoxicity`,
1165
+ `efficacy`, `tradeoff`, `immune_dois`): documented ordinal low/moderate/high priors, every `immune_doi`
1166
+ Crossref-verified and in the curated-DOI set (citations resolve by construction).
1167
+ - **Planner** (`pen_stack/planner/delivery_immunology.py`): `safety_efficacy_profile()` reports two
1168
+ separate safety sub-axes: `immune_score` (immunogenicity; reversible, eligibility/re-dosing) and
1169
+ `genotox_score` (insertional/oncogenic; permanent), never collapsed, with a top-line
1170
+ `safety_score = min(immune_score, genotox_score)` (precautionary worst-axis). `recommend_delivery(cargo_form,
1171
+ cargo_bp, safety_weight, in_vivo)` ranks the eligible palette along the safety/efficacy frontier by a
1172
+ user-supplied weight. It reproduces the stated tradeoff: AAV is dinged on immunogenicity, lentivirus on
1173
+ genotoxicity. `prereg/ws_immune.yaml`.
1174
+ - **Verify** (`Verdict.delivery_profile` plus a `delivery_immune_profile` scope flag): `verify()` now
1175
+ surfaces the documented profile and tradeoff for a chosen vehicle, always attaching the standing
1176
+ `in_vivo_immunogenicity` known-unknown flag, never adding confidence, never predicting a magnitude.
1177
+
1178
+ ### Changed
1179
+ - Version 5.0.0 to 5.1.0 (minor, additive delivery-immunology layer); `cite.curated_dois()` now also ingests
1180
+ the per-vehicle `immune_dois`.
1181
+
1182
+ ### Scope invariant (unchanged)
1183
+ - The in-vivo immune magnitude (patient/construct-specific response) remains a declared known-unknown
1184
+ (`configs/known_unknowns.yaml: in_vivo_immunogenicity`) and is never predicted. v5.1 exposes only
1185
+ documented ordinal priors plus a transparent, user-weighted ranking; it makes the boundary legible, it does
1186
+ not close it.
1187
+
1188
+ ## [5.0.0] - 2026-06-09 - The Co-Scientist (capstone)
1189
+
1190
+ The reasoning ceiling rises while the grounding floor stays fixed: a co-scientist that proposes multiple
1191
+ distinct strategies, critiques and revises its own plans, cites its reasoning, and itemises what it cannot
1192
+ assess, with no-fabrication holding across the full reasoning stack (the central gate). Each component is SHA-locked.
1193
+
1194
+ ### Added
1195
+ - **Planning and multi-strategy** (`pen_stack/agent/co_scientist.py`): `propose_strategies()` returns 2-3 materially
1196
+ distinct strategies (at least 2 design axes differ, measured by `distinctness()`, not reworded), each
1197
+ independently legal plus confidence-tagged; `deliberate()` benchmarks the deliberative planner vs the
1198
+ deterministic baseline. `prereg/ws_plan.yaml`.
1199
+ - **Critique and scope:** `critique()` / `critique_and_revise()` (the critic only flags plus swaps a design
1200
+ choice, never invents a number; revisions re-verified) plus `critique_falsifiability()` (improves flawed plans
1201
+ illegal to legal, 0 spurious revisions on clean) plus `scope_ledger()` (per-recommendation: what was/wasn't
1202
+ assessed, the known-unknowns itemised). `prereg/ws_crit.yaml`.
1203
+ - **Citation and generalisation** (`pen_stack/agent/cite.py`): `cited_rationale()` (citations drawn from the curated
1204
+ world-model, resolve by construction) plus `citations_grounded()` guard (rejects any DOI not in the curated
1205
+ set) plus `generalise()` (adjacent tasks grounded-or-refused). `prereg/ws_cite.yaml`.
1206
+ - **Bench v0.3.2:** a `co_scientist_grounded` reference-solver task: grounded rate 1.0 vs ungrounded 0.0;
1207
+ no-fabrication across the full stack. `docs/co_scientist.md`.
1208
+
1209
+ ### Changed
1210
+ - Version 4.5.1 to 5.0.0 (major, the substrate matured into a grounded co-scientist); bench 0.3.1 to 0.3.2.
1211
+
1212
+ ## [4.5.1] - 2026-06-09 - ID-correctness patch: cell-type ontology IDs
1213
+
1214
+ ### Fixed
1215
+ Two of the three new v4.5 Tier-A cell-type ontology IDs in `configs/cell_types.yaml` were wrong (verified via
1216
+ EBI-OLS): `EFO:0002322` resolved to the RPMI8226 myeloma line (not a T cell) and `EFO:0004146` to an
1217
+ obsolete myopathy term (not hepatocyte). Corrected to the canonical, non-obsolete Cell Ontology terms:
1218
+ primary_T_cell to `CL:0000084` (T cell), hepatocyte to `CL:0000182` (hepatocyte). iPSC (`EFO:0004905`),
1219
+ K562 (`EFO:0002067`), HepG2 (`EFO:0001187`) verified correct, as was the ISPpu10 back-test record (Europe PMC
1220
+ PPR1218813, "ISPpu10 is a structure-gated bridge RNA recombinase..."). No result/test change (the IDs are
1221
+ coverage-card metadata; `cell_types.py` reads coverage, not the ontology id).
1222
+
1223
+ ## [4.5.0] - 2026-06-09 - The Living World-Model (knowledge graph plus gated living loop)
1224
+
1225
+ v4.5 promotes the flat tables into a queryable knowledge graph that keeps itself current. Each component is
1226
+ SHA-locked. The agent proposes; a gate disposes, so no process auto-edits curated truth.
1227
+
1228
+ ### Added
1229
+ - **Knowledge graph.** `pen_stack/graph/{schema,build,query}.py`: typed nodes
1230
+ (writer/locus/cargo/vehicle/cell_type/write_type/outcome) plus typed edges
1231
+ (reaches/deliverable_by/performs/durable_in/carries/used_writer/observed_at), each carrying evidence kind
1232
+ (measured > curated > predicted) plus confidence plus scope plus provenance. Built deterministically from the v4.0
1233
+ curated tables (94 nodes / 288 edges), a pure-Python JSON store. Multi-hop queries return provenanced paths;
1234
+ `deliverable_by` reproduces the v3.3 verifier (0 parity mismatches). REST `POST /graph/query` plus MCP
1235
+ `graph_query`. `docs/world_model.md`; `prereg/ws_graph.yaml`.
1236
+ - **Gated living loop.** `pen_stack/graph/ingest.py`: Candidate plus Quarantine (propose never mutates
1237
+ a graph), `automated_checks` plus `gate_admit(approved, admitted_by)` as the sole admission path with versioned
1238
+ records; the back-test surfaces ISPpu10 (Europe PMC PPR1218813). No auto-edit path (asserted). `prereg/ws_mon.yaml`.
1239
+ - **Cell-type expansion.** `configs/cell_types.yaml` Tier-A (iPSC/ESC, primary T cells, hepatocytes)
1240
+ with coverage cards plus a Tier-B roadmap; `pen_stack/graph/cell_types.py` graceful degradation (partial coverage
1241
+ caps confidence) plus cross-cell-type OOD labelling. `prereg/ws_ct.yaml`.
1242
+ - **Graph reasoning bench.** `graph_multihop_reasoning` (bench v0.3.1): graph reasoning accuracy 1.0
1243
+ vs ungrounded 0.0, every answer a provenanced path. `prereg/ws_ba_v45.yaml`.
1244
+
1245
+ ### Changed
1246
+ - Version 4.0.3 to 4.5.0; bench 0.3 to 0.3.1; README updated for v4.5; M1/M2 plus world-model note updates.
1247
+
1248
+ ## [4.0.3] - 2026-06-09 - ID-correctness patch: UniProt plus Pfam plus ontology audit
1249
+
1250
+ ### Fixed
1251
+ A whole-repo audit of structured IDs (verified against InterPro, UniProt, EBI-OLS, mygene):
1252
+ - **`pen_stack/mech/pfam_whitelist.yaml` (v1.2.1 to v1.2.2):** the 26 Pfam accessions were all correct, but
1253
+ 13 of 22 `example_uniprot` proteins did not actually contain their claimed domain (membership checked
1254
+ against each protein's UniProt Pfam cross-references), including a marine-worm Histone H3 (PF13586), a
1255
+ mouse mannosyltransferase (PF05621/TniB), I-AniI (a LAGLIDADG enzyme) mislabelled HNH (PF01844), a
1256
+ glycine-betaine transporter and a Tn3 transposase mis-filed as rve, and an obsolete 404 accession
1257
+ (PF08721), despite the header claiming a spot-check. All corrected to reviewed/curated proteins whose
1258
+ UniProt entry genuinely carries the domain (e.g. ISCro4 `D2TGM5`, Tn5 `Q46731`, Tn7-TnsA `P13988`, Bxb1
1259
+ integrase `Q9B086`, McrA `P24200`); the audit-status header was corrected to stop over-claiming.
1260
+ - **`configs/atlas_families.yaml`** (drives family expansion in `expand.py`): IS621 `A0A0F6B5L8` (a
1261
+ betaine transporter) to `A0A2X3M8B0` (IS621 transposase); phiC31 `Q9T2A6` (a plant NAD(P)H
1262
+ oxidoreductase) to `Q9T221` (phiC31 integrase). The Pfam-query signatures and discovery DOIs were
1263
+ already correct.
1264
+
1265
+ ### Verified clean
1266
+ The 4 EFO cell-type IDs map correctly (EFO:0002067=K562, EFO:0001187=HepG2, EFO:0002784=GM12878,
1267
+ EFO:0005483=ES-Bruce4); all GSH gene symbols are valid HGNC symbols; all 26 Pfam accessions resolve with the
1268
+ correct domain name.
1269
+
1270
+ ## [4.0.2] - 2026-06-09 - Citation-correctness patch: full-repo DOI audit
1271
+
1272
+ ### Fixed
1273
+ A full sweep of all 56 DOIs in the repo (verified via Crossref plus doi.org) found six incorrect or
1274
+ non-existent citations, all now corrected to verified, topically-correct references:
1275
+ - `configs/gsh_validated_heldout.yaml` H11 locus: `10.1371/journal.pone.0113481` (resolved to an unrelated
1276
+ cardiology paper) to `10.1093/nar/gkt1290` (Zhu et al. 2014, *DICE*, NAR 42:e34, the paper that
1277
+ characterized human H11 on chr22q12.2 between DRG1 and EIF4ENIF1).
1278
+ - `configs/delivery_vehicles.yaml` plus `configs/rules/{delivery,payload}.yaml`: `10.1089/hum.2017.084`
1279
+ (non-existent), `10.1089/hum.2009.213` (non-existent), `10.1038/sj.gt.3302529` (unrelated erratum) to
1280
+ `10.1128/JVI.79.15.9933-9944.2005` (Grieger & Samulski, AAV packaging capacity),
1281
+ `10.1128/JVI.72.2.926-933.1998` (multiply-deleted adenovirus vectors), `10.1038/nbt1101-1067`
1282
+ (Wade-Martins, HSV-1 amplicon large-capacity).
1283
+ - `pen_stack/validate/bench_writetype_tasks.py` provenance: `10.1038/s41586-023-06756-4` (diabetes program)
1284
+ and `10.1126/science.abm1123` (freshwater fish) to `10.1016/j.cell.2022.03.045` and
1285
+ `10.1128/JVI.79.15.9933-9944.2005`.
1286
+
1287
+ The remaining 50 DOIs resolve correctly; three legacy DOIs in `mech/pfam_whitelist.yaml` (Rice 1995 Cell,
1288
+ Kholodii 1997 Res Microbiol, Prudhomme 2002 J Bacteriol) carry full author/year/journal references and are
1289
+ real classic papers whose pre-modern DOIs do not resolve at doi.org, left unchanged (a registration artifact,
1290
+ not an error).
1291
+
1292
+ ## [4.0.1] - 2026-06-09 - Data-correctness patch: writer-verification panel verified against Perry 2025
1293
+
1294
+ ### Fixed
1295
+ - **The frozen writer-verification panel is now verbatim from the measured Perry 2025 ISCro4 DMS.** The offline-fallback panel
1296
+ in `atlas/writer_verify.py` previously used illustrative Z-scores (2.6/2.1/1.7) and invented control
1297
+ variants (G15D/P88R/L120E), and `_CORE_RESIDUES` used illustrative arginines. Replaced with the real values
1298
+ from `science.adz0276` Table S3: the top-3 enhancers N322P (Z 0.754), H50K (0.742), R278M (0.709), real
1299
+ near-neutral variants (V21R, S312Q, G286T), the most-deleterious variants (R132E -5.40, R137E -5.12,
1300
+ R195D -4.98), and the documented catalytic residues D11/E60/D102/D105/S241 ("Residue Groups" sheet). The
1301
+ real-DMS path (on the VM/Drive) was already correct; only the offline fallback constants were illustrative.
1302
+ Added `test_ws_wv.py::test_frozen_panel_matches_real_perry_dms_table_s3` to guard against drift.
1303
+
1304
+ ## [4.0.0] - 2026-06-09 - The Oracle Mesh (on top of the foundation models) plus writer verification
1305
+
1306
+ A major bump: the substrate now composes the biomolecular foundation models under one contract and verifies
1307
+ the writer enzyme itself. Each component is SHA-locked. No de-novo writer invention: score
1308
+ and critique only (the pen-assemble lesson).
1309
+
1310
+ ### Added
1311
+ - **The oracle mesh.** `pen_stack/oracles/` with `OracleResult{value, provenance(model+version),
1312
+ native_uncertainty, scope_card, in_scope, extrapolating, output_kind, available, cached}`. Adapters:
1313
+ `genome.py` (AlphaGenome OOD-gated; Evo2 likelihood=claim / generation=candidate; ChromBPNet/Borzoi
1314
+ baseline), `structure.py` (AlphaFold3/Boltz-2/Chai-1/Protenix plus `consensus()` that widens the interval on
1315
+ cross-oracle disagreement), `protein_design.py` (RFdiffusion/ProteinMPNN/ESM3, all candidates), `rna.py`
1316
+ (ViennaRNA, real, hard fold-legality), `energetics.py` (bridge off-target, MC3 gate >=0.77).
1317
+ `configs/oracles/scope_cards.yaml` (11 models); deterministic version-pinned `oracle_cache/`. Guard:
1318
+ the generative candidate `as_claim()` raises. `docs/oracles.md`; `prereg/ws_o.yaml`.
1319
+ - **Writer verification.** `pen_stack/atlas/writer_verify.py`: DMS- and structure-grounded variant
1320
+ scoring (measured=claimable, unmeasured=not), `blind_recovery` recovers N322P/H50K/R278M above
1321
+ measured-worse controls, and `critique_candidate` (fold/active-site/deliverable/reachable) wired into
1322
+ `verify()` as `Verdict.writer_critique`, always `no_claim=True`. `docs/writer_verification.md`;
1323
+ `prereg/ws_wv.yaml`.
1324
+ - **Mesh upgrade plus delivery oracle.** `wgenome/mesh_features.py` (OOD-gated feature hook plus blind
1325
+ re-validation reporting parity vs v3.x when oracles are deferred) plus a computable
1326
+ `delivery.aav_packaging_margin` soft rule (titre drops near the AAV capsid limit). `prereg/ws_atlas.yaml`.
1327
+
1328
+ ### Changed
1329
+ - Version 3.4.0 to 4.0.0; `Verdict` gains `writer_critique`; M1 plus writer-verification note plus M2 updates.
1330
+
1331
+ ## [3.4.0] - 2026-06-09 - The Environment (train/eval surface plus bench v0.3 plus outcome-calibration)
1332
+
1333
+ v3.4 turns the thin Gym interface into a full environment an AI agent can be trained and graded in, ships
1334
+ Genome-Writing Bench v0.3 (multi-write-type plus adversarial robustness), and tests whether plan-confidence
1335
+ actually predicts documented outcomes. Each component is SHA-locked. The environment is an
1336
+ interface plus an evaluation harness (a near-one-shot decision), no RL-superiority claim.
1337
+
1338
+ ### Added
1339
+ - **The genome-writing environment.** `pen_stack/env/genome_writing_env.py` upgraded to a full
1340
+ `gymnasium.Env`: a 5-stage MDP (write_type, site, writer, cargo, delivery) whose step validity comes
1341
+ from the v3.3 verifier and whose reward is the legality gate times the L4 calibrated plan confidence, with a
1342
+ reserved abstain action for a justified refusal. `pen_stack/env/policies.py` (random plus greedy-planner).
1343
+ Passes `gymnasium.utils.env_checker.check_env`; greedy(planner) >= random and greedy-legal on the frozen
1344
+ seed set. `docs/environment.md`; `prereg/ws_env.yaml` plus lock.
1345
+ - **Genome-Writing Bench v0.3.** `multi_write_type_legality` routes plus judges legality across all 6
1346
+ non-insertion write types (accuracy 1.0, ungrounded 0.0); `adversarial_robustness` probes T13-T16
1347
+ (out-of-scope-in-disguise, contradictory constraints, prompt-injection, distribution-shift): the
1348
+ verifier-backed agent passes 4/4 vs an over-confident baseline 0/4, no-fabrication holds including under
1349
+ injection. Leaderboard v0.3 robustness contrast. `prereg/ws_bench.yaml` plus lock.
1350
+ - **Plan-confidence calibrated against documented outcomes.** `pen_stack/validate/outcome_calibration.py`:
1351
+ a plan-level reliability diagram plus ECE plus bootstrap-CI selective prediction on the DOI writer panel. The
1352
+ result: useful for ranking (high-confidence 0.30 vs low-confidence 0.0 documented-choice recovery, gap
1353
+ CI95 [0.17, 0.43], monotone) but poorly calibrated in absolute terms (ECE 0.71). Feeds M-UQ.
1354
+ `prereg/ws_cal.yaml` plus lock.
1355
+
1356
+ ### Changed
1357
+ - Version 3.3.0 to 3.4.0; bench 0.2.1 to 0.3; README updated for v3.4; M2/M-UQ manuscript updates.
1358
+
1359
+ ## [3.3.0] - 2026-06-09 - The Verifier (a type checker for genome writes)
1360
+
1361
+ v3.3 lifts the laws of genome writing into a versioned, machine-readable rule base and exposes a single
1362
+ `verify(design) -> Verdict` call (legal/illegal plus named rule plus calibrated confidence plus scope) over Python,
1363
+ REST, and MCP. Each component is SHA-locked.
1364
+
1365
+ ### Added
1366
+ - **Rule base plus solver.** `pen_stack/rules/{schema,evaluators,loader,solver}.py` plus `configs/rules/*.yaml`
1367
+ (9 rules across reachability/fold/payload/multiplex/delivery), each id/kind/mechanism/param/provenance(DOI)/
1368
+ test. Evaluators delegate to the existing validated functions; a parity test proves no decision changed.
1369
+ Legality and confidence are kept as distinct axes.
1370
+ - **Delivery palette.** `configs/delivery_vehicles.yaml` plus `planner/delivery_vehicles.py`: 8 vehicles
1371
+ (AAV single/dual, lentivirus, HDAd, HSV amplicon, LNP-mRNA, eVLP, electroporation) with capacity/integration/
1372
+ cargo-form/DOIs; delivery rules (hard rejects plus soft penalties plus an immunogenicity-magnitude scope flag).
1373
+ - **Write-type router.** `planner/router.py` plus `configs/write_types.yaml`: dispatches insertion/
1374
+ excision/inversion/replacement/regulatory_rewrite/landing_pad_install/multiplex; unsupported types defer.
1375
+ - **Verification service.** `pen_stack/verify/{service,schema}.py`: `verify(design) -> Verdict`; `POST
1376
+ /verify` plus MCP `verify_write`; `docs/verify.md`. No fabrication (every number tool-sourced).
1377
+ - **Bench v0.2.1 plus agent.** T12 rule-grounded legality-with-explanation (verifier reason accuracy 1.0
1378
+ vs ungrounded 0.0); the agent submits its plan to the verifier. Bench 12/12 available, planner beats baseline
1379
+ 8/8.
1380
+ - **Docs:** `docs/verify.md`, `docs/rules.md`, `docs/delivery.md`.
1381
+
1382
+ ### Changed
1383
+ - Version 3.2.0 to 3.3.0 (pyproject, `__init__`, CITATION.cff). README updated for v3.3; bench badge v0.2.1.
1384
+
1385
+ ## [3.2.0] - 2026-06-08 - A calibrated, self-aware co-scientist
1386
+
1387
+ The v3.2 cycle makes the genome-writing funnel trustworthy: every value carries a calibrated confidence,
1388
+ an extrapolation flag, and, where the biology is beyond any tool here, an explicit out-of-scope deferral.
1389
+ Each workstream is pre-registered (`prereg/ws_{uq,ep,mc,ba}.yaml`, SHA-locked) and reports its
1390
+ negatives. The Genome-Writing Bench bumps to v0.2.
1391
+
1392
+ ### Added
1393
+ - **Calibrated uncertainty plus OOD.** Conformal prediction intervals (durability expression) and APS /
1394
+ Mondrian prediction sets (safety, silenced) wrapping the existing heads with no retraining
1395
+ (`pen_stack.wgenome.uncertainty`); an OOD detector that widens intervals out-of-distribution
1396
+ (`pen_stack.wgenome.ood`); selective prediction plus plan-level confidence
1397
+ (`pen_stack.validate.selective_prediction`). Held-out coverage 0.895 vs 0.90 nominal; risk-coverage accuracy
1398
+ 0.739 to 0.930 under abstention. OOD across human cell types is weak (0.65-0.73), reported as a heuristic.
1399
+ - **Epistemic scoping.** A three-tier status (grounded-confident / grounded-extrapolating /
1400
+ not-computable) on every agent output (`pen_stack.agent.epistemic`); a known-unknowns registry plus a scope
1401
+ matcher (`configs/known_unknowns.yaml`, `pen_stack.agent.scope`, `docs/scope.md`) that defers out-of-scope
1402
+ questions (deferral 1.0, false-defer 0.0); abstention in the agent. The no-fabrication gate is intact.
1403
+ - **Mechanistic filters.** A hard target-site/PAM/att-site reachability reject
1404
+ (`pen_stack.planner.target_site`, `configs/target_sites.yaml`; controls 9/9); vehicle-specific
1405
+ delivery-sequence penalties (`pen_stack.planner.delivery_constraints`); and an off-target energetics
1406
+ model (`pen_stack.bridge.offtarget_energetics`) that beats the 0.77 baseline at held-out AUROC 0.88 on the
1407
+ comparable (core-disrupted) construction and ships as the default ranker. A reviewer-driven re-run
1408
+ (`by_negative_construction`) shows that gap is mostly the core-penalisation artifact; with the core held
1409
+ matched the non-core substitution-identity gain is real but modest (delta ~0.04, 0.687 vs 0.646). Both AUROCs
1410
+ carry a favourable-negative-set caveat (decoys derived from real off-targets; no non-recombining background).
1411
+ - **Bench v0.2 plus uncertainty-aware agent.** Four trust tasks (T8 calibration, T9 selective prediction,
1412
+ T10 OOD honesty, T11 out-of-scope refusal) contrasting the uncertainty-aware agent with an over-confident
1413
+ baseline (4/4); PEN-Agent emits confidence plus epistemic status plus abstains; UI surfaces them. Bench re-SHA-locked.
1414
+ - **Gymnasium interface (optional).** A thin `gymnasium.Env` over the planner (`pen_stack.env`,
1415
+ `[env]` extra) for agent-developer interoperability, interface only, no RL superiority claimed.
1416
+ - **Docs:** `docs/uncertainty.md`, `docs/scope.md`, `docs/mechanistic_constraints.md`; M-UQ methods note plus
1417
+ M1/M2 manuscript updates. The Opentrons workstream is deferred to `docs/BACKLOG.md`.
1418
+
1419
+ ### Changed
1420
+ - Version 3.1.0 to 3.2.0 (pyproject, `__init__`, CITATION.cff). README updated for v3.2; badges plus bench
1421
+ v0.2. The bridge off-target default ranker is now the energetics model when its penalty table is present.
1422
+
1423
+ ## [3.1.0] - 2026-06-04 - Publishable contributions plus an adopted benchmark
1424
+
1425
+ The v3.1 cycle completes (workstreams A-H). It hardens the planning benchmark, surrounds the
1426
+ models with strong baselines, adds a predicted-structure safety axis, and ships the first benchmark and
1427
+ grounded agent for the genome-writing side. Every workstream is pre-registered (`prereg/ws_*.yaml`,
1428
+ SHA-locked) and reports its negatives.
1429
+
1430
+ ### Added
1431
+ - **Strong baselines plus safety primary-metric switch.** An endogenous-expression baseline (TRIP-trained
1432
+ Spearman 0.51 vs AlphaGenome ES-Bruce4 proxy 0.43), a multi-mark ablation (all-marks >= best single), and a
1433
+ published GSH rule-set: safe-harbour discrimination (learned 0.92, 95% CI [0.82, 0.98] vs distance-rule
1434
+ 0.38, delta CI excludes zero) is now the primary safety metric; the circular `genotoxic_cis` AUROC is a
1435
+ labeled diagnostic. (`pen_stack.wgenome.gsh_baseline`, `pen_stack.validate.durability_baselines`.)
1436
+ - **AlphaGenome integration.** A hosted-API provider with an offline cache; predicted-vs-measured track
1437
+ validation (HepG2 ATAC Pearson 0.85) with a score-level low-confidence flag; a 3D structural-risk
1438
+ axis from contact-map deltas (`pen_stack.wgenome.{providers,chromatin_seq,structure3d}`,
1439
+ `pen_stack.validate.seq_vs_measured`).
1440
+ - **Cargo Polish.** A cargo-sequence silencing-risk scan (`pen_stack.planner.cargo_polish`).
1441
+ - **Genome-Writing Bench v0.1 plus PEN-Agent.** The first writing-side benchmark (`benchmarks/`,
1442
+ `bench/run.py`) with deterministic scorers, a leaderboard, and a real LLM-agent baseline; a grounded
1443
+ write-planning state machine with a no-fabrication hard gate (`pen_stack.agent.pen_agent`).
1444
+ - **Local recalibration / private-data adaptation.** Gated recalibration / fine-tuning on private
1445
+ data, in-container; the adapted model activates only if it beats the released model AND a no-skill
1446
+ baseline; the released model is provably unchanged (`pen_stack.adapt`).
1447
+ - **Multiplex plus guide QC.** A pairwise translocation-risk screen (`pen_stack.planner.multiplex`,
1448
+ surfaced in PEN-Agent) and a bridge-RNA guide ranker (`pen_stack.bridge.guide_qc`).
1449
+ - **Release plus dissemination.** README/badges updated for v3.1, `docs/quickstart.md`,
1450
+ `docs/positioning.md`, the leaderboard submission guide, the dissemination log, and version 3.1.0.
1451
+
1452
+ ### Changed
1453
+ - The planning benchmark's `recovery_at_k` ranking is now deterministic (stable sort plus tie-breakers).
1454
+ - The LLM stack defaults to the local Ollama model on the compute tier with an automatic hosted-Nemotron
1455
+ fallback, a cooldown cache, and bounded timeouts (no more multi-minute stalls when a provider is absent).
1456
+
1457
+ ## [3.1.0a0] - 2026-06-04 - De-circularize the planning benchmark (gate)
1458
+
1459
+ The v3.1 cycle (publishable contributions plus an adopted benchmark) opens with its gate: de-circularizing the
1460
+ Phase-3 planning benchmark before anything builds on it.
1461
+
1462
+ ### Changed
1463
+ - **The Phase-3 "discriminating-stratum recovery@10 = 1.00 vs 0.00 (McNemar p, CI)" is now labeled
1464
+ definitional, not predictive,** everywhere (README, manuscript abstract, `prereg/paper3.yaml`,
1465
+ `validate/paper3_benchmark.py` docstring). An on-target identity term dominates the score, so the planner
1466
+ ranks the goal's own gene first by construction. Documented in `docs/benchmark_circularity.md`.
1467
+ - The intent result is reframed as a specification-compliance correctness table (`validate/intent_specification.py`,
1468
+ 7/7), with no recovery/p-value/CI language.
1469
+
1470
+ ### Added (the non-circular replacements)
1471
+ - **Blind safe-harbour site discovery (the new lead result):** `validate/blind_gsh_discovery.py` plus
1472
+ `configs/gsh_validated_heldout.yaml` (5 DOI-validated held-out GSH, gene-anchored to hg38) plus a
1473
+ frozen/SHA-locked `data/gsh_matched_controls.parquet`. Run genome-wide (no on-target term), the planner's
1474
+ writability separates validated GSH from matched-context controls at AUROC 0.92 (safety-only 0.50).
1475
+ - **Diversified writer-family recovery:** `validate/writer_recovery.py` plus `data/writer_panel.csv` (8 writes,
1476
+ 4 families, DOIs). recovery@1 = 1.0 vs prevalence 0.25 (smallest-capacity DSB-free writer that fits
1477
+ the cargo).
1478
+ - **Within-locus ranking** (descriptive): `validate/within_locus_ranking.py`, AAVS1 documented bin at the
1479
+ 93rd within-locus percentile (top quartile); CLYBL at the 34th (a negative result).
1480
+ - **Consolidated report** `scripts/p3_benchmark_report.py` to `out/ws_a_report.md`; `prereg/ws_a.yaml` plus
1481
+ SHA lock. Gate G-A is met: blind AUROC reported, no circular claims remain.
1482
+
1483
+ ## [Unreleased] - 2026-06-03 - Reframing, repository polish, coverage, hybrid LLM
1484
+
1485
+ ### Added
1486
+ - **Hybrid LLM backend** (`pen_stack/rag/llm.py`, `configs/llm.yaml`): a strong hosted model for
1487
+ reasoning/agent/Q&A (NVIDIA Nemotron, OpenAI-compatible, free) with automatic fallback to the local
1488
+ Ollama model, then to the deterministic no-LLM path. One `provider` switch. The agent and RAG were
1489
+ refactored onto a single provider-agnostic `chat()` (NVIDIA tool-call IDs and Ollama native message
1490
+ threading both handled). The LLM stays non-load-bearing (every number/citation still comes from
1491
+ validated tools), so the model choice does not affect scientific reproducibility; it only improves
1492
+ orchestration (Nemotron planned a goal in 2 tool calls vs the local 7B's 8-call loop). Core scientific
1493
+ compute stays local/VM and uses no LLM. API keys are read from an env var or a gitignored file and
1494
+ are never committed.
1495
+
1496
+ ### Changed
1497
+ - **Paper 4 reframed to its scope.** `pen-bridge` is positioned as the first measured-data-validated
1498
+ tool that nominates and ranks candidate off-target locations for bridge recombinases, a
1499
+ screening tool, not a quantitative safety calculator. The AUROC 0.77 vs 0.62 result is stated with
1500
+ its caveat (favourable negative set; mostly tests core integrity), and the magnitude limitation
1501
+ (sequence-risk does not rank recombination amount, rho ~0.30) is named as the single most important
1502
+ limitation. Application-Note tier, first-of-its-kind for an unoccupied gap; the Writable Genome remains
1503
+ the flagship. Manuscript plus `prereg/paper4.yaml` plus summaries updated.
1504
+ - **Variant-effect reframed:** the DMS recovers KNOWN enhancers (a catalogue feature), it is not a novel
1505
+ variant-design method; EVOLVEpro is the engine to wrap when generating new variants.
1506
+ - **Repository made clean ASCII:** removed all decorative emojis and em/en dashes and other non-ASCII
1507
+ punctuation across code, docs, configs, and manuscripts (box-drawing tree characters kept).
1508
+
1509
+ ### Added
1510
+ - 72-system ortholog characterisation (`bridge/ortholog_screen.py`), explicitly descriptive (Table S1 has
1511
+ no activity label): sequence-similarity organisation vs the validated standout ISCro4 (IS621 ranks most
1512
+ similar, a sanity check). Exploratory secondary result, N ~72.
1513
+ - Coverage: CI runs `pytest --cov`, uploads to Codecov, and publishes a self-hosted coverage badge
1514
+ (`tools/make_coverage_badge.py` to `.github/badges/coverage.svg`). Unit-test coverage of the core logic
1515
+ is 69% (integration-only modules that need GPU/VM/network/LLM are excluded via `[tool.coverage.run]`).
1516
+ - Professional, emoji-free README with connected-repo badges (genome-atlas / mech-class / pen-score /
1517
+ pen-assemble / pen-compare), an architecture diagram, and the problem/gaps explanation.
1518
+
1519
+ ## [3.0.0a5] - 2026-06-02 - Phase 1.5 (Bridge-recombinase off-target engine, Paper 4)
1520
+
1521
+ The first public instrument: a bridge-recombinase off-target screening tool.
1522
+
1523
+ ### Added
1524
+ - **Off-target engine** (`pen_stack/bridge/offtarget.py` plus `configs/bridge_offtarget_profile.yaml`):
1525
+ a genome-wide hg38 pseudosite scan (CT-core seed, per-chromosome, memory-bounded) plus a position-weight
1526
+ risk model grounded in the published mechanism. Beats naive Hamming: AUROC 1.00 vs 0.59 at
1527
+ separating core-preserving (real-risk) from core-disrupting (abolished) sites. Exposes
1528
+ `predict_offtargets(family, site)`, completing the Phase-3 Planner cargo hook.
1529
+ - **Fold / cross-loop QC** (`bridge/fold_qc.py`): a ViennaRNA fold (verified MFE on a 190-nt design) plus
1530
+ TBL/DBL cross-loop complementarity.
1531
+ - **Activity framework** (`bridge/activity.py`): an exploratory DMS plus 72-system trainer (deferred; data paywalled).
1532
+ - **`pen-bridge`** (`bridge/pipeline.py`, `bridge/cli.py`, `/bridge/design` API): wraps the Arc
1533
+ BridgeRNADesigner (verified) and adds the off-target plus QC layer.
1534
+ - `validate/paper4_validation.py` plus `scripts/p4_genome_scan.py`; `prereg/paper4.yaml` plus SHA lock.
1535
+
1536
+ ### Notes
1537
+ - **Phase 1.5 complete.** The pre-registered criteria were met (or gated): the off-target engine,
1538
+ the ViennaRNA fold, and the designer wrap are verified on the VM (real hg38 scan: chr22 in ~21 s). The blind
1539
+ recall of Perry 2025's measured off-targets and the DMS/activity model are gated on the paywalled
1540
+ Perry 2025 supplementary (drop in via `ingest.load_offtarget_profile`). This completes the deferred Phase-2
1541
+ Section 2.4 and Phase-3 Section 3.2 hooks. 68 tests green; ruff clean. All program phases (0, 1, 1.5, 2, 3) now done.
1542
+
1543
+ ## [3.0.0a4] - 2026-06-02 - Phase 3 (The Write Planner plus agentic platform, Paper 3)
1544
+
1545
+ Inverse design plus the paper-defining recovery@k benchmark plus the agentic platform.
1546
+
1547
+ ### Added
1548
+ - **Inverse-design optimiser** (`pen_stack/planner/optimize.py`, `configs/intent_weights.yaml`): an
1549
+ `edit_intent`-conditioned objective whose `target_gene_sign` flips whether hitting the target gene is
1550
+ penalised or rewarded, so the same TRAC site ranks #1 (knock-in) vs #101 (safe-harbour).
1551
+ - **Cargo/delivery** (`planner/cargo.py`, `planner/delivery.py`): a donor spec plus size check plus a delivery rule
1552
+ table; bridge/seek off-target via an optional Phase-1.5 hook (pending until 1.5).
1553
+ - **End-to-end Planner** (`planner/pipeline.py`, `report.py`, `/plan` API, `pen-stack plan` CLI): ranked,
1554
+ fully traceable plans with per-field provenance.
1555
+ - **Two-stratum recovery@k benchmark** (`validate/paper3_benchmark.py`, `data/benchmark_panel.csv`,
1556
+ `prereg/paper3.yaml`): discriminating stratum planner 1.00 vs baseline 0.00, McNemar p=0.0156, gap CI
1557
+ [1.0,1.0] excludes zero; control tie 0.67=0.67. The panel is cited to Europe-PMC-verified sources.
1558
+ - **Forward hypotheses** (`validate/forward_hypotheses.py`): date-stamped novel F8/SERPINA1/CISH/HBA1
1559
+ proposals plus a grounded cited ranking.
1560
+ - **Agentic platform:** `agent/tools.py` plus `agent/orchestrator.py` (Ollama tool-calling, an auditable trace,
1561
+ no-fabrication, refusals), `agent/mcp_server.py` (fastmcp), `docker-compose.yml` plus `docker/ui.Dockerfile`
1562
+ plus a Streamlit Agent page plus `docs/DEPLOY.md`/`docs/MCP.md`, `validate/agent_eval.py`.
1563
+ - Shipped `data/curated/gene_coords.parquet` (GENCODE-derived) so tools work in any container.
1564
+
1565
+ ### Notes
1566
+ - **Phase 3 complete.** The pre-registered criteria were met (`prereg/paper3.yaml` plus `SHA256_LOCK_phase3.json`).
1567
+ The agent is verified on the VM in LLM mode (no-fabrication plus plan-equivalence plus refusals all pass). 63 tests
1568
+ green; ruff clean. Wet-lab (3.7) skipped, non-gating. The bridge off-target hook completes with Phase 1.5.
1569
+
1570
+ ## [3.0.0a3] - 2026-06-02 - Phase 2 (Writer Atlas plus Unified Stack, Paper 2)
1571
+
1572
+ The broad, cross-family Writer Atlas, the writer-to-locus cross-link, and the installable platform.
1573
+
1574
+ ### Added
1575
+ - **Writer Atlas** (`pen_stack/atlas/expand.py`, `atlas.parquet`): 33,370 systems across 8 families
1576
+ (31,885 IS110/IS1111 orthologs plus curated cores/reps), every row confidence-tagged plus at least 1 source DOI,
1577
+ targeting metadata inherited from the WT-KB. `configs/atlas_families.yaml` drives the UniProt queries.
1578
+ - **Mechanism at scale** (`pen_stack/mech/`): ported the audited 18-family Pfam whitelist v1.2.1; composite
1579
+ co-occurrence rules; core agreement 1.00 vs audited labels; conflicting calls go to a review queue.
1580
+ - **Therapeutic readiness** (`pen_stack/score/therapeutic.py`): deliverability/cargo/human-cell axes,
1581
+ components retained (ISCro4 326aa to AAV).
1582
+ - **Cross-link** (`pen_stack/atlas/crosslink.py`): bidirectional writer-to-locus queries; AAVS1 held-out
1583
+ check passes (0.90 writability plus bridge-reachable). Per-family caches for k562/hepg2/hspc.
1584
+ - **Variant proposal** (`pen_stack/atlas/variant_propose.py`): a point-mutation framework plus a retrospective
1585
+ harness, no chimeras; DMS model pluggable (Phase 1.5).
1586
+ - **PEN-MONITOR** (`pen_stack/monitor/`): a Europe PMC living-database engine; the back-test surfaces ISPpu10;
1587
+ never auto-edits the atlas; every candidate cited.
1588
+ - **Grounded RAG** (`pen_stack/rag/`, `pen_stack/agent/guardrails.py`): numbers from tool calls, claims
1589
+ cited, clinical directives refused; an optional Ollama/Qwen phrasing layer (presentation only).
1590
+ - **Stack:** unified CLI subcommands, a FastAPI server (`pen_stack/server/api.py`), a Streamlit platform UI
1591
+ (Writer Atlas plus Ask pages), an mkdocs site plus 4 use-case tutorials. 46 tests green; ruff clean.
1592
+
1593
+ ### Notes
1594
+ - **Phase 2 complete.** The pre-registered criteria were met (`prereg/paper2.yaml` plus `SHA256_LOCK_phase2.json`);
1595
+ the atlas Zenodo DOI is pending author upload. Verified on the VM (Docker): API, UI (:8501), RAG with Qwen.
1596
+
1597
+ ## [3.0.0a0] - 2026-06-01 - Phase 0 (in progress)
1598
+
1599
+ A fresh v3.0 monorepo. It supersedes the v1.0 platform repository (archived) and consolidates the five prior
1600
+ repositories (`genome-atlas`, `mech-class`, `pen-score`, `pen-assemble`, `pen-compare`) as provenance.
1601
+
1602
+ ### Added
1603
+ - A monorepo scaffold: 13 modules (`atlas`, `mech`, `score`, `wgenome`, `planner`, `bridge`, `monitor`,
1604
+ `rag`, `agent`, `ui`, `data`, `validate`, `server`), `pyproject.toml`, a Docker image spec, the `penctl`
1605
+ laptop-to-VM orchestrator, CI, `configs/`, `prereg/`.
1606
+ - `docs/INFRA.md`: the three-tier (laptop / VM / Drive) Docker-only, SFTP-only workflow.
1607
+ - `configs/llm.yaml`: a single LLM switch (Ollama plus Qwen2.5-7B-Instruct, Apache-2.0).
1608
+ - `configs/datasets.yaml`: pinned dataset accessions plus verified IDs (see VERIFICATION_REPORT_v3.0).
1609
+ - **WT-KB** (`pen_stack/atlas/`): 8 fully-sourced writer families with reachability tiers; the schema enforces the at-least-1-DOI sourcing rule.
1610
+ - **Re-grounded axes** (`pen_stack/score/recalibrate.py`, `configs/score_axes.yaml`): `S_Cargo` from measured bp, `S_Prog` from targeting modality, `length_aa` backfilled, no per-enzyme overrides.
1611
+ - **Canonical universe** (`pen_stack/atlas/universe.py::assemble`): one path joining the 1,058-entity universe plus WT-KB plus crosswalk; a cross-module consistency test.
1612
+ - **Descriptive scorecard** (`pen_stack/atlas/scorecard.py`): reframed from the circular certification; blind concordance recovers ISCro4 as the bridge standout without naming it. 21 tests green.
1613
+
1614
+ ### Notes
1615
+ - Independent verification of all datasets/IDs/DOIs/tools completed: no critical errors in the v3.0 plan
1616
+ (full report in `Final_Part_v3.0/VERIFICATION_REPORT_v3.0.md`).
1617
+ - **Phase 0 complete.** All pre-registered success criteria were met (`prereg/phase0.yaml` plus SHA lock).