diff --git a/benchmarks/corpus/morocco/preflight-v0.1/ACQUISITION-CONSTRAINTS-v0.1.json b/benchmarks/corpus/morocco/preflight-v0.1/ACQUISITION-CONSTRAINTS-v0.1.json new file mode 100644 index 0000000..faabc2a --- /dev/null +++ b/benchmarks/corpus/morocco/preflight-v0.1/ACQUISITION-CONSTRAINTS-v0.1.json @@ -0,0 +1,11 @@ +{ + "document_id": "OAM-MOROCCO-ACQUISITION-CONSTRAINTS-v0.1", + "status": "ENGINEERING_CLASSIFICATIONS_NOT_LEGAL_OPINIONS", + "no_source_bytes_acquired": true, + "constraints": [ + {"scope": "TGR_PDF_SOURCES", "disposition": "LINK_AND_RECEIPT_ONLY", "robots_observation": "No automated crawl executed", "authentication": "None observed", "visible_download": true, "direct_get": "UNTESTED", "human_download": true, "crawl_required": false, "stability": "UUID paths appear stable but bytes not frozen", "blockers": ["rights review", "redirect receipt", "exact-byte freeze authorization"]}, + {"scope": "CDC_CHALLENGE_HTML", "disposition": "LINK_AND_RECEIPT_ONLY", "robots_observation": "Single public pages observed; no crawl", "authentication": "None", "visible_download": false, "direct_get": true, "human_download": true, "crawl_required": false, "stability": "mutable HTML", "blockers": ["terms review", "immutable capture plan"]}, + {"scope": "PMP_CASE_PAGES_AND_ACTION_DOWNLOADS", "disposition": "LINK_AND_RECEIPT_ONLY", "robots_observation": "Public detail pages observed; no automated crawl or artifact action invoked", "authentication": "Detail pages render unauthenticated; artifact actions not tested", "visible_download": true, "direct_get": "DETAIL_PAGE_YES_ARTIFACT_ENDPOINT_UNRESOLVED", "human_download": true, "crawl_required": false, "stability": "stable refConsultation identity; artifact bytes untested", "blockers": ["dynamic artifact URLs", "rights review", "exact-byte freeze authorization"]} + ], + "prohibited": ["authenticated download", "CAPTCHA bypass", "portal crawl", "source-byte commit", "invented legal clearance"] +} diff --git a/benchmarks/corpus/morocco/preflight-v0.1/ACQUISITION-CONSTRAINTS-v0.1.md b/benchmarks/corpus/morocco/preflight-v0.1/ACQUISITION-CONSTRAINTS-v0.1.md new file mode 100644 index 0000000..e69ad13 --- /dev/null +++ b/benchmarks/corpus/morocco/preflight-v0.1/ACQUISITION-CONSTRAINTS-v0.1.md @@ -0,0 +1,21 @@ +# Morocco Acquisition Constraints v0.1 + +Status: **ENGINEERING_CLASSIFICATIONS_NOT_LEGAL_OPINIONS** + +No source bytes acquired: **YES** + +## Constraints + +| Scope | Disposition | Robots | Authentication | Visible | Direct GET | Human | Crawl | Stability | Blockers | +|---|---|---|---|---|---|---|---|---|---| +| TGR_PDF_SOURCES | LINK_AND_RECEIPT_ONLY | No automated crawl executed | None observed | YES | UNTESTED | YES | NO | UUID paths appear stable but bytes not frozen | rights review; redirect receipt; exact-byte freeze authorization | +| CDC_CHALLENGE_HTML | LINK_AND_RECEIPT_ONLY | Single public pages observed; no crawl | None | NO | YES | YES | NO | mutable HTML | terms review; immutable capture plan | +| PMP_CASE_PAGES_AND_ACTION_DOWNLOADS | LINK_AND_RECEIPT_ONLY | Public detail pages observed; no automated crawl or artifact action invoked | Detail pages render unauthenticated; artifact actions not tested | YES | DETAIL_PAGE_YES_ARTIFACT_ENDPOINT_UNRESOLVED | YES | NO | stable refConsultation identity; artifact bytes untested | dynamic artifact URLs; rights review; exact-byte freeze authorization | + +## Prohibited + +- authenticated download +- CAPTCHA bypass +- portal crawl +- source-byte commit +- invented legal clearance diff --git a/benchmarks/corpus/morocco/preflight-v0.1/MISSION-SELECTION-SCORECARD-v0.1.json b/benchmarks/corpus/morocco/preflight-v0.1/MISSION-SELECTION-SCORECARD-v0.1.json new file mode 100644 index 0000000..f2132dd --- /dev/null +++ b/benchmarks/corpus/morocco/preflight-v0.1/MISSION-SELECTION-SCORECARD-v0.1.json @@ -0,0 +1,83 @@ +{ + "document_id": "OAM-MISSION-SELECTION-SCORECARD-v0.1", + "scale": { + "0": "absent", + "1": "partial_or_uncertain", + "2": "present_and_official" + }, + "mission_selection_status": "PROVISIONAL_UNRECONCILED", + "proposed_mission_id": "MAR-MISSION-001", + "institutional_admission": "NONE", + "golden_mission_status": "NOT_ADMITTED", + "cross_repository_reconciliation_required": true, + "semantic_implementation_gate": "BLOCKED", + "dimensions": [ + "stable_official_identity", + "french_source_availability", + "tender_notice_availability", + "dao_specifications_tor", + "administrative_or_technical_clauses", + "amendment_or_addendum_evidence", + "evaluation_criteria_grid", + "commission_minute_or_extract", + "award_or_result", + "programme_previsionnel_linkage", + "buyer_procedure_value_date_completeness", + "exact_byte_downloadable_artifacts", + "no_login_captcha_access_control", + "tender_evaluation_award_suitability" + ], + "scores": [ + { + "candidate_id": "PMP-CASE-001", + "values": [2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1], + "total": 11, + "mandatory_gate_result": "PASS", + "gate_evidence_reference": "PMP-CASE-001#mandatory_gate", + "nomination": "NOT_SELECTED" + }, + { + "candidate_id": "PMP-CASE-002", + "values": [2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1], + "total": 11, + "mandatory_gate_result": "PASS", + "gate_evidence_reference": "PMP-CASE-002#mandatory_gate", + "nomination": "NOT_SELECTED" + }, + { + "candidate_id": "PMP-CASE-003", + "values": [2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1], + "total": 11, + "mandatory_gate_result": "PASS", + "gate_evidence_reference": "PMP-CASE-003#mandatory_gate", + "nomination": "NOT_SELECTED" + }, + { + "candidate_id": "PMP-CASE-004", + "values": [2, 2, 2, 1, 0, 0, 0, 2, 2, 0, 1, 1, 1, 2], + "total": 16, + "mandatory_gate_result": "PASS", + "gate_evidence_reference": "PMP-CASE-004#mandatory_gate", + "nomination": "PREFERRED_MAR-MISSION-001" + }, + { + "candidate_id": "PMP-CASE-005", + "values": [2, 2, 2, 1, 0, 0, 0, 2, 2, 0, 1, 1, 1, 2], + "total": 16, + "mandatory_gate_result": "PASS", + "gate_evidence_reference": "PMP-CASE-005#mandatory_gate", + "nomination": "FALLBACK" + } + ], + "selection_rule": "Derive the eight mandatory criteria from candidate evidence before scoring. Aggregate score never overrides the mandatory gate. Open state is recorded separately and never counted as award evidence.", + "selection_outcome": "ADMISSIBLE_CASES_FOUND", + "preferred": { + "mission_id": "MAR-MISSION-001", + "candidate_id": "PMP-CASE-004", + "result_linkage_result": "VERIFIED_MATCH" + }, + "fallback": { + "candidate_id": "PMP-CASE-005", + "result_linkage_result": "VERIFIED_MATCH" + } +} diff --git a/benchmarks/corpus/morocco/preflight-v0.1/MISSION-SELECTION-SCORECARD-v0.1.md b/benchmarks/corpus/morocco/preflight-v0.1/MISSION-SELECTION-SCORECARD-v0.1.md new file mode 100644 index 0000000..1a5a32c --- /dev/null +++ b/benchmarks/corpus/morocco/preflight-v0.1/MISSION-SELECTION-SCORECARD-v0.1.md @@ -0,0 +1,33 @@ +# Morocco Mission Selection Scorecard v0.1 + +Scores: 0 absent; 1 partial/uncertain; 2 present and official. + +Mission status: **PROVISIONAL_UNRECONCILED** + +Proposed mission ID: **MAR-MISSION-001** + +Institutional admission: **NONE** + +Golden mission: **NOT_ADMITTED** + +Cross-repository reconciliation required: **YES** + +Semantic implementation gate: **BLOCKED** + +Rule: Derive the eight mandatory criteria from candidate evidence before scoring. Aggregate score never overrides the mandatory gate. Open state is recorded separately and never counted as award evidence. + +## Complete scorecard + +| Candidate | stable_official_identity | french_source_availability | tender_notice_availability | dao_specifications_tor | administrative_or_technical_clauses | amendment_or_addendum_evidence | evaluation_criteria_grid | commission_minute_or_extract | award_or_result | programme_previsionnel_linkage | buyer_procedure_value_date_completeness | exact_byte_downloadable_artifacts | no_login_captcha_access_control | tender_evaluation_award_suitability | Total | Mandatory | Nomination | +|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| +| PMP-CASE-001 | 2 | 2 | 2 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 11 | PASS | NOT_SELECTED | +| PMP-CASE-002 | 2 | 2 | 2 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 11 | PASS | NOT_SELECTED | +| PMP-CASE-003 | 2 | 2 | 2 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 11 | PASS | NOT_SELECTED | +| PMP-CASE-004 | 2 | 2 | 2 | 1 | 0 | 0 | 0 | 2 | 2 | 0 | 1 | 1 | 1 | 2 | 16 | PASS | PREFERRED_MAR-MISSION-001 | +| PMP-CASE-005 | 2 | 2 | 2 | 1 | 0 | 0 | 0 | 2 | 2 | 0 | 1 | 1 | 1 | 2 | 16 | PASS | FALLBACK | + +Outcome: **ADMISSIBLE_CASES_FOUND** + +Preferred: **MAR-MISSION-001 → PMP-CASE-004** + +Fallback: **PMP-CASE-005** diff --git a/benchmarks/corpus/morocco/preflight-v0.1/NORMATIVE-SOURCE-MAP-v0.1.json b/benchmarks/corpus/morocco/preflight-v0.1/NORMATIVE-SOURCE-MAP-v0.1.json new file mode 100644 index 0000000..2e14b40 --- /dev/null +++ b/benchmarks/corpus/morocco/preflight-v0.1/NORMATIVE-SOURCE-MAP-v0.1.json @@ -0,0 +1,59 @@ +{ + "document_id": "OAM-MOROCCO-NORMATIVE-SOURCE-MAP-v0.1", + "status": "PREFLIGHT_NO_LEGAL_INTERPRETATION", + "french_first": true, + "entries": [ + { + "source_id": "MAR-NORM-001", + "role": "PRIMARY_FRENCH_NORMATIVE_CANDIDATE", + "authoritative_for_semantics": "OWNER_AND_LEGAL_CONFIRMATION_REQUIRED", + "relationship": "Decree 2-22-431" + }, + { + "source_id": "MAR-NORM-001-EN", + "role": "UNOFFICIAL_TRANSLATION_COMPANION", + "authoritative_for_semantics": false, + "relationship": "Navigation companion to MAR-NORM-001" + }, + { + "source_id": "MAR-IMPL-001", + "role": "IMPLEMENTING_ORDERS_COMPILATION", + "authoritative_for_semantics": "OWNER_AND_LEGAL_CONFIRMATION_REQUIRED", + "relationship": "Orders expressly cite Decree 2-22-431" + }, + { + "source_id": "MAR-CCAG-001", + "role": "DISCOVERY_CANDIDATE_NOT_APPLICABLE_TO_CURRENT_MISSION", + "authoritative_for_semantics": false, + "relationship": "Works CCAG excluded from the proposed normative corpus because the selected mission is a goods procurement" + }, + { + "source_id": "CDC-CHALLENGE-001", + "role": "MISSION_FRAMING_EN", + "authoritative_for_semantics": false, + "relationship": "Challenge statement, not normative text" + }, + { + "source_id": "CDC-CHALLENGE-001-FR", + "role": "MISSION_FRAMING_FR", + "authoritative_for_semantics": false, + "relationship": "French challenge page, not normative text" + } + ], + "proposed_normative_corpus": [ + "MAR-NORM-001", + "MAR-NORM-001-EN", + "MAR-IMPL-001" + ], + "excluded_from_proposed_normative_corpus": [ + { + "source_id": "MAR-CCAG-001", + "reason": "Procurement-category mismatch: works instrument versus selected goods mission" + } + ], + "unresolved": [ + "Bulletin Officiel chain and amendments", + "Complete implementing-order inventory", + "Applicable official goods instrument, if any, was not identified without policy interpretation" + ] +} diff --git a/benchmarks/corpus/morocco/preflight-v0.1/NORMATIVE-SOURCE-MAP-v0.1.md b/benchmarks/corpus/morocco/preflight-v0.1/NORMATIVE-SOURCE-MAP-v0.1.md new file mode 100644 index 0000000..91be056 --- /dev/null +++ b/benchmarks/corpus/morocco/preflight-v0.1/NORMATIVE-SOURCE-MAP-v0.1.md @@ -0,0 +1,34 @@ +# Morocco Normative Source Map v0.1 + +Status: **PREFLIGHT_NO_LEGAL_INTERPRETATION** + +No legal meaning or applicability conclusion is expressed. + +## Map + +| ID | Role | Authoritative | Relationship | +|---|---|---|---| +| MAR-NORM-001 | PRIMARY_FRENCH_NORMATIVE_CANDIDATE | OWNER_AND_LEGAL_CONFIRMATION_REQUIRED | Decree 2-22-431 | +| MAR-NORM-001-EN | UNOFFICIAL_TRANSLATION_COMPANION | NO | Navigation companion to MAR-NORM-001 | +| MAR-IMPL-001 | IMPLEMENTING_ORDERS_COMPILATION | OWNER_AND_LEGAL_CONFIRMATION_REQUIRED | Orders expressly cite Decree 2-22-431 | +| MAR-CCAG-001 | DISCOVERY_CANDIDATE_NOT_APPLICABLE_TO_CURRENT_MISSION | NO | Works CCAG excluded from the proposed normative corpus because the selected mission is a goods procurement | +| CDC-CHALLENGE-001 | MISSION_FRAMING_EN | NO | Challenge statement, not normative text | +| CDC-CHALLENGE-001-FR | MISSION_FRAMING_FR | NO | French challenge page, not normative text | + +## Proposed normative corpus + +- MAR-NORM-001 +- MAR-NORM-001-EN +- MAR-IMPL-001 + +## Excluded discovery candidates + +| ID | Reason | +|---|---| +| MAR-CCAG-001 | Procurement-category mismatch: works instrument versus selected goods mission | + +## Unresolved + +- Bulletin Officiel chain and amendments +- Complete implementing-order inventory +- Applicable official goods instrument, if any, was not identified without policy interpretation diff --git a/benchmarks/corpus/morocco/preflight-v0.1/OFFICIAL-SOURCE-REGISTER-v0.1.json b/benchmarks/corpus/morocco/preflight-v0.1/OFFICIAL-SOURCE-REGISTER-v0.1.json new file mode 100644 index 0000000..51d9cb1 --- /dev/null +++ b/benchmarks/corpus/morocco/preflight-v0.1/OFFICIAL-SOURCE-REGISTER-v0.1.json @@ -0,0 +1,224 @@ +{ + "document_id": "OAM-MOROCCO-OFFICIAL-SOURCE-REGISTER-v0.1", + "status": "PREFLIGHT_ONLY_NO_BYTES_ACQUIRED", + "observed_utc": "2026-07-31T20:49:46Z", + "permitted_domains": ["tgr.gov.ma", "marchespublics.gov.ma", "sgg.gov.ma", "courdescomptes.ma", "govtech.trustvalley.swiss", "worldbank.org"], + "engineering_dispositions": ["PUBLIC_REPO_BYTES_CANDIDATE", "LOCAL_REAL_BYTES_HASHED", "LINK_AND_RECEIPT_ONLY", "BLOCKED_TECHNICALLY", "BLOCKED_ACCESS_CONTROL", "UNRESOLVED"], + "sources": [ + { + "source_id": "MAR-NORM-001", + "complete_title": "Décret n° 2-22-431 du 15 chaabane 1444 (8 mars 2023) relatif aux marchés publics — édition française 2023", + "issuing_authority": "Chef du Gouvernement; publication hosted by Trésorerie Générale du Royaume", + "canonical_url": "https://www.tgr.gov.ma/wps/portal/Textes%20reglementaires/Marches%20publics/Textes%20legislatifs/Decrets/", + "download_url": "https://www.tgr.gov.ma/wps/wcm/connect/1f3081fc-2d01-41de-8339-9a2c7de0480f/DECRET%2B2-22-431%2BFR.pdf?MOD=AJPERES", + "language": "fr", + "authority_rank": "OFFICIAL_GOVERNMENT_HOSTED_NORMATIVE_TEXT", + "publication_or_effective_date": "2023-03-08; portal edition 2023", + "content_type": "application/pdf", + "public_accessibility": "PUBLIC_METADATA_AND_VISIBLE_PDF_LINK", + "login_requirement": "NONE_OBSERVED", + "redirect_behavior": "NOT_BYTE_TESTED_IN_PREFLIGHT", + "expected_byte_format": "PDF", + "translation_status": "ORIGINAL_FRENCH_PUBLICATION", + "proposed_corpus_use": "French-first normative acquisition candidate", + "proposed_storage_disposition": "LINK_AND_RECEIPT_ONLY_PENDING_RIGHTS_AND_BYTE_FREEZE", + "engineering_disposition": "LINK_AND_RECEIPT_ONLY", + "robots_observation": "No crawler execution; single canonical link provenance can be recorded without bypass", + "visible_download_mechanism": true, + "one_direct_get_technically_possible": "UNTESTED", + "human_browser_download_available": true, + "automated_crawling_required": false, + "source_bytes_appear_stable": "LIKELY_UUID_PATH_NOT_VERIFIED", + "provenance_without_bypass": true, + "acquisition_risks": ["Rights and redistribution not reviewed", "Redirect and exact bytes not frozen"], + "unresolved_issues": ["Confirm authoritative publication relationship to Bulletin Officiel before acquisition"] + }, + { + "source_id": "MAR-NORM-001-EN", + "complete_title": "Decree no. 2-22-431 of 15 Chaabane 1444 (8 March 2023) on public procurement", + "issuing_authority": "Trésorerie Générale du Royaume", + "canonical_url": "https://www.tgr.gov.ma/wps/portal/Publication/Brochures%20et%20depliants/", + "download_url": "https://www.tgr.gov.ma/wps/wcm/connect/6afbc2bd-5715-4a68-8afa-0cc19d768173/Decree%2BPublic%2Bprocurement_ENG%2Bversion.pdf?ContentCache=NONE&MOD=AJPERES", + "language": "en", + "authority_rank": "OFFICIAL_GOVERNMENT_HOSTED_COMPANION", + "publication_or_effective_date": "Translation publication date unresolved; underlying decree dated 2023-03-08", + "content_type": "application/pdf", + "public_accessibility": "PUBLIC_METADATA_AND_VISIBLE_PDF_LINK", + "login_requirement": "NONE_OBSERVED", + "redirect_behavior": "NOT_BYTE_TESTED_IN_PREFLIGHT", + "expected_byte_format": "PDF", + "translation_status": "UNOFFICIAL_TRANSLATION_COMPANION", + "proposed_corpus_use": "Non-authoritative English navigation companion only", + "proposed_storage_disposition": "LINK_AND_RECEIPT_ONLY_PENDING_RIGHTS_AND_BYTE_FREEZE", + "engineering_disposition": "LINK_AND_RECEIPT_ONLY", + "robots_observation": "No crawler execution; single canonical link provenance can be recorded without bypass", + "visible_download_mechanism": true, + "one_direct_get_technically_possible": "UNTESTED", + "human_browser_download_available": true, + "automated_crawling_required": false, + "source_bytes_appear_stable": "LIKELY_UUID_PATH_NOT_VERIFIED", + "provenance_without_bypass": true, + "acquisition_risks": ["Must never be promoted to authoritative", "Rights and exact bytes not reviewed"], + "unresolved_issues": ["Publication date and translation provenance need receipt evidence"] + }, + { + "source_id": "MAR-IMPL-001", + "complete_title": "Arrêtés d’application du décret n° 2-22-431 — compilation officielle, édition 2023", + "issuing_authority": "Ministre délégué chargé du budget; hosted by Trésorerie Générale du Royaume", + "canonical_url": "https://www.tgr.gov.ma/wps/portal/Textes%20reglementaires/Marches%20publics/", + "download_url": "https://www.tgr.gov.ma/wps/wcm/connect/69ff3b86-7c5b-46c7-83fb-bce87a5f0774/ARRETE%2Bdecret%2B2-22-431%2BFR.pdf?MOD=AJPERES", + "language": "fr", + "authority_rank": "OFFICIAL_GOVERNMENT_HOSTED_IMPLEMENTING_ORDERS_COMPILATION", + "publication_or_effective_date": "Orders dated 2023-06-09 through 2023-07-03; compilation date unresolved", + "content_type": "application/pdf", + "public_accessibility": "PUBLIC_METADATA_AND_VISIBLE_PDF_LINK", + "login_requirement": "NONE_OBSERVED", + "redirect_behavior": "NOT_BYTE_TESTED_IN_PREFLIGHT", + "expected_byte_format": "PDF", + "translation_status": "ORIGINAL_FRENCH_PUBLICATION", + "proposed_corpus_use": "Implementing-order acquisition candidate; order boundaries must be indexed after byte freeze", + "proposed_storage_disposition": "LINK_AND_RECEIPT_ONLY_PENDING_RIGHTS_AND_BYTE_FREEZE", + "engineering_disposition": "LINK_AND_RECEIPT_ONLY", + "robots_observation": "No crawler execution; direct compilation link found through official index/search", + "visible_download_mechanism": true, + "one_direct_get_technically_possible": "UNTESTED", + "human_browser_download_available": true, + "automated_crawling_required": false, + "source_bytes_appear_stable": "LIKELY_UUID_PATH_NOT_VERIFIED", + "provenance_without_bypass": true, + "acquisition_risks": ["Compilation may contain multiple orders", "Exact order inventory requires non-semantic structural indexing after acquisition authorization"], + "unresolved_issues": ["Confirm complete order list and current amendment status"] + }, + { + "source_id": "MAR-CCAG-001", + "complete_title": "Décret n° 2-14-394 du 6 chaabane 1437 approuvant le cahier des clauses administratives générales applicables aux marchés de travaux", + "issuing_authority": "Chef du Gouvernement; hosted by Trésorerie Générale du Royaume", + "canonical_url": "https://www.tgr.gov.ma/wps/portal/Textes%20reglementaires/Marches%20publics/", + "download_url": "https://www.tgr.gov.ma/wps/wcm/connect/48e2b53e-6fa9-4ee9-a6ae-bbde89b37b6f/2-14-394ccag.pdf?CACHEID=48e2b53e-6fa9-4ee9-a6ae-bbde89b37b6f&MOD=AJPERES", + "language": "fr", + "authority_rank": "OFFICIAL_GOVERNMENT_HOSTED_SECTORAL_TEXT", + "publication_or_effective_date": "2016-05-13; B.O. 6470 dated 2016-06-02", + "content_type": "application/pdf", + "public_accessibility": "PUBLIC_METADATA_AND_VISIBLE_PDF_LINK", + "login_requirement": "NONE_OBSERVED", + "redirect_behavior": "NOT_BYTE_TESTED_IN_PREFLIGHT", + "expected_byte_format": "PDF", + "translation_status": "ORIGINAL_FRENCH_PUBLICATION", + "proposed_corpus_use": "DISCOVERY_CANDIDATE_NOT_APPLICABLE_TO_CURRENT_MISSION; works CCAG excluded from the proposed normative corpus for the selected goods mission", + "proposed_storage_disposition": "LINK_ONLY_NOT_IN_PROPOSED_NORMATIVE_CORPUS", + "engineering_disposition": "LINK_AND_RECEIPT_ONLY", + "robots_observation": "No crawler execution; direct official PDF link is visible", + "visible_download_mechanism": true, + "one_direct_get_technically_possible": "UNTESTED", + "human_browser_download_available": true, + "automated_crawling_required": false, + "source_bytes_appear_stable": "LIKELY_UUID_PATH_NOT_VERIFIED", + "provenance_without_bypass": true, + "acquisition_risks": ["Predates Decree 2-22-431", "Not applicable to the selected goods mission by procurement category"], + "unresolved_issues": ["Current status outside the selected goods mission was not assessed"] + }, + { + "source_id": "CDC-CHALLENGE-001", + "complete_title": "Morocco — Supreme Audit Institution (Cour des Comptes / CDC): Public Procurement Audit Challenge", + "issuing_authority": "Cour des Comptes / CRC with World Bank, SECO and Trust Valley", + "canonical_url": "https://govtech.trustvalley.swiss/challenges/cdc-morocco/", + "download_url": null, + "language": "en", + "authority_rank": "OFFICIAL_PROGRAM_CHALLENGE_PAGE", + "publication_or_effective_date": "Launch 2026-06-26; page states 2026", + "content_type": "text/html", + "public_accessibility": "PUBLIC_HTML", + "login_requirement": "NONE_FOR_VIEWING", + "redirect_behavior": "DIRECT_CANONICAL_PAGE_OBSERVED", + "expected_byte_format": "HTML", + "translation_status": "OFFICIAL_ENGLISH_CHALLENGE_STATEMENT", + "proposed_corpus_use": "Mission framing evidence only; not normative authority", + "proposed_storage_disposition": "LINK_AND_RECEIPT_ONLY", + "engineering_disposition": "LINK_AND_RECEIPT_ONLY", + "robots_observation": "Public page observed through single-page retrieval; no crawl required", + "visible_download_mechanism": false, + "one_direct_get_technically_possible": true, + "human_browser_download_available": true, + "automated_crawling_required": false, + "source_bytes_appear_stable": "HTML_MUTABLE", + "provenance_without_bypass": true, + "acquisition_risks": ["Mutable HTML", "Terms and redistribution not reviewed"], + "unresolved_issues": ["Full challenge-statement link target not acquired"] + }, + { + "source_id": "CDC-CHALLENGE-001-FR", + "complete_title": "Morocco — Cour des Comptes (CDC) : défi contrôle de la commande publique", + "issuing_authority": "Cour des Comptes / CRC avec Banque mondiale, SECO et Trust Valley", + "canonical_url": "https://govtech.trustvalley.swiss/fr/challenges/cdc-morocco/", + "download_url": null, + "language": "fr", + "authority_rank": "OFFICIAL_PROGRAM_CHALLENGE_PAGE", + "publication_or_effective_date": "Lancement 2026-06-26; page states 2026", + "content_type": "text/html", + "public_accessibility": "PUBLIC_HTML", + "login_requirement": "NONE_FOR_VIEWING", + "redirect_behavior": "DIRECT_CANONICAL_PAGE_OBSERVED", + "expected_byte_format": "HTML", + "translation_status": "OFFICIAL_FRENCH_CHALLENGE_STATEMENT", + "proposed_corpus_use": "French-first mission framing evidence only; not normative authority", + "proposed_storage_disposition": "LINK_AND_RECEIPT_ONLY", + "engineering_disposition": "LINK_AND_RECEIPT_ONLY", + "robots_observation": "Public page observed through single-page retrieval; no crawl required", + "visible_download_mechanism": false, + "one_direct_get_technically_possible": true, + "human_browser_download_available": true, + "automated_crawling_required": false, + "source_bytes_appear_stable": "HTML_MUTABLE", + "provenance_without_bypass": true, + "acquisition_risks": ["Mutable HTML", "Terms and redistribution not reviewed"], + "unresolved_issues": ["Full French challenge attachment, if any, not acquired"] + } + ], + "mission_evidence_observations": [ + { + "candidate_id": "PMP-CASE-001", + "consultation_record_url": "https://www.marchespublics.gov.ma/index.php5?orgAcronyme=p8x&page=entreprise.EntrepriseDetailConsultation&refConsultation=1024549", + "verified_tender_artifact_url": "https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDemandeTelechargementDce&refConsultation=1024549&orgAcronyme=p8x", + "verified_commission_artifact_url": null, + "verified_result_artifact_url": null, + "observed_utc": "2026-07-31T20:49:46Z", + "bytes_acquired": false + }, + { + "candidate_id": "PMP-CASE-002", + "consultation_record_url": "https://www.marchespublics.gov.ma/index.php5?orgAcronyme=q1s&page=entreprise.EntrepriseDetailConsultation&refConsultation=1017000", + "verified_tender_artifact_url": "https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDemandeTelechargementDce&refConsultation=1017000&orgAcronyme=q1s", + "verified_commission_artifact_url": null, + "verified_result_artifact_url": null, + "observed_utc": "2026-07-31T20:49:46Z", + "bytes_acquired": false + }, + { + "candidate_id": "PMP-CASE-003", + "consultation_record_url": "https://www.marchespublics.gov.ma/index.php5?orgAcronyme=t5y&page=entreprise.EntrepriseDetailConsultation&refConsultation=1012408", + "verified_tender_artifact_url": "https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDemandeTelechargementDce&refConsultation=1012408&orgAcronyme=t5y", + "verified_commission_artifact_url": null, + "verified_result_artifact_url": null, + "observed_utc": "2026-07-31T20:49:46Z", + "bytes_acquired": false + }, + { + "candidate_id": "PMP-CASE-004", + "consultation_record_url": "https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDetailConsultation&refConsultation=1015612&orgAcronyme=g0u", + "verified_tender_artifact_url": "https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDemandeTelechargementDce&refConsultation=1015612&orgAcronyme=g0u", + "verified_commission_artifact_url": "https://www.marchespublics.gov.ma/index.php?page=entreprise.ExtraitPV&refConsultation=1015612&orgAcronyme=g0u", + "verified_result_artifact_url": "https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDetailConsultation&refConsultation=1029218&orgAcronyme=g0u", + "observed_utc": "2026-07-31T20:49:46Z", + "bytes_acquired": false + }, + { + "candidate_id": "PMP-CASE-005", + "consultation_record_url": "https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDetailConsultation&refConsultation=1010827&orgAcronyme=g0u", + "verified_tender_artifact_url": "https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDemandeTelechargementDce&refConsultation=1010827&orgAcronyme=g0u", + "verified_commission_artifact_url": "https://www.marchespublics.gov.ma/index.php?page=entreprise.ExtraitPV&refConsultation=1010827&orgAcronyme=g0u", + "verified_result_artifact_url": "https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDetailConsultation&refConsultation=1029211&orgAcronyme=g0u", + "observed_utc": "2026-07-31T20:49:46Z", + "bytes_acquired": false + } + ] +} diff --git a/benchmarks/corpus/morocco/preflight-v0.1/OFFICIAL-SOURCE-REGISTER-v0.1.md b/benchmarks/corpus/morocco/preflight-v0.1/OFFICIAL-SOURCE-REGISTER-v0.1.md new file mode 100644 index 0000000..5fc0604 --- /dev/null +++ b/benchmarks/corpus/morocco/preflight-v0.1/OFFICIAL-SOURCE-REGISTER-v0.1.md @@ -0,0 +1,37 @@ +# Morocco Official Source Register v0.1 + +Status: **PREFLIGHT_ONLY_NO_BYTES_ACQUIRED** + +Engineering acquisition classifications only; they are not legal opinions. + +## Sources + +| ID | Title | Authority | Lang | Canonical | Download | Translation | Disposition | +|---|---|---|---|---|---|---|---| +| MAR-NORM-001 | Décret n° 2-22-431 du 15 chaabane 1444 (8 mars 2023) relatif aux marchés publics — édition française 2023 | Chef du Gouvernement; publication hosted by Trésorerie Générale du Royaume | fr | https://www.tgr.gov.ma/wps/portal/Textes%20reglementaires/Marches%20publics/Textes%20legislatifs/Decrets/ | https://www.tgr.gov.ma/wps/wcm/connect/1f3081fc-2d01-41de-8339-9a2c7de0480f/DECRET%2B2-22-431%2BFR.pdf?MOD=AJPERES | ORIGINAL_FRENCH_PUBLICATION | LINK_AND_RECEIPT_ONLY | +| MAR-NORM-001-EN | Decree no. 2-22-431 of 15 Chaabane 1444 (8 March 2023) on public procurement | Trésorerie Générale du Royaume | en | https://www.tgr.gov.ma/wps/portal/Publication/Brochures%20et%20depliants/ | https://www.tgr.gov.ma/wps/wcm/connect/6afbc2bd-5715-4a68-8afa-0cc19d768173/Decree%2BPublic%2Bprocurement_ENG%2Bversion.pdf?ContentCache=NONE&MOD=AJPERES | UNOFFICIAL_TRANSLATION_COMPANION | LINK_AND_RECEIPT_ONLY | +| MAR-IMPL-001 | Arrêtés d’application du décret n° 2-22-431 — compilation officielle, édition 2023 | Ministre délégué chargé du budget; hosted by Trésorerie Générale du Royaume | fr | https://www.tgr.gov.ma/wps/portal/Textes%20reglementaires/Marches%20publics/ | https://www.tgr.gov.ma/wps/wcm/connect/69ff3b86-7c5b-46c7-83fb-bce87a5f0774/ARRETE%2Bdecret%2B2-22-431%2BFR.pdf?MOD=AJPERES | ORIGINAL_FRENCH_PUBLICATION | LINK_AND_RECEIPT_ONLY | +| MAR-CCAG-001 | Décret n° 2-14-394 du 6 chaabane 1437 approuvant le cahier des clauses administratives générales applicables aux marchés de travaux | Chef du Gouvernement; hosted by Trésorerie Générale du Royaume | fr | https://www.tgr.gov.ma/wps/portal/Textes%20reglementaires/Marches%20publics/ | https://www.tgr.gov.ma/wps/wcm/connect/48e2b53e-6fa9-4ee9-a6ae-bbde89b37b6f/2-14-394ccag.pdf?CACHEID=48e2b53e-6fa9-4ee9-a6ae-bbde89b37b6f&MOD=AJPERES | ORIGINAL_FRENCH_PUBLICATION | LINK_AND_RECEIPT_ONLY | +| CDC-CHALLENGE-001 | Morocco — Supreme Audit Institution (Cour des Comptes / CDC): Public Procurement Audit Challenge | Cour des Comptes / CRC with World Bank, SECO and Trust Valley | en | https://govtech.trustvalley.swiss/challenges/cdc-morocco/ | — | OFFICIAL_ENGLISH_CHALLENGE_STATEMENT | LINK_AND_RECEIPT_ONLY | +| CDC-CHALLENGE-001-FR | Morocco — Cour des Comptes (CDC) : défi contrôle de la commande publique | Cour des Comptes / CRC avec Banque mondiale, SECO et Trust Valley | fr | https://govtech.trustvalley.swiss/fr/challenges/cdc-morocco/ | — | OFFICIAL_FRENCH_CHALLENGE_STATEMENT | LINK_AND_RECEIPT_ONLY | + +## Acquisition observations + +| ID | Public | Login | Robots | Direct GET | Human | Crawl | Risks | Unresolved | +|---|---|---|---|---|---|---|---|---| +| MAR-NORM-001 | PUBLIC_METADATA_AND_VISIBLE_PDF_LINK | NONE_OBSERVED | No crawler execution; single canonical link provenance can be recorded without bypass | UNTESTED | YES | NO | Rights and redistribution not reviewed; Redirect and exact bytes not frozen | Confirm authoritative publication relationship to Bulletin Officiel before acquisition | +| MAR-NORM-001-EN | PUBLIC_METADATA_AND_VISIBLE_PDF_LINK | NONE_OBSERVED | No crawler execution; single canonical link provenance can be recorded without bypass | UNTESTED | YES | NO | Must never be promoted to authoritative; Rights and exact bytes not reviewed | Publication date and translation provenance need receipt evidence | +| MAR-IMPL-001 | PUBLIC_METADATA_AND_VISIBLE_PDF_LINK | NONE_OBSERVED | No crawler execution; direct compilation link found through official index/search | UNTESTED | YES | NO | Compilation may contain multiple orders; Exact order inventory requires non-semantic structural indexing after acquisition authorization | Confirm complete order list and current amendment status | +| MAR-CCAG-001 | PUBLIC_METADATA_AND_VISIBLE_PDF_LINK | NONE_OBSERVED | No crawler execution; direct official PDF link is visible | UNTESTED | YES | NO | Predates Decree 2-22-431; Not applicable to the selected goods mission by procurement category | Current status outside the selected goods mission was not assessed | +| CDC-CHALLENGE-001 | PUBLIC_HTML | NONE_FOR_VIEWING | Public page observed through single-page retrieval; no crawl required | YES | YES | NO | Mutable HTML; Terms and redistribution not reviewed | Full challenge-statement link target not acquired | +| CDC-CHALLENGE-001-FR | PUBLIC_HTML | NONE_FOR_VIEWING | Public page observed through single-page retrieval; no crawl required | YES | YES | NO | Mutable HTML; Terms and redistribution not reviewed | Full French challenge attachment, if any, not acquired | + +## Mission evidence observations + +| Candidate | Consultation | Tender artifact | Commission artifact | Result artifact | Observed | Bytes | +|---|---|---|---|---|---|---| +| PMP-CASE-001 | https://www.marchespublics.gov.ma/index.php5?orgAcronyme=p8x&page=entreprise.EntrepriseDetailConsultation&refConsultation=1024549 | https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDemandeTelechargementDce&refConsultation=1024549&orgAcronyme=p8x | — | — | 2026-07-31T20:49:46Z | NO | +| PMP-CASE-002 | https://www.marchespublics.gov.ma/index.php5?orgAcronyme=q1s&page=entreprise.EntrepriseDetailConsultation&refConsultation=1017000 | https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDemandeTelechargementDce&refConsultation=1017000&orgAcronyme=q1s | — | — | 2026-07-31T20:49:46Z | NO | +| PMP-CASE-003 | https://www.marchespublics.gov.ma/index.php5?orgAcronyme=t5y&page=entreprise.EntrepriseDetailConsultation&refConsultation=1012408 | https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDemandeTelechargementDce&refConsultation=1012408&orgAcronyme=t5y | — | — | 2026-07-31T20:49:46Z | NO | +| PMP-CASE-004 | https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDetailConsultation&refConsultation=1015612&orgAcronyme=g0u | https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDemandeTelechargementDce&refConsultation=1015612&orgAcronyme=g0u | https://www.marchespublics.gov.ma/index.php?page=entreprise.ExtraitPV&refConsultation=1015612&orgAcronyme=g0u | https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDetailConsultation&refConsultation=1029218&orgAcronyme=g0u | 2026-07-31T20:49:46Z | NO | +| PMP-CASE-005 | https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDetailConsultation&refConsultation=1010827&orgAcronyme=g0u | https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDemandeTelechargementDce&refConsultation=1010827&orgAcronyme=g0u | https://www.marchespublics.gov.ma/index.php?page=entreprise.ExtraitPV&refConsultation=1010827&orgAcronyme=g0u | https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDetailConsultation&refConsultation=1029211&orgAcronyme=g0u | 2026-07-31T20:49:46Z | NO | diff --git a/benchmarks/corpus/morocco/preflight-v0.1/PMP-MISSION-CANDIDATES-v0.1.json b/benchmarks/corpus/morocco/preflight-v0.1/PMP-MISSION-CANDIDATES-v0.1.json new file mode 100644 index 0000000..52a13af --- /dev/null +++ b/benchmarks/corpus/morocco/preflight-v0.1/PMP-MISSION-CANDIDATES-v0.1.json @@ -0,0 +1,537 @@ +{ + "document_id": "OAM-PMP-MISSION-CANDIDATES-v0.1", + "status": "PUBLIC_PORTAL_EVIDENCE_ONLY_NO_DOWNLOADS", + "observed_utc": "2026-07-31T20:49:46Z", + "observation_method": "READ_ONLY_PUBLIC_PORTAL_INSPECTION_NO_ARTIFACT_DOWNLOAD", + "candidates": [ + { + "candidate_id": "PMP-CASE-001", + "reference": "44/FES/2026", + "public_buyer": "Direction Provinciale du MEN Fès", + "title_fr": "Achat de fournitures de bureau de reprographie et imprimés destinés à la formation continue, aux établissements scolaires et aux services administratifs relevant de la direction provinciale à Fès, en lot unique", + "procurement_category": "GOODS_SUPPLIES", + "procedure_type": "Appel d'offres ouvert", + "publication_date": "2026-07-17", + "submission_deadline": "2026-09-04T10:00:00+01:00", + "official_portal_url": "https://www.marchespublics.gov.ma/index.php5?orgAcronyme=p8x&page=entreprise.EntrepriseDetailConsultation&refConsultation=1024549", + "structured_consultation_record": { + "evidence_id": "PMP-CASE-001-NOTICE", + "language": "fr", + "record_type": "OFFICIAL_STRUCTURED_CONSULTATION_RECORD", + "exact_official_url": "https://www.marchespublics.gov.ma/index.php5?orgAcronyme=p8x&page=entreprise.EntrepriseDetailConsultation&refConsultation=1024549" + }, + "verified_tender_document_artifacts": [ + { + "artifact_id": "PMP-CASE-001-DCE-001", + "artifact_type": "DOSSIER_DE_CONSULTATION_DCE", + "exact_official_url": "https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDemandeTelechargementDce&refConsultation=1024549&orgAcronyme=p8x", + "source_candidate_id": "PMP-CASE-001", + "public_accessibility_state": "PUBLIC_LINK_TO_DOWNLOAD_REQUEST_FORM", + "login_required": false, + "captcha_required": false, + "access_control_bypass_required": false, + "form_submission_required_for_bytes": true, + "observed_utc": "2026-07-31T20:49:46Z", + "distinct_from_structured_consultation_record": true, + "portal_displayed_size": "375.42 KiB", + "bytes_acquired": false + } + ], + "verified_commission_or_evaluation_artifacts": [], + "verified_award_or_result_artifacts": [], + "state": "OPEN_DEADLINE_FUTURE_AT_OBSERVATION", + "explicit_official_current_open_state": true, + "synthetic": false, + "engineering_disposition": "LINK_AND_RECEIPT_ONLY", + "mandatory_gate": { + "eligible": true, + "criteria": { + "stable_official_procurement_reference": {"passed": true, "evidence_refs": ["reference", "official_portal_url"]}, + "official_french_notice_or_consultation_record": {"passed": true, "evidence_refs": ["PMP-CASE-001-NOTICE"]}, + "buyer_and_procedure_metadata": {"passed": true, "evidence_refs": ["public_buyer", "procedure_type"]}, + "verified_real_tender_document_artifact": {"passed": true, "evidence_refs": ["PMP-CASE-001-DCE-001"]}, + "verified_award_or_result_or_explicit_open_state": {"passed": true, "evidence_refs": ["explicit_official_current_open_state"]}, + "no_login_captcha_or_access_control_bypass": {"passed": true, "evidence_refs": ["PMP-CASE-001-DCE-001"]}, + "no_synthetic_object": {"passed": true, "evidence_refs": ["synthetic"]}, + "all_urls_on_permitted_official_domain": {"passed": true, "evidence_refs": ["official_portal_url", "PMP-CASE-001-DCE-001"]} + } + }, + "missing_objects": [ + "DCE contents and specifications not inspected or acquired", + "Administrative and technical clauses not verified", + "Evaluation grid not available", + "Commission minutes and award not available for this open case", + "Programme prévisionnel link not established", + "Exact artifact bytes not acquired" + ] + }, + { + "candidate_id": "PMP-CASE-002", + "reference": "14/2026", + "public_buyer": "Directeur Régional d'Agriculture de la Région Béni Mellal-Khénifra", + "title_fr": "Achat de matériel et mobilier de bureau au profit du Centre Régional des Jeunes Entrepreneurs Agricoles et Agro-alimentaires relevant de la Direction Régionale de l’Agriculture de Béni Mellal-Khénifra en lot unique", + "procurement_category": "GOODS_SUPPLIES", + "procedure_type": "Appel d'offres ouvert simplifié", + "publication_date": "2026-07-22", + "submission_deadline": "2026-09-03T11:00:00+01:00", + "official_portal_url": "https://www.marchespublics.gov.ma/index.php5?orgAcronyme=q1s&page=entreprise.EntrepriseDetailConsultation&refConsultation=1017000", + "structured_consultation_record": { + "evidence_id": "PMP-CASE-002-NOTICE", + "language": "fr", + "record_type": "OFFICIAL_STRUCTURED_CONSULTATION_RECORD", + "exact_official_url": "https://www.marchespublics.gov.ma/index.php5?orgAcronyme=q1s&page=entreprise.EntrepriseDetailConsultation&refConsultation=1017000" + }, + "verified_tender_document_artifacts": [ + { + "artifact_id": "PMP-CASE-002-DCE-001", + "artifact_type": "DOSSIER_DE_CONSULTATION_DCE", + "exact_official_url": "https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDemandeTelechargementDce&refConsultation=1017000&orgAcronyme=q1s", + "source_candidate_id": "PMP-CASE-002", + "public_accessibility_state": "PUBLIC_LINK_TO_DOWNLOAD_REQUEST_FORM", + "login_required": false, + "captcha_required": false, + "access_control_bypass_required": false, + "form_submission_required_for_bytes": true, + "observed_utc": "2026-07-31T20:49:46Z", + "distinct_from_structured_consultation_record": true, + "portal_displayed_size": "725.5 KiB", + "bytes_acquired": false + } + ], + "verified_commission_or_evaluation_artifacts": [], + "verified_award_or_result_artifacts": [], + "state": "OPEN_DEADLINE_FUTURE_AT_OBSERVATION", + "explicit_official_current_open_state": true, + "synthetic": false, + "engineering_disposition": "LINK_AND_RECEIPT_ONLY", + "mandatory_gate": { + "eligible": true, + "criteria": { + "stable_official_procurement_reference": {"passed": true, "evidence_refs": ["reference", "official_portal_url"]}, + "official_french_notice_or_consultation_record": {"passed": true, "evidence_refs": ["PMP-CASE-002-NOTICE"]}, + "buyer_and_procedure_metadata": {"passed": true, "evidence_refs": ["public_buyer", "procedure_type"]}, + "verified_real_tender_document_artifact": {"passed": true, "evidence_refs": ["PMP-CASE-002-DCE-001"]}, + "verified_award_or_result_or_explicit_open_state": {"passed": true, "evidence_refs": ["explicit_official_current_open_state"]}, + "no_login_captcha_or_access_control_bypass": {"passed": true, "evidence_refs": ["PMP-CASE-002-DCE-001"]}, + "no_synthetic_object": {"passed": true, "evidence_refs": ["synthetic"]}, + "all_urls_on_permitted_official_domain": {"passed": true, "evidence_refs": ["official_portal_url", "PMP-CASE-002-DCE-001"]} + } + }, + "missing_objects": [ + "DCE contents and specifications not inspected or acquired", + "Administrative and technical clauses not verified", + "Evaluation grid not available", + "Commission minutes and award not available for this open case", + "Programme prévisionnel link not established", + "Exact artifact bytes not acquired" + ] + }, + { + "candidate_id": "PMP-CASE-003", + "reference": "22/2026", + "public_buyer": "Ministère de la Justice", + "title_fr": "Achat de fournitures de classement et d’archivage pour le compte des Juridictions du Royaume en lot unique", + "procurement_category": "GOODS_SUPPLIES", + "procedure_type": "Appel d'offres ouvert", + "publication_date": "2026-07-23", + "submission_deadline": "2026-09-03T10:00:00+01:00", + "official_portal_url": "https://www.marchespublics.gov.ma/index.php5?orgAcronyme=t5y&page=entreprise.EntrepriseDetailConsultation&refConsultation=1012408", + "structured_consultation_record": { + "evidence_id": "PMP-CASE-003-NOTICE", + "language": "fr", + "record_type": "OFFICIAL_STRUCTURED_CONSULTATION_RECORD", + "exact_official_url": "https://www.marchespublics.gov.ma/index.php5?orgAcronyme=t5y&page=entreprise.EntrepriseDetailConsultation&refConsultation=1012408" + }, + "verified_tender_document_artifacts": [ + { + "artifact_id": "PMP-CASE-003-DCE-001", + "artifact_type": "DOSSIER_DE_CONSULTATION_DCE", + "exact_official_url": "https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDemandeTelechargementDce&refConsultation=1012408&orgAcronyme=t5y", + "source_candidate_id": "PMP-CASE-003", + "public_accessibility_state": "PUBLIC_LINK_TO_DOWNLOAD_REQUEST_FORM", + "login_required": false, + "captcha_required": false, + "access_control_bypass_required": false, + "form_submission_required_for_bytes": true, + "observed_utc": "2026-07-31T20:49:46Z", + "distinct_from_structured_consultation_record": true, + "portal_displayed_size": "9.41 MiB", + "bytes_acquired": false + } + ], + "verified_commission_or_evaluation_artifacts": [], + "verified_award_or_result_artifacts": [], + "state": "OPEN_DEADLINE_FUTURE_AT_OBSERVATION", + "explicit_official_current_open_state": true, + "synthetic": false, + "engineering_disposition": "LINK_AND_RECEIPT_ONLY", + "mandatory_gate": { + "eligible": true, + "criteria": { + "stable_official_procurement_reference": {"passed": true, "evidence_refs": ["reference", "official_portal_url"]}, + "official_french_notice_or_consultation_record": {"passed": true, "evidence_refs": ["PMP-CASE-003-NOTICE"]}, + "buyer_and_procedure_metadata": {"passed": true, "evidence_refs": ["public_buyer", "procedure_type"]}, + "verified_real_tender_document_artifact": {"passed": true, "evidence_refs": ["PMP-CASE-003-DCE-001"]}, + "verified_award_or_result_or_explicit_open_state": {"passed": true, "evidence_refs": ["explicit_official_current_open_state"]}, + "no_login_captcha_or_access_control_bypass": {"passed": true, "evidence_refs": ["PMP-CASE-003-DCE-001"]}, + "no_synthetic_object": {"passed": true, "evidence_refs": ["synthetic"]}, + "all_urls_on_permitted_official_domain": {"passed": true, "evidence_refs": ["official_portal_url", "PMP-CASE-003-DCE-001"]} + } + }, + "missing_objects": [ + "DCE contents and specifications not inspected or acquired", + "Administrative and technical clauses not verified", + "Evaluation grid not available", + "Commission minutes and award not available for this open case", + "Programme prévisionnel link not established", + "Exact artifact bytes not acquired" + ] + }, + { + "candidate_id": "PMP-CASE-004", + "reference": "14/2026", + "public_buyer": "Secrétariat Général du Gouvernement", + "title_fr": "Achat de matériel de bureau pour le compte du Secrétariat Général du Gouvernement", + "procurement_category": "GOODS_SUPPLIES", + "procedure_type": "Appel d'offres ouvert simplifié", + "publication_date": "2026-07-10", + "submission_deadline": "2026-07-22T10:30:00+01:00", + "official_portal_url": "https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDetailConsultation&refConsultation=1015612&orgAcronyme=g0u", + "structured_consultation_record": { + "evidence_id": "PMP-CASE-004-NOTICE", + "language": "fr", + "record_type": "OFFICIAL_STRUCTURED_CONSULTATION_RECORD", + "exact_official_url": "https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDetailConsultation&refConsultation=1015612&orgAcronyme=g0u" + }, + "verified_tender_document_artifacts": [ + { + "artifact_id": "PMP-CASE-004-DCE-001", + "artifact_type": "DOSSIER_DE_CONSULTATION_DCE", + "exact_official_url": "https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDemandeTelechargementDce&refConsultation=1015612&orgAcronyme=g0u", + "source_candidate_id": "PMP-CASE-004", + "public_accessibility_state": "PUBLIC_LINK_TO_DOWNLOAD_REQUEST_FORM", + "login_required": false, + "captcha_required": false, + "access_control_bypass_required": false, + "form_submission_required_for_bytes": true, + "observed_utc": "2026-07-31T20:49:46Z", + "distinct_from_structured_consultation_record": true, + "portal_displayed_size": "1.76 MiB", + "bytes_acquired": false + } + ], + "verified_commission_or_evaluation_artifacts": [ + { + "artifact_id": "PMP-CASE-004-PV-001", + "artifact_type": "PUBLIC_EXTRAIT_DE_PV", + "exact_official_url": "https://www.marchespublics.gov.ma/index.php?page=entreprise.ExtraitPV&refConsultation=1015612&orgAcronyme=g0u", + "source_candidate_id": "PMP-CASE-004", + "public_accessibility_state": "PUBLIC_STRUCTURED_HTML", + "login_required": false, + "captcha_required": false, + "access_control_bypass_required": false, + "observed_utc": "2026-07-31T20:49:46Z", + "distinct_from_structured_consultation_record": true, + "bytes_acquired": false + } + ], + "verified_award_or_result_artifacts": [ + { + "artifact_id": "PMP-CASE-004-RESULT-001", + "artifact_type": "DEFINITIVE_RESULT_NOTICE", + "exact_official_url": "https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDetailConsultation&refConsultation=1029218&orgAcronyme=g0u", + "attached_notice_url": "https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDownloadAvisJAL&refConsultation=1029218&orgAcronyme=g0u&idAvis=527659", + "source_candidate_id": "PMP-CASE-004", + "public_accessibility_state": "PUBLIC_RESULT_RECORD_WITH_ATTACHED_NOTICE_LINK", + "cross_record_linkage_id": "PMP-CASE-004-LINK-001", + "result_evidence_eligible": true, + "login_required": false, + "captcha_required": false, + "access_control_bypass_required": false, + "observed_utc": "2026-07-31T20:49:46Z", + "distinct_from_structured_consultation_record": true, + "bytes_acquired": false + } + ], + "cross_record_linkage": { + "linkage_id": "PMP-CASE-004-LINK-001", + "original_consultation_url": "https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDetailConsultation&refConsultation=1015612&orgAcronyme=g0u", + "result_record_url": "https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDetailConsultation&refConsultation=1029218&orgAcronyme=g0u", + "original_refConsultation": "1015612", + "result_refConsultation": "1029218", + "observed_procurement_reference": { + "original_record": "14/2026", + "result_record": "14/2026" + }, + "observed_buyer": { + "original_record": { + "display_name": null, + "display_name_observation": "NOT_EXPOSED_AS_A_DISTINCT_FIELD_ON_PUBLIC_RECORD", + "portal_organization_acronym": "g0u" + }, + "result_record": { + "display_name": null, + "display_name_observation": "NOT_EXPOSED_AS_A_DISTINCT_FIELD_ON_PUBLIC_RECORD", + "portal_organization_acronym": "g0u" + } + }, + "observed_procurement_object": { + "original_record": "Achat de matériel de bureau pour le compte du Secrétariat Général du Gouvernement", + "result_record": "Achat de matériel de bureau pour le compte du Secrétariat Général du Gouvernement" + }, + "observed_procedure_or_lot_information": { + "original_record": null, + "result_record": null, + "observation": "NOT_EXPOSED_ON_EITHER_PUBLIC_RECORD" + }, + "explicit_portal_linkage_field": { + "field_name": null, + "value": null, + "observation": "NO_EXPLICIT_ORIGINAL_TO_RESULT_LINKAGE_FIELD_EXPOSED" + }, + "normalized_matching_fields": [ + { + "field": "procurement_reference", + "original": "14/2026", + "result": "14/2026", + "evidence_refs": ["PMP-CASE-004-LINK-ORIGINAL", "PMP-CASE-004-LINK-RESULT"] + }, + { + "field": "buyer_portal_organization_acronym", + "original": "g0u", + "result": "g0u", + "evidence_refs": ["PMP-CASE-004-LINK-ORIGINAL", "PMP-CASE-004-LINK-RESULT"] + }, + { + "field": "procurement_object", + "original": "achat de matériel de bureau pour le compte du secrétariat général du gouvernement", + "result": "achat de matériel de bureau pour le compte du secrétariat général du gouvernement", + "evidence_refs": ["PMP-CASE-004-LINK-ORIGINAL", "PMP-CASE-004-LINK-RESULT"] + } + ], + "mismatch_fields": [ + { + "field": "refConsultation", + "original": "1015612", + "result": "1029218", + "recorded_linkage_basis": "Separate portal record identifiers are reconciled by the exact matching procurement reference, procurement object and portal organization acronym.", + "evidence_refs": ["PMP-CASE-004-LINK-ORIGINAL", "PMP-CASE-004-LINK-RESULT"] + } + ], + "evidence_references": [ + { + "evidence_id": "PMP-CASE-004-LINK-ORIGINAL", + "record_role": "ORIGINAL_CONSULTATION", + "exact_official_url": "https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDetailConsultation&refConsultation=1015612&orgAcronyme=g0u", + "observed_fields": ["refConsultation=1015612", "reference=14/2026", "orgAcronyme=g0u", "object=Achat de matériel de bureau pour le compte du Secrétariat Général du Gouvernement"] + }, + { + "evidence_id": "PMP-CASE-004-LINK-RESULT", + "record_role": "DEFINITIVE_RESULT", + "exact_official_url": "https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDetailConsultation&refConsultation=1029218&orgAcronyme=g0u", + "observed_fields": ["refConsultation=1029218", "reference=14/2026", "orgAcronyme=g0u", "object=Achat de matériel de bureau pour le compte du Secrétariat Général du Gouvernement"] + } + ], + "observed_utc": "2026-07-31T21:23:40Z", + "linkage_result": "VERIFIED_MATCH" + }, + "state": "DEFINITIVE_RESULT_PUBLISHED", + "explicit_official_current_open_state": false, + "synthetic": false, + "engineering_disposition": "LINK_AND_RECEIPT_ONLY", + "mandatory_gate": { + "eligible": true, + "criteria": { + "stable_official_procurement_reference": {"passed": true, "evidence_refs": ["reference", "official_portal_url"]}, + "official_french_notice_or_consultation_record": {"passed": true, "evidence_refs": ["PMP-CASE-004-NOTICE"]}, + "buyer_and_procedure_metadata": {"passed": true, "evidence_refs": ["public_buyer", "procedure_type"]}, + "verified_real_tender_document_artifact": {"passed": true, "evidence_refs": ["PMP-CASE-004-DCE-001"]}, + "verified_award_or_result_or_explicit_open_state": {"passed": true, "evidence_refs": ["PMP-CASE-004-RESULT-001"]}, + "no_login_captcha_or_access_control_bypass": {"passed": true, "evidence_refs": ["PMP-CASE-004-DCE-001", "PMP-CASE-004-PV-001", "PMP-CASE-004-RESULT-001"]}, + "no_synthetic_object": {"passed": true, "evidence_refs": ["synthetic"]}, + "all_urls_on_permitted_official_domain": {"passed": true, "evidence_refs": ["official_portal_url", "PMP-CASE-004-DCE-001", "PMP-CASE-004-PV-001", "PMP-CASE-004-RESULT-001"]} + } + }, + "missing_objects": [ + "DCE contents and specifications not inspected or acquired", + "Administrative and technical clauses not verified", + "Evaluation criteria grid not verified as a distinct artifact", + "Programme prévisionnel link not established", + "Exact artifact bytes not acquired" + ] + }, + { + "candidate_id": "PMP-CASE-005", + "reference": "13/2026", + "public_buyer": "Secrétariat Général du Gouvernement", + "title_fr": "Achat de toners pour le compte du Secrétariat Général du Gouvernement", + "procurement_category": "GOODS_SUPPLIES", + "procedure_type": "Appel d'offres ouvert simplifié", + "publication_date": "2026-06-19", + "submission_deadline": "2026-07-02T10:30:00+01:00", + "official_portal_url": "https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDetailConsultation&refConsultation=1010827&orgAcronyme=g0u", + "structured_consultation_record": { + "evidence_id": "PMP-CASE-005-NOTICE", + "language": "fr", + "record_type": "OFFICIAL_STRUCTURED_CONSULTATION_RECORD", + "exact_official_url": "https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDetailConsultation&refConsultation=1010827&orgAcronyme=g0u" + }, + "verified_tender_document_artifacts": [ + { + "artifact_id": "PMP-CASE-005-DCE-001", + "artifact_type": "DOSSIER_DE_CONSULTATION_DCE", + "exact_official_url": "https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDemandeTelechargementDce&refConsultation=1010827&orgAcronyme=g0u", + "source_candidate_id": "PMP-CASE-005", + "public_accessibility_state": "PUBLIC_LINK_TO_DOWNLOAD_REQUEST_FORM", + "login_required": false, + "captcha_required": false, + "access_control_bypass_required": false, + "form_submission_required_for_bytes": true, + "observed_utc": "2026-07-31T20:49:46Z", + "distinct_from_structured_consultation_record": true, + "portal_displayed_size": "1.7 MiB", + "bytes_acquired": false + } + ], + "verified_commission_or_evaluation_artifacts": [ + { + "artifact_id": "PMP-CASE-005-PV-001", + "artifact_type": "PUBLIC_EXTRAIT_DE_PV", + "exact_official_url": "https://www.marchespublics.gov.ma/index.php?page=entreprise.ExtraitPV&refConsultation=1010827&orgAcronyme=g0u", + "source_candidate_id": "PMP-CASE-005", + "public_accessibility_state": "PUBLIC_STRUCTURED_HTML", + "login_required": false, + "captcha_required": false, + "access_control_bypass_required": false, + "observed_utc": "2026-07-31T20:49:46Z", + "distinct_from_structured_consultation_record": true, + "bytes_acquired": false + } + ], + "verified_award_or_result_artifacts": [ + { + "artifact_id": "PMP-CASE-005-RESULT-001", + "artifact_type": "DEFINITIVE_RESULT_NOTICE", + "exact_official_url": "https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDetailConsultation&refConsultation=1029211&orgAcronyme=g0u", + "attached_notice_url": "https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDownloadAvisJAL&refConsultation=1029211&orgAcronyme=g0u&idAvis=527649", + "source_candidate_id": "PMP-CASE-005", + "public_accessibility_state": "PUBLIC_RESULT_RECORD_WITH_ATTACHED_NOTICE_LINK", + "cross_record_linkage_id": "PMP-CASE-005-LINK-001", + "result_evidence_eligible": true, + "login_required": false, + "captcha_required": false, + "access_control_bypass_required": false, + "observed_utc": "2026-07-31T20:49:46Z", + "distinct_from_structured_consultation_record": true, + "bytes_acquired": false + } + ], + "cross_record_linkage": { + "linkage_id": "PMP-CASE-005-LINK-001", + "original_consultation_url": "https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDetailConsultation&refConsultation=1010827&orgAcronyme=g0u", + "result_record_url": "https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDetailConsultation&refConsultation=1029211&orgAcronyme=g0u", + "original_refConsultation": "1010827", + "result_refConsultation": "1029211", + "observed_procurement_reference": { + "original_record": "13/2026", + "result_record": "13/2026" + }, + "observed_buyer": { + "original_record": { + "display_name": null, + "display_name_observation": "NOT_EXPOSED_AS_A_DISTINCT_FIELD_ON_PUBLIC_RECORD", + "portal_organization_acronym": "g0u" + }, + "result_record": { + "display_name": null, + "display_name_observation": "NOT_EXPOSED_AS_A_DISTINCT_FIELD_ON_PUBLIC_RECORD", + "portal_organization_acronym": "g0u" + } + }, + "observed_procurement_object": { + "original_record": "Achat de toners pour le compte du Secrétariat Général du Gouvernement", + "result_record": "Achat de toners pour le compte du Secrétariat Général du Gouvernement" + }, + "observed_procedure_or_lot_information": { + "original_record": null, + "result_record": null, + "observation": "NOT_EXPOSED_ON_EITHER_PUBLIC_RECORD" + }, + "explicit_portal_linkage_field": { + "field_name": null, + "value": null, + "observation": "NO_EXPLICIT_ORIGINAL_TO_RESULT_LINKAGE_FIELD_EXPOSED" + }, + "normalized_matching_fields": [ + { + "field": "procurement_reference", + "original": "13/2026", + "result": "13/2026", + "evidence_refs": ["PMP-CASE-005-LINK-ORIGINAL", "PMP-CASE-005-LINK-RESULT"] + }, + { + "field": "buyer_portal_organization_acronym", + "original": "g0u", + "result": "g0u", + "evidence_refs": ["PMP-CASE-005-LINK-ORIGINAL", "PMP-CASE-005-LINK-RESULT"] + }, + { + "field": "procurement_object", + "original": "achat de toners pour le compte du secrétariat général du gouvernement", + "result": "achat de toners pour le compte du secrétariat général du gouvernement", + "evidence_refs": ["PMP-CASE-005-LINK-ORIGINAL", "PMP-CASE-005-LINK-RESULT"] + } + ], + "mismatch_fields": [ + { + "field": "refConsultation", + "original": "1010827", + "result": "1029211", + "recorded_linkage_basis": "Separate portal record identifiers are reconciled by the exact matching procurement reference, procurement object and portal organization acronym.", + "evidence_refs": ["PMP-CASE-005-LINK-ORIGINAL", "PMP-CASE-005-LINK-RESULT"] + } + ], + "evidence_references": [ + { + "evidence_id": "PMP-CASE-005-LINK-ORIGINAL", + "record_role": "ORIGINAL_CONSULTATION", + "exact_official_url": "https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDetailConsultation&refConsultation=1010827&orgAcronyme=g0u", + "observed_fields": ["refConsultation=1010827", "reference=13/2026", "orgAcronyme=g0u", "object=Achat de toners pour le compte du Secrétariat Général du Gouvernement"] + }, + { + "evidence_id": "PMP-CASE-005-LINK-RESULT", + "record_role": "DEFINITIVE_RESULT", + "exact_official_url": "https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDetailConsultation&refConsultation=1029211&orgAcronyme=g0u", + "observed_fields": ["refConsultation=1029211", "reference=13/2026", "orgAcronyme=g0u", "object=Achat de toners pour le compte du Secrétariat Général du Gouvernement"] + } + ], + "observed_utc": "2026-07-31T21:23:40Z", + "linkage_result": "VERIFIED_MATCH" + }, + "state": "DEFINITIVE_RESULT_PUBLISHED", + "explicit_official_current_open_state": false, + "synthetic": false, + "engineering_disposition": "LINK_AND_RECEIPT_ONLY", + "mandatory_gate": { + "eligible": true, + "criteria": { + "stable_official_procurement_reference": {"passed": true, "evidence_refs": ["reference", "official_portal_url"]}, + "official_french_notice_or_consultation_record": {"passed": true, "evidence_refs": ["PMP-CASE-005-NOTICE"]}, + "buyer_and_procedure_metadata": {"passed": true, "evidence_refs": ["public_buyer", "procedure_type"]}, + "verified_real_tender_document_artifact": {"passed": true, "evidence_refs": ["PMP-CASE-005-DCE-001"]}, + "verified_award_or_result_or_explicit_open_state": {"passed": true, "evidence_refs": ["PMP-CASE-005-RESULT-001"]}, + "no_login_captcha_or_access_control_bypass": {"passed": true, "evidence_refs": ["PMP-CASE-005-DCE-001", "PMP-CASE-005-PV-001", "PMP-CASE-005-RESULT-001"]}, + "no_synthetic_object": {"passed": true, "evidence_refs": ["synthetic"]}, + "all_urls_on_permitted_official_domain": {"passed": true, "evidence_refs": ["official_portal_url", "PMP-CASE-005-DCE-001", "PMP-CASE-005-PV-001", "PMP-CASE-005-RESULT-001"]} + } + }, + "missing_objects": [ + "DCE contents and specifications not inspected or acquired", + "Administrative and technical clauses not verified", + "Evaluation criteria grid not verified as a distinct artifact", + "Programme prévisionnel link not established", + "Exact artifact bytes not acquired" + ] + } + ] +} diff --git a/benchmarks/corpus/morocco/preflight-v0.1/PMP-MISSION-CANDIDATES-v0.1.md b/benchmarks/corpus/morocco/preflight-v0.1/PMP-MISSION-CANDIDATES-v0.1.md new file mode 100644 index 0000000..5e7e1c5 --- /dev/null +++ b/benchmarks/corpus/morocco/preflight-v0.1/PMP-MISSION-CANDIDATES-v0.1.md @@ -0,0 +1,122 @@ +# PMP Mission Candidates v0.1 + +Status: **PUBLIC_PORTAL_EVIDENCE_ONLY_NO_DOWNLOADS** + +No procurement is classified as compliant or non-compliant. + +## Candidates + +| ID | Reference | Buyer | Procedure | Deadline | State | Portal | Tender artifacts | Commission artifacts | Result artifacts | Gate | Disposition | +|---|---|---|---|---|---|---|---|---|---|---|---| +| PMP-CASE-001 | 44/FES/2026 | Direction Provinciale du MEN Fès | Appel d'offres ouvert | 2026-09-04T10:00:00+01:00 | OPEN_DEADLINE_FUTURE_AT_OBSERVATION | https://www.marchespublics.gov.ma/index.php5?orgAcronyme=p8x&page=entreprise.EntrepriseDetailConsultation&refConsultation=1024549 | PMP-CASE-001-DCE-001 | — | — | PASS | LINK_AND_RECEIPT_ONLY | +| PMP-CASE-002 | 14/2026 | Directeur Régional d'Agriculture de la Région Béni Mellal-Khénifra | Appel d'offres ouvert simplifié | 2026-09-03T11:00:00+01:00 | OPEN_DEADLINE_FUTURE_AT_OBSERVATION | https://www.marchespublics.gov.ma/index.php5?orgAcronyme=q1s&page=entreprise.EntrepriseDetailConsultation&refConsultation=1017000 | PMP-CASE-002-DCE-001 | — | — | PASS | LINK_AND_RECEIPT_ONLY | +| PMP-CASE-003 | 22/2026 | Ministère de la Justice | Appel d'offres ouvert | 2026-09-03T10:00:00+01:00 | OPEN_DEADLINE_FUTURE_AT_OBSERVATION | https://www.marchespublics.gov.ma/index.php5?orgAcronyme=t5y&page=entreprise.EntrepriseDetailConsultation&refConsultation=1012408 | PMP-CASE-003-DCE-001 | — | — | PASS | LINK_AND_RECEIPT_ONLY | +| PMP-CASE-004 | 14/2026 | Secrétariat Général du Gouvernement | Appel d'offres ouvert simplifié | 2026-07-22T10:30:00+01:00 | DEFINITIVE_RESULT_PUBLISHED | https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDetailConsultation&refConsultation=1015612&orgAcronyme=g0u | PMP-CASE-004-DCE-001 | PMP-CASE-004-PV-001 | PMP-CASE-004-RESULT-001 | PASS | LINK_AND_RECEIPT_ONLY | +| PMP-CASE-005 | 13/2026 | Secrétariat Général du Gouvernement | Appel d'offres ouvert simplifié | 2026-07-02T10:30:00+01:00 | DEFINITIVE_RESULT_PUBLISHED | https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDetailConsultation&refConsultation=1010827&orgAcronyme=g0u | PMP-CASE-005-DCE-001 | PMP-CASE-005-PV-001 | PMP-CASE-005-RESULT-001 | PASS | LINK_AND_RECEIPT_ONLY | + +## Verified tender-document artifacts + +| Candidate | Artifact | Type | Exact official URL | Public state | Login | CAPTCHA | Bypass | Observed | Bytes | +|---|---|---|---|---|---|---|---|---|---| +| PMP-CASE-001 | PMP-CASE-001-DCE-001 | DOSSIER_DE_CONSULTATION_DCE | https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDemandeTelechargementDce&refConsultation=1024549&orgAcronyme=p8x | PUBLIC_LINK_TO_DOWNLOAD_REQUEST_FORM | NO | NO | NO | 2026-07-31T20:49:46Z | NO | +| PMP-CASE-002 | PMP-CASE-002-DCE-001 | DOSSIER_DE_CONSULTATION_DCE | https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDemandeTelechargementDce&refConsultation=1017000&orgAcronyme=q1s | PUBLIC_LINK_TO_DOWNLOAD_REQUEST_FORM | NO | NO | NO | 2026-07-31T20:49:46Z | NO | +| PMP-CASE-003 | PMP-CASE-003-DCE-001 | DOSSIER_DE_CONSULTATION_DCE | https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDemandeTelechargementDce&refConsultation=1012408&orgAcronyme=t5y | PUBLIC_LINK_TO_DOWNLOAD_REQUEST_FORM | NO | NO | NO | 2026-07-31T20:49:46Z | NO | +| PMP-CASE-004 | PMP-CASE-004-DCE-001 | DOSSIER_DE_CONSULTATION_DCE | https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDemandeTelechargementDce&refConsultation=1015612&orgAcronyme=g0u | PUBLIC_LINK_TO_DOWNLOAD_REQUEST_FORM | NO | NO | NO | 2026-07-31T20:49:46Z | NO | +| PMP-CASE-005 | PMP-CASE-005-DCE-001 | DOSSIER_DE_CONSULTATION_DCE | https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDemandeTelechargementDce&refConsultation=1010827&orgAcronyme=g0u | PUBLIC_LINK_TO_DOWNLOAD_REQUEST_FORM | NO | NO | NO | 2026-07-31T20:49:46Z | NO | + +## Cross-record result lineage + +| Candidate | Linkage | Original record | Result record | Original refConsultation | Result refConsultation | Reference match | Buyer portal ID match | Object match | Mismatch fields | Explicit portal linkage | Result | Observed | +|---|---|---|---|---|---|---|---|---|---|---|---|---| +| PMP-CASE-004 | PMP-CASE-004-LINK-001 | https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDetailConsultation&refConsultation=1015612&orgAcronyme=g0u | https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDetailConsultation&refConsultation=1029218&orgAcronyme=g0u | 1015612 | 1029218 | {'original_record': '14/2026', 'result_record': '14/2026'} | {'original': 'g0u', 'result': 'g0u'} | {'original_record': 'Achat de matériel de bureau pour le compte du Secrétariat Général du Gouvernement', 'result_record': 'Achat de matériel de bureau pour le compte du Secrétariat Général du Gouvernement'} | {'field': 'refConsultation', 'original': '1015612', 'result': '1029218', 'recorded_linkage_basis': 'Separate portal record identifiers are reconciled by the exact matching procurement reference, procurement object and portal organization acronym.', 'evidence_refs': ['PMP-CASE-004-LINK-ORIGINAL', 'PMP-CASE-004-LINK-RESULT']} | {'field_name': None, 'value': None, 'observation': 'NO_EXPLICIT_ORIGINAL_TO_RESULT_LINKAGE_FIELD_EXPOSED'} | VERIFIED_MATCH | 2026-07-31T21:23:40Z | +| PMP-CASE-005 | PMP-CASE-005-LINK-001 | https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDetailConsultation&refConsultation=1010827&orgAcronyme=g0u | https://www.marchespublics.gov.ma/index.php?page=entreprise.EntrepriseDetailConsultation&refConsultation=1029211&orgAcronyme=g0u | 1010827 | 1029211 | {'original_record': '13/2026', 'result_record': '13/2026'} | {'original': 'g0u', 'result': 'g0u'} | {'original_record': 'Achat de toners pour le compte du Secrétariat Général du Gouvernement', 'result_record': 'Achat de toners pour le compte du Secrétariat Général du Gouvernement'} | {'field': 'refConsultation', 'original': '1010827', 'result': '1029211', 'recorded_linkage_basis': 'Separate portal record identifiers are reconciled by the exact matching procurement reference, procurement object and portal organization acronym.', 'evidence_refs': ['PMP-CASE-005-LINK-ORIGINAL', 'PMP-CASE-005-LINK-RESULT']} | {'field_name': None, 'value': None, 'observation': 'NO_EXPLICIT_ORIGINAL_TO_RESULT_LINKAGE_FIELD_EXPOSED'} | VERIFIED_MATCH | 2026-07-31T21:23:40Z | + +## Evidence-derived mandatory gate + +| Candidate | Criterion | Passed | Evidence | +|---|---|---|---| +| PMP-CASE-001 | stable_official_procurement_reference | YES | reference; official_portal_url | +| PMP-CASE-001 | official_french_notice_or_consultation_record | YES | PMP-CASE-001-NOTICE | +| PMP-CASE-001 | buyer_and_procedure_metadata | YES | public_buyer; procedure_type | +| PMP-CASE-001 | verified_real_tender_document_artifact | YES | PMP-CASE-001-DCE-001 | +| PMP-CASE-001 | verified_award_or_result_or_explicit_open_state | YES | explicit_official_current_open_state | +| PMP-CASE-001 | no_login_captcha_or_access_control_bypass | YES | PMP-CASE-001-DCE-001 | +| PMP-CASE-001 | no_synthetic_object | YES | synthetic | +| PMP-CASE-001 | all_urls_on_permitted_official_domain | YES | official_portal_url; PMP-CASE-001-DCE-001 | +| PMP-CASE-002 | stable_official_procurement_reference | YES | reference; official_portal_url | +| PMP-CASE-002 | official_french_notice_or_consultation_record | YES | PMP-CASE-002-NOTICE | +| PMP-CASE-002 | buyer_and_procedure_metadata | YES | public_buyer; procedure_type | +| PMP-CASE-002 | verified_real_tender_document_artifact | YES | PMP-CASE-002-DCE-001 | +| PMP-CASE-002 | verified_award_or_result_or_explicit_open_state | YES | explicit_official_current_open_state | +| PMP-CASE-002 | no_login_captcha_or_access_control_bypass | YES | PMP-CASE-002-DCE-001 | +| PMP-CASE-002 | no_synthetic_object | YES | synthetic | +| PMP-CASE-002 | all_urls_on_permitted_official_domain | YES | official_portal_url; PMP-CASE-002-DCE-001 | +| PMP-CASE-003 | stable_official_procurement_reference | YES | reference; official_portal_url | +| PMP-CASE-003 | official_french_notice_or_consultation_record | YES | PMP-CASE-003-NOTICE | +| PMP-CASE-003 | buyer_and_procedure_metadata | YES | public_buyer; procedure_type | +| PMP-CASE-003 | verified_real_tender_document_artifact | YES | PMP-CASE-003-DCE-001 | +| PMP-CASE-003 | verified_award_or_result_or_explicit_open_state | YES | explicit_official_current_open_state | +| PMP-CASE-003 | no_login_captcha_or_access_control_bypass | YES | PMP-CASE-003-DCE-001 | +| PMP-CASE-003 | no_synthetic_object | YES | synthetic | +| PMP-CASE-003 | all_urls_on_permitted_official_domain | YES | official_portal_url; PMP-CASE-003-DCE-001 | +| PMP-CASE-004 | stable_official_procurement_reference | YES | reference; official_portal_url | +| PMP-CASE-004 | official_french_notice_or_consultation_record | YES | PMP-CASE-004-NOTICE | +| PMP-CASE-004 | buyer_and_procedure_metadata | YES | public_buyer; procedure_type | +| PMP-CASE-004 | verified_real_tender_document_artifact | YES | PMP-CASE-004-DCE-001 | +| PMP-CASE-004 | verified_award_or_result_or_explicit_open_state | YES | PMP-CASE-004-RESULT-001 | +| PMP-CASE-004 | no_login_captcha_or_access_control_bypass | YES | PMP-CASE-004-DCE-001; PMP-CASE-004-PV-001; PMP-CASE-004-RESULT-001 | +| PMP-CASE-004 | no_synthetic_object | YES | synthetic | +| PMP-CASE-004 | all_urls_on_permitted_official_domain | YES | official_portal_url; PMP-CASE-004-DCE-001; PMP-CASE-004-PV-001; PMP-CASE-004-RESULT-001 | +| PMP-CASE-005 | stable_official_procurement_reference | YES | reference; official_portal_url | +| PMP-CASE-005 | official_french_notice_or_consultation_record | YES | PMP-CASE-005-NOTICE | +| PMP-CASE-005 | buyer_and_procedure_metadata | YES | public_buyer; procedure_type | +| PMP-CASE-005 | verified_real_tender_document_artifact | YES | PMP-CASE-005-DCE-001 | +| PMP-CASE-005 | verified_award_or_result_or_explicit_open_state | YES | PMP-CASE-005-RESULT-001 | +| PMP-CASE-005 | no_login_captcha_or_access_control_bypass | YES | PMP-CASE-005-DCE-001; PMP-CASE-005-PV-001; PMP-CASE-005-RESULT-001 | +| PMP-CASE-005 | no_synthetic_object | YES | synthetic | +| PMP-CASE-005 | all_urls_on_permitted_official_domain | YES | official_portal_url; PMP-CASE-005-DCE-001; PMP-CASE-005-PV-001; PMP-CASE-005-RESULT-001 | + +## Missing objects + +### PMP-CASE-001 — 44/FES/2026 + +- DCE contents and specifications not inspected or acquired +- Administrative and technical clauses not verified +- Evaluation grid not available +- Commission minutes and award not available for this open case +- Programme prévisionnel link not established +- Exact artifact bytes not acquired + +### PMP-CASE-002 — 14/2026 + +- DCE contents and specifications not inspected or acquired +- Administrative and technical clauses not verified +- Evaluation grid not available +- Commission minutes and award not available for this open case +- Programme prévisionnel link not established +- Exact artifact bytes not acquired + +### PMP-CASE-003 — 22/2026 + +- DCE contents and specifications not inspected or acquired +- Administrative and technical clauses not verified +- Evaluation grid not available +- Commission minutes and award not available for this open case +- Programme prévisionnel link not established +- Exact artifact bytes not acquired + +### PMP-CASE-004 — 14/2026 + +- DCE contents and specifications not inspected or acquired +- Administrative and technical clauses not verified +- Evaluation criteria grid not verified as a distinct artifact +- Programme prévisionnel link not established +- Exact artifact bytes not acquired + +### PMP-CASE-005 — 13/2026 + +- DCE contents and specifications not inspected or acquired +- Administrative and technical clauses not verified +- Evaluation criteria grid not verified as a distinct artifact +- Programme prévisionnel link not established +- Exact artifact bytes not acquired diff --git a/benchmarks/corpus/morocco/preflight-v0.1/PREFLIGHT-DECISION-v0.1.json b/benchmarks/corpus/morocco/preflight-v0.1/PREFLIGHT-DECISION-v0.1.json new file mode 100644 index 0000000..e104edd --- /dev/null +++ b/benchmarks/corpus/morocco/preflight-v0.1/PREFLIGHT-DECISION-v0.1.json @@ -0,0 +1,49 @@ +{ + "document_id": "OAM-MOROCCO-PREFLIGHT-DECISION-v0.1", + "status": "PROPOSED_PREFLIGHT_DECISION_NOT_SEMANTIC_ADMISSION", + "mission_selection_status": "PROVISIONAL_UNRECONCILED", + "mission_selection_outcome": "ADMISSIBLE_CASES_FOUND", + "proposed_mission_id": "MAR-MISSION-001", + "institutional_admission": "NONE", + "golden_mission_status": "NOT_ADMITTED", + "cross_repository_reconciliation_required": true, + "exact_base": "29daa374b7e5cdc30ca7788310fbabb85f19912b", + "normative_candidates": [ + "MAR-NORM-001", + "MAR-NORM-001-EN", + "MAR-IMPL-001" + ], + "excluded_normative_discovery_candidates": [ + { + "source_id": "MAR-CCAG-001", + "disposition": "DISCOVERY_CANDIDATE_NOT_APPLICABLE_TO_CURRENT_MISSION", + "reason": "Works CCAG does not match the selected goods mission" + } + ], + "challenge_sources": [ + "CDC-CHALLENGE-001", + "CDC-CHALLENGE-001-FR" + ], + "pmp_candidate_count": 5, + "preferred_mission": { + "mission_id": "MAR-MISSION-001", + "candidate_id": "PMP-CASE-004", + "reference": "14/2026", + "result_linkage_result": "VERIFIED_MATCH" + }, + "fallback_mission": { + "candidate_id": "PMP-CASE-005", + "reference": "13/2026", + "result_linkage_result": "VERIFIED_MATCH" + }, + "decision_basis": "The preferred and fallback candidates independently pass the evidence-derived eight-criterion gate. Each has an official French consultation record, a distinct verified DCE link, a public Extrait de PV and a separate definitive-result record whose cross-record lineage is VERIFIED_MATCH through the exact procurement reference, procurement object and portal organization acronym. The differing refConsultation identifiers are recorded explicitly. The three retained open candidates pass through their explicit official open state and distinct DCE links but have no award evidence. Aggregate scores did not override the gate. This nomination is provisional and remains unreconciled with the separate OAM CDC repository.", + "no_source_bytes_acquired": true, + "no_tender_document_bytes_acquired": true, + "no_semantic_processing": true, + "semantic_implementation_gate": "BLOCKED", + "next_owner_decisions": [ + "Authorize rights review and exact-byte acquisition receipts", + "Decide whether to authorize acquisition of the preferred and fallback DCE, PV and result artifacts", + "Decide whether a separate applicable goods-sector instrument should be researched" + ] +} diff --git a/benchmarks/corpus/morocco/preflight-v0.1/PREFLIGHT-DECISION-v0.1.md b/benchmarks/corpus/morocco/preflight-v0.1/PREFLIGHT-DECISION-v0.1.md new file mode 100644 index 0000000..421811b --- /dev/null +++ b/benchmarks/corpus/morocco/preflight-v0.1/PREFLIGHT-DECISION-v0.1.md @@ -0,0 +1,39 @@ +# Morocco Preflight Decision v0.1 + +Status: **PROPOSED_PREFLIGHT_DECISION_NOT_SEMANTIC_ADMISSION** + +Exact base: `29daa374b7e5cdc30ca7788310fbabb85f19912b` + +PMP candidates: **5** + +Mission selection: **PROVISIONAL_UNRECONCILED** + +Selection outcome: **ADMISSIBLE_CASES_FOUND** + +Proposed mission ID: **MAR-MISSION-001** + +Institutional admission: **NONE** + +Golden mission: **NOT_ADMITTED** + +Cross-repository reconciliation required: **YES** + +Preferred: **MAR-MISSION-001 — 14/2026** + +Fallback: **13/2026** + +The preferred and fallback candidates independently pass the evidence-derived eight-criterion gate. Each has an official French consultation record, a distinct verified DCE link, a public Extrait de PV and a separate definitive-result record whose cross-record lineage is VERIFIED_MATCH through the exact procurement reference, procurement object and portal organization acronym. The differing refConsultation identifiers are recorded explicitly. The three retained open candidates pass through their explicit official open state and distinct DCE links but have no award evidence. Aggregate scores did not override the gate. This nomination is provisional and remains unreconciled with the separate OAM CDC repository. + +No source bytes acquired: **YES** + +No tender-document bytes acquired: **YES** + +No semantic processing: **YES** + +Semantic implementation gate: **BLOCKED** + +## Owner decisions still required + +- Authorize rights review and exact-byte acquisition receipts +- Decide whether to authorize acquisition of the preferred and fallback DCE, PV and result artifacts +- Decide whether a separate applicable goods-sector instrument should be researched diff --git a/tests/contract/test_morocco_preflight.py b/tests/contract/test_morocco_preflight.py new file mode 100644 index 0000000..890f186 --- /dev/null +++ b/tests/contract/test_morocco_preflight.py @@ -0,0 +1,663 @@ +"""Contract tests for the Morocco official-source and real-mission preflight.""" + +from __future__ import annotations + +import copy +import json +import subprocess +import sys +from collections.abc import Iterator +from pathlib import Path +from typing import Any, cast +from urllib.parse import parse_qs, urlparse + +import pytest + +ROOT = Path(__file__).resolve().parents[2] +PREFLIGHT = ROOT / "benchmarks/corpus/morocco/preflight-v0.1" +BASE = "29daa374b7e5cdc30ca7788310fbabb85f19912b" +PERMITTED = { + "tgr.gov.ma", + "marchespublics.gov.ma", + "sgg.gov.ma", + "courdescomptes.ma", + "govtech.trustvalley.swiss", + "worldbank.org", +} +LEGAL_CLEARANCE = "LEGALLY_CLEARED" +GATE_CRITERIA = ( + "stable_official_procurement_reference", + "official_french_notice_or_consultation_record", + "buyer_and_procedure_metadata", + "verified_real_tender_document_artifact", + "verified_award_or_result_or_explicit_open_state", + "no_login_captcha_or_access_control_bypass", + "no_synthetic_object", + "all_urls_on_permitted_official_domain", +) + + +def load(name: str) -> dict[str, Any]: + return cast(dict[str, Any], json.loads((PREFLIGHT / name).read_text(encoding="utf-8"))) + + +def official_url(value: object) -> bool: + if not isinstance(value, str) or not value.startswith("https://"): + return False + host = (urlparse(value).hostname or "").removeprefix("www.") + return host in PERMITTED + + +def normalized(value: object) -> str: + return " ".join(value.casefold().split()) if isinstance(value, str) else "" + + +def portal_record_fields(value: object) -> dict[str, str] | None: + if not official_url(value): + return None + parsed = urlparse(cast(str, value)) + query = parse_qs(parsed.query) + fields = { + "page": query.get("page", [""])[0], + "refConsultation": query.get("refConsultation", [""])[0], + "orgAcronyme": query.get("orgAcronyme", [""])[0], + } + return fields if all(fields.values()) else None + + +def derive_result_linkage(case: dict[str, Any], artifact: dict[str, Any]) -> str: + linkage = case.get("cross_record_linkage") + if not isinstance(linkage, dict): + return "NOT_VERIFIED" + original_url = linkage.get("original_consultation_url") + result_url = linkage.get("result_record_url") + original_fields = portal_record_fields(original_url) + result_fields = portal_record_fields(result_url) + if original_fields is None or result_fields is None: + return "NOT_VERIFIED" + if original_fields["page"] != "entreprise.EntrepriseDetailConsultation": + return "NOT_VERIFIED" + if result_fields["page"] != "entreprise.EntrepriseDetailConsultation": + return "NOT_VERIFIED" + if original_url != case.get("official_portal_url"): + return "NOT_VERIFIED" + if result_url != artifact.get("exact_official_url"): + return "NOT_VERIFIED" + if original_fields["refConsultation"] != linkage.get("original_refConsultation"): + return "NOT_VERIFIED" + if result_fields["refConsultation"] != linkage.get("result_refConsultation"): + return "NOT_VERIFIED" + if original_fields["refConsultation"] == result_fields["refConsultation"]: + return "NOT_VERIFIED" + + evidence = linkage.get("evidence_references", []) + evidence_by_id = {item.get("evidence_id"): item for item in evidence if isinstance(item, dict)} + expected_evidence_ids = { + f"{case['candidate_id']}-LINK-ORIGINAL", + f"{case['candidate_id']}-LINK-RESULT", + } + if set(evidence_by_id) != expected_evidence_ids: + return "NOT_VERIFIED" + if ( + evidence_by_id[f"{case['candidate_id']}-LINK-ORIGINAL"].get("exact_official_url") + != original_url + ): + return "NOT_VERIFIED" + if ( + evidence_by_id[f"{case['candidate_id']}-LINK-RESULT"].get("exact_official_url") + != result_url + ): + return "NOT_VERIFIED" + + observed_reference = linkage.get("observed_procurement_reference", {}) + observed_buyer = linkage.get("observed_buyer", {}) + observed_object = linkage.get("observed_procurement_object", {}) + original_buyer = observed_buyer.get("original_record", {}) + result_buyer = observed_buyer.get("result_record", {}) + expected_matches = { + "procurement_reference": ( + normalized(observed_reference.get("original_record")), + normalized(observed_reference.get("result_record")), + normalized(case.get("reference")), + ), + "buyer_portal_organization_acronym": ( + normalized(original_buyer.get("portal_organization_acronym")), + normalized(result_buyer.get("portal_organization_acronym")), + normalized(original_fields["orgAcronyme"]), + ), + "procurement_object": ( + normalized(observed_object.get("original_record")), + normalized(observed_object.get("result_record")), + normalized(case.get("title_fr")), + ), + } + matching_fields = linkage.get("normalized_matching_fields", []) + matching_by_name = { + item.get("field"): item for item in matching_fields if isinstance(item, dict) + } + if set(matching_by_name) != set(expected_matches): + return "NOT_VERIFIED" + for field, (original, result, expected) in expected_matches.items(): + stored = matching_by_name[field] + if not original or original != result or original != expected: + return "NOT_VERIFIED" + if normalized(stored.get("original")) != original: + return "NOT_VERIFIED" + if normalized(stored.get("result")) != result: + return "NOT_VERIFIED" + if set(stored.get("evidence_refs", [])) != expected_evidence_ids: + return "NOT_VERIFIED" + if normalized(result_buyer.get("portal_organization_acronym")) != normalized( + result_fields["orgAcronyme"] + ): + return "NOT_VERIFIED" + + mismatches = linkage.get("mismatch_fields", []) + if len(mismatches) != 1 or mismatches[0].get("field") != "refConsultation": + return "NOT_VERIFIED" + mismatch = mismatches[0] + if mismatch.get("original") != original_fields["refConsultation"]: + return "NOT_VERIFIED" + if mismatch.get("result") != result_fields["refConsultation"]: + return "NOT_VERIFIED" + if not mismatch.get("recorded_linkage_basis"): + return "NOT_VERIFIED" + if set(mismatch.get("evidence_refs", [])) != expected_evidence_ids: + return "NOT_VERIFIED" + if not linkage.get("observed_utc"): + return "NOT_VERIFIED" + if artifact.get("cross_record_linkage_id") != linkage.get("linkage_id"): + return "NOT_VERIFIED" + return "VERIFIED_MATCH" + + +def iter_urls(value: object, key: str = "") -> Iterator[str]: + if isinstance(value, dict): + for child_key, child_value in value.items(): + yield from iter_urls(child_value, child_key) + elif isinstance(value, list): + for child in value: + yield from iter_urls(child, key) + elif isinstance(value, str) and key.endswith("url"): + yield value + + +def artifact_access_ok(artifact: dict[str, Any]) -> bool: + return ( + artifact.get("login_required") is False + and artifact.get("captcha_required") is False + and artifact.get("access_control_bypass_required") is False + ) + + +def verified_tender_artifact(case: dict[str, Any], artifact: dict[str, Any]) -> bool: + return ( + artifact.get("artifact_type") == "DOSSIER_DE_CONSULTATION_DCE" + and artifact.get("source_candidate_id") == case.get("candidate_id") + and official_url(artifact.get("exact_official_url")) + and bool(artifact.get("public_accessibility_state")) + and bool(artifact.get("observed_utc")) + and artifact.get("distinct_from_structured_consultation_record") is True + and artifact.get("bytes_acquired") is False + ) + + +def verified_award_artifact(case: dict[str, Any], artifact: dict[str, Any]) -> bool: + return ( + artifact.get("artifact_type") == "DEFINITIVE_RESULT_NOTICE" + and artifact.get("source_candidate_id") == case.get("candidate_id") + and official_url(artifact.get("exact_official_url")) + and bool(artifact.get("public_accessibility_state")) + and bool(artifact.get("observed_utc")) + and artifact.get("distinct_from_structured_consultation_record") is True + and artifact.get("bytes_acquired") is False + and derive_result_linkage(case, artifact) == "VERIFIED_MATCH" + and case.get("cross_record_linkage", {}).get("linkage_result") == "VERIFIED_MATCH" + and artifact.get("result_evidence_eligible") is True + ) + + +def derive_gate(case: dict[str, Any]) -> dict[str, bool]: + notice = case.get("structured_consultation_record", {}) + tenders = case.get("verified_tender_document_artifacts", []) + commission = case.get("verified_commission_or_evaluation_artifacts", []) + awards = case.get("verified_award_or_result_artifacts", []) + urls = list(iter_urls(case)) + access_objects = [*tenders, *commission, *awards] + criteria = { + "stable_official_procurement_reference": bool(case.get("reference")) + and official_url(case.get("official_portal_url")), + "official_french_notice_or_consultation_record": notice.get("language") == "fr" + and notice.get("record_type") == "OFFICIAL_STRUCTURED_CONSULTATION_RECORD" + and official_url(notice.get("exact_official_url")), + "buyer_and_procedure_metadata": bool(case.get("public_buyer")) + and bool(case.get("procedure_type")), + "verified_real_tender_document_artifact": any( + verified_tender_artifact(case, artifact) for artifact in tenders + ), + "verified_award_or_result_or_explicit_open_state": any( + verified_award_artifact(case, artifact) for artifact in awards + ) + or case.get("explicit_official_current_open_state") is True, + "no_login_captcha_or_access_control_bypass": bool(access_objects) + and all(artifact_access_ok(artifact) for artifact in access_objects), + "no_synthetic_object": case.get("synthetic") is False, + "all_urls_on_permitted_official_domain": bool(urls) + and all(official_url(url) for url in urls), + } + assert tuple(criteria) == GATE_CRITERIA + return criteria + + +def validate( + register: dict[str, Any], + candidates: dict[str, Any], + scorecard: dict[str, Any], + normative: dict[str, Any], + decision: dict[str, Any], +) -> None: + sources = register["sources"] + source_ids = [source["source_id"] for source in sources] + assert len(source_ids) == len(set(source_ids)) + assert LEGAL_CLEARANCE not in register["engineering_dispositions"] + for source in sources: + assert source["language"] + for key in ("canonical_url", "download_url"): + if source[key] is not None: + assert official_url(source[key]) + assert source["engineering_disposition"] in register["engineering_dispositions"] + assert source["engineering_disposition"] != LEGAL_CLEARANCE + if source["language"] == "en": + assert source["translation_status"] + if source["translation_status"] == "UNOFFICIAL_TRANSLATION_COMPANION": + assert "NORMATIVE_TEXT" not in source["authority_rank"] + + cases = candidates["candidates"] + candidate_ids = [case["candidate_id"] for case in cases] + assert 3 <= len(cases) <= 7 + assert len(candidate_ids) == len(set(candidate_ids)) + assert all(case["publication_date"] for case in cases) + assert all(case["procurement_category"] == "GOODS_SUPPLIES" for case in cases) + assert all("mandatory_minimum" not in case for case in cases) + + observations = register["mission_evidence_observations"] + assert [item["candidate_id"] for item in observations] == candidate_ids + for observation in observations: + assert observation["bytes_acquired"] is False + assert all(official_url(url) for url in iter_urls(observation)) + + derived_by_id: dict[str, dict[str, bool]] = {} + for case in cases: + criteria = derive_gate(case) + derived_by_id[case["candidate_id"]] = criteria + stored = case["mandatory_gate"] + assert tuple(stored["criteria"]) == GATE_CRITERIA + assert { + criterion: result["passed"] for criterion, result in stored["criteria"].items() + } == criteria + assert stored["eligible"] is all(criteria.values()) + assert all( + not artifact["bytes_acquired"] + for artifact in case["verified_tender_document_artifacts"] + ) + + dimensions = scorecard["dimensions"] + assert len(dimensions) == 14 + assert len(scorecard["scores"]) == len(cases) + score_by_id = {score["candidate_id"]: score for score in scorecard["scores"]} + assert set(score_by_id) == set(candidate_ids) + award_index = dimensions.index("award_or_result") + commission_index = dimensions.index("commission_minute_or_extract") + exact_artifact_index = dimensions.index("exact_byte_downloadable_artifacts") + suitability_index = dimensions.index("tender_evaluation_award_suitability") + for case in cases: + score = score_by_id[case["candidate_id"]] + assert "mandatory_minimum" not in score + assert len(score["values"]) == len(dimensions) + assert all(value in {0, 1, 2} for value in score["values"]) + assert score["total"] == sum(score["values"]) + gate_passed = all(derived_by_id[case["candidate_id"]].values()) + assert score["mandatory_gate_result"] == ("PASS" if gate_passed else "FAIL") + assert score["gate_evidence_reference"] == f"{case['candidate_id']}#mandatory_gate" + award_artifacts = case["verified_award_or_result_artifacts"] + commission_artifacts = case["verified_commission_or_evaluation_artifacts"] + assert all(verified_award_artifact(case, artifact) for artifact in award_artifacts) + assert score["values"][award_index] == (2 if award_artifacts else 0) + assert score["values"][commission_index] == (2 if commission_artifacts else 0) + assert score["values"][exact_artifact_index] > 0 + assert all( + verified_tender_artifact(case, artifact) + for artifact in case["verified_tender_document_artifacts"] + ) + if not award_artifacts and not commission_artifacts: + assert score["values"][suitability_index] <= 1 + if score["nomination"] != "NOT_SELECTED": + assert gate_passed + assert award_artifacts + assert all(verified_award_artifact(case, artifact) for artifact in award_artifacts) + + preferred_scores = [ + score for score in scorecard["scores"] if score["nomination"] == "PREFERRED_MAR-MISSION-001" + ] + fallback_scores = [score for score in scorecard["scores"] if score["nomination"] == "FALLBACK"] + if scorecard["selection_outcome"] == "NO_ADMISSIBLE_REAL_CASE": + assert scorecard["preferred"] is None + assert scorecard["fallback"] is None + assert not preferred_scores + assert not fallback_scores + else: + assert scorecard["selection_outcome"] == "ADMISSIBLE_CASES_FOUND" + assert len(preferred_scores) == 1 + assert len(fallback_scores) == 1 + assert preferred_scores[0]["candidate_id"] == scorecard["preferred"]["candidate_id"] + assert fallback_scores[0]["candidate_id"] == scorecard["fallback"]["candidate_id"] + preferred_case = next( + case for case in cases if case["candidate_id"] == scorecard["preferred"]["candidate_id"] + ) + fallback_case = next( + case for case in cases if case["candidate_id"] == scorecard["fallback"]["candidate_id"] + ) + assert ( + scorecard["preferred"]["result_linkage_result"] + == preferred_case["cross_record_linkage"]["linkage_result"] + ) + assert ( + scorecard["fallback"]["result_linkage_result"] + == fallback_case["cross_record_linkage"]["linkage_result"] + ) + + ccag = next(entry for entry in normative["entries"] if entry["source_id"] == "MAR-CCAG-001") + assert ccag["role"] == "DISCOVERY_CANDIDATE_NOT_APPLICABLE_TO_CURRENT_MISSION" + assert ccag["authoritative_for_semantics"] is False + assert "MAR-CCAG-001" not in normative["proposed_normative_corpus"] + assert any( + entry["source_id"] == "MAR-CCAG-001" + for entry in normative["excluded_from_proposed_normative_corpus"] + ) + + assert decision["pmp_candidate_count"] == len(cases) + assert scorecard["mission_selection_status"] == "PROVISIONAL_UNRECONCILED" + assert decision["mission_selection_status"] == "PROVISIONAL_UNRECONCILED" + assert decision["mission_selection_outcome"] == scorecard["selection_outcome"] + assert decision["proposed_mission_id"] == scorecard["proposed_mission_id"] + assert decision["institutional_admission"] == "NONE" + assert scorecard["institutional_admission"] == "NONE" + assert decision["golden_mission_status"] == "NOT_ADMITTED" + assert scorecard["golden_mission_status"] == "NOT_ADMITTED" + assert decision["cross_repository_reconciliation_required"] is True + assert scorecard["cross_repository_reconciliation_required"] is True + assert decision["preferred_mission"]["candidate_id"] == scorecard["preferred"]["candidate_id"] + assert decision["fallback_mission"]["candidate_id"] == scorecard["fallback"]["candidate_id"] + assert ( + decision["preferred_mission"]["result_linkage_result"] + == scorecard["preferred"]["result_linkage_result"] + ) + assert ( + decision["fallback_mission"]["result_linkage_result"] + == scorecard["fallback"]["result_linkage_result"] + ) + assert decision["normative_candidates"] == normative["proposed_normative_corpus"] + assert decision["no_source_bytes_acquired"] is True + assert decision["no_tender_document_bytes_acquired"] is True + assert decision["no_semantic_processing"] is True + assert decision["semantic_implementation_gate"] == "BLOCKED" + assert scorecard["semantic_implementation_gate"] == "BLOCKED" + + +@pytest.fixture +def bundle() -> tuple[ + dict[str, Any], dict[str, Any], dict[str, Any], dict[str, Any], dict[str, Any] +]: + return ( + load("OFFICIAL-SOURCE-REGISTER-v0.1.json"), + load("PMP-MISSION-CANDIDATES-v0.1.json"), + load("MISSION-SELECTION-SCORECARD-v0.1.json"), + load("NORMATIVE-SOURCE-MAP-v0.1.json"), + load("PREFLIGHT-DECISION-v0.1.json"), + ) + + +def test_bundle_contract( + bundle: tuple[dict[str, Any], dict[str, Any], dict[str, Any], dict[str, Any], dict[str, Any]], +) -> None: + validate(*bundle) + + +def test_deterministic_renderings_are_current() -> None: + result = subprocess.run( + [sys.executable, "tools/render_morocco_preflight.py", "--check"], + cwd=ROOT, + check=False, + capture_output=True, + text=True, + ) + assert result.returncode == 0, result.stdout + result.stderr + + +def test_no_source_bytes_committed() -> None: + allowed = {".json", ".md"} + assert all(path.suffix in allowed for path in PREFLIGHT.iterdir()) + decision = load("PREFLIGHT-DECISION-v0.1.json") + assert decision["no_source_bytes_acquired"] is True + assert decision["no_tender_document_bytes_acquired"] is True + + +def test_protected_artifacts_unchanged() -> None: + paths = ["STATUS.md", "schemas/draft", "benchmarks/corpus/canada"] + result = subprocess.run(["git", "diff", "--quiet", BASE, "--", *paths], cwd=ROOT, check=False) + assert result.returncode == 0 + + +def test_no_semantic_artifact_created() -> None: + decision = load("PREFLIGHT-DECISION-v0.1.json") + assert decision["no_semantic_processing"] is True + assert decision["semantic_implementation_gate"] == "BLOCKED" + forbidden = ("institutional-ir", "control-envelope", "warrant", "veip") + added = subprocess.run( + ["git", "diff", "--name-only", BASE], cwd=ROOT, check=True, capture_output=True, text=True + ).stdout.lower() + assert not any(token in added for token in forbidden) + + +def test_source_mutations_fail( + bundle: tuple[dict[str, Any], dict[str, Any], dict[str, Any], dict[str, Any], dict[str, Any]], +) -> None: + mutations = ( + "third_party", + "authoritative_translation", + "duplicate_id", + "missing_language", + "legal_clearance", + ) + for mutation in mutations: + register, candidates, scorecard, normative, decision = copy.deepcopy(bundle) + if mutation == "third_party": + register["sources"][0]["canonical_url"] = "https://example.com/mirror.pdf" + elif mutation == "authoritative_translation": + register["sources"][1]["authority_rank"] = "OFFICIAL_NORMATIVE_TEXT" + elif mutation == "duplicate_id": + register["sources"][1]["source_id"] = register["sources"][0]["source_id"] + elif mutation == "missing_language": + register["sources"][0]["language"] = "" + else: + register["sources"][0]["engineering_disposition"] = LEGAL_CLEARANCE + with pytest.raises(AssertionError): + validate(register, candidates, scorecard, normative, decision) + + +def test_existing_mission_mutations_fail( + bundle: tuple[dict[str, Any], dict[str, Any], dict[str, Any], dict[str, Any], dict[str, Any]], +) -> None: + mutations = ( + "missing_artifact", + "inflated_score", + "synthetic", + "login_required", + "mandatory_bypass", + ) + for mutation in mutations: + register, candidates, scorecard, normative, decision = copy.deepcopy(bundle) + if mutation == "missing_artifact": + candidates["candidates"][3]["verified_tender_document_artifacts"] = [] + elif mutation == "inflated_score": + scorecard["scores"][3]["total"] += 1 + elif mutation == "synthetic": + candidates["candidates"][3]["synthetic"] = True + elif mutation == "login_required": + candidates["candidates"][3]["verified_tender_document_artifacts"][0][ + "login_required" + ] = True + else: + candidates["candidates"][3]["mandatory_gate"]["eligible"] = False + try: + validate(register, candidates, scorecard, normative, decision) + except AssertionError: + pass + else: + raise AssertionError(f"mutation survived validation: {mutation}") + + +def test_evidence_gate_correction_mutations_fail( + bundle: tuple[dict[str, Any], dict[str, Any], dict[str, Any], dict[str, Any], dict[str, Any]], +) -> None: + mutations = ( + "unsupported_manual_mandatory_true", + "empty_verified_tender_artifacts", + "structured_notice_only", + "non_official_tender_url", + "tender_login_required", + "award_score_without_award", + "open_state_as_award_evidence", + "nomination_with_failed_criterion", + "preferred_present_under_no_admissible", + "works_ccag_applicable_without_binding", + "aggregate_score_overrides_gate", + ) + for mutation in mutations: + register, candidates, scorecard, normative, decision = copy.deepcopy(bundle) + if mutation == "unsupported_manual_mandatory_true": + scorecard["scores"][3]["mandatory_minimum"] = True + candidates["candidates"][3]["verified_tender_document_artifacts"] = [] + elif mutation == "empty_verified_tender_artifacts": + candidates["candidates"][3]["verified_tender_document_artifacts"] = [] + elif mutation == "structured_notice_only": + case = candidates["candidates"][3] + case["verified_tender_document_artifacts"] = [ + { + "artifact_id": "NOTICE-AS-DCE", + "artifact_type": "OFFICIAL_STRUCTURED_CONSULTATION_RECORD", + "exact_official_url": case["structured_consultation_record"][ + "exact_official_url" + ], + "source_candidate_id": case["candidate_id"], + "public_accessibility_state": "PUBLIC_STRUCTURED_HTML", + "login_required": False, + "captcha_required": False, + "access_control_bypass_required": False, + "observed_utc": candidates["observed_utc"], + "distinct_from_structured_consultation_record": False, + "bytes_acquired": False, + } + ] + elif mutation == "non_official_tender_url": + candidates["candidates"][3]["verified_tender_document_artifacts"][0][ + "exact_official_url" + ] = "https://example.com/dce" + elif mutation == "tender_login_required": + candidates["candidates"][3]["verified_tender_document_artifacts"][0][ + "login_required" + ] = True + elif mutation == "award_score_without_award": + scorecard["scores"][0]["values"][8] = 2 + scorecard["scores"][0]["total"] += 2 + elif mutation == "open_state_as_award_evidence": + case = candidates["candidates"][0] + case["verified_award_or_result_artifacts"] = [ + { + "artifact_id": "OPEN-STATE", + "artifact_type": "OPEN_STATE", + "exact_official_url": case["official_portal_url"], + "source_candidate_id": case["candidate_id"], + "public_accessibility_state": "PUBLIC_STRUCTURED_HTML", + "login_required": False, + "captcha_required": False, + "access_control_bypass_required": False, + "observed_utc": candidates["observed_utc"], + "distinct_from_structured_consultation_record": False, + "bytes_acquired": False, + } + ] + scorecard["scores"][0]["values"][8] = 2 + scorecard["scores"][0]["total"] += 2 + elif mutation == "nomination_with_failed_criterion": + candidates["candidates"][3]["public_buyer"] = "" + elif mutation == "preferred_present_under_no_admissible": + scorecard["selection_outcome"] = "NO_ADMISSIBLE_REAL_CASE" + elif mutation == "works_ccag_applicable_without_binding": + next(entry for entry in normative["entries"] if entry["source_id"] == "MAR-CCAG-001")[ + "role" + ] = "APPLICABLE_TO_CURRENT_MISSION" + else: + candidates["candidates"][3]["verified_tender_document_artifacts"] = [] + scorecard["scores"][3]["values"] = [2] * 14 + scorecard["scores"][3]["total"] = 28 + try: + validate(register, candidates, scorecard, normative, decision) + except AssertionError: + pass + else: + raise AssertionError(f"mutation survived validation: {mutation}") + + +def test_result_lineage_mutations_fail( + bundle: tuple[dict[str, Any], dict[str, Any], dict[str, Any], dict[str, Any], dict[str, Any]], +) -> None: + mutations = ( + "different_official_result_url", + "different_result_reference", + "different_result_buyer", + "different_result_object", + "different_ref_without_linkage_basis", + "manual_verified_unsupported", + "award_score_for_not_verified", + "nomination_on_unlinked_result", + ) + for mutation in mutations: + register, candidates, scorecard, normative, decision = copy.deepcopy(bundle) + case = candidates["candidates"][3] + linkage = case["cross_record_linkage"] + result = case["verified_award_or_result_artifacts"][0] + if mutation == "different_official_result_url": + substituted = ( + "https://www.marchespublics.gov.ma/index.php?" + "page=entreprise.EntrepriseDetailConsultation&" + "refConsultation=1029211&orgAcronyme=g0u" + ) + result["exact_official_url"] = substituted + linkage["result_record_url"] = substituted + elif mutation == "different_result_reference": + linkage["observed_procurement_reference"]["result_record"] = "13/2026" + elif mutation == "different_result_buyer": + linkage["observed_buyer"]["result_record"]["portal_organization_acronym"] = "different" + elif mutation == "different_result_object": + linkage["observed_procurement_object"]["result_record"] = ( + "Achat de toners pour le compte d'une autre institution" + ) + elif mutation == "different_ref_without_linkage_basis": + del linkage["mismatch_fields"][0]["recorded_linkage_basis"] + elif mutation == "manual_verified_unsupported": + linkage["normalized_matching_fields"][0]["result"] = "13/2026" + linkage["linkage_result"] = "VERIFIED_MATCH" + elif mutation == "award_score_for_not_verified": + linkage["linkage_result"] = "NOT_VERIFIED" + result["result_evidence_eligible"] = False + else: + linkage["linkage_result"] = "NOT_VERIFIED" + result["result_evidence_eligible"] = False + scorecard["scores"][3]["nomination"] = "PREFERRED_MAR-MISSION-001" + try: + validate(register, candidates, scorecard, normative, decision) + except AssertionError: + pass + else: + raise AssertionError(f"mutation survived validation: {mutation}") diff --git a/tools/render_morocco_preflight.py b/tools/render_morocco_preflight.py new file mode 100644 index 0000000..4b507bb --- /dev/null +++ b/tools/render_morocco_preflight.py @@ -0,0 +1,483 @@ +"""Render Morocco preflight canonical JSON files to deterministic Markdown.""" + +from __future__ import annotations + +import argparse +import json +from pathlib import Path +from typing import Any + +ROOT = Path(__file__).resolve().parents[1] +PREFLIGHT = ROOT / "benchmarks/corpus/morocco/preflight-v0.1" +STEMS = ( + "OFFICIAL-SOURCE-REGISTER-v0.1", + "NORMATIVE-SOURCE-MAP-v0.1", + "PMP-MISSION-CANDIDATES-v0.1", + "MISSION-SELECTION-SCORECARD-v0.1", + "ACQUISITION-CONSTRAINTS-v0.1", + "PREFLIGHT-DECISION-v0.1", +) + + +def _load(stem: str) -> dict[str, Any]: + return json.loads((PREFLIGHT / f"{stem}.json").read_text(encoding="utf-8")) + + +def _cell(value: object) -> str: + if value is None: + return "—" + if isinstance(value, list): + return "; ".join(str(item) for item in value) or "—" + if isinstance(value, bool): + return "YES" if value else "NO" + return str(value).replace("|", "\\|").replace("\n", " ") + + +def _table(headers: list[str], rows: list[list[object]]) -> list[str]: + lines = ["| " + " | ".join(headers) + " |", "|" + "|".join(["---"] * len(headers)) + "|"] + lines.extend("| " + " | ".join(_cell(value) for value in row) + " |" for row in rows) + return lines + + +def render_source_register(data: dict[str, Any]) -> str: + sources = data["sources"] + lines = [ + "# Morocco Official Source Register v0.1", + "", + f"Status: **{data['status']}**", + "", + "Engineering acquisition classifications only; they are not legal opinions.", + "", + "## Sources", + "", + ] + lines += _table( + ["ID", "Title", "Authority", "Lang", "Canonical", "Download", "Translation", "Disposition"], + [ + [ + source["source_id"], + source["complete_title"], + source["issuing_authority"], + source["language"], + source["canonical_url"], + source["download_url"], + source["translation_status"], + source["engineering_disposition"], + ] + for source in sources + ], + ) + lines += ["", "## Acquisition observations", ""] + lines += _table( + ["ID", "Public", "Login", "Robots", "Direct GET", "Human", "Crawl", "Risks", "Unresolved"], + [ + [ + source["source_id"], + source["public_accessibility"], + source["login_requirement"], + source["robots_observation"], + source["one_direct_get_technically_possible"], + source["human_browser_download_available"], + source["automated_crawling_required"], + source["acquisition_risks"], + source["unresolved_issues"], + ] + for source in sources + ], + ) + lines += ["", "## Mission evidence observations", ""] + lines += _table( + [ + "Candidate", + "Consultation", + "Tender artifact", + "Commission artifact", + "Result artifact", + "Observed", + "Bytes", + ], + [ + [ + observation["candidate_id"], + observation["consultation_record_url"], + observation["verified_tender_artifact_url"], + observation["verified_commission_artifact_url"], + observation["verified_result_artifact_url"], + observation["observed_utc"], + observation["bytes_acquired"], + ] + for observation in data["mission_evidence_observations"] + ], + ) + return "\n".join(lines) + "\n" + + +def render_normative_map(data: dict[str, Any]) -> str: + lines = [ + "# Morocco Normative Source Map v0.1", + "", + f"Status: **{data['status']}**", + "", + "No legal meaning or applicability conclusion is expressed.", + "", + "## Map", + "", + ] + lines += _table( + ["ID", "Role", "Authoritative", "Relationship"], + [ + [ + entry["source_id"], + entry["role"], + entry["authoritative_for_semantics"], + entry["relationship"], + ] + for entry in data["entries"] + ], + ) + lines += ["", "## Proposed normative corpus", ""] + [ + f"- {source_id}" for source_id in data["proposed_normative_corpus"] + ] + lines += ["", "## Excluded discovery candidates", ""] + lines += _table( + ["ID", "Reason"], + [ + [entry["source_id"], entry["reason"]] + for entry in data["excluded_from_proposed_normative_corpus"] + ], + ) + lines += ["", "## Unresolved", ""] + [f"- {item}" for item in data["unresolved"]] + return "\n".join(lines) + "\n" + + +def render_candidates(data: dict[str, Any]) -> str: + lines = [ + "# PMP Mission Candidates v0.1", + "", + f"Status: **{data['status']}**", + "", + "No procurement is classified as compliant or non-compliant.", + "", + "## Candidates", + "", + ] + lines += _table( + [ + "ID", + "Reference", + "Buyer", + "Procedure", + "Deadline", + "State", + "Portal", + "Tender artifacts", + "Commission artifacts", + "Result artifacts", + "Gate", + "Disposition", + ], + [ + [ + case["candidate_id"], + case["reference"], + case["public_buyer"], + case["procedure_type"], + case["submission_deadline"], + case["state"], + case["official_portal_url"], + [item["artifact_id"] for item in case["verified_tender_document_artifacts"]], + [ + item["artifact_id"] + for item in case["verified_commission_or_evaluation_artifacts"] + ], + [item["artifact_id"] for item in case["verified_award_or_result_artifacts"]], + "PASS" if case["mandatory_gate"]["eligible"] else "FAIL", + case["engineering_disposition"], + ] + for case in data["candidates"] + ], + ) + lines += ["", "## Verified tender-document artifacts", ""] + lines += _table( + [ + "Candidate", + "Artifact", + "Type", + "Exact official URL", + "Public state", + "Login", + "CAPTCHA", + "Bypass", + "Observed", + "Bytes", + ], + [ + [ + case["candidate_id"], + artifact["artifact_id"], + artifact["artifact_type"], + artifact["exact_official_url"], + artifact["public_accessibility_state"], + artifact["login_required"], + artifact["captcha_required"], + artifact["access_control_bypass_required"], + artifact["observed_utc"], + artifact["bytes_acquired"], + ] + for case in data["candidates"] + for artifact in case["verified_tender_document_artifacts"] + ], + ) + lines += ["", "## Cross-record result lineage", ""] + lines += _table( + [ + "Candidate", + "Linkage", + "Original record", + "Result record", + "Original refConsultation", + "Result refConsultation", + "Reference match", + "Buyer portal ID match", + "Object match", + "Mismatch fields", + "Explicit portal linkage", + "Result", + "Observed", + ], + [ + [ + case["candidate_id"], + case["cross_record_linkage"]["linkage_id"], + case["cross_record_linkage"]["original_consultation_url"], + case["cross_record_linkage"]["result_record_url"], + case["cross_record_linkage"]["original_refConsultation"], + case["cross_record_linkage"]["result_refConsultation"], + case["cross_record_linkage"]["observed_procurement_reference"], + { + "original": case["cross_record_linkage"]["observed_buyer"]["original_record"][ + "portal_organization_acronym" + ], + "result": case["cross_record_linkage"]["observed_buyer"]["result_record"][ + "portal_organization_acronym" + ], + }, + case["cross_record_linkage"]["observed_procurement_object"], + case["cross_record_linkage"]["mismatch_fields"], + case["cross_record_linkage"]["explicit_portal_linkage_field"], + case["cross_record_linkage"]["linkage_result"], + case["cross_record_linkage"]["observed_utc"], + ] + for case in data["candidates"] + if "cross_record_linkage" in case + ], + ) + lines += ["", "## Evidence-derived mandatory gate", ""] + lines += _table( + ["Candidate", "Criterion", "Passed", "Evidence"], + [ + [case["candidate_id"], criterion, result["passed"], result["evidence_refs"]] + for case in data["candidates"] + for criterion, result in case["mandatory_gate"]["criteria"].items() + ], + ) + lines += ["", "## Missing objects", ""] + for case in data["candidates"]: + lines += ( + [f"### {case['candidate_id']} — {case['reference']}", ""] + + [f"- {item}" for item in case["missing_objects"]] + + [""] + ) + return "\n".join(lines).rstrip() + "\n" + + +def render_scorecard(data: dict[str, Any]) -> str: + dimensions = data["dimensions"] + lines = [ + "# Morocco Mission Selection Scorecard v0.1", + "", + "Scores: 0 absent; 1 partial/uncertain; 2 present and official.", + "", + f"Mission status: **{data['mission_selection_status']}**", + "", + f"Proposed mission ID: **{data['proposed_mission_id']}**", + "", + f"Institutional admission: **{data['institutional_admission']}**", + "", + f"Golden mission: **{data['golden_mission_status']}**", + "", + "Cross-repository reconciliation required: " + f"**{_cell(data['cross_repository_reconciliation_required'])}**", + "", + f"Semantic implementation gate: **{data['semantic_implementation_gate']}**", + "", + f"Rule: {data['selection_rule']}", + "", + "## Complete scorecard", + "", + ] + lines += _table( + ["Candidate", *dimensions, "Total", "Mandatory", "Nomination"], + [ + [ + score["candidate_id"], + *score["values"], + score["total"], + score["mandatory_gate_result"], + score["nomination"], + ] + for score in data["scores"] + ], + ) + preferred = data["preferred"] + fallback = data["fallback"] + lines += ["", f"Outcome: **{data['selection_outcome']}**", ""] + lines += [ + ( + f"Preferred: **{preferred['mission_id']} → {preferred['candidate_id']}**" + if preferred is not None + else "Preferred: **none**" + ), + "", + ( + f"Fallback: **{fallback['candidate_id']}**" + if fallback is not None + else "Fallback: **none**" + ), + "", + ] + return "\n".join(lines) + + +def render_constraints(data: dict[str, Any]) -> str: + lines = [ + "# Morocco Acquisition Constraints v0.1", + "", + f"Status: **{data['status']}**", + "", + f"No source bytes acquired: **{_cell(data['no_source_bytes_acquired'])}**", + "", + "## Constraints", + "", + ] + lines += _table( + [ + "Scope", + "Disposition", + "Robots", + "Authentication", + "Visible", + "Direct GET", + "Human", + "Crawl", + "Stability", + "Blockers", + ], + [ + [ + item["scope"], + item["disposition"], + item["robots_observation"], + item["authentication"], + item["visible_download"], + item["direct_get"], + item["human_download"], + item["crawl_required"], + item["stability"], + item["blockers"], + ] + for item in data["constraints"] + ], + ) + lines += ["", "## Prohibited", ""] + [f"- {item}" for item in data["prohibited"]] + return "\n".join(lines) + "\n" + + +def render_decision(data: dict[str, Any]) -> str: + preferred = data["preferred_mission"] + fallback = data["fallback_mission"] + preferred_text = ( + f"{preferred['mission_id']} — {preferred['reference']}" if preferred is not None else "none" + ) + fallback_text = fallback["reference"] if fallback is not None else "none" + return "\n".join( + [ + "# Morocco Preflight Decision v0.1", + "", + f"Status: **{data['status']}**", + "", + f"Exact base: `{data['exact_base']}`", + "", + f"PMP candidates: **{data['pmp_candidate_count']}**", + "", + f"Mission selection: **{data['mission_selection_status']}**", + "", + f"Selection outcome: **{data['mission_selection_outcome']}**", + "", + f"Proposed mission ID: **{data['proposed_mission_id']}**", + "", + f"Institutional admission: **{data['institutional_admission']}**", + "", + f"Golden mission: **{data['golden_mission_status']}**", + "", + "Cross-repository reconciliation required: " + f"**{_cell(data['cross_repository_reconciliation_required'])}**", + "", + f"Preferred: **{preferred_text}**", + "", + f"Fallback: **{fallback_text}**", + "", + data["decision_basis"], + "", + f"No source bytes acquired: **{_cell(data['no_source_bytes_acquired'])}**", + "", + "No tender-document bytes acquired: " + f"**{_cell(data['no_tender_document_bytes_acquired'])}**", + "", + f"No semantic processing: **{_cell(data['no_semantic_processing'])}**", + "", + f"Semantic implementation gate: **{data['semantic_implementation_gate']}**", + "", + "## Owner decisions still required", + "", + *[f"- {item}" for item in data["next_owner_decisions"]], + "", + ] + ) + + +RENDERERS = { + STEMS[0]: render_source_register, + STEMS[1]: render_normative_map, + STEMS[2]: render_candidates, + STEMS[3]: render_scorecard, + STEMS[4]: render_constraints, + STEMS[5]: render_decision, +} + + +def render_all(*, check: bool) -> bool: + clean = True + for stem in STEMS: + rendered = RENDERERS[stem](_load(stem)) + path = PREFLIGHT / f"{stem}.md" + if check: + clean = clean and path.exists() and path.read_text(encoding="utf-8") == rendered + else: + path.write_text(rendered, encoding="utf-8") + return clean + + +def main() -> int: + parser = argparse.ArgumentParser() + parser.add_argument("--check", action="store_true") + args = parser.parse_args() + if not render_all(check=args.check): + print("Morocco preflight Markdown is stale") + return 1 + print("Morocco preflight Markdown is current") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main())