pen-stack 5.5.0__tar.gz → 5.6.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 (334) hide show
  1. {pen_stack-5.5.0 → pen_stack-5.6.0}/CHANGELOG.md +34 -0
  2. {pen_stack-5.5.0 → pen_stack-5.6.0}/CITATION.cff +2 -2
  3. {pen_stack-5.5.0 → pen_stack-5.6.0}/PKG-INFO +42 -9
  4. {pen_stack-5.5.0 → pen_stack-5.6.0}/README.md +41 -8
  5. pen_stack-5.6.0/configs/antipeg.yaml +28 -0
  6. {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/known_unknowns.yaml +27 -0
  7. {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/oracles/scope_cards.yaml +13 -0
  8. pen_stack-5.6.0/docs/delivery_immunology.md +150 -0
  9. {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/index.md +1 -0
  10. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/__init__.py +1 -1
  11. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/agent/cite.py +9 -0
  12. pen_stack-5.6.0/pen_stack/planner/antipeg_oracle.py +75 -0
  13. pen_stack-5.6.0/pen_stack/planner/immune_profile.py +98 -0
  14. pen_stack-5.6.0/pen_stack/validate/immune_calibration.py +122 -0
  15. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/verify/schema.py +3 -0
  16. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/verify/service.py +14 -1
  17. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack.egg-info/PKG-INFO +42 -9
  18. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack.egg-info/SOURCES.txt +11 -0
  19. pen_stack-5.6.0/prereg/SHA256_LOCK_ws_calib.json +8 -0
  20. pen_stack-5.6.0/prereg/SHA256_LOCK_ws_peg.json +8 -0
  21. pen_stack-5.6.0/prereg/SHA256_LOCK_ws_profile.json +8 -0
  22. pen_stack-5.6.0/prereg/ws_calib.yaml +28 -0
  23. pen_stack-5.6.0/prereg/ws_peg.yaml +31 -0
  24. pen_stack-5.6.0/prereg/ws_profile.yaml +32 -0
  25. {pen_stack-5.5.0 → pen_stack-5.6.0}/pyproject.toml +1 -1
  26. {pen_stack-5.5.0 → pen_stack-5.6.0}/LICENSE +0 -0
  27. {pen_stack-5.5.0 → pen_stack-5.6.0}/MANIFEST.in +0 -0
  28. {pen_stack-5.5.0 → pen_stack-5.6.0}/bench/run.py +0 -0
  29. {pen_stack-5.5.0 → pen_stack-5.6.0}/benchmarks/genome_writing_bench/LEADERBOARD.md +0 -0
  30. {pen_stack-5.5.0 → pen_stack-5.6.0}/benchmarks/genome_writing_bench/README.md +0 -0
  31. {pen_stack-5.5.0 → pen_stack-5.6.0}/benchmarks/genome_writing_bench/SHA256SUMS +0 -0
  32. {pen_stack-5.5.0 → pen_stack-5.6.0}/benchmarks/genome_writing_bench/SUBMISSIONS.md +0 -0
  33. {pen_stack-5.5.0 → pen_stack-5.6.0}/benchmarks/genome_writing_bench/tasks.yaml +0 -0
  34. {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/atlas_families.yaml +0 -0
  35. {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/bridge_offtarget_profile.yaml +0 -0
  36. {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/capsid_epitope_oracle.yaml +0 -0
  37. {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/capsid_sequences.fasta +0 -0
  38. {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/cargo_polish.yaml +0 -0
  39. {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/cell_types.yaml +0 -0
  40. {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/datasets.yaml +0 -0
  41. {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/delivery_constraints.yaml +0 -0
  42. {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/delivery_rules.yaml +0 -0
  43. {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/delivery_vehicles.yaml +0 -0
  44. {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/gates_v3.yaml +0 -0
  45. {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/genotoxicity_oracle.yaml +0 -0
  46. {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/gsh_validated_heldout.yaml +0 -0
  47. {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/intent_weights.yaml +0 -0
  48. {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/llm.yaml +0 -0
  49. {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/monitor_queries.yaml +0 -0
  50. {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/rules/delivery.yaml +0 -0
  51. {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/rules/fold.yaml +0 -0
  52. {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/rules/multiplex.yaml +0 -0
  53. {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/rules/payload.yaml +0 -0
  54. {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/rules/reachability.yaml +0 -0
  55. {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/score_axes.yaml +0 -0
  56. {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/seroprevalence.yaml +0 -0
  57. {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/target_sites.yaml +0 -0
  58. {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/universe_crosswalk.yaml +0 -0
  59. {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/write_types.yaml +0 -0
  60. {pen_stack-5.5.0 → pen_stack-5.6.0}/configs/wtkb_curated.yaml +0 -0
  61. {pen_stack-5.5.0 → pen_stack-5.6.0}/data/curated/bridge_offtarget_energetics.json +0 -0
  62. {pen_stack-5.5.0 → pen_stack-5.6.0}/data/curated/bridge_offtarget_profile_measured.parquet +0 -0
  63. {pen_stack-5.5.0 → pen_stack-5.6.0}/data/curated/gene_coords.parquet +0 -0
  64. {pen_stack-5.5.0 → pen_stack-5.6.0}/data/curated/unified_editor_universe.parquet +0 -0
  65. {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/BACKLOG.md +0 -0
  66. {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/DEPLOY.md +0 -0
  67. {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/INFRA.md +0 -0
  68. {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/MCP.md +0 -0
  69. {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/RELEASING.md +0 -0
  70. {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/REPRO.md +0 -0
  71. {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/agent.md +0 -0
  72. {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/alphagenome_feasibility.md +0 -0
  73. {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/benchmark_circularity.md +0 -0
  74. {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/cards/atlas.md +0 -0
  75. {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/cards/durability.md +0 -0
  76. {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/cards/safety.md +0 -0
  77. {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/co_scientist.md +0 -0
  78. {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/delivery.md +0 -0
  79. {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/dissemination.md +0 -0
  80. {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/environment.md +0 -0
  81. {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/mechanistic_constraints.md +0 -0
  82. {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/oracles.md +0 -0
  83. {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/positioning.md +0 -0
  84. {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/private_data_formats.md +0 -0
  85. {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/quickstart.md +0 -0
  86. {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/rules.md +0 -0
  87. {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/scope.md +0 -0
  88. {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/scorecard.md +0 -0
  89. {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/tutorials/compare-families.md +0 -0
  90. {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/tutorials/score-deliverability.md +0 -0
  91. {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/tutorials/where-can-i-write.md +0 -0
  92. {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/tutorials/which-writer-reaches-locus.md +0 -0
  93. {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/uncertainty.md +0 -0
  94. {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/verify.md +0 -0
  95. {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/world_model.md +0 -0
  96. {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/writer_verification.md +0 -0
  97. {pen_stack-5.5.0 → pen_stack-5.6.0}/docs/wtkb.md +0 -0
  98. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/_resources.py +0 -0
  99. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/adapt/__init__.py +0 -0
  100. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/adapt/finetune.py +0 -0
  101. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/adapt/ingest.py +0 -0
  102. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/adapt/pipeline.py +0 -0
  103. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/adapt/recalibrate.py +0 -0
  104. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/adapt/report.py +0 -0
  105. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/agent/__init__.py +0 -0
  106. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/agent/co_scientist.py +0 -0
  107. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/agent/epistemic.py +0 -0
  108. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/agent/guardrails.py +0 -0
  109. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/agent/mcp_server.py +0 -0
  110. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/agent/orchestrator.py +0 -0
  111. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/agent/pen_agent.py +0 -0
  112. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/agent/scope.py +0 -0
  113. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/agent/tools.py +0 -0
  114. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/atlas/__init__.py +0 -0
  115. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/atlas/build_wtkb.py +0 -0
  116. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/atlas/crosslink.py +0 -0
  117. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/atlas/expand.py +0 -0
  118. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/atlas/schema.py +0 -0
  119. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/atlas/scorecard.py +0 -0
  120. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/atlas/universe.py +0 -0
  121. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/atlas/variant_propose.py +0 -0
  122. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/atlas/writer_verify.py +0 -0
  123. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/bridge/__init__.py +0 -0
  124. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/bridge/activity.py +0 -0
  125. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/bridge/cli.py +0 -0
  126. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/bridge/fold_qc.py +0 -0
  127. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/bridge/guide_qc.py +0 -0
  128. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/bridge/ingest.py +0 -0
  129. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/bridge/offtarget.py +0 -0
  130. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/bridge/offtarget_energetics.py +0 -0
  131. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/bridge/ortholog_screen.py +0 -0
  132. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/bridge/pipeline.py +0 -0
  133. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/cli.py +0 -0
  134. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/data/__init__.py +0 -0
  135. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/data/encode.py +0 -0
  136. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/data/genome.py +0 -0
  137. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/data/ingest_chromatin.py +0 -0
  138. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/data/ingest_integration.py +0 -0
  139. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/data/ingest_safety_annot.py +0 -0
  140. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/data/ingest_trip.py +0 -0
  141. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/env/__init__.py +0 -0
  142. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/env/genome_writing_env.py +0 -0
  143. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/env/policies.py +0 -0
  144. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/graph/__init__.py +0 -0
  145. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/graph/build.py +0 -0
  146. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/graph/cell_types.py +0 -0
  147. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/graph/ingest.py +0 -0
  148. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/graph/query.py +0 -0
  149. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/graph/schema.py +0 -0
  150. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/mech/__init__.py +0 -0
  151. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/mech/classify_atlas.py +0 -0
  152. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/mech/whitelist.py +0 -0
  153. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/monitor/__init__.py +0 -0
  154. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/monitor/europepmc.py +0 -0
  155. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/monitor/run.py +0 -0
  156. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/monitor/triage.py +0 -0
  157. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/oracles/__init__.py +0 -0
  158. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/oracles/cache.py +0 -0
  159. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/oracles/energetics.py +0 -0
  160. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/oracles/genome.py +0 -0
  161. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/oracles/protein_design.py +0 -0
  162. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/oracles/rna.py +0 -0
  163. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/oracles/schema.py +0 -0
  164. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/oracles/structure.py +0 -0
  165. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/planner/__init__.py +0 -0
  166. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/planner/capsid_epitope_oracle.py +0 -0
  167. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/planner/cargo.py +0 -0
  168. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/planner/cargo_polish.py +0 -0
  169. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/planner/delivery.py +0 -0
  170. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/planner/delivery_constraints.py +0 -0
  171. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/planner/delivery_immunology.py +0 -0
  172. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/planner/delivery_vehicles.py +0 -0
  173. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/planner/genotoxicity_oracle.py +0 -0
  174. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/planner/innate_sensing.py +0 -0
  175. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/planner/multiplex.py +0 -0
  176. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/planner/optimize.py +0 -0
  177. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/planner/pipeline.py +0 -0
  178. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/planner/report.py +0 -0
  179. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/planner/router.py +0 -0
  180. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/planner/seroprevalence_oracle.py +0 -0
  181. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/planner/target_site.py +0 -0
  182. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/rag/__init__.py +0 -0
  183. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/rag/index.py +0 -0
  184. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/rag/llm.py +0 -0
  185. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/rag/qa.py +0 -0
  186. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/rules/__init__.py +0 -0
  187. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/rules/evaluators.py +0 -0
  188. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/rules/loader.py +0 -0
  189. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/rules/schema.py +0 -0
  190. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/rules/solver.py +0 -0
  191. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/score/__init__.py +0 -0
  192. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/score/recalibrate.py +0 -0
  193. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/score/therapeutic.py +0 -0
  194. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/server/__init__.py +0 -0
  195. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/server/api.py +0 -0
  196. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/ui/__init__.py +0 -0
  197. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/ui/app.py +0 -0
  198. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/__init__.py +0 -0
  199. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/adapt_demo.py +0 -0
  200. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/agent_eval.py +0 -0
  201. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/bench_adversarial_tasks.py +0 -0
  202. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/bench_coscientist_tasks.py +0 -0
  203. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/bench_graph_tasks.py +0 -0
  204. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/bench_rule_tasks.py +0 -0
  205. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/bench_trust_tasks.py +0 -0
  206. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/bench_writetype_tasks.py +0 -0
  207. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/blind_gsh_discovery.py +0 -0
  208. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/cargo_directionality.py +0 -0
  209. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/durability_baselines.py +0 -0
  210. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/forward_hypotheses.py +0 -0
  211. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/guide_qc_demo.py +0 -0
  212. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/intent_specification.py +0 -0
  213. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/offtarget_energetics_eval.py +0 -0
  214. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/out_of_scope_refusal.py +0 -0
  215. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/outcome_calibration.py +0 -0
  216. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/paper3_benchmark.py +0 -0
  217. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/paper4_real_validation.py +0 -0
  218. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/paper4_validation.py +0 -0
  219. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/selective_prediction.py +0 -0
  220. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/seq_vs_measured.py +0 -0
  221. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/target_site_controls.py +0 -0
  222. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/uncertainty_eval.py +0 -0
  223. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/ungrounded_baseline.py +0 -0
  224. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/within_locus_ranking.py +0 -0
  225. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/validate/writer_recovery.py +0 -0
  226. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/verify/__init__.py +0 -0
  227. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/wgenome/__init__.py +0 -0
  228. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/wgenome/chromatin_seq.py +0 -0
  229. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/wgenome/durability.py +0 -0
  230. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/wgenome/export_tracks.py +0 -0
  231. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/wgenome/features.py +0 -0
  232. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/wgenome/gsh_baseline.py +0 -0
  233. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/wgenome/mesh_features.py +0 -0
  234. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/wgenome/ood.py +0 -0
  235. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/wgenome/providers.py +0 -0
  236. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/wgenome/safety.py +0 -0
  237. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/wgenome/structure3d.py +0 -0
  238. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/wgenome/uncertainty.py +0 -0
  239. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack/wgenome/writability.py +0 -0
  240. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack.egg-info/dependency_links.txt +0 -0
  241. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack.egg-info/entry_points.txt +0 -0
  242. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack.egg-info/requires.txt +0 -0
  243. {pen_stack-5.5.0 → pen_stack-5.6.0}/pen_stack.egg-info/top_level.txt +0 -0
  244. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_phase0.json +0 -0
  245. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_phase1_5.json +0 -0
  246. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_phase2.json +0 -0
  247. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_phase3.json +0 -0
  248. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_a.json +0 -0
  249. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_atlas.json +0 -0
  250. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_b.json +0 -0
  251. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_ba.json +0 -0
  252. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_ba_v33.json +0 -0
  253. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_ba_v45.json +0 -0
  254. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_bench.json +0 -0
  255. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_c.json +0 -0
  256. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_cal.json +0 -0
  257. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_cite.json +0 -0
  258. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_crit.json +0 -0
  259. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_ct.json +0 -0
  260. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_d.json +0 -0
  261. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_e.json +0 -0
  262. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_env.json +0 -0
  263. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_ep.json +0 -0
  264. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_epitope.json +0 -0
  265. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_f.json +0 -0
  266. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_g.json +0 -0
  267. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_genotox.json +0 -0
  268. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_graph.json +0 -0
  269. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_h.json +0 -0
  270. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_immune.json +0 -0
  271. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_innate.json +0 -0
  272. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_mc.json +0 -0
  273. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_mon.json +0 -0
  274. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_o.json +0 -0
  275. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_plan.json +0 -0
  276. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_r.json +0 -0
  277. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_route.json +0 -0
  278. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_seroprev.json +0 -0
  279. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_uq.json +0 -0
  280. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_v.json +0 -0
  281. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/SHA256_LOCK_ws_wv.json +0 -0
  282. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/paper1.yaml +0 -0
  283. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/paper2.yaml +0 -0
  284. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/paper3.yaml +0 -0
  285. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/paper4.yaml +0 -0
  286. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/phase0.yaml +0 -0
  287. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_a.yaml +0 -0
  288. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_atlas.yaml +0 -0
  289. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_b.yaml +0 -0
  290. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_ba.yaml +0 -0
  291. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_ba_v33.yaml +0 -0
  292. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_ba_v45.yaml +0 -0
  293. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_bench.yaml +0 -0
  294. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_c.yaml +0 -0
  295. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_cal.yaml +0 -0
  296. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_cite.yaml +0 -0
  297. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_crit.yaml +0 -0
  298. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_ct.yaml +0 -0
  299. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_d.yaml +0 -0
  300. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_e.yaml +0 -0
  301. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_env.yaml +0 -0
  302. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_ep.yaml +0 -0
  303. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_epitope.yaml +0 -0
  304. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_f.yaml +0 -0
  305. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_g.yaml +0 -0
  306. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_genotox.yaml +0 -0
  307. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_graph.yaml +0 -0
  308. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_h.yaml +0 -0
  309. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_immune.yaml +0 -0
  310. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_innate.yaml +0 -0
  311. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_mc.yaml +0 -0
  312. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_mon.yaml +0 -0
  313. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_o.yaml +0 -0
  314. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_plan.yaml +0 -0
  315. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_r.yaml +0 -0
  316. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_route.yaml +0 -0
  317. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_seroprev.yaml +0 -0
  318. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_uq.yaml +0 -0
  319. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_v.yaml +0 -0
  320. {pen_stack-5.5.0 → pen_stack-5.6.0}/prereg/ws_wv.yaml +0 -0
  321. {pen_stack-5.5.0 → pen_stack-5.6.0}/scripts/p1_build_atlas.py +0 -0
  322. {pen_stack-5.5.0 → pen_stack-5.6.0}/scripts/p1_build_durability.py +0 -0
  323. {pen_stack-5.5.0 → pen_stack-5.6.0}/scripts/p1_export_tracks.py +0 -0
  324. {pen_stack-5.5.0 → pen_stack-5.6.0}/scripts/p1_safety_concordance.py +0 -0
  325. {pen_stack-5.5.0 → pen_stack-5.6.0}/scripts/p1_train_safety.py +0 -0
  326. {pen_stack-5.5.0 → pen_stack-5.6.0}/scripts/p1_validation_report.py +0 -0
  327. {pen_stack-5.5.0 → pen_stack-5.6.0}/scripts/p2_build_atlas.py +0 -0
  328. {pen_stack-5.5.0 → pen_stack-5.6.0}/scripts/p3_benchmark_report.py +0 -0
  329. {pen_stack-5.5.0 → pen_stack-5.6.0}/scripts/p4_genome_scan.py +0 -0
  330. {pen_stack-5.5.0 → pen_stack-5.6.0}/scripts/p52_build_genotox_oracle.py +0 -0
  331. {pen_stack-5.5.0 → pen_stack-5.6.0}/scripts/p53_build_epitope_oracle.py +0 -0
  332. {pen_stack-5.5.0 → pen_stack-5.6.0}/scripts/ws_b_report.py +0 -0
  333. {pen_stack-5.5.0 → pen_stack-5.6.0}/scripts/ws_c_report.py +0 -0
  334. {pen_stack-5.5.0 → pen_stack-5.6.0}/setup.cfg +0 -0
@@ -3,6 +3,40 @@
3
3
  All notable changes to PEN-STACK are documented here. This file follows
4
4
  [Keep a Changelog](https://keepachangelog.com/) and the program's phase structure.
5
5
 
6
+ ## [5.6.0] - 2026-06-11 - v5.6 release: Immunology completion & calibration (anti-PEG · proxy honesty · unified profile)
7
+
8
+ Finishes the delivery-immunology arc (v5.1–v5.5): adds the missing **anti-PEG** axis, **calibrates** the
9
+ proxies honestly, and exposes a **unified per-design immune-risk profile** that never collapses into one number.
10
+ Workstreams WS-{PEG,CALIB,PROFILE} (+ optional WS-EXT), SHA-locked.
11
+
12
+ ### Added
13
+ - **WS-PEG** — `pen_stack/planner/antipeg_oracle.py` + `configs/antipeg.yaml`: pre-existing/induced anti-PEG
14
+ antibodies gate **re-dosing** of PEGylated LNP. Population prevalence range (25–72 %) →
15
+ `preexisting_antipeg_score = 1 − midpoint/100`, range surfaced as `native_uncertainty`; **abstains** for
16
+ non-PEGylated vehicles. Serosurvey DOIs Crossref-verified (Chen 2016 `10.1021/acs.analchem.6b03109`, Yang &
17
+ Lai `10.1002/wnan.1339`, Armstrong `10.1002/cncr.22739`, Kozma `10.1016/j.addr.2020.07.024`). Scope card `antipeg`.
18
+ - **WS-CALIB** — `pen_stack/validate/immune_calibration.py`: `calibrate_axis()` (Spearman ρ + percentile
19
+ bootstrap CI) labels an axis **outcome-validated only when the CI excludes zero**, else `weak_proxy`, and
20
+ `mechanistic_proxy` when N < 6. With no sufficient public paired (proxy, observed) dataset, **every axis is
21
+ honestly labelled a mechanistic/population proxy** — the label travels with the profile. (No fabricated
22
+ outcome data; machinery proven on synthetic input.)
23
+ - **WS-PROFILE** — `pen_stack/planner/immune_profile.py` + **`Verdict.immune_profile`**: a per-design **vector**
24
+ of all axes (genotoxicity, CD8 epitope, innate, pre-existing NAb, anti-PEG), each with its own value +
25
+ uncertainty + scope + validation label. **`collapsed_score is None`** (never fused — asserted); known-unknowns
26
+ listed; abstaining axes report `None`.
27
+ - **WS-EXT** — a documented qualitative **route/immune-privilege modifier** (eye/CNS lower realized
28
+ immunogenicity vs systemic; Streilein 2003 `10.1038/nri1224`; no fabricated magnitude); **CD4/MHC-II helper
29
+ epitopes**, **pre-existing capsid-specific T-cell immunity**, and **complement/CARPA** registered as
30
+ known-unknowns. `prereg/ws_{peg,calib,profile}.yaml` + SHA locks.
31
+
32
+ ### Changed
33
+ - Version 5.5.0 -> 5.6.0 (minor — additive); `cite.curated_dois()` ingests the anti-PEG + immune-privilege DOIs.
34
+
35
+ ### Honesty invariant (unchanged)
36
+ - Every axis is a **relative-risk screen** (sequence/mechanistic or population proxy), labelled as such until
37
+ outcome-validated; the profile is **never** collapsed into one number; patient-specific titer, post-dose-1
38
+ induced immunity, and exact in-vivo magnitude stay **known-unknowns**.
39
+
6
40
  ## [5.5.0] - 2026-06-10 - v5.5 release: Anti-vector seroprevalence oracle (the last immune axis, from data)
7
41
 
8
42
  Completes the computable delivery-immunology axes. **Pre-existing humoral immunity** (B-cell / neutralizing
@@ -1,8 +1,8 @@
1
1
  cff-version: 1.2.0
2
2
  message: "If you use PEN-STACK, please cite it as below."
3
3
  title: "PEN-STACK: open infrastructure for genome writing"
4
- version: 5.5.0
5
- date-released: 2026-06-10
4
+ version: 5.6.0
5
+ date-released: 2026-06-11
6
6
  authors:
7
7
  - family-names: "Mahaboob Ali"
8
8
  given-names: "Anees Ahmed"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pen-stack
3
- Version: 5.5.0
3
+ Version: 5.6.0
4
4
  Summary: Open infrastructure for genome writing: the Writable Genome atlas, the Writer Atlas, and the Write Planner.
5
5
  Author-email: Anees Ahmed Mahaboob Ali <ahmedaneesm@gmail.com>
6
6
  License: MIT
@@ -87,11 +87,10 @@ every design against rule-grounded mechanism, reports calibrated confidence, cit
87
87
  [![PyPI](https://img.shields.io/pypi/v/pen-stack.svg)](https://pypi.org/project/pen-stack/)
88
88
  [![CI](https://github.com/ahmedanees-m/pen-stack/actions/workflows/ci.yml/badge.svg)](https://github.com/ahmedanees-m/pen-stack/actions/workflows/ci.yml)
89
89
  [![Publish](https://github.com/ahmedanees-m/pen-stack/actions/workflows/publish.yml/badge.svg)](https://github.com/ahmedanees-m/pen-stack/actions/workflows/publish.yml)
90
- [![coverage](https://raw.githubusercontent.com/ahmedanees-m/pen-stack/main/.github/badges/coverage.svg)](https://github.com/ahmedanees-m/pen-stack/actions/workflows/ci.yml)
91
90
  [![codecov](https://codecov.io/gh/ahmedanees-m/pen-stack/branch/main/graph/badge.svg)](https://codecov.io/gh/ahmedanees-m/pen-stack)
92
91
  [![License: MIT](https://img.shields.io/badge/License-MIT-informational.svg)](LICENSE)
93
92
  [![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue.svg)](https://www.python.org/)
94
- [![Version](https://img.shields.io/badge/version-5.5.0-blue.svg)](CHANGELOG.md)
93
+ [![Version](https://img.shields.io/badge/version-5.6.0-blue.svg)](CHANGELOG.md)
95
94
  [![Tests](https://img.shields.io/badge/tests-240%20passing-success.svg)](tests/)
96
95
  [![Lint: ruff](https://img.shields.io/badge/lint-ruff-purple.svg)](https://github.com/astral-sh/ruff)
97
96
  [![Runtime: Docker](https://img.shields.io/badge/runtime-docker-2496ED.svg)](docker/)
@@ -135,6 +134,22 @@ Two questions gate every genome-writing project, and before PEN-STACK no resourc
135
134
  Everything is built on bulk-downloadable public data, runs on a single GPU, and is validated **blind** against
136
135
  a pre-registered, honest baseline before release.
137
136
 
137
+ ## What is new in v5.6 — Immunology completion & calibration (anti-PEG · proxy honesty · unified profile)
138
+
139
+ v5.6 finishes the delivery-immunology arc and tells the truth about it. It adds the missing **anti-PEG** axis
140
+ (gates LNP re-dosing), **calibrates** every proxy two-sided, and exposes a **unified per-design immune-risk
141
+ profile** in which each axis keeps its own uncertainty and none is ever fused into one overconfident number.
142
+
143
+ | Workstream | What it adds | Result |
144
+ |---|---|---|
145
+ | **PEG** | `planner/antipeg_oracle.py` + `configs/antipeg.yaml` | anti-PEG prevalence (25–72%) → `preexisting_antipeg_score`; gates **re-dosing**; abstains for non-PEG vehicles; range surfaced as uncertainty |
146
+ | **CALIB** | `validate/immune_calibration.py` | each axis labelled **outcome-validated** (ρ + CI excluding 0) or **mechanistic/population proxy**; with no public paired-outcome data, all axes are honestly labelled proxies (the label travels with the profile) |
147
+ | **PROFILE** | `planner/immune_profile.py` + `Verdict.immune_profile` | per-design **vector** of all axes, each with value + uncertainty + scope + validation label; **`collapsed_score is None`** (never fused); known-unknowns listed |
148
+ | **EXT** | route/immune-privilege modifier + new known-unknowns | eye/CNS immune-privilege as a *documented qualitative* modifier (no magnitude); CD4/MHC-II, pre-existing capsid T-cell, complement/CARPA registered as known-unknowns |
149
+
150
+ The in-vivo magnitude and patient-specific titer stay declared known-unknowns. See
151
+ [`docs/delivery_immunology.md`](docs/delivery_immunology.md) and `prereg/ws_{peg,calib,profile}.yaml`.
152
+
138
153
  ## What is new in v5.5 — Anti-vector seroprevalence oracle (the last immune axis, from data)
139
154
 
140
155
  This completes the computable delivery-immunology axes. **Pre-existing humoral immunity** (B-cell / NAb) to a
@@ -217,6 +232,11 @@ efficacious integrator but its genotoxicity is the dominant concern). Crucially,
217
232
  **magnitude** stays a declared known-unknown — v5.1 surfaces documented priors, it does **not** predict a
218
233
  patient-specific immune response.
219
234
 
235
+ > **The full delivery-immunology story (v5.1 → v5.5), with every axis, method, and outcome, is in
236
+ > [`docs/delivery_immunology.md`](docs/delivery_immunology.md).** By v5.5, four of the five immune/safety axes
237
+ > are computed from data or sequence (genotoxicity, adaptive/CD8, innate, pre-existing/NAb) rather than
238
+ > hand-typed tiers.
239
+
220
240
  | Workstream | What it adds | Result |
221
241
  |---|---|---|
222
242
  | **IMMUNE config** | `immune_safety` block on all 8 vehicles in `configs/delivery_vehicles.yaml` | documented ordinal (low/moderate/high) priors for pre-existing immunity, neutralizing antibody, innate/adaptive immune, **genotoxicity**, efficacy — every `immune_doi` Crossref-verified and in the curated-DOI set |
@@ -381,6 +401,10 @@ benchmark with deterministic scorers and no circular labels. See
381
401
  | off-target + DMS (Perry 2025) |
382
402
  +-------------------------------------------------------------------------+
383
403
 
404
+ Delivery layer (v5.1-5.5, feeds the planner): a safety<->efficacy balance over the 8-vehicle palette,
405
+ with four of five immune/safety axes computed from data/sequence (genotoxicity = VISDB x COSMIC;
406
+ adaptive/CD8 = MHCflurry over the capsid; innate = CpG/dsRNA of the cargo; pre-existing/NAb = serosurveys).
407
+
384
408
  Platform services (on top of the validated core): PEN-MONITOR (Europe PMC living database),
385
409
  grounded RAG/Q&A, a tool-using agent + MCP server, and a Streamlit web app.
386
410
  ```
@@ -395,6 +419,7 @@ PEN-STACK is organised as **two reference layers + one engine + a services layer
395
419
  | **Writer Atlas** (companion) | `pen_stack.atlas`, `.mech`, `.score` | cross-family enzyme catalogue + Writer-Targeting KB | Paper 2 |
396
420
  | **Cross-link** | `pen_stack.atlas.crosslink` | bidirectional writer to locus queries | Paper 2 |
397
421
  | **Write Planner** (engine) | `pen_stack.planner` | inverse design, `edit_intent`-conditioned | Paper 3 |
422
+ | **Delivery immunology** (v5.1-5.5) | `pen_stack.planner.delivery_immunology` + `{genotoxicity,capsid_epitope,seroprevalence}_oracle`, `innate_sensing` | safety↔efficacy balance over the 8-vehicle palette; 4 of 5 immune axes **computed from data/sequence**, magnitude stays a known-unknown ([docs](docs/delivery_immunology.md)) | M2 |
398
423
  | **Agentic platform** | `pen_stack.agent` | goal to cited, auditable plan; MCP server; one-command deploy | Paper 3 |
399
424
  | **Bridge off-target engine** | `pen_stack.bridge` | "CRISPOR for bridge recombinases" + guide QC (v3.1) | Paper 4 |
400
425
  | **Genome-Writing Bench** (v3.1) | `benchmarks/`, `bench/run.py` | first writing-side benchmark; deterministic scorers, leaderboard | M2 |
@@ -519,12 +544,16 @@ pen-stack/
519
544
  │ ├── planner/ Write Planner (Paper 3): optimize / cargo / cargo_polish / multiplex / pipeline
520
545
  │ │ + v3.2 target_site (hard PAM/att/core reject) / delivery_constraints
521
546
  │ │ + v3.3 router (write-type dispatch) / delivery_vehicles (8-vehicle palette)
547
+ │ │ + v5.1-5.5 delivery_immunology (safety<->efficacy balance) and the four
548
+ │ │ computed immune-axis oracles: genotoxicity_oracle (VISDB x COSMIC) /
549
+ │ │ capsid_epitope_oracle (MHCflurry) / innate_sensing (CpG-O/E + dsRNA) /
550
+ │ │ seroprevalence_oracle (anti-vector NAb serosurveys)
522
551
  │ ├── bridge/ bridge off-target engine (Paper 4): offtarget / fold_qc / guide_qc / pipeline / cli
523
552
  │ │ + v3.2 offtarget_energetics (position x substitution; held-out 0.88, ships)
524
553
  │ ├── agent/ agentic platform: tools / orchestrator / pen_agent / mcp_server / guardrails; v5.0 co_scientist + cite (multi-strategy, self-critique, cited rationale, scope ledger)
525
554
  │ │ + v3.2 epistemic (3-tier status) / scope (known-unknowns matcher)
526
555
  │ ├── graph/ v4.5 living world-model knowledge graph (schema/build/query/ingest/cell_types); typed provenanced edges; gated living loop (propose-only)
527
- │ ├── oracles/ v4.0 L1 oracle mesh: OracleResult contract + adapters (genome/structure/protein_design/rna/energetics) over the foundation models; version-pinned cache
556
+ │ ├── oracles/ v4.0 L1 oracle mesh: OracleResult contract + adapters (genome/structure/protein_design/rna/energetics) over the foundation models; version-pinned cache; v5.2-5.5 delivery-immunology scope cards (delivery_genotoxicity/capsid_epitope/innate_sensing/seroprevalence)
528
557
  │ ├── rules/ v3.3 machine-readable rules engine (schema/evaluators/loader/solver) over configs/rules/*.yaml
529
558
  │ ├── verify/ v3.3 verification service: verify(design) -> Verdict (legal+reasons+confidence+scope; v4.0 writer_critique)
530
559
  │ ├── adapt/ local recalibration / private-data adaptation behind a gate (v3.1, WS-F)
@@ -540,12 +569,16 @@ pen-stack/
540
569
  │ ├── server/api.py FastAPI REST (atlas, crosslink, writable, plan, bridge, ask)
541
570
  │ ├── ui/app.py Streamlit web app (16 pages; v3.2 PEN-Agent shows confidence + epistemic status)
542
571
  │ └── cli.py unified CLI
543
- ├── benchmarks/genome_writing_bench/ Genome-Writing Bench v0.2 (T1-T11; tasks / harness / solvers / LEADERBOARD / SHAs)
572
+ ├── benchmarks/genome_writing_bench/ Genome-Writing Bench v0.3 (T1-T16 + co_scientist; tasks / harness / solvers / LEADERBOARD / SHAs)
544
573
  ├── bench/run.py one-command bench entrypoint (--agent, --verify)
545
- ├── scripts/ reproducible pipeline drivers (p1_*, p2_*, p4_*, ws_*_report)
546
- ├── configs/ pinned datasets + thresholds + curation (YAML); v3.2: known_unknowns /
547
- │ target_sites / delivery_constraints
548
- ├── prereg/ SHA-locked success criteria (paper1..4 + ws_a..ws_h + v3.2 ws_{uq,ep,mc,ba} + locks)
574
+ ├── scripts/ reproducible pipeline drivers (p1_*, p2_*, p4_*, p52/p53 delivery-immunology oracle builds, ws_*_report)
575
+ ├── configs/ pinned datasets + thresholds + curation (YAML); v3.2 known_unknowns /
576
+ │ target_sites / delivery_constraints; v5.1-5.5 delivery_vehicles immune_safety /
577
+ │ genotoxicity_oracle / capsid_epitope_oracle + capsid_sequences.fasta /
578
+ │ seroprevalence + oracles/scope_cards
579
+ ├── prereg/ SHA-locked success criteria (paper1..4 + ws_a..ws_h + v3.2-v5.5 ws_{uq,ep,mc,ba,
580
+ │ r,v,route,env,bench,cal,o,wv,atlas,graph,mon,ct,plan,crit,cite,immune,
581
+ │ genotox,epitope,innate,seroprev} + SHA256 locks)
549
582
  ├── data/curated/ small committed tables (universe, gene coords, measured bridge profile,
550
583
  │ v3.2 bridge_offtarget_energetics.json)
551
584
  ├── data/llm_bench_cache/ 28 cached ungrounded-LLM transcripts (T7, offline/CI replay)
@@ -12,11 +12,10 @@ every design against rule-grounded mechanism, reports calibrated confidence, cit
12
12
  [![PyPI](https://img.shields.io/pypi/v/pen-stack.svg)](https://pypi.org/project/pen-stack/)
13
13
  [![CI](https://github.com/ahmedanees-m/pen-stack/actions/workflows/ci.yml/badge.svg)](https://github.com/ahmedanees-m/pen-stack/actions/workflows/ci.yml)
14
14
  [![Publish](https://github.com/ahmedanees-m/pen-stack/actions/workflows/publish.yml/badge.svg)](https://github.com/ahmedanees-m/pen-stack/actions/workflows/publish.yml)
15
- [![coverage](https://raw.githubusercontent.com/ahmedanees-m/pen-stack/main/.github/badges/coverage.svg)](https://github.com/ahmedanees-m/pen-stack/actions/workflows/ci.yml)
16
15
  [![codecov](https://codecov.io/gh/ahmedanees-m/pen-stack/branch/main/graph/badge.svg)](https://codecov.io/gh/ahmedanees-m/pen-stack)
17
16
  [![License: MIT](https://img.shields.io/badge/License-MIT-informational.svg)](LICENSE)
18
17
  [![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue.svg)](https://www.python.org/)
19
- [![Version](https://img.shields.io/badge/version-5.5.0-blue.svg)](CHANGELOG.md)
18
+ [![Version](https://img.shields.io/badge/version-5.6.0-blue.svg)](CHANGELOG.md)
20
19
  [![Tests](https://img.shields.io/badge/tests-240%20passing-success.svg)](tests/)
21
20
  [![Lint: ruff](https://img.shields.io/badge/lint-ruff-purple.svg)](https://github.com/astral-sh/ruff)
22
21
  [![Runtime: Docker](https://img.shields.io/badge/runtime-docker-2496ED.svg)](docker/)
@@ -60,6 +59,22 @@ Two questions gate every genome-writing project, and before PEN-STACK no resourc
60
59
  Everything is built on bulk-downloadable public data, runs on a single GPU, and is validated **blind** against
61
60
  a pre-registered, honest baseline before release.
62
61
 
62
+ ## What is new in v5.6 — Immunology completion & calibration (anti-PEG · proxy honesty · unified profile)
63
+
64
+ v5.6 finishes the delivery-immunology arc and tells the truth about it. It adds the missing **anti-PEG** axis
65
+ (gates LNP re-dosing), **calibrates** every proxy two-sided, and exposes a **unified per-design immune-risk
66
+ profile** in which each axis keeps its own uncertainty and none is ever fused into one overconfident number.
67
+
68
+ | Workstream | What it adds | Result |
69
+ |---|---|---|
70
+ | **PEG** | `planner/antipeg_oracle.py` + `configs/antipeg.yaml` | anti-PEG prevalence (25–72%) → `preexisting_antipeg_score`; gates **re-dosing**; abstains for non-PEG vehicles; range surfaced as uncertainty |
71
+ | **CALIB** | `validate/immune_calibration.py` | each axis labelled **outcome-validated** (ρ + CI excluding 0) or **mechanistic/population proxy**; with no public paired-outcome data, all axes are honestly labelled proxies (the label travels with the profile) |
72
+ | **PROFILE** | `planner/immune_profile.py` + `Verdict.immune_profile` | per-design **vector** of all axes, each with value + uncertainty + scope + validation label; **`collapsed_score is None`** (never fused); known-unknowns listed |
73
+ | **EXT** | route/immune-privilege modifier + new known-unknowns | eye/CNS immune-privilege as a *documented qualitative* modifier (no magnitude); CD4/MHC-II, pre-existing capsid T-cell, complement/CARPA registered as known-unknowns |
74
+
75
+ The in-vivo magnitude and patient-specific titer stay declared known-unknowns. See
76
+ [`docs/delivery_immunology.md`](docs/delivery_immunology.md) and `prereg/ws_{peg,calib,profile}.yaml`.
77
+
63
78
  ## What is new in v5.5 — Anti-vector seroprevalence oracle (the last immune axis, from data)
64
79
 
65
80
  This completes the computable delivery-immunology axes. **Pre-existing humoral immunity** (B-cell / NAb) to a
@@ -142,6 +157,11 @@ efficacious integrator but its genotoxicity is the dominant concern). Crucially,
142
157
  **magnitude** stays a declared known-unknown — v5.1 surfaces documented priors, it does **not** predict a
143
158
  patient-specific immune response.
144
159
 
160
+ > **The full delivery-immunology story (v5.1 → v5.5), with every axis, method, and outcome, is in
161
+ > [`docs/delivery_immunology.md`](docs/delivery_immunology.md).** By v5.5, four of the five immune/safety axes
162
+ > are computed from data or sequence (genotoxicity, adaptive/CD8, innate, pre-existing/NAb) rather than
163
+ > hand-typed tiers.
164
+
145
165
  | Workstream | What it adds | Result |
146
166
  |---|---|---|
147
167
  | **IMMUNE config** | `immune_safety` block on all 8 vehicles in `configs/delivery_vehicles.yaml` | documented ordinal (low/moderate/high) priors for pre-existing immunity, neutralizing antibody, innate/adaptive immune, **genotoxicity**, efficacy — every `immune_doi` Crossref-verified and in the curated-DOI set |
@@ -306,6 +326,10 @@ benchmark with deterministic scorers and no circular labels. See
306
326
  | off-target + DMS (Perry 2025) |
307
327
  +-------------------------------------------------------------------------+
308
328
 
329
+ Delivery layer (v5.1-5.5, feeds the planner): a safety<->efficacy balance over the 8-vehicle palette,
330
+ with four of five immune/safety axes computed from data/sequence (genotoxicity = VISDB x COSMIC;
331
+ adaptive/CD8 = MHCflurry over the capsid; innate = CpG/dsRNA of the cargo; pre-existing/NAb = serosurveys).
332
+
309
333
  Platform services (on top of the validated core): PEN-MONITOR (Europe PMC living database),
310
334
  grounded RAG/Q&A, a tool-using agent + MCP server, and a Streamlit web app.
311
335
  ```
@@ -320,6 +344,7 @@ PEN-STACK is organised as **two reference layers + one engine + a services layer
320
344
  | **Writer Atlas** (companion) | `pen_stack.atlas`, `.mech`, `.score` | cross-family enzyme catalogue + Writer-Targeting KB | Paper 2 |
321
345
  | **Cross-link** | `pen_stack.atlas.crosslink` | bidirectional writer to locus queries | Paper 2 |
322
346
  | **Write Planner** (engine) | `pen_stack.planner` | inverse design, `edit_intent`-conditioned | Paper 3 |
347
+ | **Delivery immunology** (v5.1-5.5) | `pen_stack.planner.delivery_immunology` + `{genotoxicity,capsid_epitope,seroprevalence}_oracle`, `innate_sensing` | safety↔efficacy balance over the 8-vehicle palette; 4 of 5 immune axes **computed from data/sequence**, magnitude stays a known-unknown ([docs](docs/delivery_immunology.md)) | M2 |
323
348
  | **Agentic platform** | `pen_stack.agent` | goal to cited, auditable plan; MCP server; one-command deploy | Paper 3 |
324
349
  | **Bridge off-target engine** | `pen_stack.bridge` | "CRISPOR for bridge recombinases" + guide QC (v3.1) | Paper 4 |
325
350
  | **Genome-Writing Bench** (v3.1) | `benchmarks/`, `bench/run.py` | first writing-side benchmark; deterministic scorers, leaderboard | M2 |
@@ -444,12 +469,16 @@ pen-stack/
444
469
  │ ├── planner/ Write Planner (Paper 3): optimize / cargo / cargo_polish / multiplex / pipeline
445
470
  │ │ + v3.2 target_site (hard PAM/att/core reject) / delivery_constraints
446
471
  │ │ + v3.3 router (write-type dispatch) / delivery_vehicles (8-vehicle palette)
472
+ │ │ + v5.1-5.5 delivery_immunology (safety<->efficacy balance) and the four
473
+ │ │ computed immune-axis oracles: genotoxicity_oracle (VISDB x COSMIC) /
474
+ │ │ capsid_epitope_oracle (MHCflurry) / innate_sensing (CpG-O/E + dsRNA) /
475
+ │ │ seroprevalence_oracle (anti-vector NAb serosurveys)
447
476
  │ ├── bridge/ bridge off-target engine (Paper 4): offtarget / fold_qc / guide_qc / pipeline / cli
448
477
  │ │ + v3.2 offtarget_energetics (position x substitution; held-out 0.88, ships)
449
478
  │ ├── agent/ agentic platform: tools / orchestrator / pen_agent / mcp_server / guardrails; v5.0 co_scientist + cite (multi-strategy, self-critique, cited rationale, scope ledger)
450
479
  │ │ + v3.2 epistemic (3-tier status) / scope (known-unknowns matcher)
451
480
  │ ├── graph/ v4.5 living world-model knowledge graph (schema/build/query/ingest/cell_types); typed provenanced edges; gated living loop (propose-only)
452
- │ ├── oracles/ v4.0 L1 oracle mesh: OracleResult contract + adapters (genome/structure/protein_design/rna/energetics) over the foundation models; version-pinned cache
481
+ │ ├── oracles/ v4.0 L1 oracle mesh: OracleResult contract + adapters (genome/structure/protein_design/rna/energetics) over the foundation models; version-pinned cache; v5.2-5.5 delivery-immunology scope cards (delivery_genotoxicity/capsid_epitope/innate_sensing/seroprevalence)
453
482
  │ ├── rules/ v3.3 machine-readable rules engine (schema/evaluators/loader/solver) over configs/rules/*.yaml
454
483
  │ ├── verify/ v3.3 verification service: verify(design) -> Verdict (legal+reasons+confidence+scope; v4.0 writer_critique)
455
484
  │ ├── adapt/ local recalibration / private-data adaptation behind a gate (v3.1, WS-F)
@@ -465,12 +494,16 @@ pen-stack/
465
494
  │ ├── server/api.py FastAPI REST (atlas, crosslink, writable, plan, bridge, ask)
466
495
  │ ├── ui/app.py Streamlit web app (16 pages; v3.2 PEN-Agent shows confidence + epistemic status)
467
496
  │ └── cli.py unified CLI
468
- ├── benchmarks/genome_writing_bench/ Genome-Writing Bench v0.2 (T1-T11; tasks / harness / solvers / LEADERBOARD / SHAs)
497
+ ├── benchmarks/genome_writing_bench/ Genome-Writing Bench v0.3 (T1-T16 + co_scientist; tasks / harness / solvers / LEADERBOARD / SHAs)
469
498
  ├── bench/run.py one-command bench entrypoint (--agent, --verify)
470
- ├── scripts/ reproducible pipeline drivers (p1_*, p2_*, p4_*, ws_*_report)
471
- ├── configs/ pinned datasets + thresholds + curation (YAML); v3.2: known_unknowns /
472
- │ target_sites / delivery_constraints
473
- ├── prereg/ SHA-locked success criteria (paper1..4 + ws_a..ws_h + v3.2 ws_{uq,ep,mc,ba} + locks)
499
+ ├── scripts/ reproducible pipeline drivers (p1_*, p2_*, p4_*, p52/p53 delivery-immunology oracle builds, ws_*_report)
500
+ ├── configs/ pinned datasets + thresholds + curation (YAML); v3.2 known_unknowns /
501
+ │ target_sites / delivery_constraints; v5.1-5.5 delivery_vehicles immune_safety /
502
+ │ genotoxicity_oracle / capsid_epitope_oracle + capsid_sequences.fasta /
503
+ │ seroprevalence + oracles/scope_cards
504
+ ├── prereg/ SHA-locked success criteria (paper1..4 + ws_a..ws_h + v3.2-v5.5 ws_{uq,ep,mc,ba,
505
+ │ r,v,route,env,bench,cal,o,wv,atlas,graph,mon,ct,plan,crit,cite,immune,
506
+ │ genotox,epitope,innate,seroprev} + SHA256 locks)
474
507
  ├── data/curated/ small committed tables (universe, gene coords, measured bridge profile,
475
508
  │ v3.2 bridge_offtarget_energetics.json)
476
509
  ├── data/llm_bench_cache/ 28 cached ungrounded-LLM transcripts (T7, offline/CI replay)
@@ -0,0 +1,28 @@
1
+ # PEN-STACK v5.6 — anti-PEG antibody prevalence (WS-PEG).
2
+ #
3
+ # Pre-existing / induced anti-PEG antibodies gate RE-DOSING of PEGylated LNP. Anti-PEG is a property of the
4
+ # PEGylation chemistry, NOT of any encoded sequence — so, like the v5.5 anti-vector seroprevalence, the only
5
+ # honest grounding is published serosurvey DATA. Curated as a population prevalence RANGE (wide assay/region
6
+ # variation), with serosurvey DOIs.
7
+ #
8
+ # preexisting_antipeg_score = 1 - midpoint(anti_PEG_prevalence_pct) / 100 (1 = fewest patients excluded).
9
+ #
10
+ # HONESTY (scope card `antipeg`): a POPULATION prevalence, NOT a given patient's anti-PEG titer (a clinical
11
+ # test, patient-specific -> a known-unknown); region/age/assay-dependent (a range, surfaced as uncertainty);
12
+ # applies ONLY to PEGylated vehicles (abstains otherwise). INDUCED anti-PEG after dose 1 (boosted markedly by
13
+ # mRNA-LNP vaccination) is a separate, larger dynamic — NOTED here, not modelled (a known-unknown).
14
+
15
+ version: "1.0"
16
+
17
+ prevalence:
18
+ anti_peg_prevalence_pct: [25, 72]
19
+ note: "pre-existing anti-PEG IgG/IgM in healthy adults; wide assay/region variation (Chen 2016 ~72% had
20
+ detectable anti-PEG; high-TITER prevalence is lower). Induced anti-PEG post-dose-1 is separate + larger."
21
+ dois:
22
+ - "10.1021/acs.analchem.6b03109" # Chen 2016 — pre-existing IgG/IgM anti-PEG in healthy individuals
23
+ - "10.1002/wnan.1339" # Yang & Lai 2015 — anti-PEG immunity review
24
+ - "10.1002/cncr.22739" # Armstrong 2007 — anti-PEG antibodies adversely affect PEG-asparaginase
25
+ - "10.1016/j.addr.2020.07.024" # Kozma 2020 — anti-PEG antibodies (properties/formation/testing)
26
+
27
+ # which palette vehicles are PEGylated (LNP-mRNA uses a PEG-lipid). All others abstain.
28
+ pegylated_vehicles: [lnp_mrna]
@@ -65,3 +65,30 @@ known_unknowns:
65
65
  match_terms: ["germline", "heritable", "pass to offspring", "embryo", "inherited by children",
66
66
  "future generations"]
67
67
  patterns: []
68
+
69
+ # v5.6 WS-EXT — immune axes that are mechanistically distinct from what the v5.2-v5.6 oracles compute, and
70
+ # for which PEN-STACK has no grounded model: declared known-unknowns rather than faked.
71
+ - id: cd4_mhcii_help
72
+ title: "CD4 / MHC-II helper-epitope load"
73
+ requires: "MHC-II binding prediction over the capsid/transgene + a model linking CD4 help to antibody/memory formation"
74
+ why: "the v5.3 capsid-epitope oracle computes CD8 / MHC-I presentation ONLY; CD4 / MHC-II helper epitopes
75
+ (which drive antibody formation and durable memory) are NOT modelled — a distinct, ungrounded axis here"
76
+ match_terms: ["cd4", "mhc-ii", "mhc class ii", "helper t", "helper epitope", "th cell", "t-helper"]
77
+ patterns: []
78
+
79
+ - id: preexisting_capsid_tcell
80
+ title: "pre-existing capsid-specific memory T-cell immunity"
81
+ requires: "population prevalence of capsid-specific memory T cells (distinct from neutralizing-antibody serosurveys)"
82
+ why: "v5.5 seroprevalence is anti-vector ANTIBODY (B-cell) prevalence; pre-existing capsid-specific
83
+ memory T-CELL immunity is a separate dimension PEN-STACK does NOT model (sparse, assay-dependent data)"
84
+ match_terms: ["pre-existing t-cell", "preexisting t cell", "capsid-specific t cell", "memory t cell",
85
+ "t-cell immunity to capsid", "cellular pre-existing immunity"]
86
+ patterns: []
87
+
88
+ - id: complement_carpa
89
+ title: "complement activation / CARPA (complement-activation-related pseudoallergy)"
90
+ requires: "a model of complement activation by the vector/LNP surface (C3/C5 turnover, anaphylatoxins) and infusion-reaction risk"
91
+ why: "complement/CARPA is mechanistically distinct from the cargo CpG/dsRNA innate axis (v5.4) and the
92
+ capsid epitope axis; PEN-STACK does NOT model complement activation or infusion-reaction risk"
93
+ match_terms: ["complement", "carpa", "c3a", "c5a", "anaphylatox", "infusion reaction", "pseudoallergy"]
94
+ patterns: []
@@ -166,3 +166,16 @@ oracles:
166
166
  generalizes_to_unseen_loci: false
167
167
  license: "open (this work; Calcedo 10.1086/595830, Boutin 10.1089/hum.2009.182, Mast
168
168
  10.1016/j.vaccine.2009.10.145, Looker 10.1371/journal.pone.0140765)"
169
+
170
+ antipeg: # v5.6 WS-PEG: anti-PEG antibody prevalence (gates LNP re-dosing)
171
+ family: genome
172
+ version: "serosurvey-2026"
173
+ output_kind: baseline # curated empirical population data, not a model
174
+ valid_for: "POPULATION pre-existing anti-PEG antibody prevalence for PEGylated LNP (a property of the PEG
175
+ chemistry, not an encoded sequence); preexisting_antipeg_score = 1 - midpoint/100; gates RE-DOSING"
176
+ not_valid_for: "a given PATIENT's anti-PEG titer / sero-status (a clinical test, patient-specific -> a
177
+ known-unknown); INDUCED anti-PEG after dose 1 (a separate, larger dynamic, esp. post mRNA-LNP); precise
178
+ region/age/assay values (a range, not a point); non-PEGylated vehicles (abstains)"
179
+ generalizes_to_unseen_loci: false
180
+ license: "open (this work; Chen 10.1021/acs.analchem.6b03109, Yang&Lai 10.1002/wnan.1339,
181
+ Armstrong 10.1002/cncr.22739, Kozma 10.1016/j.addr.2020.07.024)"
@@ -0,0 +1,150 @@
1
+ # Delivery immunology — the safety↔efficacy balance (v5.1 → v5.5)
2
+
3
+ PEN-STACK scores and constrains the **whole** delivery palette (8 vehicles), not just dual-AAV. v5.1–v5.5 added
4
+ a delivery **safety↔efficacy** layer: a per-vehicle immune / safety / efficacy profile, a user-weightable
5
+ ranking, and — crucially — **four of the five immune/safety axes are now grounded in real data or sequence**
6
+ rather than hand-typed `low/moderate/high` tiers.
7
+
8
+ > **The honesty invariant (unchanged across the program).** The in-vivo immune *magnitude* — how strongly a
9
+ > given patient or construct will actually react — is a declared **known-unknown**
10
+ > (`configs/known_unknowns.yaml: in_vivo_immunogenicity`) and is **never predicted**. Every oracle below
11
+ > abstains rather than fabricate when it lacks data, and each carries a scope card stating exactly what it is
12
+ > *not* valid for. What is surfaced is a relative, auditable, cited signal — not a per-patient prediction.
13
+
14
+ ## The 8-vehicle palette
15
+
16
+ `configs/delivery_vehicles.yaml` — AAV (single / dual), lentivirus, helper-dependent adenovirus, HSV amplicon,
17
+ LNP-mRNA, eVLP, electroporation. Each carries cargo capacity, integration, cargo form, an `immune_safety` block
18
+ (documented ordinal priors + cited DOIs), and the computed-oracle hooks below.
19
+
20
+ ## The safety↔efficacy profile
21
+
22
+ `pen_stack/planner/delivery_immunology.py::safety_efficacy_profile(vehicle)` returns, per vehicle:
23
+
24
+ - **two separate safety sub-axes** — never collapsed, because they are different *kinds* of risk:
25
+ - `immune_score` — immunogenicity (largely reversible; bears on eligibility / re-dosing), the mean of four
26
+ immune axes (pre-existing, NAb, innate, adaptive);
27
+ - `genotox_score` — insertional / oncogenic risk (permanent);
28
+ - a headline `safety_score = min(immune_score, genotox_score)` (precautionary worst-axis);
29
+ - `efficacy_score`, the documented `tradeoff` sentence, and the standing magnitude scope flag.
30
+
31
+ `recommend_delivery(cargo_form, cargo_bp, safety_weight, in_vivo)` ranks the eligible palette along the
32
+ frontier: `balance = safety_weight·safety + (1−safety_weight)·efficacy`. Move `safety_weight` from 0→1 to slide
33
+ from efficacy-first to safety-first. This reproduces the motivating tradeoff: **AAV** is dinged on
34
+ immunogenicity (non-integrating, but NAb-limited), **lentivirus** on genotoxicity (a highly efficacious
35
+ integrator whose insertional risk is the dominant concern).
36
+
37
+ `verify(design)` surfaces the profile as `delivery_profile` plus a `delivery_immune_profile` scope flag, and —
38
+ when a `cargo_seq` is supplied — a `cargo_innate_sensing` flag (see below).
39
+
40
+ ## v5.6 — completion & calibration: anti-PEG, proxy honesty, and the unified profile
41
+
42
+ v5.6 finishes the picture and tells the truth about it (`docs` + `pen_stack/planner/{antipeg_oracle,immune_profile}.py`,
43
+ `pen_stack/validate/immune_calibration.py`):
44
+
45
+ - **Anti-PEG axis (WS-PEG)** — `antipeg_oracle.py` + `configs/antipeg.yaml`. Pre-existing/induced anti-PEG
46
+ antibodies gate **re-dosing** of PEGylated LNP. Same honest serosurvey pattern as v5.5: a population
47
+ prevalence **range** (25–72 %, Chen 2016 / Yang & Lai 2015 / Armstrong 2007 / Kozma 2020) →
48
+ `preexisting_antipeg_score = 1 − midpoint/100 = 0.515`, range surfaced as uncertainty. **Abstains** for
49
+ non-PEGylated vehicles. Patient titer and post-dose-1 *induced* anti-PEG stay known-unknowns.
50
+ - **Proxy calibration (WS-CALIB)** — `immune_calibration.py`. `calibrate_axis()` computes a Spearman ρ +
51
+ bootstrap CI and labels an axis **outcome-validated only when the CI excludes zero** (else `weak_proxy`;
52
+ `mechanistic_proxy` when N < 6). Because no sufficient public *paired* (proxy, observed-immunogenicity)
53
+ dataset exists, **every axis is currently labelled a mechanistic/population proxy** — that honest label is
54
+ the deliverable, and it travels with the profile. (The machinery is proven on synthetic data; it will
55
+ promote an axis only from real data.)
56
+ - **Unified immune-risk profile (WS-PROFILE)** — `immune_profile.py`, exposed as **`Verdict.immune_profile`**.
57
+ A per-design **vector** of all axes, each with its own value + uncertainty + scope + validation label;
58
+ **`collapsed_score is None`** (never fused into one overconfident number — asserted by test);
59
+ `known_unknowns` listed; abstaining axes report `None`, not a guess.
60
+ - **WS-EXT** — a documented qualitative **route/immune-privilege modifier** (eye/CNS materially lower realized
61
+ immunogenicity vs systemic; Streilein 2003 `10.1038/nri1224`; *no* fabricated magnitude), and three
62
+ mechanistically-distinct axes registered as **known-unknowns**: CD4/MHC-II helper epitopes,
63
+ pre-existing capsid-specific T-cell immunity, and complement/CARPA.
64
+
65
+ ## The axes — four computed/grounded, anti-PEG added, one documented
66
+
67
+ | Axis | Risk kind | v5.1 | Now | Grounding |
68
+ |---|---|---|---|---|
69
+ | **Genotoxicity** | permanent / oncogenic | tier | **computed** (v5.2) | integration-site catalogues × oncogene loci |
70
+ | **Adaptive (CD8 T-cell)** | reversible | tier | **computed** (v5.3) | MHC-I epitope load over the capsid sequence |
71
+ | **Innate** | reversible | tier | **computed** (v5.4) | CpG / dsRNA motif load of the cargo sequence |
72
+ | **Pre-existing / NAb (B-cell)** | reversible (eligibility) | tier | **data-grounded** (v5.5) | published serosurveys |
73
+ | **Anti-PEG (LNP re-dosing)** | reversible (re-dosing) | — | **data-grounded** (v5.6) | anti-PEG serosurveys |
74
+ | **Efficacy** | — | tier | documented | construct/context-specific by nature |
75
+
76
+ Each computed signal answers through the v4.0 `OracleResult` contract (value + provenance + native uncertainty
77
+ + scope card + `output_kind="baseline"`), and the small committed artifacts (where any) keep the heavy
78
+ data/models on the VM so the package and CI stay light.
79
+
80
+ ### Genotoxicity — `genotoxicity_oracle.py` (v5.2, WS-GENOTOX)
81
+
82
+ For an **integrating** vector, the observed enrichment of its integration sites near COSMIC Cancer-Gene-Census
83
+ oncogenes: `P(site within 50 kb of an oncogene)` over the vector class's VISDB catalogue, vs genome background
84
+ (2.21 %). `genotox_score = min(1, 1/enrichment)`.
85
+
86
+ - **Lentiviral (HIV) 2.08×** enrichment (n = 88,743, robust) vs **gammaretroviral (MLV) 5.65×** (the LMO2 /
87
+ SCID-X1 comparator; n = 32, flagged small-n) — reproducing the *lentivirus-safer-than-gammaretrovirus*
88
+ ordering **from data**. The computed lentivirus score (0.48) **validates** the v5.1 documented "moderate"
89
+ tier (0.5).
90
+ - Non-integrating vehicles → 1.0 by mechanism. *Not valid for:* the in-vivo clonal / leukemogenesis **outcome**
91
+ (a known-unknown). Build: `scripts/p52_build_genotox_oracle.py` → `configs/genotoxicity_oracle.yaml`.
92
+ Provenance: VISDB `10.1093/nar/gkz867`, COSMIC CGC `10.1038/s41568-018-0060-1`.
93
+
94
+ ### Adaptive / CD8 — `capsid_epitope_oracle.py` (v5.3, WS-EPITOPE)
95
+
96
+ For a **viral** vector, the fraction of its capsid/envelope antigen presentable to CD8 T cells across a
97
+ frequent HLA-I panel (MHCflurry 2.0, %rank ≤ 0.5 over 9-mers × 12 alleles): `capsid_immune_score = 1 −
98
+ epitope_fraction_strong`.
99
+
100
+ - AAV2 VP1 is the **least** epitope-dense capsid (0.72), Ad5 hexon among the most (0.82) — the documented
101
+ adaptive ordering reproduced **from sequence**. All 8 vehicles covered (5 viral computed, 3 non-viral 1.0 by
102
+ mechanism).
103
+ - The score is *intrinsic* presentability, so it is folded into the adaptive axis **only for in-vivo**
104
+ vehicles; for **ex-vivo lentivirus** (VSV-G is intrinsically epitope-dense but barely seen ex vivo) it is
105
+ reported but muted. *Not valid for:* the patient-HLA-specific response (a known-unknown); antibody immunity
106
+ (this is CD8/MHC-I only). Sequences UniProt-verified (`configs/capsid_sequences.fasta`: AAV2 VP1 P03135, Ad5
107
+ hexon P04133, VSV-G P03522, HSV-1 gD P57083 + gB P06437). Provenance: MHCflurry `10.1016/j.cels.2020.06.010`,
108
+ HLA supertypes `10.1186/1471-2172-9-1`.
109
+
110
+ ### Innate — `innate_sensing.py` (v5.4, WS-INNATE)
111
+
112
+ For the **cargo sequence** (computed live in `verify()` when a `cargo_seq` is supplied):
113
+
114
+ - **DNA** → CpG observed/expected (TLR9/cGAS): vertebrate genome ~0.2 is tolerated, non-depleted DNA → 1 is
115
+ stimulatory; `innate_score = max(0, 1 − CpG_O/E)`.
116
+ - **mRNA** → U-richness + ViennaRNA dsRNA pairing (TLR7/8 + RIG-I/MDA5/PKR); a **partial** signal (flagged
117
+ `extrapolating`) — the dominant evasion lever, nucleoside modification (m1-pseudouridine), is *not*
118
+ sequence-derivable.
119
+ - **RNP** → minimal/transient. *Not valid for:* the realized in-vivo innate response, RNA nucleoside
120
+ modification, DNA methylation state. Provenance: CpG-TLR9 `10.1073/pnas.161293498`, CpG-depleted AAV
121
+ `10.1172/JCI68205`, RNA modification `10.1016/j.immuni.2005.06.008`.
122
+
123
+ ### Pre-existing / neutralizing antibody — `seroprevalence_oracle.py` (v5.5, WS-SEROPREV)
124
+
125
+ The one axis that **cannot** be computed from sequence — anti-capsid NAb seroprevalence is a population
126
+ prevalence from natural exposure. Grounded in published serosurveys (`configs/seroprevalence.yaml`, ranges with
127
+ DOIs): `preexisting_score = 1 − midpoint(seroprevalence)/100`, range half-width surfaced as native uncertainty.
128
+
129
+ | Serotype (vehicle) | NAb seroprevalence | pre-existing score |
130
+ |---|---|---|
131
+ | Ad5 → HDAd | 40–90 % | 0.35 |
132
+ | HSV-1 → HSV | 50–70 % | 0.40 |
133
+ | AAV (aggregate) → AAV | 30–60 % | 0.55 |
134
+ | VSV → lentivirus | 0–5 % | 0.975 (muted, ex-vivo) |
135
+
136
+ Folded for in-vivo vehicles (serum NAb neutralises the vector in vivo), muted for ex-vivo; non-viral → 1.0 by
137
+ mechanism. *Not valid for:* a given **patient's** NAb titer / sero-status (a clinical test, patient-specific →
138
+ a known-unknown). Provenance: Calcedo `10.1086/595830`, Boutin `10.1089/hum.2009.182`, Mast
139
+ `10.1016/j.vaccine.2009.10.145`, Looker `10.1371/journal.pone.0140765`.
140
+
141
+ ## Outcome
142
+
143
+ Across v5.1→v5.5 the delivery immune/safety profile moved from documented `low/moderate/high` tiers to **real
144
+ calculations from data and sequence** on four of the five axes, spanning all 8 vehicles — each grounded, each
145
+ abstaining rather than fabricating, with the in-vivo magnitude always a declared known-unknown. The result is
146
+ the safety↔efficacy balance the program set out to provide: *computed wherever the science allows, documented
147
+ where it does not, and explicitly out-of-scope where no one can yet predict.*
148
+
149
+ See also: [Oracle mesh](oracles.md) · [Delivery palette & router](delivery.md) · [Verification](verify.md) ·
150
+ [Scope & known-unknowns](scope.md). Pre-registrations: `prereg/ws_{immune,genotox,epitope,innate,seroprev}.yaml`.
@@ -12,6 +12,7 @@ Three layers, one engine:
12
12
  | **Writer Atlas** (`pen_stack.atlas` / `mech` / `score`) | What can write, and how well? (33,370 systems across 8 families, measured axes) |
13
13
  | **Cross-link** (`pen_stack.atlas.crosslink`) | Which writers reach a locus / which loci a writer reaches |
14
14
  | **Write Planner** (`pen_stack.planner`, Phase 3) | Find the optimal site x writer x cargo x delivery for a goal |
15
+ | **Delivery immunology** (`pen_stack.planner.delivery_immunology` + oracles) | Balance safety vs efficacy across the 8-vehicle palette — four of five immune/safety axes **computed from data/sequence** ([details](delivery_immunology.md)) |
15
16
 
16
17
  ## Install
17
18
 
@@ -1,2 +1,2 @@
1
1
  """PEN-STACK v3.0 - open infrastructure for genome writing."""
2
- __version__ = "5.5.0"
2
+ __version__ = "5.6.0"
@@ -46,6 +46,15 @@ def curated_dois() -> frozenset[str]:
46
46
  dois.update(_rec.get("dois", []) or [])
47
47
  except FileNotFoundError:
48
48
  pass
49
+ # v5.6 anti-PEG serosurvey provenance
50
+ try:
51
+ ap = yaml.safe_load(resource("configs/antipeg.yaml").read_text(encoding="utf-8"))
52
+ dois.update((ap.get("prevalence") or {}).get("dois", []) or [])
53
+ except FileNotFoundError:
54
+ pass
55
+ # v5.6 WS-EXT route/immune-privilege modifier provenance
56
+ from pen_stack.planner.immune_profile import ROUTE_MODIFIER_DOI
57
+ dois.add(ROUTE_MODIFIER_DOI)
49
58
  gsh = yaml.safe_load(resource("configs/gsh_validated_heldout.yaml").read_text(encoding="utf-8"))["gsh"]
50
59
  for g in gsh:
51
60
  if g.get("doi"):
@@ -0,0 +1,75 @@
1
+ """Anti-PEG immunity axis for PEGylated LNP (v5.6, WS-PEG).
2
+
3
+ The one delivery-immunology axis missing from v5.1-v5.5: pre-existing / induced anti-PEG antibodies, which
4
+ gate RE-DOSING of PEGylated LNP. Anti-PEG is a property of the PEGylation chemistry, not of any encoded
5
+ sequence — so, exactly like the v5.5 anti-vector seroprevalence oracle, it is grounded in published serosurvey
6
+ DATA (configs/antipeg.yaml, a population prevalence range with DOIs):
7
+
8
+ preexisting_antipeg_score = 1 - midpoint(anti_PEG_prevalence_pct) / 100 # 1 = fewest excluded
9
+
10
+ Answers through the v4.0 OracleResult contract (output_kind="baseline"). ABSTAINS for non-PEGylated vehicles.
11
+ HONESTY: a POPULATION prevalence (a range, region/age/assay-dependent), NOT a given patient's anti-PEG titer
12
+ (a clinical test, patient-specific -> a known-unknown); induced anti-PEG after dose 1 is a separate, larger
13
+ dynamic (noted, not modelled).
14
+ """
15
+ from __future__ import annotations
16
+
17
+ from functools import lru_cache
18
+
19
+ import yaml
20
+
21
+ from pen_stack._resources import resource
22
+ from pen_stack.oracles.schema import OracleResult, Provenance
23
+
24
+ _SCOPE_CARD = "antipeg"
25
+
26
+
27
+ @lru_cache(maxsize=1)
28
+ def _table() -> dict:
29
+ return yaml.safe_load(resource("configs/antipeg.yaml").read_text(encoding="utf-8"))
30
+
31
+
32
+ def _all_dois() -> list[str]:
33
+ return list((_table().get("prevalence") or {}).get("dois", []) or [])
34
+
35
+
36
+ def _prov(**extra) -> Provenance:
37
+ return Provenance(model="anti_peg_seroprevalence", version=str(_table().get("version", "1.0")),
38
+ source="cache", extra=extra)
39
+
40
+
41
+ def antipeg_oracle(vehicle_name: str, pegylated: bool | None = None) -> OracleResult:
42
+ """Anti-PEG pre-existing immunity for a vehicle, as an OracleResult (v4.0 contract).
43
+
44
+ - PEGylated vehicle -> preexisting_antipeg_score = 1 - midpoint(prevalence)/100 (gates RE-DOSING).
45
+ - non-PEGylated vehicle -> ABSTAINS (available=False, value=None): the anti-PEG axis is not applicable.
46
+ `pegylated` overrides the config's vehicle list when given. Never fabricates a patient titer."""
47
+ t = _table()
48
+ is_peg = pegylated if pegylated is not None else (vehicle_name in (t.get("pegylated_vehicles") or []))
49
+ if not is_peg:
50
+ return OracleResult(oracle="genome", value=None, provenance=_prov(), scope_card=_SCOPE_CARD,
51
+ in_scope=False, available=False, output_kind="baseline",
52
+ note=f"non-PEGylated vehicle {vehicle_name!r}: anti-PEG axis not applicable (abstains).")
53
+
54
+ rec = t["prevalence"]
55
+ lo, hi = rec["anti_peg_prevalence_pct"]
56
+ mid = (lo + hi) / 2.0
57
+ score = max(0.0, min(1.0, 1.0 - mid / 100.0))
58
+ return OracleResult(
59
+ oracle="genome",
60
+ value={"preexisting_antipeg_score": round(score, 3), "anti_peg_prevalence_pct": [lo, hi],
61
+ "midpoint_pct": mid, "gates": "re-dosing", "dois": rec.get("dois", [])},
62
+ provenance=_prov(dois=rec.get("dois", [])), native_uncertainty=round((hi - lo) / 200.0, 4),
63
+ scope_card=_SCOPE_CARD, in_scope=True, extrapolating=False, output_kind="baseline", available=True,
64
+ note=(f"population anti-PEG prevalence {lo}-{hi}% -> preexisting_antipeg_score={score:.3f}; gates "
65
+ "RE-DOSING of PEGylated LNP. A POPULATION range (region/age/assay-dependent) - NOT a patient's "
66
+ "anti-PEG titer (a known-unknown); induced anti-PEG after dose 1 is a separate, larger dynamic "
67
+ "(not modelled)."))
68
+
69
+
70
+ def computed_antipeg_score(vehicle_name: str, pegylated: bool | None = None) -> tuple[float | None, OracleResult]:
71
+ """Convenience: (anti-PEG score or None, full OracleResult). None when the oracle abstains (non-PEG).
72
+ Never fabricates."""
73
+ r = antipeg_oracle(vehicle_name, pegylated)
74
+ val = (r.value or {}).get("preexisting_antipeg_score") if (r.available and r.value) else None
75
+ return val, r