Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: help demo test lint ci clean bench-leakage bench-multi-negatives bench-baseline bench-hidden-active bench-cluster-split bench-expert-ablation bench-expert-ablation-500 bench-selectivity bench-feature-decomp bench-gate bench-easy-baseline bench-charge-matched bench-order-dependent bench-precision-at-k bench-per-family bench-simulation-ablation bench-simulation-ablation-within-amp simulation-gate bench-strategy-compare regenerate-all generate phase3 pilot validate-scoring validate-scoring-phase3 validate-scoring-strict external-pilot pilot-confident presynth-qc gold-standard diversity synthesis-order novelty-broad external-consensus questionnaire gate-check ip-report benchmark-card wave0-5-gate-check wave0-5-novelty-audit wave0-5-novelty-audit-v2 wave0-5-panel wave0-5-evidence wave0-5-fill-external wave0-5b-generate wave0-5b-filter recalibration-engine recalibration-engine-dry-run validate-policy-version generate-synthetic-lab-results bump-policy-version generate-review-packet failed-candidate-report safe-publication-filter classify-negative-informativeness validate-rejection-events negative-result-dashboard calibration-audit calibration-audit-example calibration-overfit-check
.PHONY: help demo test lint ci clean bench-leakage bench-multi-negatives bench-baseline bench-hidden-active bench-cluster-split bench-expert-ablation bench-expert-ablation-500 bench-selectivity bench-feature-decomp bench-gate bench-easy-baseline bench-charge-matched bench-order-dependent bench-precision-at-k bench-per-family bench-simulation-ablation bench-simulation-ablation-within-amp simulation-gate bench-strategy-compare regenerate-all generate phase3 pilot validate-scoring validate-scoring-phase3 validate-scoring-strict external-pilot pilot-confident presynth-qc gold-standard diversity synthesis-order novelty-broad external-consensus questionnaire gate-check ip-report benchmark-card wave0-5-gate-check wave0-5-novelty-audit wave0-5-novelty-audit-v2 wave0-5-panel wave0-5-evidence wave0-5-fill-external wave0-5b-generate wave0-5b-filter recalibration-engine recalibration-engine-dry-run validate-policy-version generate-synthetic-lab-results bump-policy-version generate-review-packet failed-candidate-report safe-publication-filter classify-negative-informativeness validate-rejection-events negative-result-dashboard calibration-audit calibration-audit-example calibration-overfit-check result-quality-filter

PYTHON := $(shell [ -f .venv/bin/python ] && echo .venv/bin/python || echo python3)
PYTEST := $(shell [ -f .venv/bin/pytest ] && echo .venv/bin/pytest || echo pytest)
Expand Down Expand Up @@ -678,3 +678,10 @@ calibration-overfit-check:
--cohort-sizes 8,25,50 --model-params 10 --n-features 5 \
--out-json /tmp/overfit_check.json --out-md /tmp/overfit_check.md
@echo "Overfit check complete. See /tmp/overfit_check.json"

result-quality-filter:
echo '[{"candidate_id":"AMP001","flags":[]},{"candidate_id":"AMP002","flags":["contamination"]},{"candidate_id":"AMP003","flags":["replicate_disagreement","borderline_threshold"]}]' > /tmp/rq_input.json
.venv/bin/openamp-foundry result-quality-filter \
--results-json /tmp/rq_input.json \
--out-json /tmp/rq_output.json --out-md /tmp/rq_output.md
@echo "Result quality filter done. See /tmp/rq_output.json"
5 changes: 3 additions & 2 deletions docs/evidence/METRICS_CURRENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ Machine-readable snapshot: `outputs/metrics_snapshot.json` regenerated with `mak
> **Purpose:** One authoritative table of current pipeline metrics. If any doc disagrees
> with this file, this file wins. Updated whenever benchmark/benchmark config changes.
>
> **Last updated:** 2026-07-09 (Phase G G6 — calibration-overfit warning — v0.5.84)
> **Last updated:** 2026-07-09 (Phase G G7 — result-quality flag propagation — v0.5.85)
> **New in v0.5.85:** Result-quality flag propagation (G7) — `assess_result_quality()` and `filter_results_for_calibration()` propagate result-quality flags into the calibration engine. Candidates with contamination or assay interference are excluded; candidates with 2+ quality flags are excluded; candidates with 1 flag are included with caution; clean candidates are fully included. `QUALITY_FLAGS` dictionary (8 flags). `ResultQualityReport` dataclass. CLI (`openamp-foundry result-quality-filter`) accepts `--results-json`, `--out-json`, `--out-md`. JSON + Markdown output. Schema (`schemas/result_quality_report.schema.json`). `make result-quality-filter` target. 27 tests. 3022 total.
> **New in v0.5.84:** Calibration-overfit warning (G6) — `check_cohort_overfit_risk()` and `run_overfit_check()` flag when a calibration cohort is too small relative to model parameters. Warns at three severity levels (critical/warning/caution/none). CLI (`openamp-foundry calibration-overfit-check`) accepts comma-separated cohort sizes, model params, n features. JSON + Markdown output. Schema (`schemas/calibration_overfit_check.schema.json`). `make calibration-overfit-check` target. 21 tests. 2995 total.
> **New in v0.5.83:** Batch-2 selection rationale report (G5) — CLI (`openamp-foundry batch-rationale`) that generates a synthetic candidate pool, runs the batch-2 selector with configurable weights, and produces a per-candidate rationale report classifying each selected candidate into exploit / explore / diversity / combined roles. Reports weight configuration, role breakdown summary, per-candidate contributions (ensemble×weight, uncertainty×weight, diversity×weight), safety gate impact, and caveats. Schema (`schemas/batch_rationale_report.schema.json`). `make batch-rationale` target. 19 tests. 2974 total.
> **New in v0.5.82:** Active-learning strategy comparison report (G4) — CLI (`openamp-foundry bench strategy-compare`) that compares 5 selection strategies (exploitation, exploration, diversity, combined, random) on the same synthetic pool with identical hidden active candidates. Each strategy runs multi-round recovery of hidden actives; the report ranks strategies by recall, compares the production selector vs pure strategies and random baseline, and produces structured JSON + Markdown output with caveats. Prevents one-selector bias by making strategy performance transparent. Schema (`schemas/active_learning_strategy_comparison.schema.json`). `make bench-strategy-compare` target. 18 tests. 2955 total.
Expand Down Expand Up @@ -76,7 +77,7 @@ Machine-readable snapshot: `outputs/metrics_snapshot.json` regenerated with `mak
> **New in v0.5.31:** Added dipeptide-order features for sequence-order awareness. `dipeptide_order_score` achieves AUROC 0.7861 on AMP-vs-scrambled discrimination — the strongest order-dependent feature in the pipeline. Only 7/31 features survive scrambling (amphipathicity/helix-wheel + dipeptide). All composition features are purely position-independent (exactly 0.5000 AUROC on scrambled test).
> **New in v0.5.30:** Easy baseline benchmark added — charge density alone (AUROC 0.8166) outperforms the full pipeline ensemble (0.7792) on AMP-vs-Swiss-Prot-decoy discrimination. Honest finding documented: expected because pipeline optimizes for safety, not raw discrimination.
> **New in v0.5.29:** Expanded benchmark to 500 AMPs + 500 composition-matched decoys (n=1000). AUROC 0.7792 (CI₉₅: 0.7505–0.8065) confirms signal generalizes. Cluster-aware CI: 0.746–0.8102. Representative AUROC: 0.778. Standard benchmark (n=191) retained for backward comparison.
> **Pipeline version:** v0.5.84 (G6)
> **Pipeline version:** v0.5.85 (G7)
> **Branch:** main

---
Expand Down
50 changes: 50 additions & 0 deletions docs/research/ROADMAP.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,55 @@
# Roadmap

## v0.5.85 — Loop 85: Phase G G7 — Result-Quality Flag Propagation into Calibration Engine ✓ (2026-07-09)

`assess_result_quality()` and `filter_results_for_calibration()` propagate
result-quality flags into the calibration engine. Low-quality outcomes cannot
drive updates — garbage results must not update the scoring model.

Changes:
- `src/openamp_foundry/calibration/result_quality.py` (G7) — Core module with
`QUALITY_FLAGS` dictionary (8 standard flags), `EXCLUDED_FLAGS` set
(contamination, assay_interference), `ResultQualityReport` dataclass (7 fields:
candidate_id, flags, quality_level, can_drive_update, propagation_action,
explanation, dry_lab_only), `assess_result_quality()` applying multi-tier rules
(excluded flags → excluded, 2+ minor flags → low/excluded, 1 flag → acceptable,
0 flags → high), `filter_results_for_calibration()` grouping results into
included/included_with_caution/excluded with summary counts,
`write_result_quality_json()` and `write_result_quality_markdown()` for output.
- `schemas/result_quality_report.schema.json` (G7) — JSON Schema Draft 07 for
per-candidate or aggregate result quality reports. Validates all 7 required
fields including flag enum constraint and dry_lab_only const=true.
- `src/openamp_foundry/calibration/__init__.py` — Exports all result-quality
symbols.
- `src/openamp_foundry/cli/commands/reports.py` — Added `_run_result_quality_filter()`
CLI handler with `--results-json`, `--out-json`, `--out-md` flags.
- `src/openamp_foundry/cli/main.py` — Registered `result-quality-filter` subcommand
with all argument flags and dispatch to handler.
- `Makefile` — Added `result-quality-filter` target with default example data writing
to `/tmp/rq_output.json` and `/tmp/rq_output.md`. Added to `.PHONY`.
- `tests/calibration/test_result_quality.py` — 27 tests covering: high quality (no
flags), contamination excluded, assay_interference excluded, 2 minor flags excluded
(low quality), 1 minor flag include_with_caution, can_drive_update True/False for
all quality levels, dry_lab_only always True, unknown flag raises ValueError,
explanation non-empty, to_dict output, contamination+other flags still excluded,
assay_interference+other flags still excluded, filter_results_for_calibration
empty/summary counts/per-action grouping/can_drive_update_count, missing flags
handling, EXCLUDED_FLAGS set, QUALITY_FLAGS descriptions and count.
- `docs/evidence/METRICS_CURRENT.md` — v0.5.85 G7 changelog. Test count: 3022.
- `tests/test_test_count_regression.py` — baseline updated to 3022.

Honest boundaries:
- Quality assessment is a computational filter on structural and metadata criteria.
A "high quality" result does not confirm biological activity.
- Flag-based classification uses a pre-defined rule set. Edge cases (e.g.,
borderline_threshold with ambiguous_activity) are treated the same as any
other 2-flag combination — excluded for caution.
- Excluded results may still contain useful scientific information and should
remain available for expert review.
- The `dry_lab_only=True` constraint is an attestation, not a technical proof.
- All calibration decisions require qualified human review regardless of
result quality assessment.

## v0.5.84 — Loop 84: Phase G G6 — Calibration-Overfit Warning for Small Cohorts ✓ (2026-07-09)

`check_cohort_overfit_risk()` and `run_overfit_check()` flag when a calibration
Expand Down
63 changes: 63 additions & 0 deletions schemas/result_quality_report.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://openamp.ai/schemas/result_quality_report.schema.json",
"title": "Result Quality Report",
"description": "Schema for a result quality assessment report. Dry-lab only — does not measure biological activity.",
"type": "object",
"properties": {
"candidate_id": {
"type": "string",
"description": "Identifier for the candidate peptide."
},
"flags": {
"type": "array",
"items": {
"type": "string",
"enum": [
"low_sample_quality",
"assay_interference",
"ambiguous_activity",
"contamination",
"protocol_deviation",
"borderline_threshold",
"replicate_disagreement",
"missing_negative_control"
]
},
"description": "Quality flags assigned to this result."
},
"quality_level": {
"type": "string",
"enum": ["high", "acceptable", "low", "excluded"],
"description": "Overall quality assessment level."
},
"can_drive_update": {
"type": "boolean",
"description": "Whether this result may drive a calibration update."
},
"propagation_action": {
"type": "string",
"enum": ["include", "include_with_caution", "exclude"],
"description": "Propagation action for the calibration engine."
},
"explanation": {
"type": "string",
"description": "Human-readable explanation of the quality assessment."
},
"dry_lab_only": {
"type": "boolean",
"description": "Always true. This is a computational assessment, not biological proof.",
"const": true
}
},
"required": [
"candidate_id",
"flags",
"quality_level",
"can_drive_update",
"propagation_action",
"explanation",
"dry_lab_only"
],
"additionalProperties": false
}
16 changes: 16 additions & 0 deletions src/openamp_foundry/calibration/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,15 @@
auto_increment_version,
)

from openamp_foundry.calibration.result_quality import (
QUALITY_FLAGS,
ResultQualityReport,
assess_result_quality,
filter_results_for_calibration,
write_result_quality_json,
write_result_quality_markdown,
)

__all__ = [
# Constants
"MIN_COHORT_SIZE",
Expand Down Expand Up @@ -120,4 +129,11 @@
"run_overfit_check",
"write_overfit_check_json",
"write_overfit_check_markdown",
# Result quality
"QUALITY_FLAGS",
"ResultQualityReport",
"assess_result_quality",
"filter_results_for_calibration",
"write_result_quality_json",
"write_result_quality_markdown",
]
Loading
Loading