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
5 changes: 4 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 result-quality-filter synthetic-result-policy-check calibration-decision-checklist calibration-rollback-plan simulation-registry validate-simulation-result-schema simulation-baseline-check adapter-gate-check simulation-provenance simulation-ensemble-check simulation-ci-report simulation-deprecation-check simulation-scope-check simulation-evidence-packet artifact-version candidate-manifest artifact-changelog integration-check adapter-author-check license-check artifact-compat-check contribution-check adoption-scorecard release-gate-check decision-log release-request-check coi-check rotation-plan-check security-report-check citation-check roadmap-sync-check advisory-review-check annual-review-check selection-rationale-check batch-priority-check pilot-package-check calibration-intake-check uncertainty-report-check preprint-bundle-check reproducibility-manifest-check candidate-summary-card-check multi-candidate-comparison-check pipeline-decision-audit-check dataset-release-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 synthetic-result-policy-check calibration-decision-checklist calibration-rollback-plan simulation-registry validate-simulation-result-schema simulation-baseline-check adapter-gate-check simulation-provenance simulation-ensemble-check simulation-ci-report simulation-deprecation-check simulation-scope-check simulation-evidence-packet artifact-version candidate-manifest artifact-changelog integration-check adapter-author-check license-check artifact-compat-check contribution-check adoption-scorecard release-gate-check decision-log release-request-check coi-check rotation-plan-check security-report-check citation-check roadmap-sync-check advisory-review-check annual-review-check selection-rationale-check batch-priority-check pilot-package-check calibration-intake-check uncertainty-report-check preprint-bundle-check reproducibility-manifest-check candidate-summary-card-check multi-candidate-comparison-check pipeline-decision-audit-check claim-to-evidence-check dataset-release-check

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 @@ -936,6 +936,9 @@ pipeline-decision-audit-check:
--entry-json '{"audit_id":"AUD-001","batch_id":"BATCH-001","pipeline_version":"0.8.9","decision_date":"2026-07-09","decision_type":"filter_applied","decision_description":"Applied hemolysis fraction filter at threshold 0.15.","rationale":"Threshold pre-specified in BENCHMARK_GOVERNANCE.md based on Wave 0 data.","alternatives_considered":["threshold 0.10","threshold 0.20"],"affected_candidate_count":47,"evidence_level":4,"pre_specified":true,"reviewer":"alice","dry_lab_only":true}' \
--format text

claim-to-evidence-check:
.venv/bin/openamp-foundry claim-to-evidence-check --entry-json '{"mapping_id":"CEM-001","batch_id":"BATCH-001","pipeline_version":"0.9.0","claim_text":"Test claim","claim_type":"activity_prediction","supporting_artifact_ids":["CERT-001","SEL-001"],"evidence_level":3,"pre_specified":true,"reviewer":"test@example.com","dry_lab_only":true}' --format text

dataset-release-check:
.venv/bin/openamp-foundry dataset-release-check \
--entry-json '{"release_id":"DSR-001","dataset_name":"OpenAMP Wave 0.5 Candidates","dataset_version":"1.0.0","release_date":"2026-07-09","license_identifier":"CC-BY-4.0","data_sources":["UniProt AMP database","APD3","in-house pipeline"],"contains_sequences":true,"contains_activity_data":false,"dual_use_assessed":true,"usage_policy_url":"https://openamp.example.org/data-policy","contact_email":"data@openamp.example.org","release_approved":true,"dry_lab_only":true}' \
Expand Down
62 changes: 62 additions & 0 deletions docs/evidence/CLAIM_TO_EVIDENCE_GUIDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Claim-to-Evidence Mapper Guide

## Purpose

The claim-to-evidence mapper records which artifacts support each scientific
claim made by the pipeline. Every claim must trace to at least one artifact.
External auditors use this map to verify that claims are not free-floating.

## Schema Fields

| Field | Type | Description |
|---|---|---|
| mapping_id | str | Unique identifier (prefix "CEM-") |
| batch_id | str | Batch this mapping belongs to |
| pipeline_version | str | Pipeline version string |
| claim_text | str | The claim being made (max 500 chars) |
| claim_type | str | Category of claim (see valid types) |
| supporting_artifact_ids | list[str] | IDs of artifacts that support this claim |
| evidence_level | int | 1–6 evidence hierarchy level |
| pre_specified | bool | True if claim was pre-specified before analysis |
| reviewer | str | Reviewer who validated this mapping |
| dry_lab_only | bool | Always True for computational claims |

## Valid Claim Types

- `activity_prediction` — predicted antimicrobial activity
- `calibration_statement` — statements about model calibration
- `novelty_claim` — claim about sequence novelty vs. known AMPs
- `performance_comparison` — comparison against a baseline or benchmark
- `reproducibility_claim` — claim that results can be reproduced
- `safety_assessment` — claims about toxicity/hemolysis/dual-use risk
- `selection_rationale` — rationale for selecting a candidate

## Validation Rules

1. mapping_id must start with "CEM-"
2. claim_text must not be empty and must not exceed 500 characters
3. claim_type must be one of the valid types listed above
4. supporting_artifact_ids must contain at least 1 artifact ID
5. evidence_level must be between 1 and 6
6. reviewer must not be empty
7. dry_lab_only must be True (computational claims only)

## Warning Conditions

- Post-hoc claim: pre_specified=False → warn that claim may be exploratory
- Weak evidence: evidence_level <= 2 → warn that evidence is limited
- Single artifact: exactly 1 supporting artifact → warn to seek corroboration
- Long claim text: claim_text > 300 chars → warn for conciseness

## Honest Use Boundary

A claim-to-evidence mapping records the *computational* support for a claim.
It does not imply biological validity. Claims mapped here are dry-lab outputs
only. Do not use this schema to record claims from wet-lab experiments.

## CLI Usage

```bash
openamp-foundry claim-to-evidence-check --entry-json '{"mapping_id": "CEM-001", ...}' --format text
openamp-foundry claim-to-evidence-check --entry-json '{"mapping_id": "CEM-001", ...}' --format json
```
3 changes: 2 additions & 1 deletion 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 M M1 — pipeline decision audit entry schema — v0.8.9)
> **Last updated:** 2026-07-09 (Phase M M2 — claim-to-evidence mapper schema — v0.9.0)
> **New in v0.9.0:** Claim-to-evidence mapper schema (M2 — Loop 129) — docs/evidence/CLAIM_TO_EVIDENCE_GUIDE.md with purpose, schema fields table (10 fields), valid claim types (7), validation rules (7), warning conditions (4), honest-use boundary, CLI usage. src/openamp_foundry/evidence/claim_to_evidence_mapper.py with ClaimToEvidenceEntry dataclass (10 fields: mapping_id, batch_id, pipeline_version, claim_text, claim_type, supporting_artifact_ids, evidence_level, pre_specified, reviewer, dry_lab_only=True), ClaimToEvidenceResult dataclass (7 fields: mapping_id, batch_id, claim_type, passed, errors, warnings, dry_lab_only=True), VALID_CLAIM_TYPES (7: activity_prediction, calibration_statement, novelty_claim, performance_comparison, reproducibility_claim, safety_assessment, selection_rationale), VALID_EVIDENCE_LEVELS (6: 1-6), MAX_CLAIM_TEXT_LENGTH (500), LONG_CLAIM_TEXT_THRESHOLD (300), WEAK_EVIDENCE_THRESHOLD (2), validate_claim_to_evidence() (7 error checks: CEM- prefix, non-empty claim_text<=500 chars, valid claim_type, non-empty supporting_artifact_ids, valid evidence_level 1-6, non-empty reviewer, dry_lab_only must be True; 4 warning conditions: post-hoc, weak evidence, single artifact, long claim text), validate_claim_to_evidence_dict() (9 required fields guard). CLI (openamp-foundry claim-to-evidence-check) with --entry-json, --format text|json. make claim-to-evidence-check target. Phase M M2: every scientific claim is now machine-mapped to its supporting artifacts for external audit.
> **New in v0.8.9:** Pipeline decision audit entry schema (M1 — Loop 128) — docs/evidence/PIPELINE_DECISION_AUDIT_GUIDE.md with purpose, required field table (13 fields), valid decision types (7), warnings, validation workflow, honest-use boundary. src/openamp_foundry/evidence/pipeline_decision_audit.py with PipelineDecisionAuditEntry dataclass (13 fields: audit_id, batch_id, pipeline_version, decision_date, decision_type, decision_description, rationale, alternatives_considered, affected_candidate_count, evidence_level, pre_specified, reviewer, dry_lab_only), PipelineDecisionAuditResult dataclass (5 fields: audit_id, batch_id, decision_type, passed, errors, warnings, dry_lab_only=True), VALID_DECISION_TYPES (7: benchmark_updated, calibration_adjusted, candidate_ranked, candidate_rejected, filter_applied, safety_flag_applied, threshold_chosen), VALID_EVIDENCE_LEVELS (6: 1-6), MAX_DESCRIPTION_LENGTH (500), MAX_RATIONALE_LENGTH (1000), validate_pipeline_decision_audit() (12 checks: AUD- prefix, non-empty batch_id/pipeline_version/reviewer, YYYY-MM-DD decision_date, valid decision_type, non-empty description<=500 chars, non-empty rationale<=1000 chars, affected_candidate_count>=0, valid evidence_level, dry_lab_only must be True; post-hoc warns, empty alternatives warns, low evidence warns, zero affected warns), validate_pipeline_decision_audit_dict() (12 required fields guard). CLI (openamp-foundry pipeline-decision-audit-check) with --entry-json, --format text|json. make pipeline-decision-audit-check target. Phase M M1: every pipeline decision is now machine-validated and traceable for external audit.
> **New in v0.8.8:** Dataset release package checker (L5 — Loop 127) — docs/evidence/DATASET_RELEASE_GUIDE.md with purpose, required field table (13 fields), valid license identifiers (5), warnings, validation workflow, honest-use boundary. src/openamp_foundry/evidence/dataset_release.py with DatasetReleaseEntry dataclass (13 fields: release_id, dataset_name, dataset_version, release_date, license_identifier, data_sources, contains_sequences, contains_activity_data, dual_use_assessed, usage_policy_url, contact_email, release_approved, dry_lab_only), DatasetReleaseResult dataclass (4 fields: release_id, dataset_name, passed, errors, warnings, dry_lab_only=True), VALID_LICENSE_IDENTIFIERS (5: Apache-2.0, CC-BY-4.0, CC-BY-NC-4.0, CC0-1.0, MIT), MINIMUM_DATA_SOURCES (1), validate_dataset_release() (11 checks: DSR- prefix, non-empty dataset_name/dataset_version/usage_policy_url/contact_email, YYYY-MM-DD release_date, valid license_identifier, data_sources>=1, dual_use_assessed must be True, release_approved must be True, dry_lab_only must be True; CC-BY-NC-4.0 warns, single source warns), validate_dataset_release_dict() (12 required fields guard). CLI (openamp-foundry dataset-release-check) with --entry-json, --format text|json. make dataset-release-check target. Phase L L5 completes Phase L: open dataset releases now have machine-validated data governance checks.
> **New in v0.8.7:** Multi-candidate comparison schema (L4 — Loop 126b) — docs/evidence/MULTI_CANDIDATE_COMPARISON_GUIDE.md with purpose, required field table (11 fields), minimum requirements (2 candidates, 2 criteria), warnings, validation workflow, honest-use boundary. src/openamp_foundry/evidence/multi_candidate_comparison.py with MultiCandidateComparisonEntry dataclass (11 fields: comparison_id, batch_id, pipeline_version, comparison_date, candidate_ids, comparison_criteria, top_candidate_id, top_candidate_rationale, evidence_level, reviewer, dry_lab_only), MultiCandidateComparisonResult dataclass (5 fields: comparison_id, batch_id, candidate_count, passed, errors, warnings, dry_lab_only=True), MINIMUM_CANDIDATES (2), MINIMUM_CRITERIA (2), RECOMMENDED_CRITERIA (3), MAX_RATIONALE_LENGTH (500), LARGE_CANDIDATE_SET_THRESHOLD (10), VALID_EVIDENCE_LEVELS (6: 1-6), validate_multi_candidate_comparison() (11 checks: CMP- prefix, non-empty batch_id/pipeline_version/reviewer, YYYY-MM-DD comparison_date, candidate_ids>=2, comparison_criteria>=2, top_candidate_id in candidate_ids, non-empty rationale<=500 chars, valid evidence_level, dry_lab_only must be True; evidence_level<=2 warns, candidate_count>10 warns, criteria_count<3 warns), validate_multi_candidate_comparison_dict() (10 required fields guard). CLI (openamp-foundry multi-candidate-comparison-check) with --entry-json, --format text|json. make multi-candidate-comparison-check target. Phase L L4: side-by-side candidate comparisons are now machine-validated for publication-ready supplementary tables.
Expand Down
2 changes: 1 addition & 1 deletion docs/research/NEXT_100_PR_MAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ Make every pipeline decision traceable, independently verifiable, and resistant
| PR | Task | Why it matters | Review class |
|---:|---|---|---|
| M1 | Add pipeline decision audit entry schema (complete — Loop 128). | Records filter/threshold/rank decisions with rationale for external audit. | B |
| M2 | Add claim-to-evidence mapper schema. | Maps each scientific claim to the artifact that supports it. | B |
| M2 | Add claim-to-evidence mapper schema (complete — Loop 129). | Maps each scientific claim to the artifact that supports it. | B |
| M3 | Add score decomposition report schema. | Documents how composite scores are computed from components. | B |
| M4 | Add reviewer briefing package checker. | One-stop summary that external reviewers need before auditing. | B |
| M5 | Add audit chain completeness checker. | Validates the evidence chain has no gaps from sequences to submission. | B/D |
Expand Down
6 changes: 6 additions & 0 deletions docs/research/ROADMAP.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Roadmap

### v0.9.0 — Phase M M2: Claim-to-Evidence Mapper
- Added `ClaimToEvidenceEntry` schema mapping each claim to supporting artifacts
- 7 valid claim types; 4 warning conditions for exploratory or weakly-evidenced claims
- CLI: `openamp-foundry claim-to-evidence-check`
- 50 tests; all passing

### v0.8.9
- Phase M M1: pipeline decision audit entry schema — records each filter/threshold/rank decision with rationale and alternatives considered for external audit. PipelineDecisionAuditEntry dataclass, validate_pipeline_decision_audit(), CLI pipeline-decision-audit-check.

Expand Down
33 changes: 33 additions & 0 deletions src/openamp_foundry/cli/commands/reports.py
Original file line number Diff line number Diff line change
Expand Up @@ -3192,3 +3192,36 @@ def _run_pipeline_decision_audit_check(args: argparse.Namespace) -> int:
print(" Pipeline decision audit validated. Decision is traceable and reviewable.")

return 0 if result.passed else 3


def _run_claim_to_evidence_check(args: argparse.Namespace) -> int:
import json as _json
from openamp_foundry.evidence.claim_to_evidence_mapper import validate_claim_to_evidence_dict

try:
d = _json.loads(args.entry_json)
except _json.JSONDecodeError as exc:
print(_json.dumps({"status": "error", "error": f"Invalid JSON: {exc}"}))
return 2

if not isinstance(d, dict):
print(_json.dumps({"status": "error", "error": "--entry-json must be a JSON object"}))
return 2

result = validate_claim_to_evidence_dict(d)
output_format = getattr(args, "format", "text")

if output_format == "json":
import dataclasses
print(_json.dumps(dataclasses.asdict(result), indent=2))
else:
status = "PASS" if result.passed else "FAIL"
print(f"[{status}] Claim-to-Evidence Check: {result.mapping_id}")
for e in result.errors:
print(f" ERROR: {e}")
for w in result.warnings:
print(f" WARN: {w}")
if result.passed:
print(" Claim-to-evidence mapping validated. Claim is traceable to supporting artifacts.")

return 0 if result.passed else 3
Loading
Loading