Skip to content

Commit b34619c

Browse files
committed
[fix.pose.λ.D8+] preserve atom-pair evidence through campaign projections
The prepared pose objects contained exact nearest, contact, and clash atom-pair witnesses, but the campaign preparation response and prepared-system listing projected only scalar summaries. The reviewer therefore correctly refused otherwise valid live 1CBS poses because it could not see server evidence. Carry the complete server pose report through both projections, require its geometry and atom-pair fields in the public system-list contract, and make pose acceptance independently reject a missing nearest-pair witness. This keeps the visible human review and the server execution gate on the same evidence object.
1 parent a3c2179 commit b34619c

3 files changed

Lines changed: 35 additions & 1 deletion

File tree

‎backend/motif/rbfe_references.py‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1076,6 +1076,7 @@ def list_systems(self, actor: dict[str, str],
10761076
"core_coverage": pose.get("pose_report", {}).get("minimum_bidirectional_coverage"),
10771077
"minimum_heavy_atom_distance_angstrom": pose.get("pose_report", {}).get("minimum_heavy_atom_distance_angstrom"),
10781078
"protein_contacts_within_6_angstrom": pose.get("pose_report", {}).get("protein_contacts_within_6_angstrom"),
1079+
"pose_report": pose.get("pose_report"),
10791080
"coordinate_artifact_ref": pose.get("coordinate_artifact_ref"),
10801081
"review_state": pose_state,
10811082
})
@@ -1934,6 +1935,7 @@ def prepare_campaign(self, payload: dict, store,
19341935
"core_coverage": pose["report"]["minimum_bidirectional_coverage"],
19351936
"minimum_heavy_atom_distance_angstrom": pose["report"]["minimum_heavy_atom_distance_angstrom"],
19361937
"protein_contacts_within_6_angstrom": pose["report"]["protein_contacts_within_6_angstrom"],
1938+
"pose_report": pose["report"],
19371939
"coordinate_artifact_ref": _artifact_ref(artifact),
19381940
"review_state": "pending",
19391941
})
@@ -2158,6 +2160,7 @@ def accept_poses(self, payload: dict, actor: dict[str, str]) -> dict:
21582160
"reviewed pose ref digest does not match the registered object")
21592161
report = pose.get("pose_report") or {}
21602162
if (report.get("geometry_gate") != "passed"
2163+
or not isinstance(report.get("nearest_pair_witness"), dict)
21612164
or float(report.get("core_rmsd_angstrom", 999)) > 1.0
21622165
or float(report.get("minimum_bidirectional_coverage", 0)) < .5
21632166
or float(report.get(

‎backend/tests/test_rbfe_public_contracts.py‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,17 @@ def test_system_list_items_have_one_exact_scientific_scope_contract():
282282
"core_rmsd_angstrom": None, "core_coverage": None,
283283
"minimum_heavy_atom_distance_angstrom": None,
284284
"protein_contacts_within_6_angstrom": None,
285+
"pose_report": {
286+
"geometry_gate": "passed",
287+
"nearest_pair_witness": {"distance_angstrom": 2.5},
288+
"contact_cutoff_angstrom": 6.0,
289+
"contact_pair_total": 1,
290+
"contact_pair_witnesses": [{"distance_angstrom": 2.5}],
291+
"hard_clash_cutoff_angstrom": 1.5,
292+
"hard_clash_pair_total": 0,
293+
"hard_clash_pair_witnesses": [],
294+
"pair_witness_limit": 32,
295+
},
285296
"coordinate_artifact_ref": None, "review_state": "pending",
286297
}],
287298
}
@@ -308,6 +319,13 @@ def test_system_list_items_have_one_exact_scientific_scope_contract():
308319
invalid_scope = json.loads(json.dumps(output))
309320
invalid_scope["systems"][0]["campaign_scope"] = "stale"
310321
assert list(validator_for(schema).iter_errors(invalid_scope))
322+
missing_pose_evidence = json.loads(json.dumps(output))
323+
del missing_pose_evidence["systems"][0]["poses"][0]["pose_report"]
324+
assert list(validator_for(schema).iter_errors(missing_pose_evidence))
325+
missing_nearest_pair = json.loads(json.dumps(output))
326+
del missing_nearest_pair["systems"][0]["poses"][0]["pose_report"][
327+
"nearest_pair_witness"]
328+
assert list(validator_for(schema).iter_errors(missing_nearest_pair))
311329

312330

313331
def test_import_and_all_runset_outputs_require_scientific_currency_and_exact_execution_refs():

‎contracts/commands/registry.json‎

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,14 +389,27 @@
389389
"preparation_state": {"enum": ["server-attested", "import-required"]},
390390
"claim_boundary": {"type": "string", "minLength": 1},
391391
"poses": {"type": "array", "items": {"type": "object", "additionalProperties": false,
392-
"required": ["pose_ref", "label", "canonical_smiles", "core_rmsd_angstrom", "core_coverage", "minimum_heavy_atom_distance_angstrom", "protein_contacts_within_6_angstrom", "coordinate_artifact_ref", "review_state"],
392+
"required": ["pose_ref", "label", "canonical_smiles", "core_rmsd_angstrom", "core_coverage", "minimum_heavy_atom_distance_angstrom", "protein_contacts_within_6_angstrom", "pose_report", "coordinate_artifact_ref", "review_state"],
393393
"properties": {
394394
"pose_ref": {"type": "object"}, "label": {"type": "string", "minLength": 1},
395395
"canonical_smiles": {"type": "string", "minLength": 1},
396396
"core_rmsd_angstrom": {"type": ["number", "null"]},
397397
"core_coverage": {"type": ["number", "null"]},
398398
"minimum_heavy_atom_distance_angstrom": {"type": ["number", "null"]},
399399
"protein_contacts_within_6_angstrom": {"type": ["integer", "null"], "minimum": 0},
400+
"pose_report": {"type": "object", "additionalProperties": true,
401+
"required": ["geometry_gate", "nearest_pair_witness", "contact_cutoff_angstrom", "contact_pair_total", "contact_pair_witnesses", "hard_clash_cutoff_angstrom", "hard_clash_pair_total", "hard_clash_pair_witnesses", "pair_witness_limit"],
402+
"properties": {
403+
"geometry_gate": {"const": "passed"},
404+
"nearest_pair_witness": {"type": "object", "minProperties": 1},
405+
"contact_cutoff_angstrom": {"type": "number", "exclusiveMinimum": 0},
406+
"contact_pair_total": {"type": "integer", "minimum": 1},
407+
"contact_pair_witnesses": {"type": "array", "minItems": 1, "items": {"type": "object", "minProperties": 1}},
408+
"hard_clash_cutoff_angstrom": {"type": "number", "exclusiveMinimum": 0},
409+
"hard_clash_pair_total": {"const": 0},
410+
"hard_clash_pair_witnesses": {"type": "array", "maxItems": 0},
411+
"pair_witness_limit": {"type": "integer", "minimum": 1}
412+
}},
400413
"coordinate_artifact_ref": {"type": ["object", "null"]},
401414
"review_state": {"type": "string", "minLength": 1}
402415
}}

0 commit comments

Comments
 (0)