forge-pilot 0.1.0

Closed-loop orchestrator over runtime advisories, kernel oracles, and canonical Forge export/import lanes
Documentation
mod common;

use common::{
    base_loop_config, import_v3_bundle, open_forge_store, open_memory_store, point_config_at_dir,
    resources, sample_bundle, tempdir, write_source_file,
};
use forge_pilot::{
    observe_scope, score_targets, CanonicalCaseClass, LawfulStepKind, LoopRunner, PilotHistory,
    TargetKind,
};
use knowledge_runtime::Scope;

#[tokio::test]
async fn target_taxonomy_normalizes_to_canonical_case_classes() {
    assert_eq!(
        TargetKind::ActiveSyndrome {
            signature: "sig".into()
        }
        .canonical_case_class(),
        CanonicalCaseClass::ContradictionInvestigation
    );
    assert_eq!(
        TargetKind::ThinExport {
            marker: "thin".into()
        }
        .canonical_case_class(),
        CanonicalCaseClass::ThinExportGap
    );
    assert_eq!(
        TargetKind::ScopeStale {
            last_import_at: None
        }
        .canonical_case_class(),
        CanonicalCaseClass::ScopeFreshness
    );
}

#[tokio::test]
async fn decision_audit_records_cheapest_and_blocked_steps_deterministically() {
    let dir = tempdir();
    let memory_store = open_memory_store(dir.path());
    let forge_store = open_forge_store(dir.path());
    let scope = Scope::new("pilot-normalization-audit");
    let mut config = base_loop_config(scope.clone());
    point_config_at_dir(&mut config, dir.path());
    write_source_file(
        dir.path(),
        "src/lib.rs",
        "pub fn audit_fixture() -> bool { true }\n",
    );

    import_v3_bundle(
        &memory_store,
        &forge_store,
        &scope.namespace,
        &sample_bundle("audit-1"),
    )
    .await;

    let resources = resources(memory_store, forge_store, &config);
    let observation = observe_scope(&resources.runtime, &resources.memory_store, &config)
        .await
        .unwrap();
    let candidates = score_targets(&observation, &PilotHistory::default(), &config);
    let candidate = candidates.first().unwrap();
    let audit = forge_pilot::decide::build_decision_audit(candidate);

    assert!(audit.cheapest_admissible.is_some());
    assert!(audit
        .fallback_steps
        .iter()
        .all(|step| step.step_kind >= audit.cheapest_admissible.unwrap()));
    assert!(audit
        .blocked_steps
        .iter()
        .all(|blocked| !blocked.reason.is_empty()));
}

#[tokio::test]
async fn loop_iteration_report_carries_normalization_and_lineage_receipts() {
    let dir = tempdir();
    let memory_store = open_memory_store(dir.path());
    let forge_store = open_forge_store(dir.path());
    let scope = Scope::new("pilot-normalization-loop");
    let mut config = base_loop_config(scope.clone());
    point_config_at_dir(&mut config, dir.path());
    write_source_file(
        dir.path(),
        "src/lib.rs",
        "pub fn loop_fixture() -> bool { true }\n",
    );

    import_v3_bundle(
        &memory_store,
        &forge_store,
        &scope.namespace,
        &sample_bundle("loop-normalized"),
    )
    .await;

    let resources = resources(memory_store, forge_store, &config);
    let mut runner = LoopRunner::new(config, resources);
    let report = runner.run().await.unwrap();
    let iteration = &report.iterations[0];

    assert!(iteration.target_normalization.is_some());
    assert!(iteration.decision_audit.is_some());
    assert!(iteration.lineage_receipt.is_some());
    assert!(iteration.export_trace.is_some());
    assert!(iteration.stop_rule_evaluation.is_some());
    assert!(matches!(
        iteration
            .decision_audit
            .as_ref()
            .unwrap()
            .cheapest_admissible,
        Some(
            LawfulStepKind::ContractSchemaCheck
                | LawfulStepKind::ProvenanceReceiptAudit
                | LawfulStepKind::TemporalConsistencyCheck
                | LawfulStepKind::ExactReplay
                | LawfulStepKind::PairedComparativeCheck
                | LawfulStepKind::ExactOracleSlice
                | LawfulStepKind::ConservativeOracleSlice
                | LawfulStepKind::MinimalPerturbationRefuter
                | LawfulStepKind::NuisanceComparabilityAudit
                | LawfulStepKind::HumanReviewRequest
                | LawfulStepKind::CanonicalExportRequest
                | LawfulStepKind::CanonicalImportRequest
        )
    ));
}