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, resources,
    sample_bundle, tempdir,
};
use forge_pilot::{
    canonical_roundtrip, execute_plan, observe_scope, score_targets, ActionFamily, PilotHistory,
};
use knowledge_runtime::Scope;
use verification_control::{
    CaseRegion, CheckMethod, CheckPlan, PromotionClass, ReversibilityClass, VerificationCase,
    VerificationCaseClass,
};
use verification_policy::{evaluate_policy, PolicySnapshot};

fn method_for_plan(plan: &forge_pilot::PlanKind) -> CheckMethod {
    match plan {
        forge_pilot::PlanKind::OracleExactBounded { .. } => CheckMethod::ExactBoundedOracle,
        forge_pilot::PlanKind::OracleConservative => CheckMethod::ConservativeOracle,
        forge_pilot::PlanKind::OracleDeltaParity { .. } => CheckMethod::DeltaParityOracle,
        forge_pilot::PlanKind::OracleTemporalReplay { .. } => CheckMethod::TemporalReplayOracle,
        forge_pilot::PlanKind::OracleCausalRefuter { .. } => CheckMethod::CausalRefuter,
        forge_pilot::PlanKind::OracleMinimalPerturbation { .. } => {
            CheckMethod::MinimalPerturbationOracle
        }
        forge_pilot::PlanKind::PairedPatch { .. } => CheckMethod::PairedPatch,
        forge_pilot::PlanKind::AdvisoryOnlyVerificationPlan(_) => CheckMethod::AdvisoryOnly,
    }
}

#[tokio::test]
async fn oracle_plan_executes_and_roundtrips_through_canonical_v3_lane() {
    let dir = tempdir();
    let memory_store = open_memory_store(dir.path());
    let forge_store = open_forge_store(dir.path());
    let scope = Scope::new("pilot-oracle");
    let config = base_loop_config(scope.clone());

    import_v3_bundle(
        &memory_store,
        &forge_store,
        &scope.namespace,
        &sample_bundle("oracle-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
        .into_iter()
        .find(|candidate| !matches!(candidate.plan, forge_pilot::PlanKind::PairedPatch { .. }))
        .unwrap();
    let verification_case = VerificationCase::new(
        VerificationCaseClass::ThinExport,
        CaseRegion {
            namespace: scope.namespace.clone(),
            scope_key: Some(config.scope.key()),
            target_key: candidate.stable_key.clone(),
            region_id: None,
            region_digest_id: None,
            claim_version_id: candidate.target.primary_claim_version_id(),
            as_of_recorded_at: None,
        },
        stack_ids::TraceCtx::generate(),
        stack_ids::AttemptId::generate(),
        "2026-03-24T00:00:00Z",
        false,
        false,
    );
    let check_plan = CheckPlan::new(
        verification_case.case_id.clone(),
        method_for_plan(&candidate.plan),
        candidate.plan.check_names(),
        PromotionClass::P2,
        ReversibilityClass::ReversibleScoped,
        true,
        false,
        false,
        "oracle plan test",
        serde_json::json!({"target_key": candidate.stable_key.clone()}),
    );
    let policy_snapshot = PolicySnapshot::permissive("oracle-plan-test", "2026-03-24T00:00:00Z");
    let policy_decision = evaluate_policy(
        &policy_snapshot,
        &verification_case,
        &check_plan,
        &[],
        false,
        false,
    );
    let permit = policy_decision
        .issue_execution_permit(&verification_case, &check_plan, &[])
        .unwrap();

    let action = execute_plan(
        &observation,
        &candidate.stable_key,
        &candidate.plan,
        &permit,
        &config,
    )
    .await
    .unwrap();
    assert_eq!(action.family, ActionFamily::Oracle);

    let roundtrip = canonical_roundtrip(
        action.bundle.as_ref().unwrap(),
        &scope.namespace,
        &resources.forge_store,
        &resources.memory_store,
    )
    .await
    .unwrap();

    assert_eq!(roundtrip.import_result.status, "complete");
}