mirror of
https://github.com/HKUDS/OpenSpace.git
synced 2026-08-28 05:15:00 +00:00
189 lines
7.1 KiB
Python
189 lines
7.1 KiB
Python
from datetime import datetime
|
|
|
|
from openspace.skill_engine.decision.analysis_adapter import AnalyzerDecisionAdapter
|
|
from openspace.skill_engine.evidence.types import (
|
|
EvidencePacket,
|
|
EvidenceScope,
|
|
PacketBudget,
|
|
ResourceRef,
|
|
)
|
|
from openspace.skill_engine.evolution.admission import EvolutionAdmission
|
|
from openspace.skill_engine.types import (
|
|
CaptureContract,
|
|
EvolutionSuggestion,
|
|
EvolutionType,
|
|
ExecutionAnalysis,
|
|
)
|
|
|
|
|
|
def test_incomplete_task_can_capture_a_validated_subworkflow() -> None:
|
|
packet = _packet(status="error", validation_status="success")
|
|
analysis = _analysis(task_completed=False, with_contract=True)
|
|
|
|
decisions = AnalyzerDecisionAdapter().from_analysis(analysis, packet)
|
|
|
|
assert len(decisions) == 1
|
|
assert decisions[0].proposed_action == "CAPTURED"
|
|
assert decisions[0].proposal_contract["capability"]
|
|
assert decisions[0].evidence_claims[0].refs == ["tool:procedure"]
|
|
assert decisions[0].evidence_claims[1].refs == ["tool:validation"]
|
|
|
|
|
|
def test_completed_task_without_capture_contract_is_not_captured() -> None:
|
|
packet = _packet(status="success", validation_status="success")
|
|
analysis = _analysis(task_completed=True, with_contract=False)
|
|
|
|
decisions = AnalyzerDecisionAdapter().from_analysis(analysis, packet)
|
|
|
|
assert len(decisions) == 1
|
|
assert decisions[0].proposed_action == "NOOP"
|
|
assert decisions[0].noop_reason == "missing_capture_contract"
|
|
|
|
|
|
def test_qemu_launch_with_failed_login_validation_is_not_captured() -> None:
|
|
packet = _packet(status="success", validation_status="error")
|
|
analysis = _analysis(task_completed=True, with_contract=True)
|
|
|
|
decisions = AnalyzerDecisionAdapter().from_analysis(analysis, packet)
|
|
|
|
assert len(decisions) == 1
|
|
assert decisions[0].proposed_action == "NOOP"
|
|
assert decisions[0].noop_reason == "capture_validation_failed"
|
|
|
|
|
|
def test_video_output_without_independent_validation_is_not_captured() -> None:
|
|
packet = _packet(status="success", validation_status="success")
|
|
analysis = _analysis(task_completed=True, with_contract=True)
|
|
contract = analysis.evolution_suggestions[0].capture_contract
|
|
assert contract is not None
|
|
contract.validation_refs = []
|
|
|
|
decisions = AnalyzerDecisionAdapter().from_analysis(analysis, packet)
|
|
|
|
assert decisions[0].proposed_action == "NOOP"
|
|
assert decisions[0].noop_reason == "missing_validation_refs"
|
|
|
|
|
|
def test_polyglot_write_plus_separate_compile_run_check_is_admitted() -> None:
|
|
packet = _packet(status="success", validation_status="success")
|
|
analysis = _analysis(task_completed=True, with_contract=True)
|
|
decision = AnalyzerDecisionAdapter().from_analysis(analysis, packet)[0]
|
|
|
|
admission = EvolutionAdmission().admit(decision, packet)
|
|
|
|
assert decision.proposed_action == "CAPTURED"
|
|
assert admission.outcome == "direct"
|
|
assert admission.source_validation_passed is True
|
|
|
|
|
|
def test_procedure_and_validation_must_use_distinct_refs() -> None:
|
|
packet = _packet(status="success", validation_status="success")
|
|
analysis = _analysis(task_completed=True, with_contract=True)
|
|
analysis.evolution_suggestions[0].capture_contract.validation_refs = [
|
|
"tool:procedure"
|
|
]
|
|
|
|
decisions = AnalyzerDecisionAdapter().from_analysis(analysis, packet)
|
|
|
|
assert decisions[0].proposed_action == "NOOP"
|
|
assert decisions[0].noop_reason == "procedure_validation_refs_overlap"
|
|
|
|
|
|
def test_event_and_result_from_same_tool_call_are_not_independent_validation() -> None:
|
|
packet = _packet(status="success", validation_status="success")
|
|
packet.selected_refs["tool_event"][0].metadata["tool_use_id"] = "call_one"
|
|
packet.selected_refs["tool_event"][1].metadata["tool_use_id"] = "call_one"
|
|
analysis = _analysis(task_completed=True, with_contract=True)
|
|
|
|
decisions = AnalyzerDecisionAdapter().from_analysis(analysis, packet)
|
|
|
|
assert decisions[0].proposed_action == "NOOP"
|
|
assert decisions[0].noop_reason == "procedure_validation_observation_overlap"
|
|
|
|
|
|
def test_no_analyzer_suggestion_has_no_generic_capture_fallback() -> None:
|
|
packet = _packet(status="success", validation_status="success")
|
|
analysis = ExecutionAnalysis(
|
|
task_id="task_test",
|
|
timestamp=datetime.now(),
|
|
task_completed=True,
|
|
execution_note="Task completed successfully.",
|
|
evolution_suggestions=[],
|
|
)
|
|
|
|
assert AnalyzerDecisionAdapter().from_analysis(analysis, packet) == []
|
|
|
|
|
|
def _analysis(*, task_completed: bool, with_contract: bool) -> ExecutionAnalysis:
|
|
return ExecutionAnalysis(
|
|
task_id="task_test",
|
|
timestamp=datetime.now(),
|
|
task_completed=task_completed,
|
|
execution_note="The overall task may be incomplete, but extraction passed.",
|
|
evolution_suggestions=[
|
|
EvolutionSuggestion(
|
|
evolution_type=EvolutionType.CAPTURED,
|
|
direction="Capture only the validated extraction subworkflow.",
|
|
capture_contract=(
|
|
CaptureContract(
|
|
capability="Extract one file and verify its bytes.",
|
|
preconditions=["The input archive is readable."],
|
|
procedure_refs=["tool:procedure"],
|
|
validation_refs=["tool:validation"],
|
|
validation_summary=(
|
|
"A separate checksum command matched the expected bytes."
|
|
),
|
|
limitations=["No evidence covers encrypted archives."],
|
|
)
|
|
if with_contract
|
|
else None
|
|
),
|
|
)
|
|
],
|
|
)
|
|
|
|
|
|
def _packet(*, status: str, validation_status: str) -> EvidencePacket:
|
|
return EvidencePacket(
|
|
packet_id="pkt_test",
|
|
trigger_job_id="trg_test",
|
|
packet_type="analysis",
|
|
profile_name="analysis_current_task",
|
|
subprofile="task_finished",
|
|
manifest_watermark=1,
|
|
scope=EvidenceScope(source_task_ids=("task_test",)),
|
|
selected_refs={
|
|
"runtime_snapshot": [
|
|
ResourceRef(
|
|
ref_id="runtime:finish",
|
|
ref_type="runtime_snapshot",
|
|
preview="Runtime status.",
|
|
metadata={"status": status},
|
|
)
|
|
],
|
|
"tool_event": [
|
|
ResourceRef(
|
|
ref_id="tool:procedure",
|
|
ref_type="tool_event",
|
|
preview="Wrote the extracted bytes.",
|
|
metadata={"tool_name": "bash", "status": "success"},
|
|
),
|
|
ResourceRef(
|
|
ref_id="tool:validation",
|
|
ref_type="tool_event",
|
|
preview="Checked the extracted checksum.",
|
|
metadata={
|
|
"tool_name": "bash",
|
|
"status": validation_status,
|
|
},
|
|
),
|
|
],
|
|
},
|
|
expanded_snippets=[],
|
|
readable_paths=[],
|
|
instructions={},
|
|
budget=PacketBudget(max_chars=0, used_chars=0),
|
|
redaction_status="ok",
|
|
build_status="ok",
|
|
missing_ref_types=[],
|
|
)
|