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
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,12 @@ bench-strategy-compare:
--out-json outputs/strategy_comparison.json \
--out-md outputs/strategy_comparison.md

batch-rationale:
PYTHONPATH=src $(PYTHON) -m openamp_foundry.cli batch-rationale \
--n-total 50 --n-active 10 --batch-size 10 \
--out-json outputs/batch_rationale_report.json \
--out-md outputs/batch_rationale_report.md

bench-cross-dataset:
PYTHONPATH=src $(PYTHON) scripts/benchmarks/benchmark_cross_dataset.py \
--out outputs/cross_dataset_benchmark.json
Expand Down
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 G4 — active-learning strategy comparison report — v0.5.82)
> **Last updated:** 2026-07-09 (Phase G G5 — batch-2 selection rationale report — v0.5.83)
> **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.
> **New in v0.5.81:** Calibration pipeline consistency audit (G3) — CLI (`openamp-foundry calibration-audit`) that checks consistency across calibration pipeline artifacts (intake report, gate verdict, engine proposal, recalibration report). Checks intake↔gate count matching, engine↔gate verdict agreement, engine L1 budget compliance, report↔gate verdict consistency, report↔engine proposal consistency, timestamp sanity, and cohort-metrics warnings. Schema (`schemas/calibration_audit.schema.json`). `make calibration-audit` and `make calibration-audit-example` targets. 18 tests. 2937 total.
> **New in v0.5.80:** Negative-result archive completeness checker (F10) — CLI (`scripts/check_negative_archive_completeness.py`) that reads a JSON archive of negative-result entries and checks each entry against completeness criteria: all required fields present, no duplicate candidate_ids, each entry has at least one content field (assay_result, score_safety, reviewer_notes, or reason_detail), date format valid YYYY-MM-DD, and optional intake_report_id references are well-formed. Outputs a structured completeness report as JSON and Markdown with summary, per-check results, and per-entry pass/fail. Schema (`schemas/negative_result_archive_completeness.schema.json`). Example file (`examples/negative_result_archive_example.json`) with 4 toy entries. 35 tests. 2919 total.
Expand Down Expand Up @@ -74,7 +75,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.82 (G4)
> **Pipeline version:** v0.5.83 (G5)
> **Branch:** main

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

## v0.5.83 — Loop 83: Phase G G5 — Batch-2 Selection Rationale Report ✓ (2026-07-09)

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. Report includes weight configuration, role breakdown
summary, per-candidate contribution detail (ensemble×weight, uncertainty×weight,
diversity×weight), safety gate impact, and caveats. Enables reviewers to
understand why each candidate was selected in terms of the three active-learning
roles.

Changes:
- `src/openamp_foundry/active_learning/batch_rationale.py` (G5) —
`build_batch_rationale_report()` generates a synthetic pool, runs
`select_batch_2` with configurable weights, classifies each selected candidate
into exploit/explore/diversity/combined roles based on which weight
contribution dominates (threshold: > 0.05 above second-place), and produces a
`BatchRationaleReport` with per-candidate rationales, role summary, and
selector metadata. `PerCandidateRationale` dataclass tracks scores,
contributions, safety gate status, and human-readable explanation.
`write_rationale_json()` and `write_rationale_markdown()` produce structured
output.
- `schemas/batch_rationale_report.schema.json` (G5) — JSON Schema Draft 2020-12
for the batch-2 rationale report. Validates all required fields including
per-candidate rationales, role summary, role descriptions, selected IDs,
and notes.
- `src/openamp_foundry/active_learning/__init__.py` — Exports
`BatchRationaleReport`, `PerCandidateRationale`, `build_batch_rationale_report`,
`write_rationale_json`, `write_rationale_markdown`.
- `src/openamp_foundry/cli/main.py` — Registered `batch-rationale` subcommand
with all argument flags and dispatch to `_run_batch_rationale`.
- `src/openamp_foundry/cli/commands/selection.py` — Added
`_run_batch_rationale()` CLI handler with `--n-total`, `--n-active`,
`--batch-size`, `--safety-threshold`, `--selectivity-threshold`,
`--ensemble-weight`, `--uncertainty-weight`, `--diversity-weight`,
`--min-uncertainty-probes`, `--rng-seed`, `--out-json`, `--out-md` flags.
- `Makefile` — Added `batch-rationale` target with default params writing to
`outputs/batch_rationale_report.json` and `outputs/batch_rationale_report.md`.
- `tests/active_learning/test_batch_rationale.py` — 19 tests covering: all
required top-level fields, candidates selected, per-candidate required fields,
valid role (exploit/explore/diversity/combined), scores in [0,1], role summary
counts match candidates, selected IDs match candidate IDs, probes non-negative,
notes present, weight config matches input, JSON and Markdown output writing,
CLI exit 0, CLI writes files, JSON Schema conformance, high exploitation weight
produces more exploit roles, all candidates have explanations with role mention,
role descriptions present for all roles, empty roles not in summary.
- `docs/evidence/METRICS_CURRENT.md` — v0.5.83 G5 changelog. Test count: 2974.
- `tests/test_test_count_regression.py` — baseline updated to 2974.

Honest boundaries:
- This report uses **synthetic data** with known labels. Results reflect
code-path integrity, not biological performance.
- Role classification is based solely on weight contributions. A candidate
classified as "exploit" may also have meaningful uncertainty or diversity
signal — the role label is the dominant contribution, not an exclusive
category.
- The threshold (> 0.05 above second-place) is an arbitrary cutoff; candidates
near the boundary are classified as "combined" to avoid false precision.
- The production selector optimises for multiple objectives (activity, safety,
diversity) that a single-role label does not fully capture.
- This report is informational and requires qualified human review before
influencing selection decisions.

## v0.5.82 — Loop 82: Phase G G4 — Active-Learning Strategy Comparison Report ✓ (2026-07-09)

CLI (`openamp-foundry bench strategy-compare`) that compares 5 selection strategies
Expand Down
137 changes: 137 additions & 0 deletions schemas/batch_rationale_report.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openamp.ai/schemas/batch_rationale_report.schema.json",
"title": "Batch-2 Selection Rationale Report",
"description": "Report explaining why each candidate was selected in batch-2, decomposing selection into exploit, explore, and diversity roles. All fields are computational results — not biological evidence.",
"type": "object",
"required": [
"version",
"pool_size",
"n_requested",
"n_selected",
"n_after_safety_gate",
"n_gated_out",
"ensemble_weight",
"uncertainty_weight",
"diversity_weight",
"candidates",
"role_summary",
"role_descriptions",
"selected_ids",
"probes_in_top_n",
"notes"
],
"properties": {
"version": {
"type": "string",
"description": "Schema/report version."
},
"pool_size": {
"type": "integer",
"minimum": 1,
"description": "Total number of candidates in the pool."
},
"n_requested": {
"type": "integer",
"minimum": 0,
"description": "Number of candidates requested for batch-2."
},
"n_selected": {
"type": "integer",
"minimum": 0,
"description": "Number of candidates actually selected."
},
"n_after_safety_gate": {
"type": "integer",
"minimum": 0,
"description": "Number of candidates remaining after safety gating."
},
"n_gated_out": {
"type": "integer",
"minimum": 0,
"description": "Number of candidates blocked by safety/selectivity gate."
},
"ensemble_weight": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Weight for ensemble score in selection."
},
"uncertainty_weight": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Weight for uncertainty score in selection."
},
"diversity_weight": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Weight for diversity score in selection."
},
"candidates": {
"type": "array",
"description": "Per-candidate selection rationales.",
"items": {
"type": "object",
"required": [
"candidate_id",
"role",
"ensemble_score",
"uncertainty_score",
"diversity_score",
"ensemble_contribution",
"uncertainty_contribution",
"diversity_contribution",
"combined_score",
"passed_safety_gate",
"safety_gate_reason",
"explanation"
],
"properties": {
"candidate_id": { "type": "string" },
"role": {
"type": "string",
"enum": ["exploit", "explore", "diversity", "combined"]
},
"ensemble_score": { "type": "number", "minimum": 0, "maximum": 1 },
"uncertainty_score": { "type": "number", "minimum": 0, "maximum": 1 },
"diversity_score": { "type": "number", "minimum": 0, "maximum": 1 },
"ensemble_contribution": { "type": "number", "minimum": 0, "maximum": 1 },
"uncertainty_contribution": { "type": "number", "minimum": 0, "maximum": 1 },
"diversity_contribution": { "type": "number", "minimum": 0, "maximum": 1 },
"combined_score": { "type": "number", "minimum": 0, "maximum": 1 },
"passed_safety_gate": { "type": "boolean" },
"safety_gate_reason": { "type": "string" },
"explanation": { "type": "string" }
}
}
},
"role_summary": {
"type": "object",
"description": "Count of candidates per role.",
"additionalProperties": { "type": "integer", "minimum": 0 }
},
"role_descriptions": {
"type": "object",
"description": "Descriptions for each role.",
"additionalProperties": { "type": "string" }
},
"selected_ids": {
"type": "array",
"description": "IDs of selected candidates.",
"items": { "type": "string" }
},
"probes_in_top_n": {
"type": "integer",
"minimum": 0,
"description": "Number of uncertainty probes placed in the top-n."
},
"notes": {
"type": "array",
"description": "Human-readable notes and caveats.",
"items": { "type": "string" }
}
},
"_caveat": "This report is a computational decomposition of selection rationale on synthetic data. It is not biological evidence of sampling efficiency, candidate quality, or real-world selection performance."
}
12 changes: 12 additions & 0 deletions src/openamp_foundry/active_learning/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@
BatchSelection,
select_batch_2,
)
from openamp_foundry.active_learning.batch_rationale import (
BatchRationaleReport,
PerCandidateRationale,
build_batch_rationale_report,
write_rationale_json,
write_rationale_markdown,
)
from openamp_foundry.active_learning.strategy_comparison import (
STRATEGY_WEIGHTS,
StrategyComparisonReport,
Expand All @@ -40,16 +47,21 @@

__all__ = [
"ActiveLearningBenchmarkResult",
"BatchRationaleReport",
"BatchSelection",
"PerCandidateRationale",
"RecoveryRound",
"STRATEGY_WEIGHTS",
"StrategyComparisonReport",
"StrategyResult",
"build_batch_rationale_report",
"generate_benchmark_pool",
"run_active_learning_benchmark",
"run_strategy_comparison",
"select_batch_2",
"write_benchmark_pool",
"write_comparison_json",
"write_comparison_markdown",
"write_rationale_json",
"write_rationale_markdown",
]
Loading
Loading