factorforge-cds 3.2.2__tar.gz → 3.2.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {factorforge_cds-3.2.2/src/factorforge_cds.egg-info → factorforge_cds-3.2.4}/PKG-INFO +10 -9
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/README.md +8 -7
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/pyproject.toml +2 -2
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/__init__.py +1 -1
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/analysis/feasibility.py +2 -2
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/cli/main.py +8 -1
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/engines/__init__.py +1 -1
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/engines/profile/__init__.py +1 -1
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/engines/profile/construct_builder.py +5 -2
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/engines/profile/optimizer.py +15 -1
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/engines/profile/rules/reverse_translator.py +1 -1
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/engines/profile/rules/rule_engine.py +2 -2
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/engines/profile/scoring.py +1 -1
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/validation/cli.py +3 -3
- factorforge_cds-3.2.4/src/factorforge/validation_registry.py +322 -0
- factorforge_cds-3.2.4/src/factorforge/validation_report.py +90 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4/src/factorforge_cds.egg-info}/PKG-INFO +10 -9
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge_cds.egg-info/SOURCES.txt +5 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/tests/test_benchmark_codon_table_metadata.py +1 -1
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/tests/test_codon_table_manifest.py +1 -1
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/tests/test_docs_consistency.py +15 -4
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/tests/test_host_profile_metadata.py +1 -1
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/tests/test_registry_production_sync.py +2 -2
- factorforge_cds-3.2.4/tests/test_validation_contract_compat.py +51 -0
- factorforge_cds-3.2.4/tests/test_validation_registry.py +103 -0
- factorforge_cds-3.2.4/tests/test_validation_report.py +130 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/LICENSE +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/setup.cfg +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/__main__.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/analysis/__init__.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/analysis/metrics.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/cli/__init__.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/cli/legacy_cli.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/core/interfaces/__init__.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/core/interfaces/exporter.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/core/interfaces/optimizer.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/core/interfaces/validator.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/data/nbenthamiana_codons.json +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/data/nbenthamiana_golden_set.json +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/data/ntabacum_codons.json +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/data/templates/high_expression.json +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/data/templates/standard_expression.json +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/data/wolffia_globosa_codons.json +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/database.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/engines/profile/codon_table_builder.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/engines/profile/exporter.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/engines/profile/pipeline.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/engines/profile/rules/__init__.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/engines/profile/rules/domesticator.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/engines/profile/scoring_ml.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/engines/profile/utils.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/engines/profile/validator.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/engines/registry.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/io/__init__.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/io/fasta.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/io/validation.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/protein_risk/__init__.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/protein_risk/annotate.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/protein_risk/kd_scale.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/protein_risk/risk_classifier.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/protein_risk/sp_predict.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/protein_risk/tm_predict.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/registry/__init__.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/registry/registry_loader.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/schemas/__init__.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/schemas/design_package.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/schemas/design_package.schema.json +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/utils/__init__.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/utils/construct_id.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/utils/exceptions.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/utils/restriction_sites.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/utils/sequence_validator.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/utils/validation.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/validation/__init__.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/validation/package_generator.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge_cds.egg-info/dependency_links.txt +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge_cds.egg-info/entry_points.txt +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge_cds.egg-info/requires.txt +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge_cds.egg-info/top_level.txt +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/tests/test_baselines.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/tests/test_benchmark_regression.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/tests/test_benchmark_scoring.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/tests/test_benchmark_smoke.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/tests/test_cai.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/tests/test_database.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/tests/test_design_package_schema.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/tests/test_design_package_semantics.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/tests/test_design_package_serialization.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/tests/test_fasta_io.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/tests/test_gc_content.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/tests/test_iupac_validation.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/tests/test_legacy_cli.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/tests/test_no_raw_sequence_logging.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/tests/test_openbio_missing_metric_contract.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/tests/test_parameter_registry.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/tests/test_protein_risk.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/tests/test_restriction_sites.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/tests/test_sequence_validator.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/tests/test_translation_integrity.py +0 -0
- {factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/tests/test_worked_example.py +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: factorforge-cds
|
|
3
|
-
Version: 3.2.
|
|
4
|
-
Summary: FactorForge - open-source
|
|
3
|
+
Version: 3.2.4
|
|
4
|
+
Summary: FactorForge - open-source CDS design and pre-synthesis sequence review engine by Eijex.
|
|
5
5
|
Author-email: Eijex <eijex.lab@gmail.com>
|
|
6
6
|
License-Expression: AGPL-3.0-only
|
|
7
7
|
Project-URL: Homepage, https://factorforge.eijex.com
|
|
@@ -33,19 +33,19 @@ Dynamic: license-file
|
|
|
33
33
|
|
|
34
34
|
# FactorForge
|
|
35
35
|
|
|
36
|
-
**Open-source constraint-based CDS design engine for
|
|
36
|
+
**Open-source constraint-based CDS design and pre-synthesis sequence review engine for plant CDS workflows, with primary support for *Nicotiana benthamiana* (Tobacco BY-2: experimental).**
|
|
37
37
|
|
|
38
38
|
[](LICENSE)
|
|
39
39
|
[](https://www.python.org/)
|
|
40
40
|
[](https://pypi.org/project/factorforge-cds/)
|
|
41
41
|
[](https://github.com/eijex/factorforge-cds/actions/workflows/ci.yml)
|
|
42
42
|
[](https://codecov.io/gh/eijex/factorforge-cds)
|
|
43
|
-
[](https://doi.org/10.5281/zenodo.20407330)
|
|
44
44
|
[](https://factorforge.eijex.com)
|
|
45
45
|
|
|
46
|
-
FactorForge performs profile-guided CDS design with CAI/GC metrics, PolyA-signal screening, and Golden Gate/MoClo-aware checks. Primary support: *N. benthamiana* (agroinfiltration). Experimental host context: Tobacco BY-2 (`--host by2`).
|
|
46
|
+
FactorForge performs profile-guided CDS design with CAI/GC metrics, PolyA-signal screening, and Golden Gate/MoClo-aware checks. It is positioned as a pre-synthesis review harness: it helps teams generate reproducible CDS candidates, inspect assembly-relevant sequence constraints, and package design metadata before downstream synthesis, cloning, or experimental review. Primary support: *N. benthamiana* (agroinfiltration). Experimental host context: Tobacco BY-2 (`--host by2`).
|
|
47
47
|
|
|
48
|
-
**→ [Full Documentation](https://eijex.github.io/factorforge-cds/)**
|
|
48
|
+
**→ [Full Documentation](https://eijex.github.io/factorforge-cds/)** · **[Roadmap](https://eijex.github.io/factorforge-cds/roadmap/)**
|
|
49
49
|
|
|
50
50
|
---
|
|
51
51
|
|
|
@@ -86,14 +86,14 @@ and are not imported by the installed package or exposed as supported engines.
|
|
|
86
86
|
|
|
87
87
|
## ⚠️ Validation Status
|
|
88
88
|
|
|
89
|
-
FactorForge outputs are **in-silico only** and have not been experimentally validated in wet-lab conditions. See [Validation](https://eijex.github.io/factorforge-cds/validation/) and [VALIDATION.md](VALIDATION.md).
|
|
89
|
+
FactorForge outputs are **in-silico only** and have not been experimentally validated in wet-lab conditions. These checks support reviewability and reproducibility; they do not guarantee expression, yield, synthesis acceptance, folding, glycosylation, regulatory approval, or downstream biological performance. See [Validation](https://eijex.github.io/factorforge-cds/validation/) and [VALIDATION.md](VALIDATION.md).
|
|
90
90
|
|
|
91
91
|
---
|
|
92
92
|
|
|
93
93
|
## Citing
|
|
94
94
|
|
|
95
95
|
```
|
|
96
|
-
FactorForge v3.2.
|
|
96
|
+
FactorForge v3.2.4 (2026). Open-source constraint-based CDS design engine.
|
|
97
97
|
Eijex. https://github.com/eijex/factorforge-cds
|
|
98
98
|
```
|
|
99
99
|
|
|
@@ -114,8 +114,9 @@ GNU Affero General Public License v3.0 — see [LICENSE](LICENSE).
|
|
|
114
114
|
## Get in Touch
|
|
115
115
|
|
|
116
116
|
- **Docs** — [eijex.github.io/factorforge-cds](https://eijex.github.io/factorforge-cds/)
|
|
117
|
-
- **Wet-lab
|
|
117
|
+
- **Wet-lab Feedback** — Public-safe feedback summaries are welcome via [Share Wet-lab Feedback (GitHub)](https://github.com/eijex/factorforge-cds/issues/new?template=wet_lab_result.yml). Do not submit raw sequences, confidential construct details, internal batch IDs, patient data, private contact information, exact process parameters, or confidential partner/customer data. Email `eijex.lab@gmail.com` for private or sensitive summaries. See [VALIDATION.md](VALIDATION.md) before submitting.
|
|
118
118
|
- **GitHub Issues** — bugs, features: [github.com/eijex/factorforge-cds/issues](https://github.com/eijex/factorforge-cds/issues)
|
|
119
119
|
- **Email** — eijex.lab@gmail.com
|
|
120
120
|
- **FactorForge** — [factorforge.eijex.com](https://factorforge.eijex.com)
|
|
121
|
+
- **Eijex MCP** — [mcp.eijex.com](https://mcp.eijex.com)
|
|
121
122
|
- **Lab** — [www.eijex.com](https://www.eijex.com)
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
# FactorForge
|
|
2
2
|
|
|
3
|
-
**Open-source constraint-based CDS design engine for
|
|
3
|
+
**Open-source constraint-based CDS design and pre-synthesis sequence review engine for plant CDS workflows, with primary support for *Nicotiana benthamiana* (Tobacco BY-2: experimental).**
|
|
4
4
|
|
|
5
5
|
[](LICENSE)
|
|
6
6
|
[](https://www.python.org/)
|
|
7
7
|
[](https://pypi.org/project/factorforge-cds/)
|
|
8
8
|
[](https://github.com/eijex/factorforge-cds/actions/workflows/ci.yml)
|
|
9
9
|
[](https://codecov.io/gh/eijex/factorforge-cds)
|
|
10
|
-
[](https://doi.org/10.5281/zenodo.20407330)
|
|
11
11
|
[](https://factorforge.eijex.com)
|
|
12
12
|
|
|
13
|
-
FactorForge performs profile-guided CDS design with CAI/GC metrics, PolyA-signal screening, and Golden Gate/MoClo-aware checks. Primary support: *N. benthamiana* (agroinfiltration). Experimental host context: Tobacco BY-2 (`--host by2`).
|
|
13
|
+
FactorForge performs profile-guided CDS design with CAI/GC metrics, PolyA-signal screening, and Golden Gate/MoClo-aware checks. It is positioned as a pre-synthesis review harness: it helps teams generate reproducible CDS candidates, inspect assembly-relevant sequence constraints, and package design metadata before downstream synthesis, cloning, or experimental review. Primary support: *N. benthamiana* (agroinfiltration). Experimental host context: Tobacco BY-2 (`--host by2`).
|
|
14
14
|
|
|
15
|
-
**→ [Full Documentation](https://eijex.github.io/factorforge-cds/)**
|
|
15
|
+
**→ [Full Documentation](https://eijex.github.io/factorforge-cds/)** · **[Roadmap](https://eijex.github.io/factorforge-cds/roadmap/)**
|
|
16
16
|
|
|
17
17
|
---
|
|
18
18
|
|
|
@@ -53,14 +53,14 @@ and are not imported by the installed package or exposed as supported engines.
|
|
|
53
53
|
|
|
54
54
|
## ⚠️ Validation Status
|
|
55
55
|
|
|
56
|
-
FactorForge outputs are **in-silico only** and have not been experimentally validated in wet-lab conditions. See [Validation](https://eijex.github.io/factorforge-cds/validation/) and [VALIDATION.md](VALIDATION.md).
|
|
56
|
+
FactorForge outputs are **in-silico only** and have not been experimentally validated in wet-lab conditions. These checks support reviewability and reproducibility; they do not guarantee expression, yield, synthesis acceptance, folding, glycosylation, regulatory approval, or downstream biological performance. See [Validation](https://eijex.github.io/factorforge-cds/validation/) and [VALIDATION.md](VALIDATION.md).
|
|
57
57
|
|
|
58
58
|
---
|
|
59
59
|
|
|
60
60
|
## Citing
|
|
61
61
|
|
|
62
62
|
```
|
|
63
|
-
FactorForge v3.2.
|
|
63
|
+
FactorForge v3.2.4 (2026). Open-source constraint-based CDS design engine.
|
|
64
64
|
Eijex. https://github.com/eijex/factorforge-cds
|
|
65
65
|
```
|
|
66
66
|
|
|
@@ -81,8 +81,9 @@ GNU Affero General Public License v3.0 — see [LICENSE](LICENSE).
|
|
|
81
81
|
## Get in Touch
|
|
82
82
|
|
|
83
83
|
- **Docs** — [eijex.github.io/factorforge-cds](https://eijex.github.io/factorforge-cds/)
|
|
84
|
-
- **Wet-lab
|
|
84
|
+
- **Wet-lab Feedback** — Public-safe feedback summaries are welcome via [Share Wet-lab Feedback (GitHub)](https://github.com/eijex/factorforge-cds/issues/new?template=wet_lab_result.yml). Do not submit raw sequences, confidential construct details, internal batch IDs, patient data, private contact information, exact process parameters, or confidential partner/customer data. Email `eijex.lab@gmail.com` for private or sensitive summaries. See [VALIDATION.md](VALIDATION.md) before submitting.
|
|
85
85
|
- **GitHub Issues** — bugs, features: [github.com/eijex/factorforge-cds/issues](https://github.com/eijex/factorforge-cds/issues)
|
|
86
86
|
- **Email** — eijex.lab@gmail.com
|
|
87
87
|
- **FactorForge** — [factorforge.eijex.com](https://factorforge.eijex.com)
|
|
88
|
+
- **Eijex MCP** — [mcp.eijex.com](https://mcp.eijex.com)
|
|
88
89
|
- **Lab** — [www.eijex.com](https://www.eijex.com)
|
|
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "factorforge-cds"
|
|
7
|
-
version = "3.2.
|
|
8
|
-
description = "FactorForge - open-source
|
|
7
|
+
version = "3.2.4"
|
|
8
|
+
description = "FactorForge - open-source CDS design and pre-synthesis sequence review engine by Eijex."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "AGPL-3.0-only"
|
|
11
11
|
license-files = ["LICENSE"]
|
|
@@ -15,7 +15,7 @@ from factorforge.analysis.metrics import (
|
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
# Defaults calibrated to nbenthamiana profile engine output distribution
|
|
18
|
-
# (
|
|
18
|
+
# (internal benchmark, n=49): avg CAI=0.76, avg GC=60.1% (range 55-71%).
|
|
19
19
|
# DEFAULT_CAI_TARGET=0.82 aligns with industry practice (>0.8) and is achievable.
|
|
20
20
|
# Exported as named constants so tests/test_registry_production_sync.py can
|
|
21
21
|
# strictly compare them against the registry (single source of truth).
|
|
@@ -110,7 +110,7 @@ def analyze_feasibility(
|
|
|
110
110
|
codon weights.
|
|
111
111
|
|
|
112
112
|
See module-level DEFAULT_CAI_TARGET / DEFAULT_GC_LOW / DEFAULT_GC_HIGH for
|
|
113
|
-
the calibration rationale (
|
|
113
|
+
the calibration rationale (internal benchmark, n=49).
|
|
114
114
|
"""
|
|
115
115
|
protein = "".join(protein_sequence.upper().split()).rstrip("*")
|
|
116
116
|
if not protein:
|
|
@@ -161,7 +161,7 @@ def list_engines():
|
|
|
161
161
|
@click.option(
|
|
162
162
|
"--objective",
|
|
163
163
|
default="feasibility_best",
|
|
164
|
-
type=click.Choice(["feasibility_best"
|
|
164
|
+
type=click.Choice(["feasibility_best"], case_sensitive=False),
|
|
165
165
|
help="DP objective",
|
|
166
166
|
)
|
|
167
167
|
@click.option("--gc-min", type=float, default=55.0, help="Minimum target GC percentage")
|
|
@@ -212,6 +212,13 @@ def optimize(
|
|
|
212
212
|
if host_was_explicit and engine == "dp" and internal_host != "nbenthamiana":
|
|
213
213
|
engine = "profile"
|
|
214
214
|
|
|
215
|
+
if host_was_explicit and internal_host != "nbenthamiana":
|
|
216
|
+
if profile == "high_cai" or "high_cai" in (compare_profile_list or []):
|
|
217
|
+
raise click.UsageError(
|
|
218
|
+
"high_cai requires the N. benthamiana golden-set reference "
|
|
219
|
+
"and is not available for non-default hosts."
|
|
220
|
+
)
|
|
221
|
+
|
|
215
222
|
if compare_profile_list:
|
|
216
223
|
if engine == "dp" and _engine_option_was_explicitly_set():
|
|
217
224
|
raise click.UsageError("--compare-profiles cannot be used with --engine dp.")
|
{factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/engines/profile/construct_builder.py
RENAMED
|
@@ -19,10 +19,13 @@ if TYPE_CHECKING:
|
|
|
19
19
|
class ConstructBuilder:
|
|
20
20
|
"""Assemble constructs from JSON templates."""
|
|
21
21
|
|
|
22
|
-
def __init__(self, template_dir: Path) -> None:
|
|
22
|
+
def __init__(self, template_dir: Path | None = None) -> None:
|
|
23
23
|
"""
|
|
24
24
|
Args:
|
|
25
|
-
template_dir: Directory containing construct templates.
|
|
25
|
+
template_dir: Directory containing construct templates. Optional —
|
|
26
|
+
omit when only using template-independent methods such as
|
|
27
|
+
check_internal_overhang_collisions() or validate_overhangs(),
|
|
28
|
+
which do not read from disk.
|
|
26
29
|
"""
|
|
27
30
|
self.template_dir = template_dir
|
|
28
31
|
|
{factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/engines/profile/optimizer.py
RENAMED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import logging
|
|
5
6
|
from typing import Any
|
|
6
7
|
|
|
7
8
|
from factorforge.core.interfaces import OptimizationResult, OptimizerEngine
|
|
@@ -12,12 +13,14 @@ from .rules.rule_engine import RuleEngine
|
|
|
12
13
|
from .scoring import calculate_composite_score, compute_mfe_evidence
|
|
13
14
|
from .validator import InputValidator
|
|
14
15
|
|
|
16
|
+
logger = logging.getLogger(__name__)
|
|
17
|
+
|
|
15
18
|
|
|
16
19
|
class RuleBasedOptimizer(OptimizerEngine):
|
|
17
20
|
"""Profile-based rule optimization engine."""
|
|
18
21
|
|
|
19
22
|
name = "Profile-based"
|
|
20
|
-
version = "3.2.
|
|
23
|
+
version = "3.2.4"
|
|
21
24
|
|
|
22
25
|
def __init__(self, codon_table_path: str | None = None) -> None:
|
|
23
26
|
"""
|
|
@@ -93,6 +96,17 @@ class RuleBasedOptimizer(OptimizerEngine):
|
|
|
93
96
|
f"Unknown profile: {profile_value}. Supported profiles: {supported}"
|
|
94
97
|
) from exc
|
|
95
98
|
|
|
99
|
+
if (
|
|
100
|
+
self._codon_table_path is None
|
|
101
|
+
and host != "nbenthamiana"
|
|
102
|
+
and profile_value == "high_cai"
|
|
103
|
+
):
|
|
104
|
+
logger.warning(
|
|
105
|
+
"high_cai is anchored to the N. benthamiana golden set and "
|
|
106
|
+
"ignores the requested host=%s; output is host-invariant by design.",
|
|
107
|
+
host,
|
|
108
|
+
)
|
|
109
|
+
|
|
96
110
|
if self._codon_table_path is not None or host == "nbenthamiana":
|
|
97
111
|
# An injected design table (benchmark source-profile runs) is
|
|
98
112
|
# authoritative: it already encodes the host it was derived from.
|
|
@@ -370,7 +370,7 @@ class ReverseTranslator:
|
|
|
370
370
|
Balanced profile: CAI first, GC balanced
|
|
371
371
|
|
|
372
372
|
- Preferred codon ratio: 70%
|
|
373
|
-
- Target GC: 55-65% (benchmark
|
|
373
|
+
- Target GC: 55-65% (internal benchmark: avg output 60.1%)
|
|
374
374
|
"""
|
|
375
375
|
target_gc_min = kwargs.get("target_gc_min", 55)
|
|
376
376
|
target_gc_max = kwargs.get("target_gc_max", 65)
|
{factorforge_cds-3.2.2 → factorforge_cds-3.2.4}/src/factorforge/engines/profile/rules/rule_engine.py
RENAMED
|
@@ -361,7 +361,7 @@ class RuleEngine:
|
|
|
361
361
|
by the scoring band (GC_OPT_MIN/MAX, ~55-65%) and the API/DP gc_min/gc_max
|
|
362
362
|
constraints. The wide 25-75% band intentionally flags only synthesis-hostile
|
|
363
363
|
local windows; narrowing it toward the global optimum would raise false
|
|
364
|
-
positives against the engine's own output distribution (
|
|
364
|
+
positives against the engine's own output distribution (internal benchmark: 55-71%).
|
|
365
365
|
|
|
366
366
|
Args:
|
|
367
367
|
seq: DNA sequence
|
|
@@ -704,7 +704,7 @@ class RuleEngine:
|
|
|
704
704
|
Reduce CpG and TpA dinucleotide density via greedy synonymous substitution.
|
|
705
705
|
|
|
706
706
|
Modes:
|
|
707
|
-
aggressive: dinucleotide reduction only; no CAI check
|
|
707
|
+
aggressive: dinucleotide reduction only; no CAI check.
|
|
708
708
|
balanced: dinucleotide reduction first; rollback each pass if final CAI
|
|
709
709
|
drops below cai_floor.
|
|
710
710
|
cai_preserving: rollback each pass if CAI drops more than max_cai_drop
|
|
@@ -12,7 +12,7 @@ from typing import Any
|
|
|
12
12
|
logger = logging.getLogger(__name__)
|
|
13
13
|
|
|
14
14
|
# GC band for N. benthamiana codon-optimized sequences.
|
|
15
|
-
# Benchmark (
|
|
15
|
+
# Benchmark (internal, n=49): balanced profile output average GC% = 60.1%
|
|
16
16
|
# (range 55-71%). The genome-wide average (~42%) reflects all genes, not the
|
|
17
17
|
# high-expression codon table which exhibits 3rd-position GC bias.
|
|
18
18
|
# These constants define the acceptable band — sequences within [GC_OPT_MIN, GC_OPT_MAX]
|
|
@@ -24,7 +24,7 @@ def _sequence_hash(args: argparse.Namespace) -> str:
|
|
|
24
24
|
def main() -> None:
|
|
25
25
|
parser = argparse.ArgumentParser(
|
|
26
26
|
prog="factorforge-validate",
|
|
27
|
-
description="Generate a structured
|
|
27
|
+
description="Generate a structured public-safe wet-lab feedback package.",
|
|
28
28
|
)
|
|
29
29
|
parser.add_argument(
|
|
30
30
|
"--construct-id",
|
|
@@ -58,12 +58,12 @@ def main() -> None:
|
|
|
58
58
|
parser.add_argument(
|
|
59
59
|
"--comparison",
|
|
60
60
|
required=True,
|
|
61
|
-
choices=["
|
|
61
|
+
choices=["Improved", "Equivalent", "Reduced", "Inconclusive", "No control", "Not reported"],
|
|
62
62
|
)
|
|
63
63
|
parser.add_argument(
|
|
64
64
|
"--expression-level",
|
|
65
65
|
default=None,
|
|
66
|
-
choices=["
|
|
66
|
+
choices=["Detected", "Not detected", "Weak", "Strong", "Inconclusive", "Not reported"],
|
|
67
67
|
)
|
|
68
68
|
parser.add_argument("--notes", default=None)
|
|
69
69
|
parser.add_argument("--institution", default=None)
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
"""Runtime validation-check registry — single source of truth for check_id,
|
|
2
|
+
display metadata, and per-execution-path enforcement.
|
|
3
|
+
|
|
4
|
+
Frozen reference: validation_contract_v1.yaml, factorforge commit
|
|
5
|
+
4a8be9f053797d5f54154afcbda732eaaf79f8ae (v3.2.3). This module is the
|
|
6
|
+
runtime source of truth; the contract file is a pinned manuscript snapshot
|
|
7
|
+
of what this registry's predecessor behavior was.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from typing import Any
|
|
13
|
+
|
|
14
|
+
VALIDATION_REGISTRY_VERSION = "1.0"
|
|
15
|
+
|
|
16
|
+
VALIDATION_CHECKS: tuple[dict[str, Any], ...] = (
|
|
17
|
+
# --- Domain B: Configured Constraints -----------------------------------
|
|
18
|
+
{
|
|
19
|
+
"check_id": "global_gc_range",
|
|
20
|
+
"display_name": "Global GC% target band",
|
|
21
|
+
"primary_domain": "configured_constraint",
|
|
22
|
+
"order": 1,
|
|
23
|
+
"default_enabled": True,
|
|
24
|
+
"enforcement_per_path": {
|
|
25
|
+
"bare_optimizer": "metric_only",
|
|
26
|
+
"pipeline_default": "metric_only",
|
|
27
|
+
"benchmark_scoring": "component_of_multi_constraint_pass_soft",
|
|
28
|
+
},
|
|
29
|
+
"presentation": {"web": {"visible": True, "default_status_when_not_executed": None}},
|
|
30
|
+
"claim_boundary": (
|
|
31
|
+
"Configured optimization target, not a pass/fail biological-risk scanner. "
|
|
32
|
+
"Only gates in the benchmark scoring path."
|
|
33
|
+
),
|
|
34
|
+
},
|
|
35
|
+
# --- Domain C: Advisory Sequence Scans (RuleEngine, 9 scanners) ---------
|
|
36
|
+
{
|
|
37
|
+
"check_id": "polya",
|
|
38
|
+
"display_name": "PolyA-like motifs",
|
|
39
|
+
"primary_domain": "advisory_scan",
|
|
40
|
+
"order": 2,
|
|
41
|
+
"default_enabled": True,
|
|
42
|
+
"enforcement_per_path": {
|
|
43
|
+
"bare_optimizer": "advisory_only",
|
|
44
|
+
"pipeline_default": "advisory_only",
|
|
45
|
+
"benchmark_scoring": "not_included",
|
|
46
|
+
},
|
|
47
|
+
"presentation": {"web": {"visible": True, "default_status_when_not_executed": None}},
|
|
48
|
+
"claim_boundary": "Advisory finding, not a guarantee of expression impact.",
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"check_id": "are",
|
|
52
|
+
"display_name": "AU-rich elements (ARE)",
|
|
53
|
+
"primary_domain": "advisory_scan",
|
|
54
|
+
"order": 3,
|
|
55
|
+
"default_enabled": True,
|
|
56
|
+
"enforcement_per_path": {
|
|
57
|
+
"bare_optimizer": "advisory_only",
|
|
58
|
+
"pipeline_default": "advisory_only",
|
|
59
|
+
"benchmark_scoring": "not_included",
|
|
60
|
+
},
|
|
61
|
+
"presentation": {"web": {"visible": True, "default_status_when_not_executed": None}},
|
|
62
|
+
"claim_boundary": "Advisory finding.",
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"check_id": "at_runs",
|
|
66
|
+
"display_name": "AT-rich runs",
|
|
67
|
+
"primary_domain": "advisory_scan",
|
|
68
|
+
"order": 4,
|
|
69
|
+
"default_enabled": True,
|
|
70
|
+
"enforcement_per_path": {
|
|
71
|
+
"bare_optimizer": "advisory_only",
|
|
72
|
+
"pipeline_default": "advisory_only",
|
|
73
|
+
"benchmark_scoring": "not_included",
|
|
74
|
+
},
|
|
75
|
+
"presentation": {"web": {"visible": True, "default_status_when_not_executed": None}},
|
|
76
|
+
"claim_boundary": "Advisory finding.",
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"check_id": "homopolymers",
|
|
80
|
+
"display_name": "Homopolymer runs (synthesis risk)",
|
|
81
|
+
"primary_domain": "advisory_scan",
|
|
82
|
+
"order": 5,
|
|
83
|
+
"default_enabled": True,
|
|
84
|
+
"enforcement_per_path": {
|
|
85
|
+
"bare_optimizer": "advisory_only",
|
|
86
|
+
"pipeline_default": "advisory_only",
|
|
87
|
+
"benchmark_scoring": "not_included",
|
|
88
|
+
},
|
|
89
|
+
"presentation": {"web": {"visible": True, "default_status_when_not_executed": None}},
|
|
90
|
+
"claim_boundary": (
|
|
91
|
+
"Synthesis-difficulty advisory, distinct from the separate expression-stability "
|
|
92
|
+
"homopolymer threshold used in the unrelated/archived utils/validation.py path."
|
|
93
|
+
),
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"check_id": "repeats",
|
|
97
|
+
"display_name": "Tandem / perfect repeats",
|
|
98
|
+
"primary_domain": "advisory_scan",
|
|
99
|
+
"order": 6,
|
|
100
|
+
"default_enabled": True,
|
|
101
|
+
"enforcement_per_path": {
|
|
102
|
+
"bare_optimizer": "advisory_only",
|
|
103
|
+
"pipeline_default": "advisory_only",
|
|
104
|
+
"benchmark_scoring": "not_included",
|
|
105
|
+
},
|
|
106
|
+
"presentation": {"web": {"visible": True, "default_status_when_not_executed": None}},
|
|
107
|
+
"claim_boundary": "Advisory finding.",
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"check_id": "gc_extremes",
|
|
111
|
+
"display_name": "Local GC extremes (sliding window)",
|
|
112
|
+
"primary_domain": "advisory_scan",
|
|
113
|
+
"order": 7,
|
|
114
|
+
"default_enabled": True,
|
|
115
|
+
"enforcement_per_path": {
|
|
116
|
+
"bare_optimizer": "advisory_only",
|
|
117
|
+
"pipeline_default": "advisory_only",
|
|
118
|
+
"benchmark_scoring": "not_included",
|
|
119
|
+
},
|
|
120
|
+
"presentation": {"web": {"visible": True, "default_status_when_not_executed": None}},
|
|
121
|
+
"claim_boundary": "Local synthesis-hostile GC extremes, NOT the global GC optimization target.",
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
"check_id": "splice_sites",
|
|
125
|
+
"display_name": "Cryptic splice-site-like motifs",
|
|
126
|
+
"primary_domain": "advisory_scan",
|
|
127
|
+
"order": 8,
|
|
128
|
+
"default_enabled": True,
|
|
129
|
+
"enforcement_per_path": {
|
|
130
|
+
"bare_optimizer": "advisory_only",
|
|
131
|
+
"pipeline_default": "advisory_only",
|
|
132
|
+
"benchmark_scoring": "not_included",
|
|
133
|
+
},
|
|
134
|
+
"presentation": {"web": {"visible": True, "default_status_when_not_executed": None}},
|
|
135
|
+
"claim_boundary": (
|
|
136
|
+
"Advisory pattern-match finding, low severity by default — not a validated "
|
|
137
|
+
"splicing prediction."
|
|
138
|
+
),
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"check_id": "dinucleotides",
|
|
142
|
+
"display_name": "CpG / TpA dinucleotide density",
|
|
143
|
+
"primary_domain": "advisory_scan",
|
|
144
|
+
"order": 9,
|
|
145
|
+
"default_enabled": True,
|
|
146
|
+
"enforcement_per_path": {
|
|
147
|
+
"bare_optimizer": "advisory_only",
|
|
148
|
+
"pipeline_default": "advisory_only",
|
|
149
|
+
"benchmark_scoring": "not_included",
|
|
150
|
+
},
|
|
151
|
+
"presentation": {"web": {"visible": True, "default_status_when_not_executed": None}},
|
|
152
|
+
"claim_boundary": "Advisory finding.",
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
"check_id": "rare_codon_runs",
|
|
156
|
+
"display_name": "Rare-codon runs",
|
|
157
|
+
"primary_domain": "advisory_scan",
|
|
158
|
+
"order": 10,
|
|
159
|
+
"default_enabled": True,
|
|
160
|
+
"enforcement_per_path": {
|
|
161
|
+
"bare_optimizer": "advisory_only",
|
|
162
|
+
"pipeline_default": "advisory_only",
|
|
163
|
+
"benchmark_scoring": "not_included",
|
|
164
|
+
},
|
|
165
|
+
"presentation": {"web": {"visible": True, "default_status_when_not_executed": None}},
|
|
166
|
+
"claim_boundary": "Advisory finding, not a validated translation-rate measurement.",
|
|
167
|
+
},
|
|
168
|
+
# --- Domain D: Assembly Review -------------------------------------------
|
|
169
|
+
{
|
|
170
|
+
"check_id": "restriction_sites",
|
|
171
|
+
"display_name": "Restriction Site Check (Type IIS)",
|
|
172
|
+
"primary_domain": "assembly_review",
|
|
173
|
+
"order": 11,
|
|
174
|
+
"default_enabled": True,
|
|
175
|
+
"enforcement_per_path": {
|
|
176
|
+
"bare_optimizer": "not_checked",
|
|
177
|
+
"pipeline_default": "hard_fail_raise_if_unfixable",
|
|
178
|
+
"benchmark_scoring": "component_of_assembly_pass_soft",
|
|
179
|
+
},
|
|
180
|
+
"presentation": {"web": {"visible": True, "default_status_when_not_executed": None}},
|
|
181
|
+
"claim_boundary": (
|
|
182
|
+
"Same biological check enforced at TWO different strengths: production pipeline "
|
|
183
|
+
"raises and halts; benchmark scoring records a soft boolean."
|
|
184
|
+
),
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
"check_id": "moclo_overhang",
|
|
188
|
+
"display_name": "MoClo Level-0 overhang validity",
|
|
189
|
+
"primary_domain": "assembly_review",
|
|
190
|
+
"order": 12,
|
|
191
|
+
"default_enabled": False,
|
|
192
|
+
"enforcement_per_path": {
|
|
193
|
+
"bare_optimizer": "not_checked",
|
|
194
|
+
"pipeline_default": "opt_in_non_gating",
|
|
195
|
+
"benchmark_scoring": "not_included",
|
|
196
|
+
},
|
|
197
|
+
"presentation": {"web": {"visible": True, "default_status_when_not_executed": "NOT_RUN"}},
|
|
198
|
+
"claim_boundary": (
|
|
199
|
+
"MUST be described as a non-gating, opt-in advisory check. It is not run by "
|
|
200
|
+
"default, and even when run it never blocks a result — unlike restriction_sites, "
|
|
201
|
+
"which can halt the pipeline."
|
|
202
|
+
),
|
|
203
|
+
},
|
|
204
|
+
# --- Domain A: Sequence Integrity (hard, gates pipeline via raise) ------
|
|
205
|
+
{
|
|
206
|
+
"check_id": "aa_identity",
|
|
207
|
+
"display_name": "Amino-acid identity",
|
|
208
|
+
"primary_domain": "integrity",
|
|
209
|
+
"order": 13,
|
|
210
|
+
"default_enabled": True,
|
|
211
|
+
"enforcement_per_path": {
|
|
212
|
+
"bare_optimizer": "not_checked",
|
|
213
|
+
"pipeline_default": "hard_fail_raise",
|
|
214
|
+
"benchmark_scoring": "component_of_biological_pass_soft",
|
|
215
|
+
},
|
|
216
|
+
"presentation": {"web": {"visible": False, "default_status_when_not_executed": None}},
|
|
217
|
+
"claim_boundary": "Hard structural validity check, not a biological-risk prediction.",
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
"check_id": "internal_stop",
|
|
221
|
+
"display_name": "Internal stop codons",
|
|
222
|
+
"primary_domain": "integrity",
|
|
223
|
+
"order": 14,
|
|
224
|
+
"default_enabled": True,
|
|
225
|
+
"enforcement_per_path": {
|
|
226
|
+
"bare_optimizer": "not_checked",
|
|
227
|
+
"pipeline_default": "hard_fail_raise_via_final_validation",
|
|
228
|
+
"benchmark_scoring": "component_of_biological_pass_soft",
|
|
229
|
+
},
|
|
230
|
+
"presentation": {"web": {"visible": False, "default_status_when_not_executed": None}},
|
|
231
|
+
"claim_boundary": "Hard structural validity check.",
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
"check_id": "invalid_codon",
|
|
235
|
+
"display_name": "Invalid / partial codons",
|
|
236
|
+
"primary_domain": "integrity",
|
|
237
|
+
"order": 15,
|
|
238
|
+
"default_enabled": True,
|
|
239
|
+
"enforcement_per_path": {
|
|
240
|
+
"bare_optimizer": "not_checked",
|
|
241
|
+
"pipeline_default": "hard_fail_raise_via_final_validation",
|
|
242
|
+
"benchmark_scoring": "component_of_biological_pass_soft",
|
|
243
|
+
},
|
|
244
|
+
"presentation": {"web": {"visible": False, "default_status_when_not_executed": None}},
|
|
245
|
+
"claim_boundary": "Hard structural validity check.",
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
"check_id": "frame_length",
|
|
249
|
+
"display_name": "Reading-frame / length consistency",
|
|
250
|
+
"primary_domain": "integrity",
|
|
251
|
+
"order": 16,
|
|
252
|
+
"default_enabled": True,
|
|
253
|
+
"enforcement_per_path": {
|
|
254
|
+
"bare_optimizer": "not_checked",
|
|
255
|
+
"pipeline_default": "implicit_validator_stage",
|
|
256
|
+
"benchmark_scoring": "component_of_biological_pass_soft",
|
|
257
|
+
},
|
|
258
|
+
"presentation": {"web": {"visible": False, "default_status_when_not_executed": None}},
|
|
259
|
+
"claim_boundary": "Hard structural validity check.",
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
"check_id": "custom_forbidden_motifs",
|
|
263
|
+
"display_name": "User-configured forbidden motifs",
|
|
264
|
+
"primary_domain": "configured_constraint",
|
|
265
|
+
"order": 17,
|
|
266
|
+
"default_enabled": False,
|
|
267
|
+
"enforcement_per_path": {
|
|
268
|
+
"bare_optimizer": "not_wired",
|
|
269
|
+
"pipeline_default": "not_wired",
|
|
270
|
+
"benchmark_scoring": "not_wired",
|
|
271
|
+
},
|
|
272
|
+
"presentation": {"web": {"visible": False, "default_status_when_not_executed": None}},
|
|
273
|
+
"claim_boundary": (
|
|
274
|
+
"MUST NOT be described as an active product feature. Implemented in a "
|
|
275
|
+
"legacy/archived code path, not connected to the current optimize()/pipeline()/"
|
|
276
|
+
"CLI/API surface at the pinned commit."
|
|
277
|
+
),
|
|
278
|
+
},
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
REVIEW_CONTRACT_CHECK_IDS: tuple[str, ...] = (
|
|
282
|
+
"polya",
|
|
283
|
+
"are",
|
|
284
|
+
"at_runs",
|
|
285
|
+
"homopolymers",
|
|
286
|
+
"repeats",
|
|
287
|
+
"gc_extremes",
|
|
288
|
+
"splice_sites",
|
|
289
|
+
"dinucleotides",
|
|
290
|
+
"rare_codon_runs",
|
|
291
|
+
"restriction_sites",
|
|
292
|
+
"moclo_overhang",
|
|
293
|
+
)
|
|
294
|
+
|
|
295
|
+
PUBLIC_VALIDATION_BADGE_IDS: tuple[str, ...] = ("global_gc_range",) + REVIEW_CONTRACT_CHECK_IDS
|
|
296
|
+
|
|
297
|
+
LEGACY_VALIDATION_FIELD_MAP: dict[str, str] = {
|
|
298
|
+
"polya": "polya",
|
|
299
|
+
"gc": "global_gc_range",
|
|
300
|
+
# validation.moclo carries the Type IIS restriction-site result, NOT
|
|
301
|
+
# moclo_overhang.
|
|
302
|
+
"moclo": "restriction_sites",
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
_CHECKS_BY_ID: dict[str, dict[str, Any]] = {check["check_id"]: check for check in VALIDATION_CHECKS}
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
def get_check(check_id: str) -> dict[str, Any]:
|
|
309
|
+
"""Return the registry entry for `check_id`.
|
|
310
|
+
|
|
311
|
+
Raises:
|
|
312
|
+
KeyError: If `check_id` is not in the registry.
|
|
313
|
+
"""
|
|
314
|
+
return _CHECKS_BY_ID[check_id]
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
def public_badge_checks() -> list[dict[str, Any]]:
|
|
318
|
+
"""Return the 12 public-badge checks, sorted by registry `order`."""
|
|
319
|
+
return sorted(
|
|
320
|
+
(check for check in VALIDATION_CHECKS if check["check_id"] in PUBLIC_VALIDATION_BADGE_IDS),
|
|
321
|
+
key=lambda check: check["order"],
|
|
322
|
+
)
|